commit 3a164ae699b2676a6648622fd4be2d427ca8e587 (HEAD -> master, origin/master, origin/HEAD)
Merge: dcfd089 cb95be3
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 9 10:35:38 2017 +0100

    Merge pull request #682 from walles/walles/unused
    
    Re-enable some Unused warnings

commit cb95be3d87edc40f7bb4a7502d989803f33f500a (walles/walles/unused, walles/unused)
Author: Johan Walles <johan.walles@gmail.com>
Date:   Wed Mar 8 21:52:57 2017 +0100

    Disable an unused Lint rule

diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 71a7793..e8fe111 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -20,7 +20,6 @@
     <issue id="GoogleAppIndexingWarning" severity="ignore" />
     <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
-    <issue id="IconExpectedSize" severity="ignore" />
     <issue id="IconLocation" severity="ignore" />
     <issue id="IconMissingDensityFolder" severity="ignore" />
     <issue id="InefficientWeight" severity="ignore" />

commit dcfd0893a07e7703aeb5fb61a9affb0b5f3f6c87 (walles/checks)
Merge: 0303e7d a20852c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 8 21:52:00 2017 +0100

    Merge pull request #681 from liato/feature/upgrade-build-tools
    
    Upgrade android build tools

commit 11f299972fdd6154872c68aebc4947eb816d3551
Author: Johan Walles <johan.walles@gmail.com>
Date:   Wed Mar 8 21:47:56 2017 +0100

    Re-enable some Unused warnings
    
    Before Android Studio 2.3.0 having these enabled triggered internal
    errors in Lint. Those errors have now been fixed and the checks can be
    re-enabled.

diff --git bankdroid-legacy/src/main/res/values-sv/strings.xml bankdroid-legacy/src/main/res/values-sv/strings.xml
index 36f71c5..e3f6dfa 100644
--- bankdroid-legacy/src/main/res/values-sv/strings.xml
+++ bankdroid-legacy/src/main/res/values-sv/strings.xml
@@ -2,16 +2,12 @@
     <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
     <string name="card_number">Kortnummer</string>
-    <string name="account_number">Kontonummer</string>
-    <string name="control_code">Kontrollkod</string>
     <string name="email">E-post</string>
     <string name="points">poäng</string>
     <string name="card_id">Kort ID</string>
     <string name="balance">Saldo</string>
     <string name="pno">ÅÅÅÅMMDDNNNN</string>
 
-    <string name="nordnetdirekt_extras_title">Nyckel</string>
-
     <string name="bitcoin_address">Bitcoin-adress</string>
     <string name="invalid_bitcoin_address">Ogiltig bitcoin-adress.</string>
     <string name="public_pension">Allmän pension</string>
@@ -24,7 +20,6 @@
     <string name="no_accounts_found">Inga konton funna</string>
     <string name="invalid_username">Ogiltigt användarnamn.</string>
     <string name="invalid_card_number">Ogiltigt kortnummer.</string>
-    <string name="bank_closed">Banken är för närvarande stängd.</string>
     <string name="server_error_try_again">Serverfel. Var god försök igen om en stund.</string>
     <string name="update_transactions_error">Kunde ej uppdatera transaktionsdata. Var vänlig försök igen senare.</string>
 </resources>
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
index a80426d..89167f4 100644
--- bankdroid-legacy/src/main/res/values/strings.xml
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -5,16 +5,12 @@
     <string name="password">Password</string>
     <string name="extras_field">Extras</string>
     <string name="card_number">Card number</string>
-    <string name="account_number">Account number</string>
-    <string name="control_code">Control code</string>
     <string name="email">E-mail</string>
     <string name="points">points</string>
     <string name="card_id">Card ID</string>
     <string name="balance">Balance</string>
     <string name="pno">YYYYMMDDNNNN</string>
 
-    <string name="nordnetdirekt_extras_title">Key</string>
-
     <string name="bitcoin_address">Bitcoin address</string>
     <string name="invalid_bitcoin_address">Invalid bitcoin address.</string>
     <string name="public_pension">Public pension</string>
@@ -27,7 +23,6 @@
     <string name="no_accounts_found">No accounts found</string>
     <string name="invalid_username">Invalid username.</string>
     <string name="invalid_card_number">Invalid card number.</string>
-    <string name="bank_closed">The bank is currently closed.</string>
     <string name="server_error_try_again">Server error. Please try again later.</string>
     <string name="update_transactions_error">"There was a problem updating the transaction details. Please try again later."</string>
 
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index c3565a5..71a7793 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -47,8 +47,6 @@
     <issue id="TrulyRandom" severity="ignore" />
     <issue id="UnknownIdInLayout" severity="ignore" />
     <issue id="UnusedAttribute" severity="ignore" />
-    <issue id="UnusedIds" severity="ignore" />
-    <issue id="UnusedResources" severity="ignore" />
     <issue id="UseCompoundDrawables" severity="ignore" />
     <issue id="UselessParent" severity="ignore" />
     <issue id="WorldReadableFiles" severity="ignore" />

commit a20852c17d74128d8071b7e6139115794d09cbe2 (origin/feature/upgrade-build-tools, feature/upgrade-build-tools)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 2 21:40:58 2017 +0100

    Fixes travis build

diff --git .travis.yml .travis.yml
index 6c53f33..dadb73b 100644
--- .travis.yml
+++ .travis.yml
@@ -10,14 +10,14 @@ cache:
 
 env:
   matrix:
-    - ANDROID_TARGET=android-24  ANDROID_ABI=armeabi-v7a
+    - ANDROID_TARGET=android-25  ANDROID_ABI=armeabi-v7a
 
 android:
   components:
     - tools
     - platform-tools
-    - build-tools-24.0.3
-    - android-24
+    - build-tools-25.0.1
+    - android-25
     - extra-android-m2repository
 
 script: ./gradlew assembleDebug check

commit e6e1e4fdec9bf27aadef0d5c22d35a56c2253708
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 2 21:33:49 2017 +0100

    Upgrade android build tools

diff --git app/build.gradle app/build.gradle
index 11832d8..f73b061 100644
--- app/build.gradle
+++ app/build.gradle
@@ -38,14 +38,14 @@ ext {
 }
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "24.0.3"
+    compileSdkVersion 25
+    buildToolsVersion "25.0.1"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
-        targetSdkVersion 24
+        targetSdkVersion 25
         versionCode 224 + gitVersionCode
         versionName gitVersionName
     }
@@ -87,7 +87,7 @@ dependencies {
     compile project(':bankdroid-core')
     compile 'com.jakewharton:butterknife:6.1.0'
     compile 'com.jakewharton.timber:timber:4.3.1'
-    compile "com.android.support:appcompat-v7:24.2.1"
+    compile "com.android.support:appcompat-v7:25.2.0"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
         transitive = true;
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 98c8a2b..78d7ff8 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -59,7 +59,7 @@ public class MainActivity extends LockableActivity {
 
     protected static boolean showHidden = false;
 
-    private static Bank selectedBank = null;
+    private Bank selectedBank = null;
 
     private static Account selectedAccount = null;
 
@@ -241,7 +241,7 @@ public class MainActivity extends LockableActivity {
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnWWW = (Button) root.findViewById(R.id.btnWWW);
-            if (selectedBank.getHideAccounts()) {
+            if (parent.selectedBank.getHideAccounts()) {
                 btnHide.setVisibility(View.GONE);
                 btnUnhide.setVisibility(View.VISIBLE);
                 btnUnhide.setOnClickListener(this);
@@ -250,7 +250,7 @@ public class MainActivity extends LockableActivity {
                 btnUnhide.setVisibility(View.GONE);
                 btnHide.setOnClickListener(this);
             }
-            if (selectedBank.isWebViewEnabled()) {
+            if (parent.selectedBank.isWebViewEnabled()) {
                 btnWWW.setOnClickListener(this);
             } else {
                 btnWWW.setVisibility(View.GONE);
@@ -270,29 +270,29 @@ public class MainActivity extends LockableActivity {
                 case R.id.btnHide:
                 case R.id.btnUnhide:
                     this.dismiss();
-                    selectedBank.toggleHideAccounts();
-                    DBAdapter.save(selectedBank, context);
+                    parent.selectedBank.toggleHideAccounts();
+                    DBAdapter.save(parent.selectedBank, context);
                     parent.refreshView();
                     return;
                 case R.id.btnWWW:
-                    if (selectedBank != null && selectedBank.isWebViewEnabled()) {
+                    if (parent.selectedBank != null && parent.selectedBank.isWebViewEnabled()) {
                         //Uri uri = Uri.parse(selectedBank.getURL());
                         //Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                         final Intent intent = new Intent(context, WebViewActivity.class);
-                        intent.putExtra("bankid", selectedBank.getDbId());
+                        intent.putExtra("bankid", parent.selectedBank.getDbId());
                         context.startActivity(intent);
                     }
                     this.dismiss();
                     return;
                 case R.id.btnEdit:
                     final Intent intent = new Intent(context, BankEditActivity.class);
-                    intent.putExtra("id", selectedBank.getDbId());
+                    intent.putExtra("id", parent.selectedBank.getDbId());
                     context.startActivity(intent);
                     this.dismiss();
                     return;
                 case R.id.btnRefresh:
                     this.dismiss();
-                    new DataRetrieverTask(parent, selectedBank.getDbId()).execute();
+                    new DataRetrieverTask(parent, parent.selectedBank.getDbId()).execute();
                     return;
                 case R.id.btnRemove:
                     this.dismiss();
@@ -307,7 +307,7 @@ public class MainActivity extends LockableActivity {
                                         public void onClick(final DialogInterface dialog,
                                                 final int id) {
                                             final DBAdapter db = new DBAdapter(context);
-                                            db.deleteBank(selectedBank.getDbId());
+                                            db.deleteBank(parent.selectedBank.getDbId());
                                             dialog.cancel();
                                             parent.refreshView();
                                         }
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index 4d1ce55..80b12c7 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -154,7 +154,7 @@ public class FieldBuilder {
 
         @Override
         public void validate(String value) throws IllegalArgumentException {
-            if (isRequired()) {
+            if (required) {
                 if (value == null || value.trim().isEmpty()) {
                     throw new IllegalArgumentException(String.format("%s is required", getLabel()));
                 }
@@ -168,7 +168,7 @@ public class FieldBuilder {
             if (!isLocale()) {
                 return null;
             }
-            String propertyKey = String.format("field.%s.%s", getReference(), key);
+            String propertyKey = String.format("field.%s.%s", reference, key);
             return resourceBundle.containsKey(propertyKey) ? resourceBundle.getString(propertyKey)
                     : propertyKey;
         }
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index 2cda778..e9b4290 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -2,13 +2,13 @@ apply plugin: 'com.android.library'
 apply from: '../config/quality/quality.gradle'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "24.0.3"
+    compileSdkVersion 25
+    buildToolsVersion "25.0.1"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
         minSdkVersion 9
-        targetSdkVersion 24
+        targetSdkVersion 25
         versionCode 1
         versionName "1.0"
     }
@@ -27,7 +27,7 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-interface')
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    compile 'com.android.support:appcompat-v7:25.2.0'
     compile 'com.jakewharton.timber:timber:4.3.1'
     compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'}
     compile 'org.jsoup:jsoup:1.7.3'
diff --git build.gradle build.gradle
index 76cbdfb..bf6f81e 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.2.3'
+        classpath 'com.android.tools.build:gradle:2.3.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -30,5 +30,5 @@ subprojects {
 }
 
 task wrapper(type: Wrapper) {
-    gradleVersion = '3.1'
+    gradleVersion = '3.3'
 }
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 8893515..382630b 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Sep 29 21:09:55 CEST 2016
+#Thu Mar 02 21:11:13 CET 2017
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip

commit 0303e7dbb40f21d278fa7aad7274430f4a871183
Merge: 3c25a39 a08f401
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 25 20:49:34 2017 +0100

    Merge pull request #680 from liato/feature/remove-avanza
    
    Remove support for Avanza and Avanza mini

commit a08f401c4d0b53cbbac74aaadd5527f847ccbee0
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 22 22:18:58 2017 +0100

    Remove support for Avanza and Avnza mini

diff --git CHANGELOG CHANGELOG
index 6995d6b..53ddb44 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 (Unreleased)
 * Update certificates
+* Remove support for Avanza and Avanza Mini
 
 v1.9.14 (2017-01-06)
 * Updated certificates for First Card, Osuuspankki and Östgötatrafiken
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index f95ef32..2bdf551 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -4,7 +4,6 @@ import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.americanexpress.AmericanExpress;
 import com.liato.bankdroid.banking.banks.AppeakPoker;
-import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
@@ -36,7 +35,6 @@ import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.TicketRikskortet;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
 import com.liato.bankdroid.banking.banks.Zidisha;
-import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
 import com.liato.bankdroid.banking.banks.coop.Coop;
 import com.liato.bankdroid.banking.banks.ica.ICA;
@@ -71,10 +69,6 @@ public class LegacyBankFactory {
                 return new Coop(context);
             case IBankTypes.ICA:
                 return new ICA(context);
-            case IBankTypes.AVANZA:
-                return new Avanza(context);
-            case IBankTypes.AVANZAMINI:
-                return new AvanzaMini(context);
             case IBankTypes.OKQ8:
                 return new OKQ8(context);
             case IBankTypes.FIRSTCARD:
@@ -157,8 +151,6 @@ public class LegacyBankFactory {
         banks.add(new Lansforsakringar(context));
         banks.add(new Coop(context));
         banks.add(new ICA(context));
-        banks.add(new Avanza(context));
-        banks.add(new AvanzaMini(context));
         banks.add(new OKQ8(context));
         banks.add(new FirstCard(context));
         banks.add(new Payson(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
deleted file mode 100644
index 5f7889b..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.banks.avanza.Avanza;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-public class AvanzaMini extends Avanza {
-
-    public AvanzaMini(Context context) {
-        super(context, R.drawable.logo_avanzamini);
-        url = "https://www.avanza.se/mini/hem/";
-    }
-
-    @Override
-    public int getBanktypeId() {
-        return IBankTypes.AVANZAMINI;
-    }
-
-    @Override
-    public String getName() {
-        return "Avanza Mini";
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
deleted file mode 100644
index 3d3aa64..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks.avanza;
-
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.banks.avanza.model.AccountOverview;
-import com.liato.bankdroid.banking.banks.avanza.model.Position;
-import com.liato.bankdroid.banking.banks.avanza.model.PositionAggregation;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-import com.liato.bankdroid.utils.StringUtils;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.content.Context;
-import android.support.annotation.DrawableRes;
-import android.util.Base64;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Avanza extends Bank {
-
-    private static final String API_URL = "https://iphone.avanza.se/iphone-ws/";
-
-    protected Avanza(Context context, @DrawableRes int logoResource) {
-        super(context, logoResource);
-        url = "https://iphone.avanza.se";
-    }
-
-    @Override
-    public int getBanktypeId() {
-        return IBankTypes.AVANZA;
-    }
-
-    @Override
-    public String getName() {
-        return "Avanza";
-    }
-
-    public Avanza(Context context) {
-        this(context, R.drawable.logo_avanza);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_avanza));
-        urlopen.addHeader("Referer", url + "/start");
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("j_username", getUsername()));
-        postData.add(new BasicNameValuePair("j_password", getPassword()));
-        postData.add(new BasicNameValuePair("url", url + "/start"));
-        String response = urlopen.open(url + "/ab/handlelogin", postData);
-        String homeUrl = "";
-        try {
-            JSONObject jsonResponse = new JSONObject(response);
-            homeUrl = jsonResponse.getString("redirectUrl");
-        } catch (JSONException e) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " login link.", e);
-        }
-        LoginPackage lp = new LoginPackage(urlopen, postData, "", url + homeUrl);
-        lp.setIsLoggedIn(true);
-        return lp;
-    }
-
-    public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_avanza));
-        urlopen.addHeader("ctag", "1122334455");
-        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
-                StringUtils.getBytes(getUsername() + ":" + getPassword()), Base64.NO_WRAP));
-        balance = new BigDecimal(0);
-
-        try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all",
-                    new ArrayList<NameValuePair>(), false);
-            if (httpResponse.getStatusLine().getStatusCode() == 401) {
-                throw new LoginException(context.getText(
-                        R.string.invalid_username_password).toString());
-            }
-            ObjectMapper vObjectMapper = new ObjectMapper();
-            AccountOverview r = vObjectMapper.readValue(httpResponse.getEntity().getContent(),
-                    AccountOverview.class);
-            for (com.liato.bankdroid.banking.banks.avanza.model.Account account : r.getAccounts()) {
-                Account a = new Account(account.getAccountName(),
-                        new BigDecimal(account.getOwnCapital()), account.getAccountId());
-                if (!account.getCurrencyAccounts().isEmpty()) {
-                    a.setCurrency(account.getCurrencyAccounts().get(0).getCurrency());
-                }
-                if (!account.getPositionAggregations().isEmpty()) {
-                    Date now = new Date();
-                    ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account
-                            .getCurrencyAccounts()) {
-                        transactions.add(new Transaction(Helpers.formatDate(now),
-                                "\u2014  " + currencyAccount.getCurrency() + "  \u2014",
-                                BigDecimal.valueOf(currencyAccount.getBalance()),
-                                currencyAccount.getCurrency()));
-                    }
-                    for (PositionAggregation positionAgList : account.getPositionAggregations()) {
-                        if (positionAgList.getPositions().isEmpty()) {
-                            continue;
-                        }
-                        List<Position> positions = positionAgList.getPositions();
-                        transactions.add(new Transaction(Helpers.formatDate(now),
-                                "\u2014  " + positionAgList.getInstrumentTypeName() +
-                                        "  " + positionAgList.getTotalProfitPercent() + "%  \u2014",
-                                BigDecimal.valueOf(positionAgList.getTotalValue()),
-                                a.getCurrency()));
-                        for (Position p : positions) {
-                            Transaction t = new Transaction(Helpers.formatDate(now),
-                                    p.getInstrumentName(),
-                                    BigDecimal.valueOf(p.getProfit()),
-                                    a.getCurrency());
-                            transactions.add(t);
-                        }
-                    }
-                    a.setTransactions(transactions);
-                }
-                balance = balance.add(a.getBalance());
-                accounts.add(a);
-                // Add subtypes for account as own account.
-                if (!account.getPositionAggregations().isEmpty()) {
-                    Date now = new Date();
-                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account
-                            .getCurrencyAccounts()) {
-                        Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
-                                currencyAccount.getCurrency(),
-                                new BigDecimal(currencyAccount.getBalance()),
-                                account.getAccountId() + currencyAccount.getCurrency(),
-                                Account.OTHER,
-                                currencyAccount.getCurrency());
-                        b.setHidden(true);
-                        accounts.add(b);
-                    }
-                    for (PositionAggregation positionAgList : account.getPositionAggregations()) {
-                        if (positionAgList.getPositions().isEmpty()) {
-                            continue;
-                        }
-                        Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
-                                positionAgList.getInstrumentTypeName() +
-                                "  " + positionAgList.getTotalProfitPercent() + "% ",
-                                new BigDecimal(positionAgList.getTotalValue()),
-                                account.getAccountId() + positionAgList.getInstrumentTypeName(),
-                                Account.OTHER, a.getCurrency());
-                        b.setHidden(true);
-                        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                        for (Position p : positionAgList.getPositions()) {
-                            transactions.add(new Transaction(Helpers.formatDate(now),
-                                    p.getInstrumentName(),
-                                    BigDecimal.valueOf(p.getProfit()),
-                                    a.getCurrency()));
-                        }
-                        b.setTransactions(transactions);
-                        accounts.add(b);
-                    }
-                }
-            }
-        } catch (JsonParseException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException,
-            BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(
-                    R.string.invalid_username_password).toString());
-        }
-        login();
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
deleted file mode 100644
index 114b003..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package com.liato.bankdroid.banking.banks.avanza.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-
-public class Account implements Serializable {
-
-    private static final long serialVersionUID = -5718585872348469144L;
-
-    @JsonProperty("balance")
-    private double mBalance;
-
-    @JsonProperty("totalProfit")
-    private double mTotalProfit;
-
-    @JsonProperty("accountName")
-    private String mAccountName;
-
-    @JsonProperty("totalAccruedInterest")
-    private double mTotalAccruedInterest;
-
-    @JsonProperty("adjustedForwardAmount")
-    private double mAdjustedForwardAmount;
-
-    @JsonProperty("unUsedCredit")
-    private double mUnUsedCredit;
-
-    @JsonProperty("superInterest")
-    private double mSuperInterest;
-
-    @JsonProperty("totalMarginRequirement")
-    private double mTotalMarginRequirement;
-
-    @JsonProperty("tradingPower")
-    private double mTradingPower;
-
-    @JsonProperty("resAmount")
-    private double mResAmount;
-
-    @JsonProperty("loanAmount")
-    private double mLoanAmount;
-
-    @JsonProperty("accountId")
-    private String mAccountId;
-
-    @JsonProperty("currencyAccounts")
-    private List<CurrencyAccount> mCurrencyAccounts = Collections.emptyList();
-
-    @JsonProperty("creditLimit")
-    private double mCreditLimit;
-
-    @JsonProperty("totalProfitPercent")
-    private double mTotalProfitPercent;
-
-    @JsonProperty("ownCapital")
-    private double mOwnCapital;
-
-    @JsonProperty("totalValue")
-    private double mTotalValue;
-
-    @JsonProperty("interestAmount")
-    private double mInterestAmount;
-
-    @JsonProperty("secAmount")
-    private double mSecAmount;
-
-    @JsonProperty("positionAggregations")
-    private List<PositionAggregation> mPositionAggregations = Collections.emptyList();
-
-
-    @JsonProperty("balance")
-    public double getBalance() {
-        return mBalance;
-    }
-
-    @JsonProperty("totalProfit")
-    public double getTotalProfit() {
-        return mTotalProfit;
-    }
-
-    @JsonProperty("accountName")
-    public String getAccountName() {
-        return mAccountName;
-    }
-
-    @JsonProperty("totalAccruedInterest")
-    public double getTotalAccruedInterest() {
-        return mTotalAccruedInterest;
-    }
-
-    @JsonProperty("adjustedForwardAmount")
-    public double getAdjustedForwardAmount() {
-        return mAdjustedForwardAmount;
-    }
-
-    @JsonProperty("unUsedCredit")
-    public double getUnUsedCredit() {
-        return mUnUsedCredit;
-    }
-
-    @JsonProperty("superInterest")
-    public double getSuperInterest() {
-        return mSuperInterest;
-    }
-
-    @JsonProperty("totalMarginRequirement")
-    public double getTotalMarginRequirement() {
-        return mTotalMarginRequirement;
-    }
-
-    @JsonProperty("tradingPower")
-    public double getTradingPower() {
-        return mTradingPower;
-    }
-
-    @JsonProperty("resAmount")
-    public double getResAmount() {
-        return mResAmount;
-    }
-
-    @JsonProperty("loanAmount")
-    public double getLoanAmount() {
-        return mLoanAmount;
-    }
-
-    @JsonProperty("accountId")
-    public String getAccountId() {
-        return mAccountId;
-    }
-
-    @JsonProperty("currencyAccounts")
-    public List<CurrencyAccount> getCurrencyAccounts() {
-        return mCurrencyAccounts;
-    }
-
-    @JsonProperty("creditLimit")
-    public double getCreditLimit() {
-        return mCreditLimit;
-    }
-
-    @JsonProperty("totalProfitPercent")
-    public double getTotalProfitPercent() {
-        return mTotalProfitPercent;
-    }
-
-    @JsonProperty("ownCapital")
-    public double getOwnCapital() {
-        return mOwnCapital;
-    }
-
-    @JsonProperty("totalValue")
-    public double getTotalValue() {
-        return mTotalValue;
-    }
-
-    @JsonProperty("interestAmount")
-    public double getInterestAmount() {
-        return mInterestAmount;
-    }
-
-    @JsonProperty("secAmount")
-    public double getSecAmount() {
-        return mSecAmount;
-    }
-
-    @JsonProperty("positionAggregations")
-    public List<PositionAggregation> getPositionAggregations() {
-        return mPositionAggregations;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
deleted file mode 100644
index 19ac97f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.liato.bankdroid.banking.banks.avanza.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-
-public class AccountOverview implements Serializable {
-
-    private static final long serialVersionUID = -5511775495529857976L;
-
-    @JsonProperty("totalOwnCapital")
-    private float mTotalOwnCapital;
-
-    @JsonProperty("accounts")
-    private List<Account> mAccounts = Collections.emptyList();
-
-
-    @JsonProperty("totalOwnCapital")
-    public float getTotalOwnCapital() {
-        return mTotalOwnCapital;
-    }
-
-    @JsonProperty("accounts")
-    public List<Account> getAccounts() {
-        return mAccounts;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
deleted file mode 100644
index 76cf0b6..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.liato.bankdroid.banking.banks.avanza.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class CurrencyAccount implements Serializable {
-
-    private static final long serialVersionUID = 6004713686055778196L;
-
-    @JsonProperty("currency")
-    private String mCurrency;
-
-    @JsonProperty("balance")
-    private double mBalance;
-
-    @JsonProperty("accountId")
-    private String mAccountId;
-
-
-    @JsonProperty("currency")
-    public String getCurrency() {
-        return mCurrency;
-    }
-
-    @JsonProperty("balance")
-    public double getBalance() {
-        return mBalance;
-    }
-
-    @JsonProperty("accountId")
-    public String getAccountId() {
-        return mAccountId;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
deleted file mode 100644
index 0182251..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.liato.bankdroid.banking.banks.avanza.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class Position implements Serializable {
-
-    private static final long serialVersionUID = 4138023852221811457L;
-
-    @JsonProperty("instrumentName")
-    private String mInstrumentName;
-
-    @JsonProperty("averageAcquiredPrice")
-    private double mAverageAcquiredPrice;
-
-    @JsonProperty("marketValue")
-    private double mMarketValue;
-
-    @JsonProperty("price")
-    private double mPrice;
-
-    @JsonProperty("profit")
-    private double mProfit;
-
-    @JsonProperty("modified")
-    private long mModified;
-
-    @JsonProperty("expiryDate")
-    private long mExpiryDate;
-
-    @JsonProperty("volume")
-    private int mVolume;
-
-    @JsonProperty("tradable")
-    private boolean mTradable;
-
-    @JsonProperty("orderbookId")
-    private long mOrderbookId;
-
-    @JsonProperty("profitPercent")
-    private double mProfitPercent;
-
-    @JsonProperty("type")
-    private int mType;
-
-    @JsonProperty("instrumentType")
-    private String mInstrumentType;
-
-    @JsonProperty("change")
-    private double mChange;
-
-
-    @JsonProperty("instrumentName")
-    public String getInstrumentName() {
-        return mInstrumentName;
-    }
-
-    @JsonProperty("averageAcquiredPrice")
-    public double getAverageAcquiredPrice() {
-        return mAverageAcquiredPrice;
-    }
-
-    @JsonProperty("marketValue")
-    public double getMarketValue() {
-        return mMarketValue;
-    }
-
-    @JsonProperty("price")
-    public double getPrice() {
-        return mPrice;
-    }
-
-    @JsonProperty("profit")
-    public double getProfit() {
-        return mProfit;
-    }
-
-    @JsonProperty("modified")
-    public long getModified() {
-        return mModified;
-    }
-
-    @JsonProperty("expiryDate")
-    public long getExpiryDate() {
-        return mExpiryDate;
-    }
-
-    @JsonProperty("volume")
-    public int getVolume() {
-        return mVolume;
-    }
-
-    @JsonProperty("tradable")
-    public boolean getTradable() {
-        return mTradable;
-    }
-
-    @JsonProperty("orderbookId")
-    public long getOrderbookId() {
-        return mOrderbookId;
-    }
-
-    @JsonProperty("profitPercent")
-    public double getProfitPercent() {
-        return mProfitPercent;
-    }
-
-    @JsonProperty("type")
-    public int getType() {
-        return mType;
-    }
-
-    @JsonProperty("instrumentType")
-    public String getInstrumentType() {
-        return mInstrumentType;
-    }
-
-    @JsonProperty("change")
-    public double getChange() {
-        return mChange;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
deleted file mode 100644
index 3571eca..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package com.liato.bankdroid.banking.banks.avanza.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-
-public class PositionAggregation implements Serializable {
-
-    private static final long serialVersionUID = 5531947007427482418L;
-
-    @JsonProperty("totalChange")
-    private double mTotalChange;
-
-    @JsonProperty("positions")
-    private List<Position> mPositions = Collections.emptyList();
-
-    @JsonProperty("totalProfit")
-    private double mTotalProfit;
-
-    @JsonProperty("instrumentTypeName")
-    private String mInstrumentTypeName;
-
-    @JsonProperty("totalProfitPercent")
-    private double mTotalProfitPercent;
-
-    @JsonProperty("totalValue")
-    private double mTotalValue;
-
-    @JsonProperty("instrumentType")
-    private int mInstrumentType;
-
-    @JsonProperty("totalAverage")
-    private double mTotalAverage;
-
-
-    @JsonProperty("totalChange")
-    public double getTotalChange() {
-        return mTotalChange;
-    }
-
-    @JsonProperty("positions")
-    public List<Position> getPositions() {
-        return mPositions;
-    }
-
-    @JsonProperty("totalProfit")
-    public double getTotalProfit() {
-        return mTotalProfit;
-    }
-
-    @JsonProperty("instrumentTypeName")
-    public String getInstrumentTypeName() {
-        return mInstrumentTypeName;
-    }
-
-    @JsonProperty("totalProfitPercent")
-    public double getTotalProfitPercent() {
-        return mTotalProfitPercent;
-    }
-
-    @JsonProperty("totalValue")
-    public double getTotalValue() {
-        return mTotalValue;
-    }
-
-    @JsonProperty("instrumentType")
-    public int getInstrumentType() {
-        return mInstrumentType;
-    }
-
-    @JsonProperty("totalAverage")
-    public double getTotalAverage() {
-        return mTotalAverage;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 230dbd5..b72ba85 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -27,8 +27,6 @@ public interface IBankTypes {
     int LANSFORSAKRINGAR = 4;
     int COOP = 6;
     int ICA = 7;
-    int AVANZA = 9;
-    int AVANZAMINI = 11;
     int OKQ8 = 12;
     int FIRSTCARD = 14;
     int PAYSON = 16;
diff --git bankdroid-legacy/src/main/res/drawable/logo_avanza.png bankdroid-legacy/src/main/res/drawable/logo_avanza.png
deleted file mode 100644
index 1d5b836..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_avanza.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png
deleted file mode 100644
index f19d914..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_avanza.pem bankdroid-legacy/src/main/res/raw/cert_avanza.pem
deleted file mode 100644
index 0cea5a7..0000000
--- bankdroid-legacy/src/main/res/raw/cert_avanza.pem
+++ /dev/null
@@ -1,29 +0,0 @@
------BEGIN CERTIFICATE-----

-fIBstELLSRgDEJNBmd8N
------END CERTIFICATE-----
-iphone.avanza.se:443

commit 3c25a3917ecdb1997b833ec259d3bdc42cb9d26b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 22 22:07:48 2017 +0100

    Update build tools to version 2.2.3

diff --git build.gradle build.gradle
index 43763d6..76cbdfb 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.2.2'
+        classpath 'com.android.tools.build:gradle:2.2.3'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files

commit 31bf4e66992d3057c4cab3d711f99e666fc0883c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 22 21:28:27 2017 +0100

    Update certificates

diff --git CHANGELOG CHANGELOG
index 1fbef9f..6995d6b 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+(Unreleased)
+* Update certificates
+
 v1.9.14 (2017-01-06)
 * Updated certificates for First Card, Osuuspankki and Östgötatrafiken
 
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
index 3057379..d4338ef 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
@@ -1,52 +1,48 @@
 -----BEGIN CERTIFICATE-----
-MIIJGDCCCACgAwIBAgIQBcnDhS/kTPYwT7xQkKTIiTANBgkqhkiG9w0BAQsFADB1
+MIIIYDCCB0igAwIBAgIQAaqnbsay6zOICUMaChU+CDANBgkqhkiG9w0BAQsFADB1
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
-IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE2MTIwNjAwMDAwMFoXDTE4MTIxMTEy
-MDAwMFowggEXMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysG
+IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE3MDEyNDAwMDAwMFoXDTE5MDEyOTEy
+MDAwMFowggEcMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysG
 AQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhOZXcgWW9yazEPMA0GA1UE
 BRMGMTg4MDU1MR4wHAYDVQQJExUzMTUxIFcuIEJlaHJlbmQgRHJpdmUxDjAMBgNV
 BBETBTg1MDI3MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTEQMA4GA1UE

-jTe/+O2Jm+Nw3PkYwmjtsc0EhaHp7HcPgHZPtQ==

+bdXhSyChR5z4w4lvj8HthWCs6kU+uzBHdtamdVkFU4d0dzi/
 -----END CERTIFICATE-----
 global.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem
index a01ed1e..e9de15f 100644
--- bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem
+++ bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem
@@ -1,35 +1,37 @@
 -----BEGIN CERTIFICATE-----
-MIIF4TCCBMmgAwIBAgIQVPm9MeoE7SQFdlULvDppQjANBgkqhkiG9w0BAQsFADBE
+MIIGVjCCBT6gAwIBAgIQJ7c0DjE2rrf90ZxGr+exPTANBgkqhkiG9w0BAQsFADBE
 MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU

-Lk4ymn/K6HZMbtsrXfcWX8N3UmO5

+vOINhDQg/+E6MHckR2oHKtvIDY9jhp7UsP6idjWDakl4Yc2RGsq+PPIW
 -----END CERTIFICATE-----
 bioklubben.sf.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_brummer.pem bankdroid-legacy/src/main/res/raw/cert_brummer.pem
index 57a3884..477acac 100644
--- bankdroid-legacy/src/main/res/raw/cert_brummer.pem
+++ bankdroid-legacy/src/main/res/raw/cert_brummer.pem
@@ -1,43 +1,45 @@
 -----BEGIN CERTIFICATE-----
-MIIHXTCCBkWgAwIBAgIQDdd0lRu1ru2NPo7vkvNo8jANBgkqhkiG9w0BAQsFADB1
+MIIH0jCCBrqgAwIBAgIQCRPnldXK9l40D0FXyRHdeDANBgkqhkiG9w0BAQsFADB1
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk
-IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE1MDIyNTAwMDAwMFoXDTE3MDMwMTEy
-MDAwMFowgdgxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
+IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE3MDIwMTAwMDAwMFoXDTE5MDQwNDEy
+MDAwMFowgcsxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB
 BAGCNzwCAQMTAlNFMRMwEQYDVQQFEwo1NTY2MjcyMTgyMRkwFwYDVQQJExBOb3Jy
 bWFsbXN0b3JnIDE0MQ8wDQYDVQQREwYxMTEgNDYxCzAJBgNVBAYTAlNFMRIwEAYD

-U20t5htcdjfC2PmbN/Y6FxQ=

+Hzn3KhA/seiw6RHEE6KH4ABCGcB+f+/wTWl9EpBBxaFQvsMmDTY=
 -----END CERTIFICATE-----
 www.brummer.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_minpension.pem bankdroid-legacy/src/main/res/raw/cert_minpension.pem
index a9db360..46bf04b 100644
--- bankdroid-legacy/src/main/res/raw/cert_minpension.pem
+++ bankdroid-legacy/src/main/res/raw/cert_minpension.pem
@@ -1,29 +1,46 @@
 -----BEGIN CERTIFICATE-----
-MIIEyjCCA7KgAwIBAgIQb/AHZMl0UKpzpPlDyW4CfTANBgkqhkiG9w0BAQsFADBB
+MIIH3TCCBsWgAwIBAgIQSxRugYizx9lBU/JAeD4aIzANBgkqhkiG9w0BAQsFADBB
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMRswGQYDVQQDExJ0

-Sg4ppKz/AHPCyN4SCh4pB4fVlr3XtldcQ2d1TTrN

+zA==
 -----END CERTIFICATE-----
 www.minpension.se:443

commit f8153266dd485b441c979252c9372f4920e491f3 (tag: v1.9.14)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jan 6 14:08:16 2017 +0100

    Create release v1.9.14

diff --git CHANGELOG CHANGELOG
index 06dda56..1fbef9f 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,6 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-Not yet released
+v1.9.14 (2017-01-06)
 * Updated certificates for First Card, Osuuspankki and Östgötatrafiken
 
 v1.9.13 (2016-11-03)

commit 3cf00343b0e0ee7fa6112e79946f10e937231322
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jan 6 14:06:56 2017 +0100

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
index 516f2c0..3057379 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
@@ -1,40 +1,52 @@
 -----BEGIN CERTIFICATE-----

+jTe/+O2Jm+Nw3PkYwmjtsc0EhaHp7HcPgHZPtQ==
 -----END CERTIFICATE-----
 global.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
index dab3079..240e7e3 100644
--- bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
+++ bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
@@ -1,32 +1,38 @@
 -----BEGIN CERTIFICATE-----

-hA6n1bvE4ifRPUE=

+b7/H85qGm2J9Bge974C59pUB+NiDLZIhEK9SazvkSsDEiw==
 -----END CERTIFICATE-----
 kontoutdrag.plusgirot.se:443

commit 4583f2cfb0dc5eba0b93944b8c43d2d5a1b73713
Merge: b3ca271 93a3464
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jan 6 14:05:01 2017 +0100

    Merge pull request #679 from robho/certificate_update
    
    Updated certificates for First Card, Osuuspankki and Östgötatrafiken

commit 93a3464e2d3ab1d6cae747a44df3c807f4426a58
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Wed Dec 28 18:00:06 2016 +0100

    Updated certificates for First Card, Osuuspankki and Östgötatrafiken

diff --git CHANGELOG CHANGELOG
index 91dd35a..06dda56 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+Not yet released
+* Updated certificates for First Card, Osuuspankki and Östgötatrafiken
+
 v1.9.13 (2016-11-03)
 * Fixes Crashlytics logging issue
 
diff --git bankdroid-legacy/src/main/res/raw/cert_firstcard.pem bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
index 179433a..75ced50 100644
--- bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIF/jCCBOagAwIBAgIQbq6gqE0Gd/rc9lIP11FmXjANBgkqhkiG9w0BAQsFADB+
+MIIGdzCCBV+gAwIBAgIQFoz2cyoH3choP3fYGiPTlTANBgkqhkiG9w0BAQsFADB+
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj
-IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MDYxNTAwMDAwMFoX
-DTE2MTIzMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv
+IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MTAxNDAwMDAwMFoX
+DTE4MDEwMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv
 bG0xEjAQBgNVBAcMCVN0b2NraG9sbTEXMBUGA1UECgwOTm9yZGVhIEJhbmsgQUIx
 GjAYBgNVBAsMEUlUIFJldGFpbCBCYW5raW5nMRkwFwYDVQQDDBB3d3cuZmlyc3Rj
 YXJkLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4dG7pvu0mER1
@@ -12,25 +12,27 @@ fGHY/PWIfVTl0ixk3pbriKlay9paA/dTdFVKNOZzihPmjeh29bjoYkIRUPfpSfF3
 CDcKlWVyxH9/pR9RmcNtkm5NWDBZT26wGtyqzuwmyPunxQd6PyI9X2SUMZBMsZbd
 /rE/1UEdRsgH1L0OmCe35OFIxoYVpNx7BbgVUSAJZc24Oi2AHrzKt5i7Wg2z2qqp
 6OPkZkJaH2y+lpztdSQAyFiyj1ai/V9CyW267uprA0vON/8zecFFvToIutFLZW9Z
-m0MOJzQUzwIDAQABo4ICbjCCAmowGwYDVR0RBBQwEoIQd3d3LmZpcnN0Y2FyZC5z
+m0MOJzQUzwIDAQABo4IC5zCCAuMwGwYDVR0RBBQwEoIQd3d3LmZpcnN0Y2FyZC5z
 ZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD
 AQYIKwYBBQUHAwIwYQYDVR0gBFowWDBWBgZngQwBAgIwTDAjBggrBgEFBQcCARYX
 aHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGQwXaHR0cHM6Ly9k
 LnN5bWNiLmNvbS9ycGEwHwYDVR0jBBgwFoAUX2DPYZBV34RDFIpgKrL1evRDGO8w
 KwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3NzLnN5bWNiLmNvbS9zcy5jcmwwVwYI
 KwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8vc3Muc3ltY2QuY29tMCYG

-YE4=

+0QnOSxH/5mBWvneOpWytZZ47OWWKPzalXlAK
 -----END CERTIFICATE-----
 www.firstcard.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
index 748e230..43f5e68 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -1,33 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIFiTCCBHGgAwIBAgIRAMMg/Cmbci6ISVbk/7dAE+MwDQYJKoZIhvcNAQEFBQAw
+MIIFfjCCBGagAwIBAgIRAKOKgCqyMq9biovKz3eHTo8wDQYJKoZIhvcNAQEFBQAw
 gY4xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
 BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTQwMgYD

-E1dVzW3GXPiOEh4LMGnnJERSVztgihJziES2RVE=

+S8rFrPmWlg/+TVPw8kuNxYxG
 -----END CERTIFICATE-----
 www.ostgotatrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
index 49f5f1b..d3ad09e 100644
--- bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
+++ bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
@@ -1,37 +1,37 @@
 -----BEGIN CERTIFICATE-----
-MIIGQjCCBSqgAwIBAgIQP5hSiLJfDuQhp1cXs/mT1DANBgkqhkiG9w0BAQsFADB3
+MIIGSzCCBTOgAwIBAgIQQq4J10cEVtza7iMNxJPZGjANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUxMjExMDAwMDAwWhcNMTYxMjEx
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYxMTI4MDAwMDAwWhcNMTcxMjEx
 MjM1OTU5WjCB0jETMBEGCysGAQQBgjc8AgEDEwJGSTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCTAyNDI1MjItMTELMAkGA1UEBhMCRkkx
 DjAMBgNVBBEMBTAwNTEwMRAwDgYDVQQIDAdVdXNpbWFhMREwDwYDVQQHDAhIZWxz
 aW5raTEaMBgGA1UECQwRVGVvbGxpc3V1c2thdHUgMUIxFjAUBgNVBAoMDU9QIE9z
 dXVza3VudGExEjAQBgNVBAMMCXd3dy5vcC5maTCCASIwDQYJKoZIhvcNAQEBBQAD

 EQQNMAuCCXd3dy5vcC5maTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNV

-/aCGL94jL5MWifVSVGvNLkogJSPiiA==

+cB1X7Qc6VtmqOTNuKPcPRlA7OV4N3DYNzhC2ePxoIw==
 -----END CERTIFICATE-----
 www.op.fi:443

commit b3ca27108f9677b0a172cdd155bf3bef1952d668
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Nov 28 17:12:45 2016 +0100

    Update certs for Västtrafik and Ica

diff --git bankdroid-legacy/src/main/res/raw/cert_ica.pem bankdroid-legacy/src/main/res/raw/cert_ica.pem
index 36cb10d..3df2bec 100644
--- bankdroid-legacy/src/main/res/raw/cert_ica.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ica.pem
@@ -1,31 +1,31 @@
 -----BEGIN CERTIFICATE-----

-Be2TKW8A9Zy/ke8Z3LCOsj6BVQIeAyMuZsIcvGGsEg==

+XP5rIJEjeETnTBZYVLKKjMP5+kUzD2+4o5jMz5ucz7Kzb2LcWYg=
 -----END CERTIFICATE-----
 api.ica.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
index ecc7ed3..1eb5a57 100644
--- bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
+++ bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
@@ -1,30 +1,41 @@
 -----BEGIN CERTIFICATE-----
-MIIE8zCCA9ugAwIBAgIQUeTHmHB7Xr1CudcxMmVzpjANBgkqhkiG9w0BAQsFADBE
+MIIG8TCCBdmgAwIBAgIQLw3oiO5pfyS//nmbxVLjUDANBgkqhkiG9w0BAQsFADBE
 MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU

-7lu66yWdSo3BXrk0mpe3BvNNjGY5R0U=

+3WKfVac=
 -----END CERTIFICATE-----
 www.vasttrafik.se:443

commit ef07d475822680cb39898ad433fae1be5874d475
Author: Johan Walles <johan.walles@gmail.com>
Date:   Wed Nov 9 20:17:38 2016 +0100

    Blame Urllib problems on the callers
    
    For Crashlytics.
    
    The previous attempt at doing this failed, because it tried to modify
    the *first* exception in the chain, but it turns out that it's the
    *last* exception in the chain that Crashlytics looks at.
    
    So given an Exception...
    "
    java.lang.Exception: This is a test Exception
        at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20)
        at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at ...
    "
    ... we now report to Crashlytics:
    "
    java.lang.Exception: This is a test Exception
        at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20)
        at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at ...
    Caused by: java.lang.Exception: This is a test Exception
        at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at ...
        ... 37 more
    "

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
index 468b56e..91fe4d5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
@@ -1,6 +1,8 @@
 package com.liato.bankdroid.utils;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
@@ -11,41 +13,109 @@ public class ExceptionUtils {
     private static final String PREFIX = "com.liato.bankdroid.";
 
     /**
-     * Take an exception thrown and make it look like it came from Bankdroid.
+     * Modify an Exception to make it look like it was ultimately caused by Bankdroid.
      * <p/>
-     * Specifically, if Urllib.java, called by Bankdroid code, throws an exception,
-     * rewrite the exception so that it appears as if it was thrown from the
-     * Bankdroid method calling Urllib, but caused by the original Exception.
+     * The purpose is to make Crashlytics report Urllib exceptions as coming from whatever
+     * bank Urllib is trying to access.
+     * <p/>
+     * For example, this exception:
+     * <pre>
+     * java.lang.Exception: This is a test Exception
+     *     at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20)
+     *     at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
+     *     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+     *     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+     *     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+     *     at java.lang.reflect.Method.invoke(Method.java:497)
+     *     at ...
+     * </pre>
+     *
+     * Would be turned into this exception:
+     * <pre>
+     * java.lang.Exception: This is a test Exception
+     *     at not.bankdroid.at.all.ExceptionFactory.getException(ExceptionFactory.java:20)
+     *     at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
+     *     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+     *     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+     *     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+     *     at java.lang.reflect.Method.invoke(Method.java:497)
+     *     at ...
+     * Caused by: java.lang.Exception: This is a test Exception
+     *     at com.liato.bankdroid.utils.ExceptionUtilsTest.testBlameBankdroid(ExceptionUtilsTest.java:16)
+     *     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+     *     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+     *     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+     *     at java.lang.reflect.Method.invoke(Method.java:497)
+     *     at ...
+     *     ... 37 more
+     * </pre>
      */
-    public static <T extends Throwable> T bankdroidifyException(T exception) {
+    public static void blameBankdroid(Throwable exception) {
+        Throwable ultimateCause = getUltimateCause(exception);
+        if (ultimateCause == null) {
+            // Unable to find ultimate cause, never mind
+            return;
+        }
+
         StackTraceElement[] bankdroidifiedStacktrace =
-                bankdroidifyStacktrace(exception.getStackTrace());
-        if (bankdroidifiedStacktrace.length == exception.getStackTrace().length) {
-            // Unable to bankdroidify stacktrace, never mind
-            return exception;
+                bankdroidifyStacktrace(ultimateCause.getStackTrace());
+        if (bankdroidifiedStacktrace.length == 0) {
+            // No Bankdroid stack frames found, never mind
+            return;
+        }
+        if (bankdroidifiedStacktrace.length == ultimateCause.getStackTrace().length) {
+            // Bankdroid already to blame, never mind
+            return;
         }
 
-        T returnMe = createWrapperException(exception);
-        if (returnMe == null) {
+        Throwable fakeCause = cloneException(ultimateCause);
+        if (fakeCause == null) {
             Timber.w(new RuntimeException(
-                    "Unable to bankdroidify exception of class: " + exception.getClass()));
-            return exception;
+                    "Unable to bankdroidify exception of class: " + ultimateCause.getClass()));
+            return;
         }
 
-        returnMe.initCause(exception);
+        // Put the bankdroidified stack trace before the fakeCause's actual stack trace
+        fakeCause.setStackTrace(concatArrays(bankdroidifiedStacktrace, fakeCause.getStackTrace()));
 
-        returnMe.setStackTrace(bankdroidifiedStacktrace);
+        ultimateCause.initCause(fakeCause);
+    }
 
+    @VisibleForTesting
+    static StackTraceElement[] concatArrays(StackTraceElement[] a, StackTraceElement[] b) {
+        StackTraceElement[] returnMe = new StackTraceElement[a.length + b.length];
+        System.arraycopy(a, 0, returnMe, 0, a.length);
+        System.arraycopy(b, 0, returnMe, a.length, b.length);
         return returnMe;
     }
 
+    @VisibleForTesting
+    @Nullable
+    static Throwable getUltimateCause(Throwable t) {
+        int laps = 0;
+        Throwable ultimateCause = t;
+        while (ultimateCause.getCause() != null) {
+            ultimateCause = ultimateCause.getCause();
+            if (laps++ > 10) {
+                return null;
+            }
+        }
+        return ultimateCause;
+    }
+
+    /**
+     * Clone message and stacktrace but not the cause.
+     */
     @Nullable
-    private static <T extends Throwable> T createWrapperException(T wrapMe) {
+    @VisibleForTesting
+    static <T extends Throwable> T cloneException(T wrapMe) {
         Class<?> newClass = wrapMe.getClass();
         while (newClass != null) {
             try {
-                return (T) newClass.getConstructor(String.class)
-                        .newInstance(wrapMe.getMessage());
+                T returnMe =
+                        (T) newClass.getConstructor(String.class).newInstance(wrapMe.getMessage());
+                returnMe.setStackTrace(wrapMe.getStackTrace());
+                return returnMe;
             } catch (InvocationTargetException e) {
                 newClass = newClass.getSuperclass();
             } catch (NoSuchMethodException e) {
@@ -63,9 +133,12 @@ public class ExceptionUtils {
     /**
      * Remove all initial non-Bankdroid frames from a stack.
      *
-     * @return A copy of rawStack but with the initial non-Bankdroid frames removed
+     * @return A copy of rawStack but with the initial non-Bankdroid frames removed, or null
+     * if no sensible answer can be given.
      */
-    private static StackTraceElement[] bankdroidifyStacktrace(final StackTraceElement[] rawStack) {
+    @VisibleForTesting
+    @NonNull
+    static StackTraceElement[] bankdroidifyStacktrace(final StackTraceElement[] rawStack) {
         for (int i = 0; i < rawStack.length; i++) {
             StackTraceElement stackTraceElement = rawStack[i];
             if (stackTraceElement.getClassName().startsWith(PREFIX)) {
@@ -74,6 +147,6 @@ public class ExceptionUtils {
         }
 
         // No Bankdroid stack frames found, never mind
-        return rawStack;
+        return new StackTraceElement[0];
     }
 }
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 36354b6..c064d9c 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -149,7 +149,8 @@ public class Urllib {
         try {
             return this.open(url, new ArrayList<NameValuePair>());
         } catch (IOException e) {
-            throw ExceptionUtils.bankdroidifyException(e);
+            ExceptionUtils.blameBankdroid(e);
+            throw e;
         }
     }
 
@@ -162,7 +163,8 @@ public class Urllib {
         try {
             return open(url, postData, false);
         } catch (IOException e) {
-            throw ExceptionUtils.bankdroidifyException(e);
+            ExceptionUtils.blameBankdroid(e);
+            throw e;
         }
     }
 
@@ -182,7 +184,8 @@ public class Urllib {
         try {
             return openAsHttpResponse(url, entity, forcePost);
         } catch (IOException e) {
-            throw ExceptionUtils.bankdroidifyException(e);
+            ExceptionUtils.blameBankdroid(e);
+            throw e;
         }
     }
 
@@ -200,7 +203,8 @@ public class Urllib {
                 return openAsHttpResponse(url, entity, HttpMethod.POST);
             }
         } catch (IOException e) {
-            throw ExceptionUtils.bankdroidifyException(e);
+            ExceptionUtils.blameBankdroid(e);
+            throw e;
         }
     }
 
@@ -293,7 +297,8 @@ public class Urllib {
             return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null,
                     forcePost);
         } catch (IOException e) {
-            throw ExceptionUtils.bankdroidifyException(e);
+            ExceptionUtils.blameBankdroid(e);
+            throw e;
         }
     }
 
diff --git bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
index df673c5..2b87a96 100644
--- bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
+++ bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
@@ -3,85 +3,162 @@ package com.liato.bankdroid.utils;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.net.ConnectException;
 
 import eu.nullbyte.android.urllib.Urllib;
-import not.bankdroid.at.all.ExceptionThrower;
+import not.bankdroid.at.all.ExceptionFactory;
 
-@SuppressWarnings("CallToPrintStackTrace")
 public class ExceptionUtilsTest {
     @Test
-    @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.AvoidCatchingNPE", "PMD.SystemPrintln"})
-    public void testBankdroidifyException() throws Exception {
-        Exception raw = null;
-        try {
-            //noinspection ConstantConditions
-            new Urllib(null);
-            Assert.fail("Exception expected");
-        } catch (NullPointerException e) {
-            raw = e;
+    public void testBlameBankdroid() {
+        Exception e = ExceptionFactory.getException();
+        String before = toStringWithStacktrace(e);
+        ExceptionUtils.blameBankdroid(e);
+        String after = toStringWithStacktrace(e);
+        String description =
+                String.format("\n---- Before ----\n%s---- After ----\n%s----", before, after);
+
+        String[] afterLines = after.split("\n");
+        int lastCausedByIndex = 0;
+        for (int i = 0; i < afterLines.length; i++) {
+            if (afterLines[i].startsWith("Caused by: ")) {
+                lastCausedByIndex = i;
+            }
         }
 
-        // Print stack traces, useful if the tests fail
-        System.err.println("Before:");
-        raw.printStackTrace();
+        Assert.assertNotEquals(description, 0, lastCausedByIndex);
+        Assert.assertTrue(description,
+                afterLines[lastCausedByIndex + 1].startsWith("\tat com.liato.bankdroid."));
+    }
 
-        System.err.println();
-        System.err.println("After:");
-        Exception bankdroidified = ExceptionUtils.bankdroidifyException(raw);
-        bankdroidified.printStackTrace();
+    /**
+     * Like {@link #testBlameBankdroid()} but with an Exception with a cause.
+     */
+    @Test
+    public void testBlameBankdroidWithCause() {
+        Exception e = ExceptionFactory.getExceptionWithCause();
+        String before = toStringWithStacktrace(e);
+        ExceptionUtils.blameBankdroid(e);
+        String after = toStringWithStacktrace(e);
+        String description =
+                String.format("\n---- Before ----\n%s---- After ----\n%s----", before, after);
+
+        String[] afterLines = after.split("\n");
+        int firstCausedByIndex = 0;
+        for (int i = 0; i < afterLines.length; i++) {
+            if (afterLines[i].startsWith("Caused by: ")) {
+                firstCausedByIndex = i;
+                break;
+            }
+        }
+        Assert.assertNotEquals(description, 0, firstCausedByIndex);
+        Assert.assertTrue(description,
+                afterLines[firstCausedByIndex + 1].startsWith("\tat not.bankdroid.at.all."));
+
+        int lastCausedByIndex = 0;
+        for (int i = 0; i < afterLines.length; i++) {
+            if (afterLines[i].startsWith("Caused by: ")) {
+                lastCausedByIndex = i;
+            }
+        }
+        Assert.assertNotEquals(description, 0, lastCausedByIndex);
+        Assert.assertTrue(description,
+                afterLines[lastCausedByIndex + 1].startsWith("\tat com.liato.bankdroid."));
+    }
 
-        Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid",
-                raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+    @Test
+    public void testBlameBankdroidAlreadyToBlame() {
+        // Creating it here we're already inside of Bankdroid code, blaming bankdroid should be a
+        // no-op
+        Exception e = new Exception();
 
-        Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid",
-                bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+        String before = toStringWithStacktrace(e);
 
-        // Verify that e is the cause of bankdroidified
-        Assert.assertSame(raw, bankdroidified.getCause());
+        ExceptionUtils.blameBankdroid(e);
+        String after = toStringWithStacktrace(e);
 
-        // Verify that re-bankdroidifying is a no-op
-        Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified));
+        Assert.assertEquals(before, after);
+    }
+
+    private String toStringWithStacktrace(Exception e) {
+        StringWriter stringWriter = new StringWriter();
+        PrintWriter printWriter = new PrintWriter(stringWriter);
+        e.printStackTrace(printWriter);
+        printWriter.close();
+        return stringWriter.toString();
     }
 
-    /**
-     * Test that we can wrap exceptions without (String) constructors.
-     */
     @Test
-    @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"})
-    public void testBankdroidifyWonkyException() {
-        ExceptionThrower.WonkyException raw = null;
-        try {
-            ExceptionThrower.throwWonkyException();
-            Assert.fail("Exception expected");
-        } catch (ExceptionThrower.WonkyException e) {
-            raw = e;
-        }
+    public void testBankdroidifyStacktrace() {
+        StackTraceElement[] bankdroidified = new StackTraceElement[] {
+                new StackTraceElement("not.bankdroid.SomeClass", "someMethod", "SomeClass.java", 42),
+                new StackTraceElement("com.liato.bankdroid.SomeOtherClass", "someOtherMethod", "SomeOtherClass.java", 43),
+        };
+        bankdroidified = ExceptionUtils.bankdroidifyStacktrace(bankdroidified);
 
-        // Print stack traces, useful if the tests fail
-        System.err.println("Before:");
-        raw.printStackTrace();
+        StackTraceElement[] expected = new StackTraceElement[] {
+                new StackTraceElement("com.liato.bankdroid.SomeOtherClass", "someOtherMethod", "SomeOtherClass.java", 43),
+        };
 
-        // Since bankdroidify() won't be able to create a WonkyException, it
-        // should fall back to creating something it extends
-        ConnectException bankdroidified = ExceptionUtils.bankdroidifyException(raw);
+        Assert.assertArrayEquals(expected, bankdroidified);
 
-        System.err.println();
-        System.err.println("After:");
-        bankdroidified.printStackTrace();
+        // Test re-bankdroidification
+        Assert.assertArrayEquals(expected, ExceptionUtils.bankdroidifyStacktrace(bankdroidified));
+    }
 
-        Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid",
-                raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+    @Test
+    public void testCloneExceptionWonky() {
+        ExceptionFactory.WonkyException raw = ExceptionFactory.getWonkyException();
+
+        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+        ConnectException cloned = ExceptionUtils.cloneException(raw);
+
+        assert cloned != null;
+        Assert.assertEquals(raw.getMessage(), cloned.getMessage());
+        Assert.assertArrayEquals(raw.getStackTrace(), cloned.getStackTrace());
+        Assert.assertEquals(
+                "Cloning an uninstantiable Exception should return an instance of its super class",
+                raw.getClass().getSuperclass(), cloned.getClass());
+    }
+
+    @Test
+    @SuppressWarnings({"PMD.AvoidCatchingNPE"})
+    public void testCloneExceptionNPE() {
+        NullPointerException raw = null;
+        try {
+            //noinspection ConstantConditions
+            new Urllib(null);
+            Assert.fail("Exception expected");
+        } catch (NullPointerException e) {
+            raw = e;
+        }
 
-        Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid",
-                bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+        @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+        NullPointerException cloned = ExceptionUtils.cloneException(raw);
 
-        Assert.assertEquals(raw.getMessage(), bankdroidified.getMessage());
+        assert cloned != null;
+        Assert.assertEquals(raw.getMessage(), cloned.getMessage());
+        Assert.assertArrayEquals(raw.getStackTrace(), cloned.getStackTrace());
+        Assert.assertEquals(raw.getClass(), cloned.getClass());
+    }
 
-        // Verify that e is the cause of bankdroidified
-        Assert.assertSame(raw, bankdroidified.getCause());
+    @Test(timeout = 1000)
+    public void testGetUltimateCauseRecursive() {
+        Exception recursive = new Exception();
+        Exception intermediate = new Exception(recursive);
+        recursive.initCause(intermediate);
+        Assert.assertNull(ExceptionUtils.getUltimateCause(recursive));
+    }
 
-        // Verify that re-bankdroidifying is a no-op
-        Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified));
+    @Test
+    public void testConcatArrays() {
+        StackTraceElement s1 = new StackTraceElement("a", "b", "c", 123);
+        StackTraceElement s2 = new StackTraceElement("d", "e", "f", 456);
+        StackTraceElement[] concatenated =
+                ExceptionUtils.concatArrays(
+                        new StackTraceElement[]{s1}, new StackTraceElement[]{s2});
+        Assert.assertArrayEquals(new StackTraceElement[]{ s1, s2 }, concatenated);
     }
 }
diff --git bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionFactory.java bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionFactory.java
new file mode 100644
index 0000000..bc7d6fe
--- /dev/null
+++ bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionFactory.java
@@ -0,0 +1,26 @@
+package not.bankdroid.at.all;
+
+import java.net.ConnectException;
+
+/**
+ * For the test in {@link com.liato.bankdroid.utils.ExceptionUtilsTest}
+ */
+public class ExceptionFactory {
+    public static class WonkyException extends ConnectException {
+        public WonkyException(int wonky) {
+            super("Wonky: " + wonky);
+        }
+    }
+
+    public static WonkyException getWonkyException() {
+        return new WonkyException(5);
+    }
+
+    public static Exception getException() {
+        return new Exception("This is a test Exception");
+    }
+
+    public static Exception getExceptionWithCause() {
+        return new Exception("This Exception has a cause", getException());
+    }
+}
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 8195ce2..c3565a5 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -1,8 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
-    <!-- Disable since it has external dependencies that we cannot affect.-->
+    <!-- Disable since it has external dependencies that we cannot affect. -->
     <issue id="GradleDependency" severity="ignore" />
 
+    <!-- Disable since it starts failing for non-code-related reasons. -->
+    <issue id="OldTargetApi" severity="ignore" />
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
 
     <issue id="AllowBackup" severity="ignore" />
diff --git tools/update-suppressions.sh tools/update-suppressions.sh
index 53ff534..1652568 100755
--- tools/update-suppressions.sh
+++ tools/update-suppressions.sh
@@ -21,9 +21,12 @@ function set_lint_suppressions() {
   cat > ${LINT_XML} << EOF
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
-    <!-- Disable since it has external dependencies that we cannot affect.-->
+    <!-- Disable since it has external dependencies that we cannot affect. -->
     <issue id="GradleDependency" severity="ignore" />
 
+    <!-- Disable since it starts failing for non-code-related reasons. -->
+    <issue id="OldTargetApi" severity="ignore" />
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
 
 EOF

commit d64ede1abee89d557a5f4e0ea720a265b4256e05
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Nov 3 20:55:57 2016 +0100

    Fix wrapping exceptions without String constructors
    
    Before this change, bankdroidifyException() failed if the exception
    to wrap didn't come with a String constructor.
    
    Now it works, with tests and all!

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
index e61097b..468b56e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
@@ -1,5 +1,7 @@
 package com.liato.bankdroid.utils;
 
+import android.support.annotation.Nullable;
+
 import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
 
@@ -23,21 +25,10 @@ public class ExceptionUtils {
             return exception;
         }
 
-        T returnMe;
-        try {
-            returnMe = (T)exception.getClass().getConstructor(String.class)
-                    .newInstance(exception.getMessage());
-        } catch (InstantiationException e) {
-            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
-            return exception;
-        } catch (InvocationTargetException e) {
-            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
-            return exception;
-        } catch (IllegalAccessException e) {
-            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
-            return exception;
-        } catch (NoSuchMethodException e) {
-            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
+        T returnMe = createWrapperException(exception);
+        if (returnMe == null) {
+            Timber.w(new RuntimeException(
+                    "Unable to bankdroidify exception of class: " + exception.getClass()));
             return exception;
         }
 
@@ -48,6 +39,27 @@ public class ExceptionUtils {
         return returnMe;
     }
 
+    @Nullable
+    private static <T extends Throwable> T createWrapperException(T wrapMe) {
+        Class<?> newClass = wrapMe.getClass();
+        while (newClass != null) {
+            try {
+                return (T) newClass.getConstructor(String.class)
+                        .newInstance(wrapMe.getMessage());
+            } catch (InvocationTargetException e) {
+                newClass = newClass.getSuperclass();
+            } catch (NoSuchMethodException e) {
+                newClass = newClass.getSuperclass();
+            } catch (InstantiationException e) {
+                newClass = newClass.getSuperclass();
+            } catch (IllegalAccessException e) {
+                newClass = newClass.getSuperclass();
+            }
+        }
+
+        return null;
+    }
+
     /**
      * Remove all initial non-Bankdroid frames from a stack.
      *
diff --git bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
index 803dc5f..df673c5 100644
--- bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
+++ bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
@@ -3,14 +3,19 @@ package com.liato.bankdroid.utils;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.net.ConnectException;
+
 import eu.nullbyte.android.urllib.Urllib;
+import not.bankdroid.at.all.ExceptionThrower;
 
+@SuppressWarnings("CallToPrintStackTrace")
 public class ExceptionUtilsTest {
     @Test
-    @SuppressWarnings("PMD") // This is for the stack trace printing, we really want to do it here
-    public void bankdroidifyException() throws Exception {
+    @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.AvoidCatchingNPE", "PMD.SystemPrintln"})
+    public void testBankdroidifyException() throws Exception {
         Exception raw = null;
         try {
+            //noinspection ConstantConditions
             new Urllib(null);
             Assert.fail("Exception expected");
         } catch (NullPointerException e) {
@@ -38,4 +43,45 @@ public class ExceptionUtilsTest {
         // Verify that re-bankdroidifying is a no-op
         Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified));
     }
+
+    /**
+     * Test that we can wrap exceptions without (String) constructors.
+     */
+    @Test
+    @SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"})
+    public void testBankdroidifyWonkyException() {
+        ExceptionThrower.WonkyException raw = null;
+        try {
+            ExceptionThrower.throwWonkyException();
+            Assert.fail("Exception expected");
+        } catch (ExceptionThrower.WonkyException e) {
+            raw = e;
+        }
+
+        // Print stack traces, useful if the tests fail
+        System.err.println("Before:");
+        raw.printStackTrace();
+
+        // Since bankdroidify() won't be able to create a WonkyException, it
+        // should fall back to creating something it extends
+        ConnectException bankdroidified = ExceptionUtils.bankdroidifyException(raw);
+
+        System.err.println();
+        System.err.println("After:");
+        bankdroidified.printStackTrace();
+
+        Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid",
+                raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+
+        Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid",
+                bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+
+        Assert.assertEquals(raw.getMessage(), bankdroidified.getMessage());
+
+        // Verify that e is the cause of bankdroidified
+        Assert.assertSame(raw, bankdroidified.getCause());
+
+        // Verify that re-bankdroidifying is a no-op
+        Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified));
+    }
 }
diff --git bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionThrower.java bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionThrower.java
new file mode 100644
index 0000000..1d21a09
--- /dev/null
+++ bankdroid-legacy/src/test/java/not/bankdroid/at/all/ExceptionThrower.java
@@ -0,0 +1,18 @@
+package not.bankdroid.at.all;
+
+import java.net.ConnectException;
+
+/**
+ * For the test in {@link com.liato.bankdroid.utils.ExceptionUtilsTest}
+ */
+public class ExceptionThrower {
+    public static class WonkyException extends ConnectException {
+        public WonkyException(int wonky) {
+            super("Wonky: " + wonky);
+        }
+    }
+
+    public static void throwWonkyException() throws WonkyException {
+        throw new WonkyException(5);
+    }
+}

commit 04230928f02c083eafa9c631bb82c09f54ce8143
Author: Johan Walles <walles@spotify.com>
Date:   Fri Nov 4 11:26:49 2016 +0100

    PMD: Enforce variable naming
    
    Inspired by a review for another change; these things are better found
    by tooling.
    
    Non-final fields with NAMING_INDICATING_FINALITY have been turned into
    final fields when possible.
    
    In Bank.java, refactored the API a bit so that bank names can be
    constant.

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 835c64e..88c142e 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -81,9 +81,9 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
     @InjectView(R.id.txtErrorDesc)
     TextView mErrorDescription;
 
-    private Bank SELECTED_BANK;
+    private Bank selectedBank;
 
-    private long BANKID = -1;
+    private long bankId = -1;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -101,16 +101,16 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
         Bundle extras = getIntent().getExtras();
         if (extras != null) {
-            BANKID = extras.getLong("id", -1);
-            if (BANKID != -1) {
-                Bank bank = BankFactory.bankFromDb(BANKID, this, false);
+            bankId = extras.getLong("id", -1);
+            if (bankId != -1) {
+                Bank bank = BankFactory.bankFromDb(bankId, this, false);
                 if (bank != null) {
                     mErrorDescription.setVisibility(
                             bank.isDisabled() ? View.VISIBLE : View.INVISIBLE);
                     mBankSpinner.setEnabled(false);
                     mBankSpinner.setSelection(adapter.getPosition(bank));
-                    SELECTED_BANK = bank;
-                    createForm(SELECTED_BANK.getConnectionConfiguration(),
+                    selectedBank = bank;
+                    createForm(selectedBank.getConnectionConfiguration(),
                             DefaultConnectionConfiguration.fields()
                     );
                     populateForm(bank);
@@ -125,10 +125,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
         if (!validate()) {
             return;
         }
-        SELECTED_BANK.setProperties(getFormParameters(SELECTED_BANK.getConnectionConfiguration()));
-        SELECTED_BANK.setCustomName(getFormParameter(DefaultConnectionConfiguration.NAME));
-        SELECTED_BANK.setDbid(BANKID);
-        new DataRetrieverTask(this, SELECTED_BANK).execute();
+        selectedBank.setProperties(getFormParameters(selectedBank.getConnectionConfiguration()));
+        selectedBank.setCustomName(getFormParameter(DefaultConnectionConfiguration.NAME));
+        selectedBank.setDbid(bankId);
+        new DataRetrieverTask(this, selectedBank).execute();
     }
 
     @OnClick(R.id.btnSettingsCancel)
@@ -139,10 +139,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
     @Override
     public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
         Bank selectedBank = (Bank) parentView.getItemAtPosition(pos);
-        if (SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) {
-            SELECTED_BANK = selectedBank;
+        if (this.selectedBank == null || !this.selectedBank.equals(selectedBank)) {
+            this.selectedBank = selectedBank;
                     mFormContainer.removeAllViewsInLayout();
-            createForm(SELECTED_BANK.getConnectionConfiguration(),
+            createForm(this.selectedBank.getConnectionConfiguration(),
                     DefaultConnectionConfiguration.fields()
             );
         }
@@ -233,7 +233,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
     private boolean validate() {
         boolean valid = true;
-        Iterator<Field> fields = Iterators.concat(SELECTED_BANK.getConnectionConfiguration().iterator(),
+        Iterator<Field> fields = Iterators.concat(selectedBank.getConnectionConfiguration().iterator(),
                 DefaultConnectionConfiguration.fields().iterator());
         while (fields.hasNext()) {
             Field field = fields.next();
@@ -357,8 +357,8 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
                     builder.setTitle(R.string.select_a_bank);
                     builder.setItems(items, new DialogInterface.OnClickListener() {
                         public void onClick(DialogInterface dialog, int item) {
-                            SELECTED_BANK.setExtras(e.getBanks().get(item).getId());
-                            new DataRetrieverTask(context, SELECTED_BANK).execute();
+                            selectedBank.setExtras(e.getBanks().get(item).getId());
+                            new DataRetrieverTask(context, selectedBank).execute();
                         }
                     });
                 } else {
diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index 1b5720f..397b3e1 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -40,7 +40,7 @@ import android.view.WindowManager;
 
 public class LockableActivity extends ActionBarActivity {
 
-    private static int PATTERNLOCK_UNLOCK = 42;
+    private static final int PATTERNLOCK_UNLOCK = 42;
 
     protected boolean mSkipLockOnce = false;
 
diff --git app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
index ffa55f5..b690302 100644
--- app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -31,7 +31,7 @@ import android.view.WindowManager;
 
 public class LockablePreferenceActivity extends PreferenceActivity {
 
-    private static int PATTERNLOCK_UNLOCK = 42;
+    private static final int PATTERNLOCK_UNLOCK = 42;
 
     private SharedPreferences mPrefs;
 
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 48acb74..98c8a2b 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -59,9 +59,9 @@ public class MainActivity extends LockableActivity {
 
     protected static boolean showHidden = false;
 
-    private static Bank selected_bank = null;
+    private static Bank selectedBank = null;
 
-    private static Account selected_account = null;
+    private static Account selectedAccount = null;
 
     private final BroadcastReceiver receiver = new BroadcastReceiver() {
         @Override
@@ -91,14 +91,14 @@ public class MainActivity extends LockableActivity {
             public boolean onItemLongClick(final AdapterView<?> parent, final View view,
                     final int position, final long id) {
                 if (adapter.getItem(position) instanceof Account) {
-                    selected_account = (Account) adapter.getItem(position);
+                    selectedAccount = (Account) adapter.getItem(position);
                     final PopupMenuAccount pmenu = new PopupMenuAccount(parent, view, MainActivity.this);
                     pmenu.showLikeQuickAction(0, 12);
                     return true;
                 } else if (adapter.getItem(position) instanceof Bank) {
-                    selected_bank = (Bank) adapter.getItem(position);
-                    selected_bank.toggleHideAccounts();
-                    DBAdapter.save(selected_bank, MainActivity.this);
+                    selectedBank = (Bank) adapter.getItem(position);
+                    selectedBank.toggleHideAccounts();
+                    DBAdapter.save(selectedBank, MainActivity.this);
                     refreshView();
                     return true;
                 }
@@ -110,7 +110,7 @@ public class MainActivity extends LockableActivity {
             public void onItemClick(final AdapterView<?> parent, final View view,
                     final int position, final long id) {
                 if (adapter.getItem(position) instanceof Bank) {
-                    selected_bank = (Bank) adapter.getItem(position);
+                    selectedBank = (Bank) adapter.getItem(position);
                     final PopupMenuBank pmenu = new PopupMenuBank(parent, view, MainActivity.this);
                     pmenu.showLikeQuickAction(0, 12);
                 } else {
@@ -241,7 +241,7 @@ public class MainActivity extends LockableActivity {
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnWWW = (Button) root.findViewById(R.id.btnWWW);
-            if (selected_bank.getHideAccounts()) {
+            if (selectedBank.getHideAccounts()) {
                 btnHide.setVisibility(View.GONE);
                 btnUnhide.setVisibility(View.VISIBLE);
                 btnUnhide.setOnClickListener(this);
@@ -250,7 +250,7 @@ public class MainActivity extends LockableActivity {
                 btnUnhide.setVisibility(View.GONE);
                 btnHide.setOnClickListener(this);
             }
-            if (selected_bank.isWebViewEnabled()) {
+            if (selectedBank.isWebViewEnabled()) {
                 btnWWW.setOnClickListener(this);
             } else {
                 btnWWW.setVisibility(View.GONE);
@@ -270,29 +270,29 @@ public class MainActivity extends LockableActivity {
                 case R.id.btnHide:
                 case R.id.btnUnhide:
                     this.dismiss();
-                    selected_bank.toggleHideAccounts();
-                    DBAdapter.save(selected_bank, context);
+                    selectedBank.toggleHideAccounts();
+                    DBAdapter.save(selectedBank, context);
                     parent.refreshView();
                     return;
                 case R.id.btnWWW:
-                    if (selected_bank != null && selected_bank.isWebViewEnabled()) {
-                        //Uri uri = Uri.parse(selected_bank.getURL());
+                    if (selectedBank != null && selectedBank.isWebViewEnabled()) {
+                        //Uri uri = Uri.parse(selectedBank.getURL());
                         //Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                         final Intent intent = new Intent(context, WebViewActivity.class);
-                        intent.putExtra("bankid", selected_bank.getDbId());
+                        intent.putExtra("bankid", selectedBank.getDbId());
                         context.startActivity(intent);
                     }
                     this.dismiss();
                     return;
                 case R.id.btnEdit:
                     final Intent intent = new Intent(context, BankEditActivity.class);
-                    intent.putExtra("id", selected_bank.getDbId());
+                    intent.putExtra("id", selectedBank.getDbId());
                     context.startActivity(intent);
                     this.dismiss();
                     return;
                 case R.id.btnRefresh:
                     this.dismiss();
-                    new DataRetrieverTask(parent, selected_bank.getDbId()).execute();
+                    new DataRetrieverTask(parent, selectedBank.getDbId()).execute();
                     return;
                 case R.id.btnRemove:
                     this.dismiss();
@@ -307,7 +307,7 @@ public class MainActivity extends LockableActivity {
                                         public void onClick(final DialogInterface dialog,
                                                 final int id) {
                                             final DBAdapter db = new DBAdapter(context);
-                                            db.deleteBank(selected_bank.getDbId());
+                                            db.deleteBank(selectedBank.getDbId());
                                             dialog.cancel();
                                             parent.refreshView();
                                         }
@@ -358,7 +358,7 @@ public class MainActivity extends LockableActivity {
                     .findViewById(R.id.btnDisableNotifications);
             final Button btnEnableNotifications = (Button) root
                     .findViewById(R.id.btnEnableNotifications);
-            if (selected_account.isHidden()) {
+            if (selectedAccount.isHidden()) {
                 btnHide.setVisibility(View.GONE);
                 btnUnhide.setVisibility(View.VISIBLE);
                 btnUnhide.setOnClickListener(this);
@@ -367,7 +367,7 @@ public class MainActivity extends LockableActivity {
                 btnUnhide.setVisibility(View.GONE);
                 btnHide.setOnClickListener(this);
             }
-            if (selected_account.isNotify()) {
+            if (selectedAccount.isNotify()) {
                 btnDisableNotifications.setVisibility(View.VISIBLE);
                 btnDisableNotifications.setOnClickListener(this);
                 btnEnableNotifications.setVisibility(View.GONE);
@@ -385,26 +385,26 @@ public class MainActivity extends LockableActivity {
             switch (id) {
                 case R.id.btnHide:
                     this.dismiss();
-                    selected_account.setHidden(true);
-                    DBAdapter.save(selected_account.getBank(), parent);
+                    selectedAccount.setHidden(true);
+                    DBAdapter.save(selectedAccount.getBank(), parent);
                     parent.refreshView();
                     return;
                 case R.id.btnUnhide:
                     this.dismiss();
-                    selected_account.setHidden(false);
-                    DBAdapter.save(selected_account.getBank(), parent);
+                    selectedAccount.setHidden(false);
+                    DBAdapter.save(selectedAccount.getBank(), parent);
                     parent.refreshView();
                     return;
                 case R.id.btnEnableNotifications:
                     this.dismiss();
-                    selected_account.setNotify(true);
-                    DBAdapter.save(selected_account.getBank(), parent);
+                    selectedAccount.setNotify(true);
+                    DBAdapter.save(selectedAccount.getBank(), parent);
                     parent.refreshView();
                     return;
                 case R.id.btnDisableNotifications:
                     this.dismiss();
-                    selected_account.setNotify(false);
-                    DBAdapter.save(selected_account.getBank(), parent);
+                    selectedAccount.setNotify(false);
+                    DBAdapter.save(selectedAccount.getBank(), parent);
                     parent.refreshView();
                     return;
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 7a82c5b..6af968b 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -394,15 +394,15 @@ public class AutoRefreshService extends Service {
                     }
                 } catch (final BankException e) {
                     // Refresh widgets if an update fails
-                    Timber.e(e, "Could not update bank %s", bank.getShortName());
+                    Timber.e(e, "Could not update bank %s", bank.getName());
                 } catch (final LoginException e) {
-                    Timber.d(e, "Invalid credentials for bank %s", bank.getShortName());
+                    Timber.d(e, "Invalid credentials for bank %s", bank.getName());
                     refreshWidgets = true;
                     db.disableBank(bank.getDbId());
                 } catch (BankChoiceException e) {
                     Timber.w(e, "BankChoiceException");
                 } catch (Exception e) {
-                    Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getShortName());
+                    Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getName());
                 }
             }
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index fd0011c..e6dfd7f 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -390,15 +390,15 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
                     }
 
                 } catch (BankException e) {
-                    Timber.e(e, "Could not update bank %s", bank.getShortName());
+                    Timber.e(e, "Could not update bank %s", bank.getName());
                 } catch (LoginException e) {
-                    Timber.w(e, "Invalid credentials for bank %s", bank.getShortName());
+                    Timber.w(e, "Invalid credentials for bank %s", bank.getName());
                     DBAdapter.disable(bank, context);
                 } catch (BankChoiceException e) {
                     Timber.w(e, "BankChoiceException");
                 } catch (IOException e) {
                     if (NetworkUtils.isInternetAvailable()) {
-                        Timber.e(e, "Could not update bank %s", bank.getShortName());
+                        Timber.e(e, "Could not update bank %s", bank.getName());
                     }
                 }
                 BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
diff --git app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 3e16654..0610ad7 100644
--- app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -67,44 +67,44 @@ public class BankTransactionsProvider extends ContentProvider implements
 
     private static final String TRANSACTIONS_TABLE = "transactions";
 
-    private final static UriMatcher uriMatcher;
+    private final static UriMatcher URI_MATCHER;
 
-    private final static Map<String, String> bankAccountProjectionMap;
+    private final static Map<String, String> BANK_ACCOUNT_PROJECTION_MAP;
 
-    private final static Map<String, String> transProjectionMap;
+    private final static Map<String, String> TRANS_PROJECTION_MAP;
 
     static {
-        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-        uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD,
+        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+        URI_MATCHER.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD,
                 TRANSACTIONS);
-        uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD,
+        URI_MATCHER.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD,
                 BANK_ACCOUNTS);
 
         // Projections are "Poor mans views" of the data.
-        bankAccountProjectionMap = new HashMap<String, String>();
+        BANK_ACCOUNT_PROJECTION_MAP = new HashMap<String, String>();
 
         // Must match bankAccountProjection in
         // IBankTransactionsProvider#bankAccountProjection
-        bankAccountProjectionMap.put(BANK_ID, BANK_ID);
-        bankAccountProjectionMap.put(BANK_NAME, BANK_NAME);
-        bankAccountProjectionMap.put(BANK_TYPE, BANK_TYPE);
-        bankAccountProjectionMap.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED);
-        bankAccountProjectionMap.put(ACC_ID, ACC_ID);
-        bankAccountProjectionMap.put(ACC_NAME, ACC_NAME);
+        BANK_ACCOUNT_PROJECTION_MAP.put(BANK_ID, BANK_ID);
+        BANK_ACCOUNT_PROJECTION_MAP.put(BANK_NAME, BANK_NAME);
+        BANK_ACCOUNT_PROJECTION_MAP.put(BANK_TYPE, BANK_TYPE);
+        BANK_ACCOUNT_PROJECTION_MAP.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED);
+        BANK_ACCOUNT_PROJECTION_MAP.put(ACC_ID, ACC_ID);
+        BANK_ACCOUNT_PROJECTION_MAP.put(ACC_NAME, ACC_NAME);
         // Table name has to be explicitly included here since Banks also have a column named balance.
-        bankAccountProjectionMap.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE);
-        bankAccountProjectionMap.put(ACC_TYPE, ACC_TYPE);
+        BANK_ACCOUNT_PROJECTION_MAP.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE);
+        BANK_ACCOUNT_PROJECTION_MAP.put(ACC_TYPE, ACC_TYPE);
 
-        transProjectionMap = new HashMap<String, String>();
+        TRANS_PROJECTION_MAP = new HashMap<String, String>();
 
         // Must match transactionProjection in
         // IBankTransactionsProvider#transactionProjection
-        transProjectionMap.put(TRANS_ID, TRANS_ID);
-        transProjectionMap.put(TRANS_DATE, TRANS_DATE);
-        transProjectionMap.put(TRANS_DESC, TRANS_DESC);
-        transProjectionMap.put(TRANS_AMT, TRANS_AMT);
-        transProjectionMap.put(TRANS_CUR, TRANS_CUR);
-        transProjectionMap.put(TRANS_ACCNT, TRANS_ACCNT);
+        TRANS_PROJECTION_MAP.put(TRANS_ID, TRANS_ID);
+        TRANS_PROJECTION_MAP.put(TRANS_DATE, TRANS_DATE);
+        TRANS_PROJECTION_MAP.put(TRANS_DESC, TRANS_DESC);
+        TRANS_PROJECTION_MAP.put(TRANS_AMT, TRANS_AMT);
+        TRANS_PROJECTION_MAP.put(TRANS_CUR, TRANS_CUR);
+        TRANS_PROJECTION_MAP.put(TRANS_ACCNT, TRANS_ACCNT);
     }
 
     private DatabaseHelper dbHelper;
@@ -143,7 +143,7 @@ public class BankTransactionsProvider extends ContentProvider implements
     public String getType(final Uri uri) {
         Timber.d("Got URI: %s", uri.toString());
 
-        switch (uriMatcher.match(uri)) {
+        switch (URI_MATCHER.match(uri)) {
             case BANK_ACCOUNTS:
                 return BANK_ACCOUNTS_MIME;
             case TRANSACTIONS:
@@ -207,12 +207,12 @@ public class BankTransactionsProvider extends ContentProvider implements
         if (BANK_ACCOUNTS_MIME.equals(getType(uri))) {
             qb = new SQLiteQueryBuilder();
             qb.setTables(BANK_ACCOUNT_TABLES);
-            qb.setProjectionMap(bankAccountProjectionMap);
+            qb.setProjectionMap(BANK_ACCOUNT_PROJECTION_MAP);
             qb.setDistinct(true);
         } else if (TRANSACTIONS_MIME.equals(getType(uri))) {
             qb = new SQLiteQueryBuilder();
             qb.setTables(TRANSACTIONS_TABLE);
-            qb.setProjectionMap(transProjectionMap);
+            qb.setProjectionMap(TRANS_PROJECTION_MAP);
         } else {
             throw new IllegalArgumentException("Unsupported URI: " + uri);
         }
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
index 87a0c1d..8997f8f 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -41,7 +41,7 @@ public class ColorPickerPreference
         Preference.OnPreferenceClickListener,
         ColorPickerDialog.OnColorChangedListener {
 
-    private static final String androidns = "http://schemas.android.com/apk/res/android";
+    private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android";
 
     private ViewGroup parent;
 
@@ -137,7 +137,7 @@ public class ColorPickerPreference
         mDensity = getContext().getResources().getDisplayMetrics().density;
         setOnPreferenceClickListener(this);
         if (attrs != null) {
-            String defaultValue = attrs.getAttributeValue(androidns, "defaultValue");
+            String defaultValue = attrs.getAttributeValue(ANDROID_NS, "defaultValue");
             if (defaultValue.startsWith("#")) {
                 try {
                     mDefaultValue = convertToColorInt(defaultValue);
@@ -146,7 +146,7 @@ public class ColorPickerPreference
                     mDefaultValue = convertToColorInt("#FF000000");
                 }
             } else {
-                int resourceId = attrs.getAttributeResourceValue(androidns, "defaultValue", 0);
+                int resourceId = attrs.getAttributeResourceValue(ANDROID_NS, "defaultValue", 0);
                 if (resourceId != 0) {
                     mDefaultValue = context.getResources().getInteger(resourceId);
                 }
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
index 8ff79d3..13af48e 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -64,29 +64,29 @@ public class ColorPickerView extends View {
     /**
      * The width in dp of the hue panel.
      */
-    private float HUE_PANEL_WIDTH = 30f;
+    private float huePanelWidth = 30f;
 
     /**
      * The height in dp of the alpha panel
      */
-    private float ALPHA_PANEL_HEIGHT = 20f;
+    private float alphaPanelHeight = 20f;
 
     /**
      * The distance in dp between the different
      * color panels.
      */
-    private float PANEL_SPACING = 10f;
+    private float panelSpacing = 10f;
 
     /**
      * The radius in dp of the color palette tracker circle.
      */
-    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
+    private float paletteCircleTrackerRadius = 5f;
 
     /**
      * The dp which the tracker of the hue or alpha panel
      * will extend outside of its bounds.
      */
-    private float RECTANGLE_TRACKER_OFFSET = 2f;
+    private float rectangleTrackerOffset = 2f;
 
     private float mDensity = 1f;
 
@@ -172,11 +172,11 @@ public class ColorPickerView extends View {
             setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         }
         mDensity = getContext().getResources().getDisplayMetrics().density;
-        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
-        RECTANGLE_TRACKER_OFFSET *= mDensity;
-        HUE_PANEL_WIDTH *= mDensity;
-        ALPHA_PANEL_HEIGHT *= mDensity;
-        PANEL_SPACING = PANEL_SPACING * mDensity;
+        paletteCircleTrackerRadius *= mDensity;
+        rectangleTrackerOffset *= mDensity;
+        huePanelWidth *= mDensity;
+        alphaPanelHeight *= mDensity;
+        panelSpacing = panelSpacing * mDensity;
 
         mDrawingOffset = calculateRequiredOffset();
 
@@ -216,7 +216,7 @@ public class ColorPickerView extends View {
     }
 
     private float calculateRequiredOffset() {
-        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
+        float offset = Math.max(paletteCircleTrackerRadius, rectangleTrackerOffset);
         offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
 
         return offset * 1.5f;
@@ -274,11 +274,11 @@ public class ColorPickerView extends View {
         Point p = satValToPoint(mSat, mVal);
 
         mSatValTrackerPaint.setColor(0xff000000);
-        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity,
+        canvas.drawCircle(p.x, p.y, paletteCircleTrackerRadius - 1f * mDensity,
                 mSatValTrackerPaint);
 
         mSatValTrackerPaint.setColor(0xffdddddd);
-        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
+        canvas.drawCircle(p.x, p.y, paletteCircleTrackerRadius, mSatValTrackerPaint);
 
     }
 
@@ -308,8 +308,8 @@ public class ColorPickerView extends View {
         Point p = hueToPoint(mHue);
 
         RectF r = new RectF();
-        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
-        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
+        r.left = rect.left - rectangleTrackerOffset;
+        r.right = rect.right + rectangleTrackerOffset;
         r.top = p.y - rectHeight;
         r.bottom = p.y + rectHeight;
 
@@ -359,8 +359,8 @@ public class ColorPickerView extends View {
         RectF r = new RectF();
         r.left = p.x - rectWidth;
         r.right = p.x + rectWidth;
-        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
-        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
+        r.top = rect.top - rectangleTrackerOffset;
+        r.bottom = rect.bottom + rectangleTrackerOffset;
 
         canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
 
@@ -663,22 +663,22 @@ public class ColorPickerView extends View {
 
         if (!mShowAlphaPanel) {
 
-            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
+            height = (int) (widthAllowed - panelSpacing - huePanelWidth);
 
             //If calculated height (based on the width) is more than the allowed height.
             if (height > heightAllowed || getTag().equals("landscape")) {
                 height = heightAllowed;
-                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
+                width = (int) (height + panelSpacing + huePanelWidth);
             } else {
                 width = widthAllowed;
             }
         } else {
 
-            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
+            width = (int) (heightAllowed - alphaPanelHeight + huePanelWidth);
 
             if (width > widthAllowed) {
                 width = widthAllowed;
-                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
+                height = (int) (widthAllowed - huePanelWidth + alphaPanelHeight);
             } else {
                 height = heightAllowed;
             }
@@ -709,10 +709,10 @@ public class ColorPickerView extends View {
         int width = getPrefferedHeight();
 
         if (mShowAlphaPanel) {
-            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
+            width -= (panelSpacing + alphaPanelHeight);
         }
 
-        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
+        return (int) (width + huePanelWidth + panelSpacing);
 
     }
 
@@ -721,7 +721,7 @@ public class ColorPickerView extends View {
         int height = (int) (200 * mDensity);
 
         if (mShowAlphaPanel) {
-            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+            height += panelSpacing + alphaPanelHeight;
         }
 
         return height;
@@ -748,7 +748,7 @@ public class ColorPickerView extends View {
         float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
 
         if (mShowAlphaPanel) {
-            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+            panelSide -= panelSpacing + alphaPanelHeight;
         }
 
         float left = dRect.left + BORDER_WIDTH_PX;
@@ -762,10 +762,10 @@ public class ColorPickerView extends View {
     private void setUpHueRect() {
         final RectF dRect = mDrawingRect;
 
-        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
+        float left = dRect.right - huePanelWidth + BORDER_WIDTH_PX;
         float top = dRect.top + BORDER_WIDTH_PX;
-        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING
-                + ALPHA_PANEL_HEIGHT) : 0);
+        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (panelSpacing
+                + alphaPanelHeight) : 0);
         float right = dRect.right - BORDER_WIDTH_PX;
 
         mHueRect = new RectF(left, top, right, bottom);
@@ -780,7 +780,7 @@ public class ColorPickerView extends View {
         final RectF dRect = mDrawingRect;
 
         float left = dRect.left + BORDER_WIDTH_PX;
-        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
+        float top = dRect.bottom - alphaPanelHeight + BORDER_WIDTH_PX;
         float bottom = dRect.bottom - BORDER_WIDTH_PX;
         float right = dRect.right - BORDER_WIDTH_PX;
 
diff --git app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
index b821497..5e3de22 100644
--- app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
+++ app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.appwidget;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -56,6 +57,16 @@ public class DataRetrieverTaskTest {
         public BigDecimal getBalance() {
             return getAccounts().get(0).getBalance();
         }
+
+        @Override
+        public int getBanktypeId() {
+            return IBankTypes.TESTBANK;
+        }
+
+        @Override
+        public String getName() {
+            return "Testbanken";
+        }
     }
 
     private static class TestableDataRetrieverTask extends AutoRefreshService.DataRetrieverTask {
diff --git bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
index 3a47c5b..2fefbb9 100644
--- bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
+++ bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
@@ -12,7 +12,7 @@ public class DefaultConnectionConfiguration {
 
     public static final String NAME = "provider.configuration.name";
 
-    private final static List<Field> configuration = createConfiguration();
+    private final static List<Field> CONFIGURATION = createConfiguration();
 
     private static List<Field> createConfiguration() {
         List<Field> configuration = new ArrayList<>();
@@ -24,6 +24,6 @@ public class DefaultConnectionConfiguration {
     }
 
     public static List<Field> fields() {
-        return configuration;
+        return CONFIGURATION;
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
index 2ea759a..7e53cf4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
@@ -38,7 +38,7 @@ import timber.log.Timber;
 public class Helpers {
     private static final StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan();
 
-    private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS",
+    private final static String[] CURRENCIES = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS",
             "AUD",
             "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
             "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
@@ -62,7 +62,7 @@ public class Helpers {
             "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER",
             "ZAR", "ZMK", "ZWD"};
 
-    private final static String[][] symMappings = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"},
+    private final static String[][] SYM_MAPPINGS = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"},
             {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"},
             {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"},
             {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"},
@@ -148,12 +148,12 @@ public class Helpers {
 
     public static String parseCurrency(String text, String def) {
         text = text != null ? text.toLowerCase() : "";
-        for (String currency : currencies) {
+        for (String currency : CURRENCIES) {
             if (text.contains(currency)) {
                 return currency;
             }
         }
-        for (String[] symCur : symMappings) {
+        for (String[] symCur : SYM_MAPPINGS) {
             if (text.contains(symCur[0])) {
                 return symCur[1];
             }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 18a6a0c..b3f6e97 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -54,14 +54,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     @DrawableRes
     private final int logoResource;
 
-    protected String TAG = "Bank";
-
-    protected String NAME = "Bank";
-
-    protected String NAME_SHORT = "bank";
-
-    protected int BANKTYPE_ID = 0;
-
     /**
      * URL for human-accessible web bank.
      * <p/>
@@ -71,43 +63,43 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
      * @see #isWebViewEnabled()
      */
     @Nullable
-    protected String URL;
+    protected String url;
 
-    protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+    protected int inputTypeUsername = InputType.TYPE_CLASS_TEXT;
 
-    protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT
+    protected int inputTypePassword = InputType.TYPE_CLASS_TEXT
             | InputType.TYPE_TEXT_VARIATION_PASSWORD;
 
-    protected int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT;
+    private static final int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT;
 
-    protected String INPUT_HINT_USERNAME = null;
+    protected String inputHintUsername = null;
 
-    protected boolean INPUT_HIDDEN_USERNAME = false;
+    private static final boolean INPUT_HIDDEN_USERNAME = false;
 
-    protected boolean INPUT_HIDDEN_PASSWORD = false;
+    protected boolean inputHiddenPassword = false;
 
-    protected boolean INPUT_HIDDEN_EXTRAS = true;
+    private static final boolean INPUT_HIDDEN_EXTRAS = true;
 
-    protected int INPUT_TITLETEXT_USERNAME = R.string.username;
+    protected int inputTitletextUsername = R.string.username;
 
-    protected int INPUT_TITLETEXT_PASSWORD = R.string.password;
+    private final int INPUT_TITLETEXT_PASSWORD = R.string.password;
 
-    protected int INPUT_TITLETEXT_EXTRAS = R.string.extras_field;
+    private final int INPUT_TITLETEXT_EXTRAS = R.string.extras_field;
 
-    protected boolean STATIC_BALANCE = false;
+    protected boolean staticBalance = false;
 
-    protected boolean BROKEN = false;
+    private static final boolean BROKEN = false;
 
-    protected boolean DISPLAY_DECIMALS = true;
+    protected boolean displayDecimals = true;
 
     /**
      * Whether or not we support opening the web version of a bank.
      * <p/>
      * Lots of banks don't have this any more, but have apps instead.
      * @see #isWebViewEnabled()
-     * @see #URL
+     * @see #url
      */
-    protected boolean WEB_VIEW_ENABLED = true;
+    protected boolean webViewEnabled = true;
 
     protected Context context;
 
@@ -229,7 +221,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public BigDecimal getBalance() {
-        if (STATIC_BALANCE) {
+        if (staticBalance) {
             return balance;
         } else {
             BigDecimal bal = new BigDecimal(0);
@@ -246,13 +238,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         }
     }
 
-    public int getBanktypeId() {
-        return BANKTYPE_ID;
-    }
+    public abstract int getBanktypeId();
 
-    public String getName() {
-        return NAME;
-    }
+    public abstract String getName();
 
     public String getDisplayName() {
         if (customName != null && customName.length() > 0) {
@@ -278,10 +266,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         getProperties().put(LegacyProviderConfiguration.EXTRAS, extras);
       }
 
-    public String getShortName() {
-        return NAME_SHORT;
-    }
-
     public void setData(BigDecimal balance,
             boolean disabled, long dbid, String currency, String customName,
             int hideAccounts) {
@@ -314,15 +298,15 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getURL() {
-        return URL;
+        return url;
     }
 
     public int getInputTypeUsername() {
-        return INPUT_TYPE_USERNAME;
+        return inputTypeUsername;
     }
 
     public int getInputTypePassword() {
-        return INPUT_TYPE_PASSWORD;
+        return inputTypePassword;
     }
 
     public int getInputTypeExtras() {
@@ -330,7 +314,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getInputHintUsername() {
-        return INPUT_HINT_USERNAME;
+        return inputHintUsername;
     }
 
     public boolean isInputUsernameHidden() {
@@ -338,7 +322,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public boolean isInputPasswordHidden() {
-        return INPUT_HIDDEN_PASSWORD;
+        return inputHiddenPassword;
     }
 
     public boolean isInputExtrasHidden() {
@@ -346,7 +330,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public int getInputTitleUsername() {
-        return INPUT_TITLETEXT_USERNAME;
+        return inputTitletextUsername;
     }
 
     public int getInputTitlePassword() {
@@ -361,11 +345,11 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
      * Whether or not we support opening the web version of a bank.
      * <p/>
      * Lots of banks don't have this any more, but have apps instead.
-     * @see #WEB_VIEW_ENABLED
-     * @see #URL
+     * @see #webViewEnabled
+     * @see #url
      */
     public boolean isWebViewEnabled() {
-        return URL != null && WEB_VIEW_ENABLED;
+        return url != null && webViewEnabled;
     }
 
     public Map<String, String> getProperties() {
@@ -455,7 +439,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             Timber.e(e, "Error getting session package");
         }
         String html = String.format(preloader,
-                String.format("function go(){window.location=\"%s\" }", this.URL),
+                String.format("function go(){window.location=\"%s\" }", this.url),
                 // Javascript function
                 "<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
         );
@@ -467,7 +451,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public boolean getDisplayDecimals() {
-        return DISPLAY_DECIMALS;
+        return displayDecimals;
     }
 
     protected Context getContext() {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 1abfc23..61ce9dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -58,10 +58,10 @@ public abstract class AbsIkanoPartner extends Bank {
 
     public AbsIkanoPartner(Context context, @DrawableRes int logoResource) {
         super(context, logoResource);
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = true;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = true;
     }
 
     public AbsIkanoPartner(String username, String password, Context context, @DrawableRes int logoResource)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index f84865b..848b842 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -46,8 +46,6 @@ public class AkeliusInvest extends Bank {
 
     private static final String NAME = "Akelius Invest";
 
-    private static final String NAME_SHORT = "akeliusinvest";
-
     private static final String URL = "https://online.akeliusinvest.com/";
 
     private static final int BANKTYPE_ID = IBankTypes.AKELIUSINVEST;
@@ -80,14 +78,11 @@ public class AkeliusInvest extends Bank {
 
     public AkeliusInvest(Context context) {
         super(context, R.drawable.logo_akeliusinvest);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
     }
 
     public AkeliusInvest(String username, String password, Context context) throws BankException,
@@ -137,6 +132,16 @@ public class AkeliusInvest extends Bank {
         return urlopen;
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 038f0fe..715515e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -47,8 +47,6 @@ public class AkeliusSpar extends Bank {
 
     private static final String NAME = "Akelius Spar";
 
-    private static final String NAME_SHORT = "akeliusspar";
-
     private static final String URL = "https://www.online.akeliusspar.se/";
 
     private static final int BANKTYPE_ID = IBankTypes.AKELIUSSPAR;
@@ -81,14 +79,21 @@ public class AkeliusSpar extends Bank {
 
     public AkeliusSpar(Context context) {
         super(context, R.drawable.logo_akeliusspar);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public AkeliusSpar(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 4940fed..fd2e258 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -42,8 +42,6 @@ public class AppeakPoker extends Bank {
 
     private static final String NAME = "Appeak Poker";
 
-    private static final String NAME_SHORT = "appeakpoker";
-
     private static final String URL = "http://poker.appeak.se/";
 
     private static final int BANKTYPE_ID = Bank.APPEAKPOKER;
@@ -56,16 +54,23 @@ public class AppeakPoker extends Bank {
 
     public AppeakPoker(Context context) {
         super(context, R.drawable.logo_appeakpoker);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
-        super.DISPLAY_DECIMALS = false;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHiddenPassword = INPUT_HIDDEN_PASSWORD;
+        super.displayDecimals = false;
         currency = "chips";
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public AppeakPoker(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
         this(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
index cc859ac..5f7889b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -26,9 +26,16 @@ public class AvanzaMini extends Avanza {
 
     public AvanzaMini(Context context) {
         super(context, R.drawable.logo_avanzamini);
-        NAME = "Avanza Mini";
-        NAME_SHORT = "avanzamini";
-        URL = "https://www.avanza.se/mini/hem/";
-        BANKTYPE_ID = IBankTypes.AVANZAMINI;
+        url = "https://www.avanza.se/mini/hem/";
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return IBankTypes.AVANZAMINI;
+    }
+
+    @Override
+    public String getName() {
+        return "Avanza Mini";
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index eb46cac..536aafb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -44,8 +44,6 @@ public class BetterGlobe extends Bank {
 
     private static final String NAME = "Better Globe";
 
-    private static final String NAME_SHORT = "betterglobe";
-
     private static final String URL = "http://betterglobe.com";
 
     private static final int BANKTYPE_ID = IBankTypes.BETTERGLOBE;
@@ -70,17 +68,24 @@ public class BetterGlobe extends Bank {
 
     public BetterGlobe(Context context) {
         super(context, R.drawable.logo_betterglobe);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
         super.currency = "EUR";
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public BetterGlobe(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
         this(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index df9e368..55336d7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -46,8 +46,6 @@ public class Bioklubben extends Bank {
 
     private static final String NAME = "Bioklubben";
 
-    private static final String NAME_SHORT = "bioklubben";
-
     private static final String URL = "https://bioklubben.sf.se/Start.aspx";
 
     private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
@@ -58,17 +56,24 @@ public class Bioklubben extends Bank {
 
     public Bioklubben(Context context) {
         super(context, R.drawable.logo_bioklubben);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.DISPLAY_DECIMALS = DISPLAY_DECIMALS;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+        super.url = URL;
+        super.displayDecimals = DISPLAY_DECIMALS;
+        super.inputTypeUsername = InputType.TYPE_CLASS_TEXT
                 | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-        super.INPUT_HINT_USERNAME = context.getString(R.string.email);
+        super.inputHintUsername = context.getString(R.string.email);
         currency = context.getString(R.string.points);
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public Bioklubben(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
         this(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 62d977f..d2af51a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -42,8 +42,6 @@ public class BlekingeTrafiken extends Bank {
 
     private static final String NAME = "Blekingetrafiken";
 
-    private static final String NAME_SHORT = "blekingetrafiken";
-
     private static final String URL = "https://www.blekingetrafiken.se";
 
     private static final int BANKTYPE_ID = IBankTypes.BLEKINGETRAFIKEN;
@@ -52,15 +50,21 @@ public class BlekingeTrafiken extends Bank {
 
     public BlekingeTrafiken(Context context) {
         super(context, R.drawable.logo_blekingetrafiken);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        super.INPUT_HINT_USERNAME = "XXXXXXXXXX";
-        super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
-        super.INPUT_HIDDEN_PASSWORD = true;
+        super.url = URL;
+        super.inputTypeUsername = InputType.TYPE_CLASS_PHONE;
+        super.inputHintUsername = "XXXXXXXXXX";
+        super.inputTitletextUsername = R.string.card_number;
+        super.inputHiddenPassword = true;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
 
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public BlekingeTrafiken(String username, String password, Context context)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 60145b8..309ee6a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -63,11 +63,18 @@ public class Bredband2VoIP extends Bank {
 
     public Bredband2VoIP(Context context) {
         super(context, R.drawable.logo_bredband2voip);
-        NAME = "Bredband2 VoIP";
-        NAME_SHORT = "bredband2voip";
-        BANKTYPE_ID = IBankTypes.BREDBAND2VOIP;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        super.INPUT_HINT_USERNAME = "19XXXXXX-XXXX";
+        super.inputTypeUsername = InputType.TYPE_CLASS_PHONE;
+        super.inputHintUsername = "19XXXXXX-XXXX";
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return IBankTypes.BREDBAND2VOIP;
+    }
+
+    @Override
+    public String getName() {
+        return "Bredband2 VoIP";
     }
 
     public Bredband2VoIP(String username, String password, Context context)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index 7c35408..c821869 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -46,8 +46,6 @@ public class BrummerKF extends Bank {
 
     private static final String NAME = "Brummer KF & Pension";
 
-    private static final String NAME_SHORT = "brummer_kf";
-
     private static final String URL = "https://www.brummer.se/";
 
     private static final int BANKTYPE_ID = IBankTypes.BRUMMER_KF;
@@ -78,14 +76,21 @@ public class BrummerKF extends Bank {
 
     public BrummerKF(Context context) {
         super(context, R.drawable.logo_brummer_kf);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public BrummerKF(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index 3640850..1ba7084 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -49,8 +49,6 @@ public class CSN extends Bank {
 
     private static final String NAME = "CSN";
 
-    private static final String NAME_SHORT = "csn";
-
     private static final String URL = "https://www.csn.se/bas/inloggning/pinkod.do";
 
     private static final int BANKTYPE_ID = IBankTypes.CSN;
@@ -82,14 +80,21 @@ public class CSN extends Bank {
 
     public CSN(Context context) {
         super(context, R.drawable.logo_csn);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public CSN(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 5276b57..d59b8f2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -28,8 +28,6 @@ public class Chalmrest extends Bank {
 
     private static final String NAME = "Chalmrest";
 
-    private static final String NAME_SHORT = "chalmrest";
-
     private static final int BANKTYPE_ID = IBankTypes.CHALMREST;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -47,13 +45,20 @@ public class Chalmrest extends Bank {
 
     public Chalmrest(Context context) {
         super(context, R.drawable.logo_chalmrest);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
-        super.INPUT_HINT_USERNAME = "XXXXXXXXXXXXXXXX";
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
-        super.INPUT_HIDDEN_PASSWORD = true;
+        super.inputTitletextUsername = R.string.card_number;
+        super.inputHintUsername = "XXXXXXXXXXXXXXXX";
+        super.inputTypeUsername = InputType.TYPE_CLASS_NUMBER;
+        super.inputHiddenPassword = true;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Chalmrest(String username, String password, Context context) throws BankException,
@@ -110,30 +115,30 @@ public class Chalmrest extends Bank {
         }
         urlopen = login();
         response = urlopen.open("http://kortladdning3.chalmerskonferens.se/CardLoad_Order.aspx");
-        Matcher matcher;
-        Matcher matcher_b;
+        Matcher accountMatcher;
+        Matcher balanceMatcher;
 
-        matcher = reAccount.matcher(response);
-        if (matcher.find()) {
+        accountMatcher = reAccount.matcher(response);
+        if (accountMatcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
              * 1: Name              Kalle Karlsson
              */
 
-            matcher_b = reBalance.matcher(response);
-            if (matcher_b.find()) {
+            balanceMatcher = reBalance.matcher(response);
+            if (balanceMatcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
                  * 1: Balance              118 kr
                  */
 
-                String balanceString = matcher_b.group(1).replaceAll("\\<a[^>]*>", "")
+                String balanceString = balanceMatcher.group(1).replaceAll("\\<a[^>]*>", "")
                         .replaceAll("\\<[^>]*>", "").trim();
 
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
-                        Helpers.parseBalance(balanceString), matcher.group(1)));
+                accounts.add(new Account(Html.fromHtml(accountMatcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(balanceString), accountMatcher.group(1)));
                 balance = balance.add(Helpers.parseBalance(balanceString));
             }
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index af8c51f..4f5e687 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -49,8 +49,6 @@ public class DanskeBank extends Bank {
 
     private static final String NAME = "DanskeBank";
 
-    private static final String NAME_SHORT = "danskebank";
-
     private static final String URL
             = "https://mobil.danskebank.se/XI?WP=XAI&WO=Logon&WA=MBSELogon&gsSprog=SE&gsBrand=OEB";
 
@@ -82,13 +80,20 @@ public class DanskeBank extends Bank {
 
     public DanskeBank(Context context) {
         super(context, R.drawable.logo_danskebank);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public DanskeBank(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 729c222..0e2046d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -45,8 +45,6 @@ public class Everydaycard extends Bank {
 
     private static final String NAME = "Everydaycard";
 
-    private static final String NAME_SHORT = "everydaycard";
-
     private static final String URL = "http://www.everydaycard.se/mobil/";
 
     private static final int BANKTYPE_ID = IBankTypes.EVERYDAYCARD;
@@ -67,12 +65,19 @@ public class Everydaycard extends Bank {
 
     public Everydaycard(Context context) {
         super(context, R.drawable.logo_everydaycard);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Everydaycard(String username, String password, Context context)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 90a513c..cb8b9a4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -46,8 +46,6 @@ public class FirstCard extends Bank {
 
     private static final String NAME = "First Card";
 
-    private static final String NAME_SHORT = "firstcard";
-
     private static final String URL = "https://www.firstcard.se/login.jsp";
 
     private static final int BANKTYPE_ID = IBankTypes.FIRSTCARD;
@@ -68,12 +66,19 @@ public class FirstCard extends Bank {
 
     public FirstCard(Context context) {
         super(context, R.drawable.logo_firstcard);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public FirstCard(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index 8d97593..688d147 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -50,8 +50,6 @@ public class Hemkop extends Bank {
 
     private static final String NAME = "Hemköp Kundkort";
 
-    private static final String NAME_SHORT = "hemkop";
-
     private static final String URL = "https://www.hemkop.se/Mina-sidor/Logga-in/";
 
     private static final int BANKTYPE_ID = IBankTypes.HEMKOP;
@@ -65,12 +63,19 @@ public class Hemkop extends Bank {
     public Hemkop(Context context) {
         super(context, R.drawable.logo_hemkop);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Hemkop(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
index 0930038..3fed434 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
@@ -45,8 +45,6 @@ public class Hors extends Bank {
 
     private static final String NAME = "Hörs";
 
-    private static final String NAME_SHORT = "hors";
-
     private static final String URL = "http://www.dittkort.se/hors/";
 
     private static final int BANKTYPE_ID = IBankTypes.HORS;
@@ -58,15 +56,22 @@ public class Hors extends Bank {
     public Hors(Context context) {
         super(context, R.drawable.logo_hors);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.DISPLAY_DECIMALS = DISPLAY_DECIMALS;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+        super.url = URL;
+        super.displayDecimals = DISPLAY_DECIMALS;
+        super.inputTypeUsername = InputType.TYPE_CLASS_TEXT
                 | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-        super.INPUT_HINT_USERNAME = context.getString(R.string.card_id);
-        super.INPUT_HIDDEN_PASSWORD = true;
+        super.inputHintUsername = context.getString(R.string.card_id);
+        super.inputHiddenPassword = true;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Hors(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
index 3677f55..85255d6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
@@ -30,8 +30,6 @@ public class IKEA extends AbsIkanoPartner {
 
     private static final String NAME = "IKEA HANDLA kort";
 
-    private static final String NAME_SHORT = "ikea";
-
     private static final String URL
             = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
 
@@ -40,13 +38,20 @@ public class IKEA extends AbsIkanoPartner {
     public IKEA(Context context) {
         super(context, R.drawable.logo_ikea);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+        super.url = URL;
         this.structId = "1420";
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public IKEA(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
         this(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 9ea837a..b8de01c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -47,8 +47,6 @@ public class IkanoBank extends Bank {
 
     private static final String NAME = "Ikano Bank";
 
-    private static final String NAME_SHORT = "ikanobank";
-
     private static final String URL = "https://secure.ikanobank.se/engines/page.aspx?structid=1895";
 
     private static final int BANKTYPE_ID = IBankTypes.IKANOBANK;
@@ -81,13 +79,20 @@ public class IkanoBank extends Bank {
     public IkanoBank(Context context) {
         super(context, R.drawable.logo_ikanobank);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public IkanoBank(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index fddf1bb..0b1d3ed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -48,8 +48,6 @@ public class Jojo extends Bank {
 
     private static final String NAME = "Jojo Reskassa";
 
-    private static final String NAME_SHORT = "jojo";
-
     private static final String URL = "https://www.skanetrafiken.se";
 
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
@@ -64,12 +62,19 @@ public class Jojo extends Bank {
     public Jojo(Context context) {
         super(context, R.drawable.logo_jojo);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TITLETEXT_USERNAME = R.string.email;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.url = URL;
+        super.inputTitletextUsername = R.string.email;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Jojo(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 1aeefd3..2fb50b7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -45,8 +45,6 @@ public class McDonalds extends Bank {
 
     private static final String NAME = "McDonald's Presentkort";
 
-    private static final String NAME_SHORT = "mcdonalds";
-
     private static final String URL = "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm";
 
     private static final int BANKTYPE_ID = Bank.MCDONALDS;
@@ -67,13 +65,20 @@ public class McDonalds extends Bank {
     public McDonalds(Context context) {
         super(context, R.drawable.logo_mcdonalds);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
-        super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHiddenPassword = INPUT_HIDDEN_PASSWORD;
+        super.inputTitletextUsername = INPUT_TITLETEXT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public McDonalds(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index 9b20da6..c383409 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -32,8 +32,6 @@ public class Meniga extends Bank {
 
     private static final String NAME = "Meniga";
 
-    private static final String NAME_SHORT = "meniga";
-
     private static final String URL = "https://www.meniga.is/";
 
     private static final int BANKTYPE_ID = IBankTypes.MENIGA;
@@ -53,15 +51,22 @@ public class Meniga extends Bank {
     public Meniga(Context context) {
         super(context, R.drawable.logo_meniga);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
         super.setCurrency("ISK");
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public Meniga(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
         this(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index b6f3cbb..ab68bfa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -48,13 +48,19 @@ public class MinPension extends Bank {
 
     public MinPension(Context context) {
         super(context, R.drawable.logo_minpension);
-        TAG = "MinPension";
-        NAME = "Min Pension.se";
-        NAME_SHORT = "minpension";
-        BANKTYPE_ID = IBankTypes.MINPENSION;
-        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD;
-        INPUT_HINT_USERNAME = res.getText(R.string.pno).toString();
+        inputTypeUsername = InputType.TYPE_CLASS_PHONE;
+        inputTypePassword = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+        inputHintUsername = res.getText(R.string.pno).toString();
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return IBankTypes.MINPENSION;
+    }
+
+    @Override
+    public String getName() {
+        return "Min Pension.se";
     }
 
     public MinPension(String username, String password, Context context)
@@ -128,8 +134,8 @@ public class MinPension extends Bank {
         super.updateComplete();
     }
 
-    private Account updateAccount(String URL, String selector, String name) throws IOException {
-        String response = urlopen.open(URL);
+    private Account updateAccount(String url, String selector, String name) throws IOException {
+        String response = urlopen.open(url);
         Document dResponse = Jsoup.parse(response);
         List<Transaction> transactions = new ArrayList<>();
         String institute = "";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 7552aa9..8925dc6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -48,8 +48,6 @@ public class Nordnet extends Bank {
 
     private static final String NAME = "Nordnet";
 
-    private static final String NAME_SHORT = "nordnet";
-
     private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
 
     private static final int BANKTYPE_ID = IBankTypes.NORDNET;
@@ -66,10 +64,17 @@ public class Nordnet extends Bank {
     public Nordnet(Context context) {
         super(context, R.drawable.logo_nordnet);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+        super.url = URL;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Nordnet(String username, String password, Context context) throws BankException,
@@ -128,32 +133,32 @@ public class Nordnet extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        Matcher matcher = reAccounts.matcher(response);
-        Matcher matcher_b = reBalance.matcher(response);
-        while (matcher.find()) {
+        Matcher accountMatcher = reAccounts.matcher(response);
+        Matcher balanceMatcher = reBalance.matcher(response);
+        while (accountMatcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
              * 1: Account name and number      Investeringssparkonto 1234567   | Sparkonto 1234 567890 1
              *
              */
-            if (matcher_b.find()) {
+            if (balanceMatcher.find()) {
                 /*
                 * Capture groups:
                 * GROUP                EXAMPLE DATA
                 * 1: Account balance     62 356 | 0
                 *
                 */
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
-                        Helpers.parseBalance(matcher_b.group(1)),
-                        Html.fromHtml(matcher.group(1)).toString().trim().replaceAll(" ", ""));
+                Account account = new Account(Html.fromHtml(accountMatcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(balanceMatcher.group(1)),
+                        Html.fromHtml(accountMatcher.group(1)).toString().trim().replaceAll(" ", ""));
 
                 // Saving accounts contain white space characters in the account number
-                if (!matcher.group(1).trim().contains(" ")) {
+                if (!accountMatcher.group(1).trim().contains(" ")) {
                     account.setType(Account.FUNDS);
                 }
                 accounts.add(account);
-                balance = balance.add(Helpers.parseBalance(matcher_b.group(1)));
+                balance = balance.add(Helpers.parseBalance(balanceMatcher.group(1)));
             }
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index c7fa006..540abd3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -47,8 +47,6 @@ public class OKQ8 extends Bank {
 
     private static final String NAME = "OKQ8 VISA";
 
-    private static final String NAME_SHORT = "okq8";
-
     private static final String URL
             = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
 
@@ -76,13 +74,20 @@ public class OKQ8 extends Bank {
     public OKQ8(Context context) {
         super(context, R.drawable.logo_okq8);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public OKQ8(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 8524e38..d017230 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -43,8 +43,6 @@ public class Ostgotatrafiken extends Bank {
 
     private static final String NAME = "Östgötatrafiken";
 
-    private static final String NAME_SHORT = "ogt";
-
     private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN;
 
     private Pattern reViewState = Pattern.compile(
@@ -68,10 +66,16 @@ public class Ostgotatrafiken extends Bank {
 
     public Ostgotatrafiken(Context context) {
         super(context, R.drawable.logo_ogt);
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Ostgotatrafiken(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index c597d44..f62b92a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -45,8 +45,6 @@ public class Osuuspankki extends Bank {
 
     private static final String NAME = "Osuuspankki";
 
-    private static final String NAME_SHORT = "osuuspankki";
-
     private static final String URL = "https://www.op.fi/op?kielikoodi=sv";
 
     private static final int BANKTYPE_ID = IBankTypes.OSUUSPANKKI;
@@ -62,11 +60,17 @@ public class Osuuspankki extends Bank {
 
     public Osuuspankki(Context context) {
         super(context, R.drawable.logo_osuuspankki);
+        super.url = URL;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Osuuspankki(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index f90ae79..d98a263 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -46,8 +46,6 @@ public class Payson extends Bank {
 
     private static final String NAME = "Payson";
 
-    private static final String NAME_SHORT = "payson";
-
     private static final String URL = "https://www.payson.se/signin/";
 
     private static final int BANKTYPE_ID = IBankTypes.PAYSON;
@@ -66,11 +64,18 @@ public class Payson extends Bank {
     public Payson(Context context) {
         super(context, R.drawable.logo_payson);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Payson(String username, String password, Context context) throws BankChoiceException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index a4da2e4..8e1ee5b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -45,8 +45,6 @@ public class PlusGirot extends Bank {
 
     private static final String NAME = "PlusGirot";
 
-    private static final String NAME_SHORT = "plusgirot";
-
     private static final String URL = "https://kontoutdrag.plusgirot.se/";
 
     private static final int BANKTYPE_ID = IBankTypes.PLUSGIROT;
@@ -63,11 +61,17 @@ public class PlusGirot extends Bank {
 
     public PlusGirot(Context context) {
         super(context, R.drawable.logo_plusgirot);
+        super.url = URL;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public PlusGirot(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 490046a..9990b50 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -45,8 +45,6 @@ public class SevenDay extends Bank {
 
     private static final String NAME = "SevenDay";
 
-    private static final String NAME_SHORT = "sevenday";
-
     private static final String URL = "https://www.sevenday.se/mina-sidor/mina-sidor.htm";
 
     private static final int BANKTYPE_ID = IBankTypes.SEVENDAY;
@@ -67,12 +65,19 @@ public class SevenDay extends Bank {
     public SevenDay(Context context) {
         super(context, R.drawable.logo_sevenday);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public SevenDay(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 9aef3df..2a3566d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -32,8 +32,6 @@ public class SveaDirekt extends Bank {
 
     private static final String NAME = "Svea Direkt";
 
-    private static final String NAME_SHORT = "sveadirekt";
-
     private static final String URL = "https://http://www.sveadirekt.com/sv/swe//";
 
     private static final int BANKTYPE_ID = IBankTypes.SVEADIREKT;
@@ -61,13 +59,20 @@ public class SveaDirekt extends Bank {
     public SveaDirekt(Context context) {
         super(context, R.drawable.logo_sveadirekt);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.URL = URL;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public SveaDirekt(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 85d795c..b81cdc2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -45,8 +45,6 @@ public class SvenskaSpel extends Bank {
 
     private static final String NAME = "Svenska Spel";
 
-    private static final String NAME_SHORT = "svenskaspel";
-
     private static final String URL = "https://api.www.svenskaspel.se/player/sessions";
 
     private static final int BANKTYPE_ID = Bank.SVENSKASPEL;
@@ -62,12 +60,19 @@ public class SvenskaSpel extends Bank {
     public SvenskaSpel(Context context) {
         super(context, R.drawable.logo_svenskaspel);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTitletextUsername = INPUT_TITLETEXT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public SvenskaSpel(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index 2ceec08..a3c3a5e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -43,8 +43,6 @@ public class TestBank extends Bank {
 
     private static final String NAME = "Testbank";
 
-    private static final String NAME_SHORT = "testbank";
-
     private static final String URL = "http://www.nullbyte.eu/";
 
     private static final int BANKTYPE_ID = IBankTypes.TESTBANK;
@@ -70,13 +68,20 @@ public class TestBank extends Bank {
     public TestBank(Context context) {
         super(context, R.drawable.logo_bankdroid);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public TestBank(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index ed68966..2c370fa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -44,8 +44,6 @@ public class TicketRikskortet extends Bank {
 
     private static final String NAME = "Ticket Rikskortet";
 
-    private static final String NAME_SHORT = "rikskortet";
-
     private static final String URL = "https://www.edenred.se/rikskuponger/mina-sidor/logga-in/";
 
     private static final String URL_OVERVIEW = "https://www.edenred.se/rikskuponger/mina-sidor/employee/start/";
@@ -71,10 +69,17 @@ public class TicketRikskortet extends Bank {
     public TicketRikskortet(Context context) {
         super(context, R.drawable.logo_rikskortet);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+        super.url = URL;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public TicketRikskortet(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 3c51255..0668464 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -44,8 +44,6 @@ public class Vasttrafik extends Bank {
 
     private static final String NAME = "Västtrafik";
 
-    private static final String NAME_SHORT = "vasttrafik";
-
     private static final String URL = "https://www.vasttrafik.se/mina-sidor/";
 
     private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK;
@@ -64,11 +62,17 @@ public class Vasttrafik extends Bank {
 
     public Vasttrafik(Context context) {
         super(context, R.drawable.logo_vasttrafik);
+        super.url = URL;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Vasttrafik(String username, String password, Context context) throws BankException,
@@ -127,11 +131,11 @@ public class Vasttrafik extends Bank {
         }
         urlopen = login();
         response = urlopen.open("https://www.vasttrafik.se/mina-sidor-inloggad/mina-kort/");
-        Matcher matcher;
-        Matcher matcher_b;
+        Matcher accountMatcher;
+        Matcher balanceMatcher;
 
-        matcher = reAccounts.matcher(response);
-        while (matcher.find()) {
+        accountMatcher = reAccounts.matcher(response);
+        while (accountMatcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -139,12 +143,12 @@ public class Vasttrafik extends Bank {
              * 2: Balance information
              */
 
-            if ("".equals(matcher.group(1))) {
+            if ("".equals(accountMatcher.group(1))) {
                 continue;
             }
 
-            matcher_b = reBalance.matcher(matcher.group(2));
-            if (matcher_b.find()) {
+            balanceMatcher = reBalance.matcher(accountMatcher.group(2));
+            if (balanceMatcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
@@ -152,11 +156,11 @@ public class Vasttrafik extends Bank {
                  * 2: Amount            592,80 kr
                  */
 
-                String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>", "")
+                String balanceString = balanceMatcher.group(2).replaceAll("\\<a[^>]*>", "")
                         .replaceAll("\\<[^>]*>", "").trim();
 
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
-                        Helpers.parseBalance(balanceString), matcher.group(1)));
+                accounts.add(new Account(Html.fromHtml(accountMatcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(balanceString), accountMatcher.group(1)));
                 balance = balance.add(Helpers.parseBalance(balanceString));
             }
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index a7b13e1..ab4cef3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -44,8 +44,6 @@ public class Zidisha extends Bank {
 
     private static final String NAME = "Zidisha";
 
-    private static final String NAME_SHORT = "zidisha";
-
     private static final String URL = "https://www.zidisha.org/";
 
     private static final int BANKTYPE_ID = IBankTypes.ZIDISHA;
@@ -70,17 +68,24 @@ public class Zidisha extends Bank {
     public Zidisha(Context context) {
         super(context, R.drawable.logo_zidisha);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+        super.staticBalance = STATIC_BALANCE;
         super.currency = "USD";
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public Zidisha(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
         this(context);
@@ -99,14 +104,14 @@ public class Zidisha extends Bank {
             throw new BankException(
                     res.getText(R.string.unable_to_find).toString() + " user_guess.");
         }
-        String user_guess = mUserGuess.group(1);
+        String userGuess = mUserGuess.group(1);
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("username", getUsername()));
         postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("textpassword", getUsername()));
         postData.add(new BasicNameValuePair("userlogin", ""));
-        postData.add(new BasicNameValuePair("user_guess", user_guess));
+        postData.add(new BasicNameValuePair("user_guess", userGuess));
         return new LoginPackage(urlopen, postData, response, "https://www.zidisha.org/process.php");
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
index 933ec1f..c853116 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
@@ -52,12 +52,8 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class AmericanExpress extends Bank {
 
-    private static final String TAG = "AmericanExpress";
-
     private static final String NAME = "American Express";
 
-    private static final String NAME_SHORT = "americanexpress";
-
     private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
 
     private static final ObjectMapper MAPPER = new ObjectMapper();
@@ -67,11 +63,17 @@ public class AmericanExpress extends Bank {
 
     public AmericanExpress(Context context) {
         super(context, R.drawable.logo_americanexpress);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.WEB_VIEW_ENABLED = false;
+        super.webViewEnabled = false;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public AmericanExpress(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 1e6bf30..3d3aa64 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -57,11 +57,17 @@ public class Avanza extends Bank {
 
     protected Avanza(Context context, @DrawableRes int logoResource) {
         super(context, logoResource);
-        TAG = "Avanza";
-        NAME = "Avanza";
-        NAME_SHORT = "avanza";
-        URL = "https://iphone.avanza.se";
-        BANKTYPE_ID = IBankTypes.AVANZA;
+        url = "https://iphone.avanza.se";
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return IBankTypes.AVANZA;
+    }
+
+    @Override
+    public String getName() {
+        return "Avanza";
     }
 
     public Avanza(Context context) {
@@ -72,12 +78,12 @@ public class Avanza extends Bank {
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_avanza));
-        urlopen.addHeader("Referer", URL + "/start");
+        urlopen.addHeader("Referer", url + "/start");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("j_username", getUsername()));
         postData.add(new BasicNameValuePair("j_password", getPassword()));
-        postData.add(new BasicNameValuePair("url", URL + "/start"));
-        String response = urlopen.open(URL + "/ab/handlelogin", postData);
+        postData.add(new BasicNameValuePair("url", url + "/start"));
+        String response = urlopen.open(url + "/ab/handlelogin", postData);
         String homeUrl = "";
         try {
             JSONObject jsonResponse = new JSONObject(response);
@@ -86,7 +92,7 @@ public class Avanza extends Bank {
             throw new BankException(
                     res.getText(R.string.unable_to_find).toString() + " login link.", e);
         }
-        LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl);
+        LoginPackage lp = new LoginPackage(urlopen, postData, "", url + homeUrl);
         lp.setIsLoggedIn(true);
         return lp;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index c726896..9efdf1d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -40,8 +40,6 @@ public class Bitcoin extends Bank {
 
     private static final String NAME = "Bitcoin";
 
-    private static final String NAME_SHORT = "bitcoin";
-
     private static final String URL = "http://blockchain.info";
 
     private static final int BANKTYPE_ID = IBankTypes.BITCOIN;
@@ -59,14 +57,21 @@ public class Bitcoin extends Bank {
     public Bitcoin(Context context) {
         super(context, R.drawable.logo_bitcoin);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.url = URL;
+        super.staticBalance = STATIC_BALANCE;
         super.currency = "BTC";
-        super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
-        super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+        super.inputHiddenPassword = INPUT_HIDDEN_PASSWORD;
+        super.inputTitletextUsername = INPUT_TITLETEXT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Bitcoin(String username, String password, Context context)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 1ac76d6..7c27950 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -57,8 +57,6 @@ public class Coop extends Bank {
 
     private static final String NAME = "Coop";
 
-    private static final String NAME_SHORT = "coop";
-
     private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
 
     private static final int BANKTYPE_ID = IBankTypes.COOP;
@@ -83,11 +81,18 @@ public class Coop extends Bank {
     public Coop(Context context) {
         super(context, R.drawable.logo_coop);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.STATIC_BALANCE = true;
+        super.url = URL;
+        super.staticBalance = true;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Coop(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index ffc18a5..ebdb705 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -66,19 +66,25 @@ public class ICA extends Bank {
 
     public ICA(Context context) {
         super(context, R.drawable.logo_ica);
-        TAG = "ICA";
-        NAME = "ICA";
-        NAME_SHORT = "ica";
-        URL = "http://mobil.ica.se/";
-        BANKTYPE_ID = IBankTypes.ICA;
-        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-        INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+        url = "http://mobil.ica.se/";
+        inputTypeUsername = InputType.TYPE_CLASS_PHONE;
+        inputTypePassword = InputType.TYPE_CLASS_PHONE;
+        inputHintUsername = "ÅÅMMDDXXXX";
         mHeaders.put(AUTHENTICATION_TICKET_HEADER, null);
         mHeaders.put(SESSION_TICKET_HEADER, null);
         mHeaders.put(LOGOUT_KEY_HEADER, null);
     }
 
+    @Override
+    public int getBanktypeId() {
+        return IBankTypes.ICA;
+    }
+
+    @Override
+    public String getName() {
+        return "ICA";
+    }
+
     public ICA(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index b825abf..97e4b46 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -64,8 +64,6 @@ public class Lansforsakringar extends Bank {
 
     private static final String NAME = "Länsförsäkringar";
 
-    private static final String NAME_SHORT = "lansforsakringar";
-
     private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
 
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
@@ -83,17 +81,24 @@ public class Lansforsakringar extends Bank {
     public Lansforsakringar(Context context) {
         super(context, R.drawable.logo_lansforsakringar);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
         mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
         mObjectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
     }
 
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
     public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 24dbb7e..cf8dd19 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -46,8 +46,6 @@ public class Nordea extends Bank {
 
     private static final String NAME = "Nordea";
 
-    private static final String NAME_SHORT = "nordea";
-
     private static final String BASE_URL = "https://internetbanken.privat.nordea.se/nsp/";
 
     private static final String LOGIN_URL = BASE_URL + "login";
@@ -210,13 +208,20 @@ public class Nordea extends Bank {
     public Nordea(Context context) {
         super(context, R.drawable.logo_nordea);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = BASE_URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.url = BASE_URL;
+        super.inputTypeUsername = INPUT_TYPE_USERNAME;
+        super.inputTypePassword = INPUT_TYPE_PASSWORD;
+        super.inputHintUsername = INPUT_HINT_USERNAME;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Nordea(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 1d58f40..9b08924 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -40,8 +40,6 @@ public class Rikslunchen extends Bank {
 
     private static final String NAME = "Rikslunchen";
 
-    private static final String NAME_SHORT = "rikslunchen";
-
     private static final String URL = "http://www.rikslunchen.se/index.html";
 
     private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
@@ -53,13 +51,20 @@ public class Rikslunchen extends Bank {
     public Rikslunchen(Context context) {
         super(context, R.drawable.logo_rikslunchen);
 
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        super.INPUT_TITLETEXT_USERNAME = R.string.card_id;
-        super.INPUT_HIDDEN_PASSWORD = true;
+        super.url = URL;
+        super.inputTypeUsername = InputType.TYPE_CLASS_PHONE;
+        super.inputTitletextUsername = R.string.card_id;
+        super.inputHiddenPassword = true;
+    }
+
+    @Override
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
     }
 
     public Rikslunchen(String username, String password, Context context) throws BankException,
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 2636816..36354b6 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -88,9 +88,9 @@ import timber.log.Timber;
 
 public class Urllib {
 
-    private static int MAX_RETRIES = 5;
+    private final static int MAX_RETRIES = 5;
 
-    public static String DEFAULT_USER_AGENT
+    public final static String DEFAULT_USER_AGENT
             = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
 
     private String userAgent = null;
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index f81c4ca..8195ce2 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -30,7 +30,6 @@
     <issue id="NewerVersionAvailable" severity="ignore" />
     <issue id="NotSibling" severity="ignore" />
     <issue id="ObsoleteLayoutParam" severity="ignore" />
-    <issue id="OldTargetApi" severity="ignore" />
     <issue id="Orientation" severity="ignore" />
     <issue id="Overdraw" severity="ignore" />
     <issue id="ParcelClassLoader" severity="ignore" />
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 05b8f94..68eee4b 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -113,7 +113,6 @@
         <exclude name="SimplifyBooleanReturns" />
         <exclude name="SimplifyStartsWith" />
         <exclude name="StdCyclomaticComplexity" />
-        <exclude name="SuspiciousConstantFieldName" />
         <exclude name="SwitchDensity" />
         <exclude name="SwitchStmtsShouldHaveDefault" />
         <exclude name="TooFewBranchesForASwitchStatement" />
@@ -139,6 +138,5 @@
         <exclude name="UselessOverridingMethod" />
         <exclude name="UselessParentheses" />
         <exclude name="UselessQualifiedThis" />
-        <exclude name="VariableNamingConventions" />
     </rule>
 </ruleset>

commit e1cbce765867ba88c0bf9c1931a4e47f34dacf44
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Nov 3 21:01:58 2016 +0100

    If asked for an unknown bank, log the id
    
    So instead of getting in Crashlytics...
    BankType id not found.
    ... we now get...
    BankType id not found: 1234
    
    This way it will be easier to understand why we get these exceptions and
    how they should be handled (or not).

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index d2a8b11..f95ef32 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -144,7 +144,7 @@ public class LegacyBankFactory {
             case IBankTypes.HORS:
                 return new Hors(context);
             default:
-                throw new BankException("BankType id not found.");
+                throw new BankException("BankType id not found: " + id);
         }
     }
 

commit de72b761b9a9a84ea49fb4036e942b24ca49cd5e
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Nov 3 21:21:31 2016 +0100

    Don't lose the stacks when re-throwing exceptions

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index 4f2d1ae..f90ae79 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -108,7 +108,7 @@ public class Payson extends Bank {
             userInfo = new JSONObject(
                     urlopen.open("https://www.payson.se/myaccount/user/getuserinfo"));
         } catch (JSONException e) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString(), e);
         }
         return urlopen;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index e0ee2d8..1e6bf30 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -84,7 +84,7 @@ public class Avanza extends Bank {
             homeUrl = jsonResponse.getString("redirectUrl");
         } catch (JSONException e) {
             throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " login link.");
+                    res.getText(R.string.unable_to_find).toString() + " login link.", e);
         }
         LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl);
         lp.setIsLoggedIn(true);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 0f789ff..c726896 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -96,7 +96,7 @@ public class Bitcoin extends Bank {
             setCurrency("BTC");
         } catch (JsonParseException e) {
             throw new BankException(res.getText(
-                    R.string.invalid_bitcoin_address).toString());
+                    R.string.invalid_bitcoin_address).toString(), e);
         }
 
         return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 7e8fe82..b825abf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -115,7 +115,7 @@ public class Lansforsakringar extends Bank {
                     objectAsJson(new LoginRequest(getUsername(), getPassword())), LoginResponse.class);
             urlopen.addHeader("Utoken", lr.getTicket());
         } catch (Exception e) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString(), e);
         }
         return urlopen;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
index 65446a9..67895b3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
@@ -23,4 +23,8 @@ public class LoginException extends Exception {
     public LoginException(String message) {
         super(message);
     }
+
+    public LoginException(String message, Exception cause) {
+        super(message, cause);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java
index f85b8f2..6656ba3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java
@@ -13,7 +13,7 @@ public class StringUtils {
         try {
             return string.getBytes(CHARSET);
         } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException("Internal error");
+            throw new RuntimeException("Internal error", e);
         }
     }
 
@@ -21,7 +21,7 @@ public class StringUtils {
         try {
             return new String(bytes, CHARSET);
         } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException("Internal error");
+            throw new RuntimeException("Internal error", e);
         }
     }
 }
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index 616084c..bbae0ee 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -86,7 +86,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
             context.init(keyManagers, new TrustManager[]{mTrustManager}, null);
             return context;
         } catch (Exception e) {
-            throw new IOException(e.getMessage());
+            throw new IOException(e.getMessage(), e);
         }
     }
 
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 288976e..05b8f94 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -104,7 +104,6 @@
         <exclude name="OnlyOneReturn" />
         <exclude name="PositionLiteralsFirstInComparisons" />
         <exclude name="PrematureDeclaration" />
-        <exclude name="PreserveStackTrace" />
         <exclude name="RedundantFieldInitializer" />
         <exclude name="ShortClassName" />
         <exclude name="ShortMethodName" />

commit 35a0c501384bd9bd99f998d48fd5e2cd1b32fa5e (tag: v1.9.13)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Nov 3 20:32:14 2016 +0100

    Creates release v1.9.13

diff --git CHANGELOG CHANGELOG
index f2f5b8d..91dd35a 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.13 (2016-11-03)
+* Fixes Crashlytics logging issue
+
 v1.9.12 (2016-11-02)
 * Bioklubben: Use https. It's secure and http page no longer exists.
 * Östgötatrafiken: Adapt to new login page (Facebook login not supported)

commit 709cf1fa638b955646f76775592a433b0e4ad707
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Nov 3 07:30:07 2016 +0100

    Log correct bank names to Crashlytics

diff --git app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
index bea4936..e5c019d 100644
--- app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
+++ app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
@@ -56,7 +56,7 @@ public class LoggingUtils {
         }
 
         logCustom(new CustomEvent("Disabled Bank").
-                putCustomAttribute("Name", bank.getDisplayName()));
+                putCustomAttribute("Name", bank.getName()));
     }
 
     public static void logBankUpdate(Bank bank, boolean withTransactions) {
@@ -65,7 +65,7 @@ public class LoggingUtils {
         }
 
         logCustom(new CustomEvent("Bank Updated").
-                putCustomAttribute("Name", bank.getDisplayName()).
+                putCustomAttribute("Name", bank.getName()).
                 putCustomAttribute("With Transactions", Boolean.toString(withTransactions)));
 
         boolean hasTransactions = false;
@@ -76,7 +76,7 @@ public class LoggingUtils {
         }
         if (withTransactions && !hasTransactions) {
             logCustom(new CustomEvent("Bank Without Transactions").
-                    putCustomAttribute("Name", bank.getDisplayName()));
+                    putCustomAttribute("Name", bank.getName()));
         }
     }
 

commit c60033a4f1f18446e0c298147764af052f90e0a6 (tag: v1.9.12)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Nov 2 22:25:10 2016 +0100

    Create release v1.9.12

diff --git CHANGELOG CHANGELOG
index 5ebd411..f2f5b8d 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,8 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-Not yet released
+v1.9.12 (2016-11-02)
 * Bioklubben: Use https. It's secure and http page no longer exists.
 * Östgötatrafiken: Adapt to new login page (Facebook login not supported)
+* Removes broken encryption
 
 v1.9.11 (2016-10-26)
 * Warn about disabled banks in the transactions list

commit 1e50923e7b4092101945b4f73b27e82d1cff69f0
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Nov 2 22:21:59 2016 +0100

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_danskebank.pem bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
index 328a9ec..8a9fe0a 100644
--- bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
@@ -1,31 +1,32 @@
 -----BEGIN CERTIFICATE-----

+SnEPwHpG0wzZnwfPFvU=
 -----END CERTIFICATE-----
 mobil.danskebank.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_meniga.pem bankdroid-legacy/src/main/res/raw/cert_meniga.pem
index 828d693..a899ce9 100644
--- bankdroid-legacy/src/main/res/raw/cert_meniga.pem
+++ bankdroid-legacy/src/main/res/raw/cert_meniga.pem
@@ -1,31 +1,32 @@
 -----BEGIN CERTIFICATE-----

-83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0=

+2F8WeQ==
 -----END CERTIFICATE-----
 www.meniga.is:443

commit d32deec5dbe785ef35b1cb89484d6c29653e370c
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Oct 31 21:42:39 2016 +0100

    Enable PMD's field-can-be-local-var warning

diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index e9850ef..af07d75 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -35,8 +35,6 @@ import java.util.Map;
 
 public class DBAdapter {
 
-    private DatabaseHelper mDbHelper;
-
     private SQLiteDatabase mDb;
 
     /**
@@ -46,8 +44,8 @@ public class DBAdapter {
      * @param ctx the Context within which to work
      */
     public DBAdapter(Context ctx) {
-        mDbHelper = DatabaseHelper.getHelper(ctx);
-        mDb = mDbHelper.getWritableDatabase();
+        DatabaseHelper dbHelper = DatabaseHelper.getHelper(ctx);
+        mDb = dbHelper.getWritableDatabase();
     }
 
     /**
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
index 0e7502e..f17d78b 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
@@ -36,8 +36,6 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi
 
     private View mSkipButton;
 
-    private View mImageView;
-
     private AnimationDrawable mAnimation;
 
     private Runnable mRunnable = new Runnable() {
@@ -94,10 +92,10 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi
         mSkipButton = findViewById(R.id.skip_button);
         mSkipButton.setOnClickListener(this);
 
-        mImageView = (ImageView) findViewById(R.id.lock_anim);
-        mImageView.setBackgroundResource(R.drawable.lock_anim);
-        mImageView.setOnClickListener(this);
-        mAnimation = (AnimationDrawable) mImageView.getBackground();
+        View imageView = (ImageView) findViewById(R.id.lock_anim);
+        imageView.setBackgroundResource(R.drawable.lock_anim);
+        imageView.setOnClickListener(this);
+        mAnimation = (AnimationDrawable) imageView.getBackground();
     }
 
     protected void startAnimation(final AnimationDrawable animation) {
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
index 86f7136..4817e11 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -36,8 +36,6 @@ public class ColorPickerDialog
 
     private ColorPickerView mColorPicker;
 
-    private ColorPickerPanelView mOldColor;
-
     private ColorPickerPanelView mNewColor;
 
     private OnColorChangedListener mListener;
@@ -72,20 +70,20 @@ public class ColorPickerDialog
         setTitle(R.string.dialog_color_picker);
 
         mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
-        mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
+        ColorPickerPanelView oldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
         mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
 
-        ((LinearLayout) mOldColor.getParent()).setPadding(
+        ((LinearLayout) oldColor.getParent()).setPadding(
                 Math.round(mColorPicker.getDrawingOffset()),
                 0,
                 Math.round(mColorPicker.getDrawingOffset()),
                 0
         );
 
-        mOldColor.setOnClickListener(this);
+        oldColor.setOnClickListener(this);
         mNewColor.setOnClickListener(this);
         mColorPicker.setOnColorChangedListener(this);
-        mOldColor.setColor(color);
+        oldColor.setColor(color);
         mColorPicker.setColor(color, true);
 
     }
diff --git bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
index 62a1b46..3a47c5b 100644
--- bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
+++ bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
@@ -8,19 +8,13 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.ResourceBundle;
 
-public enum DefaultConnectionConfiguration {
-
-    INSTANCE;
+public class DefaultConnectionConfiguration {
 
     public static final String NAME = "provider.configuration.name";
 
-    private List<Field> configuration;
-
-    DefaultConnectionConfiguration() {
-        configuration = createConfiguration();
-    }
+    private final static List<Field> configuration = createConfiguration();
 
-    private List<Field> createConfiguration() {
+    private static List<Field> createConfiguration() {
         List<Field> configuration = new ArrayList<>();
         configuration.add(new FieldBuilder(NAME, ResourceBundle.getBundle("i18n.application"))
                 .placeholder("")
@@ -30,6 +24,6 @@ public enum DefaultConnectionConfiguration {
     }
 
     public static List<Field> fields() {
-        return INSTANCE.configuration;
+        return configuration;
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 84bcb8d..1ac76d6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -80,8 +80,6 @@ public class Coop extends Bank {
 
     private ObjectMapper mObjectMapper;
 
-    private String response;
-
     public Coop(Context context) {
         super(context, R.drawable.logo_coop);
 
@@ -141,7 +139,7 @@ public class Coop extends Bank {
 
         login();
 
-        response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
+        String response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
         Document dResponse = Jsoup.parse(response);
         Account poang = new Account("\u2014  Poäng",
                 Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()),
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 19538ce..288976e 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -113,7 +113,6 @@
         <exclude name="SimpleDateFormatNeedsLocale" />
         <exclude name="SimplifyBooleanReturns" />
         <exclude name="SimplifyStartsWith" />
-        <exclude name="SingularField" />
         <exclude name="StdCyclomaticComplexity" />
         <exclude name="SuspiciousConstantFieldName" />
         <exclude name="SwitchDensity" />

commit 37f16fda5cc03d3b2d6b9180e6bcb2ed5d600c57
Author: Johan Walles <johan.walles@gmail.com>
Date:   Tue Nov 1 22:06:24 2016 +0100

    Fix whitespace issues

diff --git app/build.gradle app/build.gradle
index aafa141..11832d8 100644
--- app/build.gradle
+++ app/build.gradle
@@ -19,7 +19,7 @@ apply plugin: 'com.android.application'
 apply from: '../config/quality/quality.gradle'
 apply plugin: "org.ajoberstar.grgit"
 
-if(new File('app/crashlytics.properties').exists()) {
+if (new File('app/crashlytics.properties').exists()) {
     apply plugin: 'io.fabric'
 }
 
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index fce0bbe..835c64e 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -122,7 +122,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
     @OnClick(R.id.btnSettingsOk)
     public void onSubmit(View v) {
-        if(!validate()) {
+        if (!validate()) {
             return;
         }
         SELECTED_BANK.setProperties(getFormParameters(SELECTED_BANK.getConnectionConfiguration()));
@@ -139,7 +139,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
     @Override
     public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
         Bank selectedBank = (Bank) parentView.getItemAtPosition(pos);
-        if(SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) {
+        if (SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) {
             SELECTED_BANK = selectedBank;
                     mFormContainer.removeAllViewsInLayout();
             createForm(SELECTED_BANK.getConnectionConfiguration(),
@@ -154,10 +154,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
 
     private void createForm(List<Field>... configurations) {
-        for(List<Field> fields : configurations) {
+        for (List<Field> fields : configurations) {
             for (Field field : fields) {
                 createLabel(field);
-                if(field.getValues().isEmpty()) {
+                if (field.getValues().isEmpty()) {
                     createField(field);
                 } else {
                     createSpinner(field);
@@ -203,7 +203,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
                 DefaultConnectionConfiguration.NAME);
         customName.setText(bank.getCustomName());
 
-        for(Map.Entry<String, String> property : bank.getProperties().entrySet()) {
+        for (Map.Entry<String, String> property : bank.getProperties().entrySet()) {
             EditText propertyInput = (EditText) mFormContainer.findViewWithTag(property.getKey());
             propertyInput.setText(property.getValue());
         }
@@ -211,7 +211,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
     private Map<String, String> getFormParameters(List<Field> fields) {
         Map<String, String> properties = new HashMap<>();
-        for(Field field : fields) {
+        for (Field field : fields) {
             properties.put(field.getReference(), getFormParameter(field.getReference()));
         }
         return properties;
@@ -219,10 +219,10 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
     private String getFormParameter(String property) {
         View propertyView = mFormContainer.findViewWithTag(property);
-        if(propertyView instanceof EditText) {
+        if (propertyView instanceof EditText) {
             EditText propertyInput = (EditText) propertyView;
             return propertyInput.getText().toString().trim();
-        } else if(propertyView instanceof Spinner) {
+        } else if (propertyView instanceof Spinner) {
             Spinner spinnerProperty = (Spinner) propertyView;
             Entry entry = (Entry) spinnerProperty.getSelectedItem();
             return entry.getKey();
@@ -235,7 +235,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
         boolean valid = true;
         Iterator<Field> fields = Iterators.concat(SELECTED_BANK.getConnectionConfiguration().iterator(),
                 DefaultConnectionConfiguration.fields().iterator());
-        while(fields.hasNext()) {
+        while (fields.hasNext()) {
             Field field = fields.next();
             try {
                 field.validate(getFormParameter(field.getReference()));
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 215c59f..e9850ef 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -136,7 +136,7 @@ public class DBAdapter {
 
     public Cursor fetchProperties(String bankId) {
         return mDb.query(Database.PROPERTY_TABLE_NAME, null,
-                Database.PROPERTY_CONNECTION_ID+"='"+bankId+"'", null, null, null, null);
+                Database.PROPERTY_CONNECTION_ID + "='" + bankId + "'", null, null, null, null);
     }
 
     public long updateBank(Bank bank) {
@@ -162,9 +162,9 @@ public class DBAdapter {
         }
         if (bankId != -1) {
             Map<String, String> properties = bank.getProperties();
-            for(Map.Entry<String,String> property : properties.entrySet()) {
+            for (Map.Entry<String, String> property : properties.entrySet()) {
                 String value = property.getValue();
-                if(value != null && !value.isEmpty()) {
+                if (value != null && !value.isEmpty()) {
                     ContentValues propertyValues = new ContentValues();
                     propertyValues.put(Database.PROPERTY_KEY, property.getKey());
                     propertyValues.put(Database.PROPERTY_VALUE, value);
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index e4b166a..a295de8 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -74,7 +74,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
             db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " ADD " +
                     LegacyDatabase.BANK_HIDE_ACCOUNTS + " integer;");
         }
-        if(oldVersion <= 11) {
+        if (oldVersion <= 11) {
             try {
                 db.beginTransaction();
                 db.execSQL(Database.TABLE_CONNECTION_PROPERTIES);
@@ -104,7 +104,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
             + LegacyDatabase.BANK_HIDE_ACCOUNTS + " FROM " + tempTable);
 
         // Add username, password and extras fields to properties table.
-        Cursor c = db.query(tempTable, null, null, null,null,null,null);
+        Cursor c = db.query(tempTable, null, null, null, null, null, null);
         try {
             if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
                 while (!c.isLast() && !c.isAfterLast()) {
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java
index 8201e43..e0d04d0 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java
@@ -6,7 +6,7 @@ public class Entry {
     private final String mValue;
 
     public Entry(String key, String value) {
-        if(key == null || key.trim().isEmpty()) {
+        if (key == null || key.trim().isEmpty()) {
             throw new IllegalArgumentException("key cannot be null or empty.");
         }
         mKey = key;
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index ad41c8f..4d1ce55 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -13,7 +13,7 @@ public class FieldBuilder {
     private BasicField field;
 
     /**
-     * Create a new {@link Field} builder without i18n support. 
+     * Create a new {@link Field} builder without i18n support.
      */
     public FieldBuilder(String reference) {
       this(reference, null);
@@ -24,7 +24,7 @@ public class FieldBuilder {
      * The following keys needs to be in the ResourceBundle:
      * {@code field.{reference}.label} - Locale label value
      * {@code field.{reference}.placeholder} - Locale placeholder value.
-     * 
+     *
      * Setting {@link #placeholder(String)} or {@link #label(String) specifically will override the i18n values.
      * Otherwise they will be set to the value specified in the Locale bundle or in the default bundle if not present.
      * If a key is not present at all in the ResourceBundle the key will will be returned.
@@ -32,7 +32,7 @@ public class FieldBuilder {
      * @param bundle The ResourceBundle to be used for i18n support.
      */
     public FieldBuilder(String reference, ResourceBundle bundle) {
-        if(reference == null || reference.trim().isEmpty()) {
+        if (reference == null || reference.trim().isEmpty()) {
             throw new IllegalArgumentException("reference must be provided.");
         }
         field = new BasicField(reference, bundle);
@@ -146,7 +146,7 @@ public class FieldBuilder {
 
         @Override
         public List<Entry> getValues() {
-            if(values == null) {
+            if (values == null) {
                 values = Collections.emptyList();
             }
             return values;
@@ -154,18 +154,18 @@ public class FieldBuilder {
 
         @Override
         public void validate(String value) throws IllegalArgumentException {
-            if(isRequired()) {
-                if(value == null || value.trim().isEmpty()) {
+            if (isRequired()) {
+                if (value == null || value.trim().isEmpty()) {
                     throw new IllegalArgumentException(String.format("%s is required", getLabel()));
                 }
-                if(validator != null) {
+                if (validator != null) {
                     validator.validate(value);
                 }
             }
         }
 
         private String getLocaleString(String key) {
-            if(!isLocale()) {
+            if (!isLocale()) {
                 return null;
             }
             String propertyKey = String.format("field.%s.%s", getReference(), key);
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
index 44c8e9b..06b2566 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
@@ -34,7 +34,7 @@ abstract class AbstractAccountBuilder<T extends AbstractAccountBuilder<T>> {
     }
 
     public T addCustomAttribute(String key, String value) {
-        if(mCustomAttributes == null) {
+        if (mCustomAttributes == null) {
             mCustomAttributes = new HashMap<>();
         }
         mCustomAttributes.put(key, value);
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
index 8dff297..ef3c9d2 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
@@ -58,7 +58,7 @@ public class AccountBuilder extends AbstractAccountBuilder<AccountBuilder> {
 
         @Override
         public Map<String, String> getCustomAttributes() {
-            return mCustomAttributes == null ? Collections.<String,String>emptyMap() : mCustomAttributes;
+            return mCustomAttributes == null ? Collections.<String, String>emptyMap() : mCustomAttributes;
         }
     }
 }
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
index f837bab..d5343cb 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
@@ -10,7 +10,7 @@ import java.util.Map;
 
 import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
 
-public class CreditCardAccountBuilder extends AbstractAccountBuilder<CreditCardAccountBuilder>{
+public class CreditCardAccountBuilder extends AbstractAccountBuilder<CreditCardAccountBuilder> {
 
     private BigDecimal mCreditLimit;
 
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
index 67abd33..f34df22 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
@@ -11,7 +11,7 @@ import java.util.Map;
 
 import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
 
-public class EquityAccountBuilder extends AbstractAccountBuilder<EquityAccountBuilder>{
+public class EquityAccountBuilder extends AbstractAccountBuilder<EquityAccountBuilder> {
 
     private BigDecimal mCost;
 
@@ -38,7 +38,7 @@ public class EquityAccountBuilder extends AbstractAccountBuilder<EquityAccountBu
     }
 
     public EquityAccountBuilder addEquity(Equity equity) {
-        if(mEquities == null) {
+        if (mEquities == null) {
             mEquities = new ArrayList<>();
         }
         mEquities.add(equity);
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
index bd1a3e8..5743c7d 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
@@ -19,9 +19,9 @@ public class EquityBuilder {
      *                       a 25 % loss, while {@code 1.5} is 50 % profit.
      * @param currency The currency of the equity.
      */
-    public EquityBuilder(BigDecimal balance, double revenue, String currency){
+    public EquityBuilder(BigDecimal balance, double revenue, String currency) {
         mEquity = new BasicEquity(costFromBalanceAndRevenue(balance, revenue),
-                revenueFromBalanceAndRevenueAsPerecntage(balance, revenue),currency);
+                revenueFromBalanceAndRevenueAsPerecntage(balance, revenue), currency);
     }
 
     public EquityBuilder name(String name) {
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
index d99e715..1f6a20e 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
@@ -30,7 +30,7 @@ public class LiabilityAccountBuilder extends AbstractAccountBuilder<LiabilityAcc
     }
 
     public LiabilityAccountBuilder addPayment(Payment payment) {
-        if(mPayments == null) {
+        if (mPayments == null) {
             mPayments = new ArrayList<>();
         }
         mPayments.add(payment);
@@ -69,4 +69,4 @@ public class LiabilityAccountBuilder extends AbstractAccountBuilder<LiabilityAcc
             return mPayments == null ? Collections.<Payment>emptyList() : mPayments;
         }
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
index 641fd7e..814ed20 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
@@ -9,7 +9,7 @@ import java.util.Map;
 
 import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
 
-public class PrePaidCardAccountBuilder extends AbstractAccountBuilder<PrePaidCardAccountBuilder>{
+public class PrePaidCardAccountBuilder extends AbstractAccountBuilder<PrePaidCardAccountBuilder> {
 
     private DateTime mValidFrom;
     private DateTime mExpirationDate;
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
index 00e1e2f..6bd988f 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
@@ -24,7 +24,7 @@ public class TransactionAccountBuilder extends AbstractAccountBuilder<Transactio
     }
 
     public TransactionAccountBuilder addTransaction(Transaction transaction) {
-        if(mTransactions == null) {
+        if (mTransactions == null) {
             mTransactions = new ArrayList<>();
         }
         mTransactions.add(transaction);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index ceca10f..18a6a0c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -369,7 +369,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public Map<String, String> getProperties() {
-        if(this.properties == null) {
+        if (this.properties == null) {
             this.properties = new HashMap<>();
         }
         return this.properties;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
index 496f9e4..d2aa87c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
@@ -14,7 +14,7 @@ public class LegacyBankHelper {
     private static Map<Integer, String> providerReferences;
 
     public static String getReferenceFromLegacyId(int legacyId) {
-        if(providerReferences == null) {
+        if (providerReferences == null) {
             generateLegacyProviderReferences();
         }
         return providerReferences.get(legacyId);
@@ -22,7 +22,7 @@ public class LegacyBankHelper {
 
     // TODO Used during refactoring. Remove before 2.0
     public static int getLegacyIdFromReference(String reference) {
-        if(legacyProviderReferences == null) {
+        if (legacyProviderReferences == null) {
             generateLegacyProviderReferences();
         }
         return legacyProviderReferences.get(reference);
@@ -32,15 +32,14 @@ public class LegacyBankHelper {
         Map<Integer, String> references = new HashMap<>();
         Map<String, Integer> legacyIds = new HashMap<>();
         Field[] fields = IBankTypes.class.getFields();
-        for(int i = 0 ; i < fields.length; i++) {
-            Field field = fields[i];
+        for (Field field : fields) {
             try {
                 String reference = field.getName().toLowerCase().replaceAll("_", "-");
                 Integer legacyId = field.getInt(new IBankTypes() {
                 });
                 references.put(legacyId, reference);
                 legacyIds.put(reference, legacyId);
-            } catch(IllegalAccessException e) {
+            } catch (IllegalAccessException e) {
                 Timber.e(e, "Provider could not be mapped");
             }
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index b740b6e..c7fa006 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -106,7 +106,7 @@ public class OKQ8 extends Bank {
         }
         String postAction = matcher.group(1);
         postData.add(new BasicNameValuePair("javax.faces.ViewState",
-                postAction.substring(postAction.length()-5,postAction.length()-1)));
+                postAction.substring(postAction.length() - 5, postAction.length() - 1)));
         postData.add(new BasicNameValuePair("loginForm", "loginForm"));
         postData.add(new BasicNameValuePair("button", "Logga in"));
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 620c740..9aef3df 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -124,7 +124,7 @@ public class SveaDirekt extends Bank {
         response = urlopen.open(ACCOUNTS_URL);
         Document doc = Jsoup.parse(response);
         ArrayList<Account> accounts = parseAccounts(doc);
-        for(Account account : accounts) {
+        for (Account account : accounts) {
             response = urlopen.open(TRANSACTIONS_URL + "?account=" + account.getId());
             account.setTransactions(parseTransactions(response));
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
index 396af06..933ec1f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
@@ -116,9 +116,9 @@ public class AmericanExpress extends Bank {
 
         urlopen = login();
 
-        for(Card card : loginResponse.getCards()) {
+        for (Card card : loginResponse.getCards()) {
             Account account = asAccount(card);
-            if(card.isTransactionsEnabled()) {
+            if (card.isTransactionsEnabled()) {
                 account.setTransactions(fetchTransactionsFor(card));
             }
             accounts.add(account);
@@ -137,7 +137,7 @@ public class AmericanExpress extends Bank {
                         "\"sortedIndex\":" + card.getSortedIndex() +
                         "}",
                         HTTP.UTF_8), true);
-        if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
             response.getEntity().consumeContent();
             throw new BankException(
                     res.getText(R.string.update_transactions_error).toString());
@@ -147,10 +147,10 @@ public class AmericanExpress extends Bank {
                 .withType(TransactionsResponse.class)
                 .readValue(response.getEntity().getContent());
 
-        if(details.getTransactionDetails() == null) {
+        if (details.getTransactionDetails() == null) {
             throw new BankException(res.getText(R.string.server_error_try_again).toString());
         }
-        if(details.getTransactionDetails().getStatus() != 0) {
+        if (details.getTransactionDetails().getStatus() != 0) {
             throw new BankException(details.getTransactionDetails().getMessage());
         }
 
@@ -159,8 +159,8 @@ public class AmericanExpress extends Bank {
 
     private List<Transaction> transactionsOf(@Nullable TransactionDetails details) {
         List<Transaction> transactions = new ArrayList<>();
-        if(details != null) {
-            for(com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) {
+        if (details != null) {
+            for (com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) {
                 transactions.add(asTransaction(transaction));
             }
         }
@@ -196,17 +196,17 @@ public class AmericanExpress extends Bank {
     }
 
     private LoginResponse parseLoginResponse(HttpResponse response) throws IOException, BankException {
-        if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+        if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
             response.getEntity().consumeContent();
             throw new BankException(res.getText(R.string.server_error_try_again).toString());
         }
         LoginResponse loginResponse = MAPPER.reader()
                 .withType(LoginResponse.class)
                 .readValue(response.getEntity().getContent());
-        if(loginResponse == null || loginResponse.getLogonData() == null) {
+        if (loginResponse == null || loginResponse.getLogonData() == null) {
             throw new BankException(res.getText(R.string.server_error_try_again).toString());
         }
-        if(loginResponse.getLogonData().getStatus() != 0) {
+        if (loginResponse.getLogonData().getStatus() != 0) {
             throw new BankException(loginResponse.getLogonData().getMessage());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java
index c9abbe6..dbfe2d7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java
@@ -70,7 +70,7 @@ public class Card {
     }
 
     public BigDecimal getBalance() {
-        if(summary != null && summary.getTotalBalance() != null) {
+        if (summary != null && summary.getTotalBalance() != null) {
             return Helpers.parseBalance(summary.getTotalBalance().getValue()).negate();
         }
         return BigDecimal.ZERO;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
index b63fdd0..4d4ad79 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
@@ -43,7 +43,7 @@ public class LoginResponse {
     }
 
     public List<Card> getCards() {
-        if(summaryData != null && summaryData.getCardList() != null) {
+        if (summaryData != null && summaryData.getCardList() != null) {
             return summaryData.getCardList();
         }
         return Collections.emptyList();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java
index 2efa7ea..8673cb6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java
@@ -40,7 +40,7 @@ public class TransactionDetails {
     public List<Transaction> getTransactions() {
         if (activityList != null) {
             List<Transaction> transactions = new ArrayList<>();
-            for(AccountActivity activity : activityList) {
+            for (AccountActivity activity : activityList) {
                 transactions.addAll(activity.getTransactionList());
             }
             return transactions;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 6969afa..7e8fe82 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -129,7 +129,7 @@ public class Lansforsakringar extends Bank {
         } finally {
             try {
                 is.close();
-            } catch(IOException e) {
+            } catch (IOException e) {
                 Timber.w(e, "Closing JSON stream failed");
             }
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index c8b5272..1d58f40 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -86,7 +86,7 @@ public class Rikslunchen extends Bank {
         HttpResponse response = urlopen.openAsHttpResponse(
                 BASE_URL + "?cardid=" + getUsername(),
                 false);
-        if(response.getStatusLine().getStatusCode() != 200) {
+        if (response.getStatusLine().getStatusCode() != 200) {
             response.getEntity().consumeContent();
             throw new LoginException(context.getString(R.string.invalid_card_number));
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java
index 6436bdb..b57554a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java
@@ -8,7 +8,7 @@ import android.text.InputType;
 public class FieldTypeMapper {
 
     public static FieldType toFieldType(int androidFieldType) {
-        switch(androidFieldType) {
+        switch (androidFieldType) {
             case InputType.TYPE_CLASS_NUMBER:
                 return FieldType.NUMBER;
             case InputType.TYPE_CLASS_PHONE:
@@ -20,7 +20,7 @@ public class FieldTypeMapper {
         }
     }
     public static int fromFieldType(FieldType fieldType) {
-        switch(fieldType) {
+        switch (fieldType) {
             case NUMBER:
                 return InputType.TYPE_CLASS_NUMBER;
             case PHONE:
diff --git config/quality/checkstyle/checkstyle.xml config/quality/checkstyle/checkstyle.xml
index 204efc7..0493359 100644
--- config/quality/checkstyle/checkstyle.xml
+++ config/quality/checkstyle/checkstyle.xml
@@ -33,16 +33,17 @@
         <module name="EmptyForIteratorPad" />
         <module name="MethodParamPad" />
 
-        <!--
         <module name="NoWhitespaceAfter">
             <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS" />
         </module>
         <module name="NoWhitespaceBefore" />
-        <module name="WhitespaceAfter" />
+        <module name="WhitespaceAfter">
+            <property name="tokens" value="COMMA, SEMI"/> <!-- Not TYPECAST -->
+        </module>
         <module name="WhitespaceAround">
            <property name="allowEmptyMethods" value="true" />
         </module>
-        -->
+
         <module name="ParenPad" />
         <module name="TypecastParenPad" />
         <module name="RedundantModifier" />
diff --git config/quality/quality.gradle config/quality/quality.gradle
index bf2f1c6..9f4833d 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -63,7 +63,7 @@ task pmd(type: Pmd) {
     }
 }
 
-if(plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) {
+if (plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) {
     check.dependsOn 'lint'
     tasks.getByName("findbugs").dependsOn 'compileDebugSources'
     tasks.getByName('findbugs').classes = files("$project.buildDir/intermediates/classes")
@@ -85,7 +85,7 @@ if(plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) {
         }
     }
 }
-if(plugins.hasPlugin('java')) {
+if (plugins.hasPlugin('java')) {
     tasks.getByName('findbugs').classes = files("$project.buildDir/classes")
     tasks.getByName('findbugs').dependsOn 'classes'
 }

commit e8ebeb2488435fbf9f990cd6bfc2d9fa12a561ac
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Fri Oct 28 00:11:49 2016 +0200

    Östgötatrafiken: Adapt to new login page
    
    Östgötatrafiken now supports three ways to log in/authenticate:
    * An e-mail address
    * A username (for legacy users (such as me))
    * Facebook login
    
    Bankdroid only supports e-mail/username login.
    
    (I haven't tested e-mail login, but I expect it to work the same way
    as for username logins)

diff --git CHANGELOG CHANGELOG
index 970ea23..5ebd411 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 Not yet released
 * Bioklubben: Use https. It's secure and http page no longer exists.
+* Östgötatrafiken: Adapt to new login page (Facebook login not supported)
 
 v1.9.11 (2016-10-26)
 * Warn about disabled banks in the transactions list
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 37f3770..8524e38 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -45,9 +45,6 @@ public class Ostgotatrafiken extends Bank {
 
     private static final String NAME_SHORT = "ogt";
 
-    private static final String URL
-            = "https://www.ostgotatrafiken.se/Priser--biljetter/Mina-sidor/Login/";
-
     private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN;
 
     private Pattern reViewState = Pattern.compile(
@@ -75,7 +72,6 @@ public class Ostgotatrafiken extends Bank {
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
     }
 
     public Ostgotatrafiken(String username, String password, Context context) throws BankException,
@@ -90,18 +86,20 @@ public class Ostgotatrafiken extends Bank {
                 R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview));
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("Username", getUsername()));
-        postData.add(new BasicNameValuePair("Password", getPassword()));
-        postData.add(new BasicNameValuePair("Login", "Logga in"));
+        postData.add(new BasicNameValuePair("", "{\"authSource\":10," +
+                                            "\"keepMeLimitedLoggedIn\":true," +
+                                            "\"userName\":\"" + getUsername() + "\"," +
+                                            "\"password\":\"" + getPassword() + "\"," +
+                                            "\"impersonateUserName\":\"\"}"));
 
-        return new LoginPackage(urlopen, postData, response, URL);
+        return new LoginPackage(urlopen, postData, response, "https://www.ostgotatrafiken.se/ajax/Login/Attempt");
     }
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (!response.contains("Logga ut")) {
+        if (!response.contains("presentationUserName")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;

commit ff91ffbc69b9d82ce6e75063b8914c1a8bb28865
Author: Johan Walles <johan.walles@gmail.com>
Date:   Tue Nov 1 02:24:33 2016 +0100

    Log bank usage statistics to Crashlytics
    
    With this change in place we'll be able to see in Crashlytics:
    * which banks are most frequently disabled
    * which banks are most frequently used
    * for which banks transactions updating doesn't work

diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index b8145f3..331cfc3 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -24,6 +24,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.LoggingUtils;
 import com.liato.bankdroid.utils.NetworkUtils;
 
 import android.app.AlertDialog;
@@ -80,6 +81,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
         return this.dialog;
     }
 
+    @Nullable
     protected Bank getBankFromDb(long bankId, Context parent) {
         return BankFactory.bankFromDb(bankId, parent, true);
     }
@@ -122,6 +124,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
             publishProgress(i, bank);
 
             if (isListingAllBanks() && bank.isDisabled()) {
+                LoggingUtils.logDisabledBank(bank);
                 continue;
             }
 
@@ -131,6 +134,8 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
                 bank.closeConnection();
                 saveBank(bank, parent);
                 i++;
+
+                LoggingUtils.logBankUpdate(bank, true);
             } catch (final BankException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
@@ -194,6 +199,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
                     .setIcon(android.R.drawable.ic_dialog_alert)
                     .setNeutralButton("Ok",
                             new DialogInterface.OnClickListener() {
+                                @Override
                                 public void onClick(
                                         final DialogInterface dialog,
                                         final int id) {
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index f289d76..7a82c5b 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -27,6 +27,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.liveview.LiveViewService;
+import com.liato.bankdroid.utils.LoggingUtils;
 
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -289,7 +290,7 @@ public class AutoRefreshService extends Service {
 
         @Override
         protected Void doInBackground(final String... args) {
-            errors = new ArrayList<String>();
+            errors = new ArrayList<>();
             Boolean refreshWidgets = false;
             final List<Bank> banks = getBanks();
             if (banks.isEmpty()) {
@@ -300,7 +301,7 @@ public class AutoRefreshService extends Service {
             BigDecimal diff;
             BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0"));
 
-            final HashMap<String, Account> accounts = new HashMap<String, Account>();
+            final HashMap<String, Account> accounts = new HashMap<>();
 
             for (final Bank bank : banks) {
                 if (prefs.getBoolean("debug_mode", false)
@@ -311,6 +312,7 @@ public class AutoRefreshService extends Service {
                     continue;
                 }
                 if (bank.isDisabled()) {
+                    LoggingUtils.logDisabledBank(bank);
                     continue;
                 }
                 try {
@@ -320,6 +322,7 @@ public class AutoRefreshService extends Service {
                         accounts.put(account.getId(), account);
                     }
                     bank.update();
+
                     diff = currentBalance.subtract(bank.getBalance());
 
                     if (diff.compareTo(BigDecimal.ZERO) != 0) {
@@ -373,6 +376,9 @@ public class AutoRefreshService extends Service {
                         if (prefs.getBoolean(
                                 "autoupdates_transactions_enabled", true)) {
                             bank.updateAllTransactions();
+                            LoggingUtils.logBankUpdate(bank, true);
+                        } else {
+                            LoggingUtils.logBankUpdate(bank, false);
                         }
                     }
                     bank.closeConnection();
diff --git app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
index f0cf5dc..bea4936 100644
--- app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
+++ app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
@@ -4,6 +4,8 @@ import com.crashlytics.android.Crashlytics;
 import com.crashlytics.android.answers.Answers;
 import com.crashlytics.android.answers.CustomEvent;
 import com.liato.bankdroid.BuildConfig;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
 
 import android.content.Context;
 import android.text.TextUtils;
@@ -40,9 +42,41 @@ public class LoggingUtils {
     }
 
     public static void logCustom(CustomEvent event) {
-        if (isCrashlyticsEnabled()) {
-            event.putCustomAttribute("App Version", BuildConfig.VERSION_NAME);
-            Answers.getInstance().logCustom(event);
+        if (!isCrashlyticsEnabled()) {
+            return;
+        }
+
+        event.putCustomAttribute("App Version", BuildConfig.VERSION_NAME);
+        Answers.getInstance().logCustom(event);
+    }
+
+    public static void logDisabledBank(Bank bank) {
+        if (!isCrashlyticsEnabled()) {
+            return;
+        }
+
+        logCustom(new CustomEvent("Disabled Bank").
+                putCustomAttribute("Name", bank.getDisplayName()));
+    }
+
+    public static void logBankUpdate(Bank bank, boolean withTransactions) {
+        if (!isCrashlyticsEnabled()) {
+            return;
+        }
+
+        logCustom(new CustomEvent("Bank Updated").
+                putCustomAttribute("Name", bank.getDisplayName()).
+                putCustomAttribute("With Transactions", Boolean.toString(withTransactions)));
+
+        boolean hasTransactions = false;
+        for (Account account : bank.getAccounts()) {
+            if (account.getTransactions() != null && !account.getTransactions().isEmpty()) {
+                hasTransactions = true;
+            }
+        }
+        if (withTransactions && !hasTransactions) {
+            logCustom(new CustomEvent("Bank Without Transactions").
+                    putCustomAttribute("Name", bank.getDisplayName()));
         }
     }
 

commit cb2027c3121ca4c37ef8ef1c45656d27e52e37c3
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sun Oct 30 17:12:07 2016 +0100

    Require closing result cursors

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index d61e0ce..db905c8 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -84,10 +84,10 @@ public class BankFactory {
         ArrayList<Bank> banks = new ArrayList<>();
         DBAdapter db = new DBAdapter(context);
         Cursor c = db.fetchBanks();
-        if (c == null) {
-            return banks;
-        }
         try {
+            if (c == null || c.getCount() == 0) {
+                return banks;
+            }
             while (!c.isLast() && !c.isAfterLast()) {
                 c.moveToNext();
                 try {
@@ -109,7 +109,9 @@ public class BankFactory {
                 }
             }
         } finally {
-            c.close();
+            if (c != null) {
+                c.close();
+            }
         }
         return banks;
     }
@@ -118,38 +120,50 @@ public class BankFactory {
     public static Account accountFromDb(Context context, String accountId,
             boolean loadTransactions) {
         DBAdapter db = new DBAdapter(context);
-        Cursor c = db.getAccount(accountId);
+        Cursor ac = db.getAccount(accountId);
+
+        Account account;
+        try {
+            if (ac == null || ac.isClosed() || (ac.isBeforeFirst() && ac.isAfterLast())) {
+                return null;
+            }
 
-        if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
-            return null;
+            account = new Account(ac.getString(ac.getColumnIndex("name")),
+                    new BigDecimal(ac.getString(ac.getColumnIndex("balance"))),
+                    ac.getString(ac.getColumnIndex("id")).split("_", 2)[1],
+                    ac.getLong(ac.getColumnIndex("bankid")),
+                    ac.getInt(ac.getColumnIndex("acctype")));
+            account.setHidden(ac.getInt(ac.getColumnIndex("hidden")) == 1);
+            account.setNotify(ac.getInt(ac.getColumnIndex("notify")) == 1);
+            account.setCurrency(ac.getString(ac.getColumnIndex("currency")));
+            account.setAliasfor(ac.getString(ac.getColumnIndex("aliasfor")));
+        } finally {
+            if (ac != null) {
+                ac.close();
+            }
         }
 
-        Account account = new Account(c.getString(c.getColumnIndex("name")),
-                new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                c.getLong(c.getColumnIndex("bankid")),
-                c.getInt(c.getColumnIndex("acctype")));
-        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1);
-        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1);
-        account.setCurrency(c.getString(c.getColumnIndex("currency")));
-        account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
-        c.close();
         if (loadTransactions) {
             ArrayList<Transaction> transactions = new ArrayList<>();
             String fromAccount = accountId;
             if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
                 fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
             }
-            c = db.fetchTransactions(fromAccount);
-            if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
-                while (!c.isLast() && !c.isAfterLast()) {
-                    c.moveToNext();
-                    transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")),
-                            c.getString(c.getColumnIndex("btransaction")),
-                            new BigDecimal(c.getString(c.getColumnIndex("amount"))),
-                            c.getString(c.getColumnIndex("currency"))));
+            Cursor tc = db.fetchTransactions(fromAccount);
+            try {
+                if (!(tc == null || tc.isClosed() || (tc.isBeforeFirst() && tc.isAfterLast()))) {
+                    while (!tc.isLast() && !tc.isAfterLast()) {
+                        tc.moveToNext();
+                        transactions.add(new Transaction(tc.getString(tc.getColumnIndex("transdate")),
+                                tc.getString(tc.getColumnIndex("btransaction")),
+                                new BigDecimal(tc.getString(tc.getColumnIndex("amount"))),
+                                tc.getString(tc.getColumnIndex("currency"))));
+                    }
+                }
+            } finally {
+                if (tc != null) {
+                    tc.close();
                 }
-                c.close();
             }
             account.setTransactions(transactions);
         }
@@ -160,10 +174,10 @@ public class BankFactory {
         ArrayList<Account> accounts = new ArrayList<>();
         DBAdapter db = new DBAdapter(context);
         Cursor c = db.fetchAccounts(bankId);
-        if (c == null) {
-            return accounts;
-        }
         try {
+            if (c == null || c.getCount() == 0) {
+                return accounts;
+            }
             while (!c.isLast() && !c.isAfterLast()) {
                 c.moveToNext();
                 try {
@@ -183,7 +197,9 @@ public class BankFactory {
                 }
             }
         } finally {
-            c.close();
+            if (c != null) {
+                c.close();
+            }
         }
         return accounts;
     }
@@ -193,10 +209,10 @@ public class BankFactory {
         Map<String, String> decryptedProperties = new HashMap<>();
         DBAdapter db = new DBAdapter(context);
         Cursor c = db.fetchProperties(Long.toString(bankId));
-        if(c == null) {
-            return properties;
-        }
         try {
+            if (c == null || c.getCount() == 0) {
+                return properties;
+            }
             while (!c.isLast() && !c.isAfterLast()) {
                 c.moveToNext();
                 String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY));
@@ -214,7 +230,9 @@ public class BankFactory {
                 properties.put(key, value);
             }
         } finally {
-            c.close();
+          if (c != null) {
+              c.close();
+          }
         }
 
         storeDecryptedProperties(context, bankId, decryptedProperties);
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index ea72715..e4b166a 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -105,33 +105,38 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
 
         // Add username, password and extras fields to properties table.
         Cursor c = db.query(tempTable, null, null, null,null,null,null);
-        if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
-            while (!c.isLast() && !c.isAfterLast()) {
-                c.moveToNext();
-                long id = c.getLong(c.getColumnIndex(LegacyDatabase.BANK_ID));
-
-                ContentValues usernameProperty = new ContentValues();
-                usernameProperty.put(PROPERTY_CONNECTION_ID, id);
-                usernameProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.USERNAME);
-                usernameProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_USERNAME)));
-                db.insert(PROPERTY_TABLE_NAME, null, usernameProperty);
-
-                ContentValues passwordProperty = new ContentValues();
-                passwordProperty.put(PROPERTY_CONNECTION_ID, id);
-                passwordProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.PASSWORD);
-                passwordProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_PASSWORD)));
-                db.insert(PROPERTY_TABLE_NAME, null, passwordProperty);
-
-                String extras = c.getString(c.getColumnIndex(LegacyDatabase.BANK_EXTRAS));
-                if(extras != null && !extras.isEmpty()) {
-                    ContentValues extrasProperty = new ContentValues();
-                    extrasProperty.put(PROPERTY_CONNECTION_ID, id);
-                    extrasProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.EXTRAS);
-                    extrasProperty.put(PROPERTY_VALUE, extras);
-                    db.insert(PROPERTY_TABLE_NAME, null, extrasProperty);
+        try {
+            if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
+                while (!c.isLast() && !c.isAfterLast()) {
+                    c.moveToNext();
+                    long id = c.getLong(c.getColumnIndex(LegacyDatabase.BANK_ID));
+
+                    ContentValues usernameProperty = new ContentValues();
+                    usernameProperty.put(PROPERTY_CONNECTION_ID, id);
+                    usernameProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.USERNAME);
+                    usernameProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_USERNAME)));
+                    db.insert(PROPERTY_TABLE_NAME, null, usernameProperty);
+
+                    ContentValues passwordProperty = new ContentValues();
+                    passwordProperty.put(PROPERTY_CONNECTION_ID, id);
+                    passwordProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.PASSWORD);
+                    passwordProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_PASSWORD)));
+                    db.insert(PROPERTY_TABLE_NAME, null, passwordProperty);
+
+                    String extras = c.getString(c.getColumnIndex(LegacyDatabase.BANK_EXTRAS));
+                    if (extras != null && !extras.isEmpty()) {
+                        ContentValues extrasProperty = new ContentValues();
+                        extrasProperty.put(PROPERTY_CONNECTION_ID, id);
+                        extrasProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.EXTRAS);
+                        extrasProperty.put(PROPERTY_VALUE, extras);
+                        db.insert(PROPERTY_TABLE_NAME, null, extrasProperty);
+                    }
                 }
             }
-            c.close();
+        } finally {
+            if (c != null) {
+                c.close();
+            }
         }
         db.execSQL("DROP TABLE " + tempTable);
     }
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 3109e6b..19538ce 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -25,6 +25,13 @@
         </properties>
     </rule>
 
+    <!-- Add Cursor to the classes that need closing -->
+    <rule ref="rulesets/internal/all-java.xml/CloseResource">
+        <properties>
+            <property name="types" value="Connection,Statement,ResultSet,Cursor" />
+        </properties>
+    </rule>
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
 
diff --git tools/update-suppressions.sh tools/update-suppressions.sh
index 4148ea6..53ff534 100755
--- tools/update-suppressions.sh
+++ tools/update-suppressions.sh
@@ -64,6 +64,13 @@ function set_pmd_suppressions() {
         </properties>
     </rule>
 
+    <!-- Add Cursor to the classes that need closing -->
+    <rule ref="rulesets/internal/all-java.xml/CloseResource">
+        <properties>
+            <property name="types" value="Connection,Statement,ResultSet,Cursor" />
+        </properties>
+    </rule>
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
 

commit 63188088e36f3e351830d0e5b1f8b0b576fa5b54
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Oct 27 22:02:02 2016 +0200

    Ensure on-disk passwords are unencrypted
    
    This is a step towards removing password encryption alltogether.
    
    The background is that it's broken on Androin Nougat anyway, and that it
    didn't provide any extra security before that either.
    
    Since Bankdroid needs to send plain text passwords to the banks, it must
    be possible to retrieve the plain text passwords automatically. And if
    the passwords are encrypted on disk, Bankdroid needs to have the key.
    And if Bankdroid stores both the key and the encrypted password on the
    phone, a determined attacker could get both anyway, and the encryption
    is useless.
    
    The only thing the encryption has protected against is a user rooting
    their own device and retrieving their own plain text passwords. This
    would enable the attacker to read their own account balance from the
    bank.
    
    Which they likely already could even before this change...
    
    This change also disables an Android Lint check whose outcome changes
    over time; these checks are impossible to maintain. And we fixed some
    warnings.

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 9a7ea9c..d61e0ce 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -16,15 +16,20 @@
 
 package com.liato.bankdroid.banking;
 
+import com.crashlytics.android.answers.CustomEvent;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.db.Database;
+import com.liato.bankdroid.db.DatabaseHelper;
+import com.liato.bankdroid.utils.LoggingUtils;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 
+import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
 import android.support.annotation.Nullable;
 
 import java.math.BigDecimal;
@@ -37,7 +42,7 @@ import timber.log.Timber;
 
 public class BankFactory {
 
-    public static Bank fromBanktypeId(int id, Context context) throws BankException {
+    private static Bank fromBanktypeId(int id, Context context) throws BankException {
         return LegacyBankFactory.fromBanktypeId(id, context);
     }
 
@@ -58,7 +63,7 @@ public class BankFactory {
                 bank.setProperties(loadProperties(id, context));
 
                 bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                        (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+                        (c.getInt(c.getColumnIndex("disabled")) != 0),
                         c.getLong(c.getColumnIndex("_id")),
                         c.getString(c.getColumnIndex("currency")),
                         c.getString(c.getColumnIndex("custname")),
@@ -76,36 +81,40 @@ public class BankFactory {
     }
 
     public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
-        ArrayList<Bank> banks = new ArrayList<Bank>();
+        ArrayList<Bank> banks = new ArrayList<>();
         DBAdapter db = new DBAdapter(context);
         Cursor c = db.fetchBanks();
-        if (c == null || c.getCount() == 0) {
+        if (c == null) {
             return banks;
         }
-        while (!c.isLast() && !c.isAfterLast()) {
-            c.moveToNext();
-            try {
-                Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-                long id = c.getLong(c.getColumnIndex("_id"));
-                bank.setProperties(loadProperties(id, context));
-                bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                        (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-                        id,
-                        c.getString(c.getColumnIndex("currency")),
-                        c.getString(c.getColumnIndex("custname")),
-                        c.getInt(c.getColumnIndex("hideAccounts")));
-                if (loadAccounts) {
-                    bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+        try {
+            while (!c.isLast() && !c.isAfterLast()) {
+                c.moveToNext();
+                try {
+                    Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+                    long id = c.getLong(c.getColumnIndex("_id"));
+                    bank.setProperties(loadProperties(id, context));
+                    bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                            (c.getInt(c.getColumnIndex("disabled")) != 0),
+                            id,
+                            c.getString(c.getColumnIndex("currency")),
+                            c.getString(c.getColumnIndex("custname")),
+                            c.getInt(c.getColumnIndex("hideAccounts")));
+                    if (loadAccounts) {
+                        bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+                    }
+                    banks.add(bank);
+                } catch (BankException e) {
+                    Timber.w(e, "BankFactory.banksFromDb()");
                 }
-                banks.add(bank);
-            } catch (BankException e) {
-                Timber.w(e, "BankFactory.banksFromDb()");
             }
+        } finally {
+            c.close();
         }
-        c.close();
         return banks;
     }
 
+    @Nullable
     public static Account accountFromDb(Context context, String accountId,
             boolean loadTransactions) {
         DBAdapter db = new DBAdapter(context);
@@ -120,13 +129,13 @@ public class BankFactory {
                 c.getString(c.getColumnIndex("id")).split("_", 2)[1],
                 c.getLong(c.getColumnIndex("bankid")),
                 c.getInt(c.getColumnIndex("acctype")));
-        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
+        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1);
+        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1);
         account.setCurrency(c.getString(c.getColumnIndex("currency")));
         account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
         c.close();
         if (loadTransactions) {
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            ArrayList<Transaction> transactions = new ArrayList<>();
             String fromAccount = accountId;
             if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
                 fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
@@ -147,56 +156,114 @@ public class BankFactory {
         return account;
     }
 
-    public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
-        ArrayList<Account> accounts = new ArrayList<Account>();
+    private static ArrayList<Account> accountsFromDb(Context context, long bankId) {
+        ArrayList<Account> accounts = new ArrayList<>();
         DBAdapter db = new DBAdapter(context);
         Cursor c = db.fetchAccounts(bankId);
-        if (c == null || c.getCount() == 0) {
+        if (c == null) {
             return accounts;
         }
-        while (!c.isLast() && !c.isAfterLast()) {
-            c.moveToNext();
-            try {
-                Account account = new Account(c.getString(c.getColumnIndex("name")),
-                        new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                        c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                        c.getLong(c.getColumnIndex("bankid")),
-                        c.getInt(c.getColumnIndex("acctype")));
-                account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-                account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
-                account.setCurrency(c.getString(c.getColumnIndex("currency")));
-                account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
-                accounts.add(account);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // Probably an old Avanza account
-                Timber.w(e, "Attempted to load an account without an ID: %d", bankId);
+        try {
+            while (!c.isLast() && !c.isAfterLast()) {
+                c.moveToNext();
+                try {
+                    Account account = new Account(c.getString(c.getColumnIndex("name")),
+                            new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                            c.getString(c.getColumnIndex("id")).split("_", 2)[1],
+                            c.getLong(c.getColumnIndex("bankid")),
+                            c.getInt(c.getColumnIndex("acctype")));
+                    account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1);
+                    account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1);
+                    account.setCurrency(c.getString(c.getColumnIndex("currency")));
+                    account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
+                    accounts.add(account);
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    // Probably an old Avanza account
+                    Timber.w(e, "Attempted to load an account without an ID: %d", bankId);
+                }
             }
+        } finally {
+            c.close();
         }
-        c.close();
         return accounts;
     }
 
-    private static Map<String, String> loadProperties(long id, Context context) {
+    private static Map<String, String> loadProperties(long bankId, Context context) {
         Map<String, String> properties = new HashMap<>();
+        Map<String, String> decryptedProperties = new HashMap<>();
         DBAdapter db = new DBAdapter(context);
-        Cursor c = db.fetchProperties(Long.toString(id));
-        if(c == null || c.getCount() == 0) {
+        Cursor c = db.fetchProperties(Long.toString(bankId));
+        if(c == null) {
             return properties;
         }
-        while(!c.isLast() && !c.isAfterLast()) {
-            c.moveToNext();
-            String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY));
-            String value = c.getString(c.getColumnIndex(Database.PROPERTY_VALUE));
-            if(LegacyProviderConfiguration.PASSWORD.equals(key)) {
-                try {
-                    value = SimpleCrypto.decrypt(Crypto.getKey(), value);
-                } catch (Exception e) {
-                    Timber.w(e, "Failed decrypting bank properties");
+        try {
+            while (!c.isLast() && !c.isAfterLast()) {
+                c.moveToNext();
+                String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY));
+                String value = c.getString(c.getColumnIndex(Database.PROPERTY_VALUE));
+                if (LegacyProviderConfiguration.PASSWORD.equals(key)) {
+                    try {
+                        value = SimpleCrypto.decrypt(Crypto.getKey(), value);
+                        decryptedProperties.put(key, value);
+                    } catch (Exception e) {
+                        Timber.i("%s %s",
+                                "Failed decrypting bank properties.",
+                                "This usually means they are unencrypted, which is exactly what we want them to be.");
+                    }
                 }
+                properties.put(key, value);
             }
-            properties.put(key, value);
+        } finally {
+            c.close();
         }
-        c.close();
+
+        storeDecryptedProperties(context, bankId, decryptedProperties);
+
         return properties;
     }
+
+    /**
+     * Stores decrypted passwords on disk.
+     * <p/>
+     * This is a step in removing password encryption alltogether.
+     * <p/>
+     * The background is that it's broken on Androin Nougat anyway, and that it
+     * didn't provide any extra security before that either.
+     * <p/>
+     * Since Bankdroid needs to send plain text passwords to the banks, it must
+     * be possible to retrieve the plain text passwords automatically. And if the
+     * passwords are encrypted on disk, Bankdroid needs to have the key. And if
+     * Bankdroid stores both the key and the encrypted password on the phone, a
+     * determined attacker could get both anyway, and the encryption is useless.
+     * <p/>
+     * The only thing the encryption has protected against is a using rooting
+     * their own device and retrieving their own plain text passwords. This would
+     * enable the attacker to reaa their own account balance from the bank. Which
+     * they likely already could even before this change...
+     */
+    private static void storeDecryptedProperties(
+            Context context, long bankId, Map<String, String> decryptedProperties)
+    {
+        if (decryptedProperties.isEmpty()) {
+            return;
+        }
+
+        Timber.i("Storing %d decrypted properties...", decryptedProperties.size());
+        SQLiteDatabase db = DatabaseHelper.getHelper(context).getWritableDatabase();
+        for (Map.Entry<String, String> property : decryptedProperties.entrySet()) {
+            String value = property.getValue();
+            if (value != null && !value.isEmpty()) {
+                ContentValues propertyValues = new ContentValues();
+                propertyValues.put(Database.PROPERTY_KEY, property.getKey());
+                propertyValues.put(Database.PROPERTY_VALUE, value);
+                propertyValues.put(Database.PROPERTY_CONNECTION_ID, bankId);
+                db.insertWithOnConflict(
+                        Database.PROPERTY_TABLE_NAME, null, propertyValues,
+                        SQLiteDatabase.CONFLICT_REPLACE);
+            }
+        }
+        Timber.i("%d decrypted properties stored", decryptedProperties.size());
+
+        LoggingUtils.logCustom(new CustomEvent("Passwords Decrypted"));
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 240669b..215c59f 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -18,15 +18,13 @@ package com.liato.bankdroid.db;
 
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.LegacyProviderConfiguration;
 import com.liato.bankdroid.banking.Transaction;
 
-import net.sf.andhsli.hotspotlogin.SimpleCrypto;
-
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
+import android.support.annotation.Nullable;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -34,8 +32,6 @@ import java.util.Calendar;
 import java.util.List;
 import java.util.Map;
 
-import timber.log.Timber;
-
 
 public class DBAdapter {
 
@@ -169,13 +165,6 @@ public class DBAdapter {
             for(Map.Entry<String,String> property : properties.entrySet()) {
                 String value = property.getValue();
                 if(value != null && !value.isEmpty()) {
-                    if (LegacyProviderConfiguration.PASSWORD.equals(property.getKey())) {
-                        try {
-                            value = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
-                        } catch (Exception e) {
-                            Timber.e(e, "Could not encrypt password.");
-                        }
-                    }
                     ContentValues propertyValues = new ContentValues();
                     propertyValues.put(Database.PROPERTY_KEY, property.getKey());
                     propertyValues.put(Database.PROPERTY_VALUE, value);
@@ -227,6 +216,7 @@ public class DBAdapter {
         mDb.update("banks", initialValues, "_id=" + bankId, null);
     }
 
+    @Nullable
     public Cursor getBank(String bankId) {
         Cursor c = mDb.query("banks",
                 new String[]{"_id", "balance", "banktype", "disabled",
@@ -238,10 +228,12 @@ public class DBAdapter {
         return c;
     }
 
+    @Nullable
     public Cursor getBank(long bankId) {
         return getBank(Long.toString(bankId));
     }
 
+    @Nullable
     public Cursor getAccount(String id) {
         Cursor c = mDb.query("accounts",
                 new String[]{"id", "balance", "name", "bankid", "acctype", "hidden", "notify",
diff --git app/src/main/java/com/liato/bankdroid/db/Database.java app/src/main/java/com/liato/bankdroid/db/Database.java
index 0558483..93d3c14 100644
--- app/src/main/java/com/liato/bankdroid/db/Database.java
+++ app/src/main/java/com/liato/bankdroid/db/Database.java
@@ -6,7 +6,7 @@ public class Database {
 
     static final int DATABASE_VERSION = 12;
 
-    static final String PROPERTY_TABLE_NAME = "connection_properties";
+    public static final String PROPERTY_TABLE_NAME = "connection_properties";
     public static final String PROPERTY_CONNECTION_ID = "connection_id";
     public static final String PROPERTY_KEY = "property";
     public static final String PROPERTY_VALUE = "value";
diff --git app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
index 4867459..f0cf5dc 100644
--- app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
+++ app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
@@ -1,12 +1,14 @@
 package com.liato.bankdroid.utils;
 
+import com.crashlytics.android.Crashlytics;
+import com.crashlytics.android.answers.Answers;
+import com.crashlytics.android.answers.CustomEvent;
+import com.liato.bankdroid.BuildConfig;
+
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.crashlytics.android.Crashlytics;
-import com.liato.bankdroid.BuildConfig;
-
 import io.fabric.sdk.android.Fabric;
 import timber.log.Timber;
 
@@ -37,6 +39,13 @@ public class LoggingUtils {
                 !EmulatorUtils.RUNNING_ON_EMULATOR;
     }
 
+    public static void logCustom(CustomEvent event) {
+        if (isCrashlyticsEnabled()) {
+            event.putCustomAttribute("App Version", BuildConfig.VERSION_NAME);
+            Answers.getInstance().logCustom(event);
+        }
+    }
+
     private static class CrashlyticsTree extends Timber.Tree {
         CrashlyticsTree(Context context) {
             Fabric.with(context, new Crashlytics());
diff --git app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
index d4a1995..88e4154 100644
--- app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
+++ app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -22,18 +22,14 @@ import javax.crypto.spec.SecretKeySpec;
  * String cleartext = SimpleCrypto.decrypt(masterpassword, crypto)
  * </pre>
  *
+ * @deprecated <a href="http://android-developers.blogspot.se/2016/06/security-crypto-provider-deprecated-in.html">Broken
+ * on Android Nougat</a>,
+ * <a href="https://android.googlesource.com/platform/tools/base/+/2d252fc75960a3eaf7297c7a7713baf0c60b6aed/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/CipherGetInstanceDetector.java#44">considered
+ * broken by Android Lint even before then</a>.
+ *
  * @author ferenc.hechler
  */
 public class SimpleCrypto {
-
-    private final static String HEX = "0123456789ABCDEF";
-
-    public static String encrypt(String seed, String cleartext) throws Exception {
-        byte[] rawKey = getRawKey(StringUtils.getBytes(seed));
-        byte[] result = encrypt(rawKey, StringUtils.getBytes(cleartext));
-        return toHex(result);
-    }
-
     public static String decrypt(String seed, String encrypted) throws Exception {
         byte[] rawKey = getRawKey(StringUtils.getBytes(seed));
         byte[] enc = toByte(encrypted);
@@ -56,14 +52,6 @@ public class SimpleCrypto {
         return raw;
     }
 
-    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
-        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
-        Cipher cipher = Cipher.getInstance("AES");
-        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
-        byte[] encrypted = cipher.doFinal(clear);
-        return encrypted;
-    }
-
     private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
         Cipher cipher = Cipher.getInstance("AES");
@@ -72,7 +60,7 @@ public class SimpleCrypto {
         return decrypted;
     }
 
-    public static byte[] toByte(String hexString) {
+    private static byte[] toByte(String hexString) {
         int len = hexString.length() / 2;
         byte[] result = new byte[len];
         for (int i = 0; i < len; i++) {
@@ -80,19 +68,4 @@ public class SimpleCrypto {
         }
         return result;
     }
-
-    public static String toHex(byte[] buf) {
-        if (buf == null) {
-            return "";
-        }
-        StringBuffer result = new StringBuffer(2 * buf.length);
-        for (int i = 0; i < buf.length; i++) {
-            appendHex(result, buf[i]);
-        }
-        return result.toString();
-    }
-
-    private static void appendHex(StringBuffer sb, byte b) {
-        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
-    }
 }
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 8195ce2..f81c4ca 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -30,6 +30,7 @@
     <issue id="NewerVersionAvailable" severity="ignore" />
     <issue id="NotSibling" severity="ignore" />
     <issue id="ObsoleteLayoutParam" severity="ignore" />
+    <issue id="OldTargetApi" severity="ignore" />
     <issue id="Orientation" severity="ignore" />
     <issue id="Overdraw" severity="ignore" />
     <issue id="ParcelClassLoader" severity="ignore" />

commit eabc99cfadbf724f5d3129bc7b011587c6fd43d0
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Sat Oct 29 20:59:00 2016 +0200

    Bioklubben: Update start web page
    
    http://bioklubben.sf.se -> https://bioklubben.sf.se
    
    The http version no longer exists

diff --git CHANGELOG CHANGELOG
index fa02959..970ea23 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+Not yet released
+* Bioklubben: Use https. It's secure and http page no longer exists.
+
 v1.9.11 (2016-10-26)
 * Warn about disabled banks in the transactions list
 * Show warning text about disabled banks in the main activity
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index e31540f..df9e368 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -39,6 +39,7 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bioklubben extends Bank {
@@ -47,7 +48,7 @@ public class Bioklubben extends Bank {
 
     private static final String NAME_SHORT = "bioklubben";
 
-    private static final String URL = "http://bioklubben.sf.se/Start.aspx";
+    private static final String URL = "https://bioklubben.sf.se/Start.aspx";
 
     private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
 
@@ -76,9 +77,9 @@ public class Bioklubben extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context);
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bioklubben));
         urlopen.setAllowCircularRedirects(true);
-        response = urlopen.open("http://bioklubben.sf.se/Start.aspx");
+        response = urlopen.open(URL);
 
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("__VIEWSTATE");
@@ -109,7 +110,7 @@ public class Bioklubben extends Bank {
         postData.add(
                 new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$PasswordTextBox",
                         getPassword()));
-        return new LoginPackage(urlopen, postData, response, "http://bioklubben.sf.se/Start.aspx");
+        return new LoginPackage(urlopen, postData, response, URL);
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
@@ -129,7 +130,7 @@ public class Bioklubben extends Bank {
         }
         urlopen = login();
         Document d = Jsoup.parse(urlopen.open(
-                "http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
+                "https://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
         Element e = d.getElementById("ctl00_ContentPlaceHolder1_BonusPointsLabel");
         if (e == null) {
             throw new BankException(
diff --git bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem
new file mode 100644
index 0000000..a01ed1e
--- /dev/null
+++ bankdroid-legacy/src/main/res/raw/cert_bioklubben.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+Lk4ymn/K6HZMbtsrXfcWX8N3UmO5
+-----END CERTIFICATE-----
+bioklubben.sf.se:443

commit 13e94fcea34623cfd5d3fa734ef1c855f190f7ba
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Fri Oct 28 00:27:16 2016 +0200

    Remove stray Villabanken logo

diff --git assets/villabanken.psd assets/villabanken.psd
deleted file mode 100644
index 2efedbb..0000000
Binary files assets/villabanken.psd and /dev/null differ

commit 94072b6173bdcbe1f96146cf1587cdc359ea3139
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Oct 27 06:19:09 2016 +0200

    Fix empty catch blocks
    
    This should improve the Crashlytics statistics.

diff --git app/src/main/java/com/liato/bankdroid/TimePreference.java app/src/main/java/com/liato/bankdroid/TimePreference.java
index 44586c5..fc13af3 100644
--- app/src/main/java/com/liato/bankdroid/TimePreference.java
+++ app/src/main/java/com/liato/bankdroid/TimePreference.java
@@ -8,6 +8,8 @@ import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TimePicker;
 
+import timber.log.Timber;
+
 public class TimePreference extends DialogPreference {
 
     private int lastValue = 0;
@@ -64,6 +66,7 @@ public class TimePreference extends DialogPreference {
             try {
                 val = Integer.parseInt(defaultValue.toString());
             } catch (NumberFormatException e) {
+                Timber.e(e, "TimePreference's defaultValue is not a number");
             }
         }
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 7e26254..f289d76 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -394,6 +394,7 @@ public class AutoRefreshService extends Service {
                     refreshWidgets = true;
                     db.disableBank(bank.getDbId());
                 } catch (BankChoiceException e) {
+                    Timber.w(e, "BankChoiceException");
                 } catch (Exception e) {
                     Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getShortName());
                 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 17c19ae..fd0011c 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -395,6 +395,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
                     Timber.w(e, "Invalid credentials for bank %s", bank.getShortName());
                     DBAdapter.disable(bank, context);
                 } catch (BankChoiceException e) {
+                    Timber.w(e, "BankChoiceException");
                 } catch (IOException e) {
                     if (NetworkUtils.isInternetAvailable()) {
                         Timber.e(e, "Could not update bank %s", bank.getShortName());
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index b1a8888..9a7ea9c 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -99,7 +99,7 @@ public class BankFactory {
                 }
                 banks.add(bank);
             } catch (BankException e) {
-                //e.printStackTrace();
+                Timber.w(e, "BankFactory.banksFromDb()");
             }
         }
         c.close();
@@ -168,7 +168,8 @@ public class BankFactory {
                 account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
                 accounts.add(account);
             } catch (ArrayIndexOutOfBoundsException e) {
-                // Attempted to load an account without and ID, probably an old Avanza account.
+                // Probably an old Avanza account
+                Timber.w(e, "Attempted to load an account without an ID: %d", bankId);
             }
         }
         c.close();
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
index 2de42b7..87a0c1d 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -236,10 +236,9 @@ public class ColorPickerPreference
         }
         mValue = color;
         setPreviewColor();
-        try {
-            getOnPreferenceChangeListener().onPreferenceChange(this, color);
-        } catch (NullPointerException e) {
-
+        OnPreferenceChangeListener listener = getOnPreferenceChangeListener();
+        if (listener != null) {
+            listener.onPreferenceChange(this, color);
         }
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
index 2c2e4ce..2ea759a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
@@ -142,7 +142,7 @@ public class Helpers {
                     .getMethod("overridePendingTransition", int.class, int.class);
             method.invoke(activity, in, out);
         } catch (Exception e) {
-            // Can't change animation, so do nothing
+            Timber.w(e, "Can't change animation, so do nothing");
         }
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
index 82ad171..496f9e4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
@@ -6,6 +6,8 @@ import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.Map;
 
+import timber.log.Timber;
+
 public class LegacyBankHelper {
 
     private static Map<String, Integer> legacyProviderReferences;
@@ -39,7 +41,7 @@ public class LegacyBankHelper {
                 references.put(legacyId, reference);
                 legacyIds.put(reference, legacyId);
             } catch(IllegalAccessException e) {
-                //TODO log if provider could not be mapped.
+                Timber.e(e, "Provider could not be mapped");
             }
         }
         legacyProviderReferences = legacyIds;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index b3c620f..fddf1bb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -42,6 +42,7 @@ import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public class Jojo extends Bank {
 
@@ -141,6 +142,7 @@ public class Jojo extends Bank {
             }
         } catch (IOException e) {
             // Ignore and defaults to zero
+            Timber.w(e, "Getting Jojo card balance failed");
         }
         return BigDecimal.ZERO;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index d1ece28..6969afa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -130,10 +130,9 @@ public class Lansforsakringar extends Bank {
             try {
                 is.close();
             } catch(IOException e) {
-                // Ignore
+                Timber.w(e, "Closing JSON stream failed");
             }
         }
-
     }
 
     private <T> T readJsonValue(String url, String postData, Class<T> valueType)
@@ -235,8 +234,7 @@ public class Lansforsakringar extends Bank {
             }
             account.setTransactions(transactions);
         } catch (BankException e) {
-            // No transactions for account if this fails.
-            // readJsonValue will print the stack trace
+            Timber.e(e, "Failed updating Länsförsäkringar transactions");
         }
 
         super.updateComplete();
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index 2a87b49..616084c 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -46,6 +46,8 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 
+import timber.log.Timber;
+
 public class CertPinningSSLSocketFactory extends SSLSocketFactory {
 
     private SSLContext sslcontext = null;
@@ -133,7 +135,9 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
             // close the socket before re-throwing the exception
             try {
                 sslsock.close();
-            } catch (Exception x) { /*ignore*/ }
+            } catch (Exception e) {
+                Timber.w(e, "Error closing SSL socket (ignored)");
+            }
             throw iox;
         }
         return sslsock;
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
index 4bb2e20..99d7338 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
@@ -5,9 +5,6 @@ import android.content.Context;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -21,7 +18,7 @@ public class CertificateReader {
 
     public static Certificate[] getCertificates(Context context,
             int... rawResCerts) {
-        List<Certificate> certificates = new ArrayList<Certificate>();
+        List<Certificate> certificates = new ArrayList<>();
         try {
             CertificateFactory cf = CertificateFactory.getInstance("X.509");
             for (int resId : rawResCerts) {
@@ -43,26 +40,4 @@ public class CertificateReader {
         }
         return certificates.toArray(new Certificate[certificates.size()]);
     }
-
-    public static ClientCertificate getClientCertificate(Context context, int rawResCert,
-            String password) {
-        InputStream is = null;
-        try {
-            KeyStore keyStore = KeyStore.getInstance("PKCS12");
-            is = new BufferedInputStream(context.getResources().openRawResource(rawResCert));
-            keyStore.load(is, password.toCharArray());
-            return new ClientCertificate(keyStore, password);
-        } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException e) {
-            Timber.w(e, "Failed to get client certificate");
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    //noop
-                }
-            }
-        }
-        return null;
-    }
 }
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 803be41..2636816 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -16,6 +16,7 @@
 
 package eu.nullbyte.android.urllib;
 
+import com.liato.bankdroid.legacy.BuildConfig;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.utils.ExceptionUtils;
 
@@ -65,8 +66,6 @@ import org.apache.http.util.EntityUtils;
 
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.os.Build;
 import android.preference.PreferenceManager;
@@ -396,22 +395,12 @@ public class Urllib {
 
     private String createUserAgentString() {
         String appName = mContext.getString(R.string.app_name);
-        String packageName = "";
-        String appVersion = "";
-
-        try {
-            PackageInfo packageInfo = mContext.getPackageManager()
-                    .getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS);
-            packageName = packageInfo.packageName;
-            appVersion = packageInfo.versionName;
-        } catch (PackageManager.NameNotFoundException ignore) {
-        }
 
         Configuration config = mContext.getResources().getConfiguration();
         return String
                 .format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %10$s Build/%7$s; %8$s) %9$s %10$s"
                         , appName
-                        , appVersion
+                        , BuildConfig.VERSION_NAME
                         , System.getProperty("os.name", "Linux")
                         , Build.VERSION.RELEASE
                         , config.locale.getLanguage().toLowerCase()
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 9dbddb2..3109e6b 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -39,7 +39,6 @@
         <exclude name="AssignmentToNonFinalStatic" />
         <exclude name="AtLeastOneConstructor" />
         <exclude name="AvoidCatchingGenericException" />
-        <exclude name="AvoidCatchingNPE" />
         <exclude name="AvoidConstantsInterface" />
         <exclude name="AvoidDecimalLiteralsInBigDecimalConstructor" />
         <exclude name="AvoidDeeplyNestedIfStmts" />
@@ -69,7 +68,6 @@
         <exclude name="DataflowAnomalyAnalysis" />
         <exclude name="DefaultPackage" />
         <exclude name="DoNotUseThreads" />
-        <exclude name="EmptyCatchBlock" />
         <exclude name="EmptyIfStmt" />
         <exclude name="EmptyMethodInAbstractClassShouldBeAbstract" />
         <exclude name="ExcessiveClassLength" />

commit 8e477f6eef16910b02b85f66f7a1402a30087bb2 (tag: v1.9.11)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 26 21:12:58 2016 +0200

    Create release v1.9.11

diff --git CHANGELOG CHANGELOG
index 5d85914..fa02959 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,10 +1,22 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-Not yet released
+v1.9.11 (2016-10-26)
 * Warn about disabled banks in the transactions list
 * Show warning text about disabled banks in the main activity
-* Remove TrustBuddy since they're no longer in business
-* Remove unused class MobilbankenBase
+* Removes support for TrustBuddy since they're no longer in business
+* Removes support for Audi since they require MobiltBankId
+* Removes support for VolvoFinans since they require MobiltBankId
+* Removes support for EasyCard since they require MobiltBankId
+* Removes support for Preem since they require MobiltBankId
+* Removes support for ResursBank since they require MobiltBankId
+* Removes support for Seat since they require MobiltBankId
+* Removes support for Shell since they require MobiltBankId
+* Removes support for Skoda since they require MobiltBankId
+* Removes support for SupremeCard since they require MobiltBankId
+* Removes support for Villabanken since they require MobiltBankId
+* Removes support for Volkswagen since they require MobiltBankId
+* Merged NordnetDirekt with Nordnet.
+* Merged AvanzaMini with Avanza.
 
 v1.9.10.10 (2016-10-17)
 * Fixes crash for Amex

commit d42dea167a24ae90c840fcb7d6c0cb386f4db441
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 26 20:53:40 2016 +0200

    Upgrade gradle build tools to latest stable.

diff --git app/build.gradle app/build.gradle
index da46be5..aafa141 100644
--- app/build.gradle
+++ app/build.gradle
@@ -7,8 +7,12 @@ buildscript {
     }
 
     dependencies {
-        classpath 'io.fabric.tools:gradle:1.+'
         classpath "org.ajoberstar:gradle-git:1.5.1"
+
+        // The dynamic version here is explicitly recommended by the Crashlytics docs:
+        // https://docs.fabric.io/android/fabric/integration.html#modify-build-gradle
+        //noinspection GradleDynamicVersion
+        classpath 'io.fabric.tools:gradle:1.+'
     }
 }
 apply plugin: 'com.android.application'
@@ -83,7 +87,7 @@ dependencies {
     compile project(':bankdroid-core')
     compile 'com.jakewharton:butterknife:6.1.0'
     compile 'com.jakewharton.timber:timber:4.3.1'
-    compile "com.android.support:appcompat-v7:24.1.1"
+    compile "com.android.support:appcompat-v7:24.2.1"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
         transitive = true;
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index 943e966..2cda778 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -27,14 +27,14 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-interface')
-    compile 'com.android.support:appcompat-v7:24.1.1'
+    compile 'com.android.support:appcompat-v7:24.2.1'
     compile 'com.jakewharton.timber:timber:4.3.1'
     compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'}
     compile 'org.jsoup:jsoup:1.7.3'
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
     compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
     compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
-    compile('org.simpleframework:simple-xml:2.7.+') {
+    compile('org.simpleframework:simple-xml:2.7.1') {
         exclude module: 'stax'
         exclude module: 'stax-api'
         exclude module: 'xpp3'
diff --git build.gradle build.gradle
index 8f0f520..43763d6 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.2.1'
+        classpath 'com.android.tools.build:gradle:2.2.2'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 8f68763..8195ce2 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
+    <!-- Disable since it has external dependencies that we cannot affect.-->
+    <issue id="GradleDependency" severity="ignore" />
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
 
     <issue id="AllowBackup" severity="ignore" />
@@ -12,8 +15,6 @@
     <issue id="ExportedReceiver" severity="ignore" />
     <issue id="GetInstance" severity="ignore" />
     <issue id="GoogleAppIndexingWarning" severity="ignore" />
-    <issue id="GradleDependency" severity="ignore" />
-    <issue id="GradleDynamicVersion" severity="ignore" />
     <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
     <issue id="IconExpectedSize" severity="ignore" />
diff --git tools/update-suppressions.sh tools/update-suppressions.sh
index 363091b..4148ea6 100755
--- tools/update-suppressions.sh
+++ tools/update-suppressions.sh
@@ -21,6 +21,9 @@ function set_lint_suppressions() {
   cat > ${LINT_XML} << EOF
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
+    <!-- Disable since it has external dependencies that we cannot affect.-->
+    <issue id="GradleDependency" severity="ignore" />
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
 
 EOF

commit f999a2aa8ded6f873c6ab8e8502255e3f7409675
Author: Johan Walles <johan.walles@gmail.com>
Date:   Tue Oct 25 21:31:33 2016 +0200

    Fake Urllib exception stack traces
    
    In Crashlytics we have a lot of stack traces originating in Urllib.
    
    With this change in place, those exceptions will appear to be
    originating from whatever bank tried to call Urllib, and it will be
    much more obvious in Crashlytics which banks actually have the most
    problems.

diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index a5dd3f4..943e966 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -39,4 +39,7 @@ dependencies {
         exclude module: 'stax-api'
         exclude module: 'xpp3'
     }
+
+    testCompile 'junit:junit:4.12'
+    testCompile 'org.mockito:mockito-core:1.10.19'
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
new file mode 100644
index 0000000..e61097b
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/ExceptionUtils.java
@@ -0,0 +1,67 @@
+package com.liato.bankdroid.utils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+
+import timber.log.Timber;
+
+public class ExceptionUtils {
+    private static final String PREFIX = "com.liato.bankdroid.";
+
+    /**
+     * Take an exception thrown and make it look like it came from Bankdroid.
+     * <p/>
+     * Specifically, if Urllib.java, called by Bankdroid code, throws an exception,
+     * rewrite the exception so that it appears as if it was thrown from the
+     * Bankdroid method calling Urllib, but caused by the original Exception.
+     */
+    public static <T extends Throwable> T bankdroidifyException(T exception) {
+        StackTraceElement[] bankdroidifiedStacktrace =
+                bankdroidifyStacktrace(exception.getStackTrace());
+        if (bankdroidifiedStacktrace.length == exception.getStackTrace().length) {
+            // Unable to bankdroidify stacktrace, never mind
+            return exception;
+        }
+
+        T returnMe;
+        try {
+            returnMe = (T)exception.getClass().getConstructor(String.class)
+                    .newInstance(exception.getMessage());
+        } catch (InstantiationException e) {
+            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
+            return exception;
+        } catch (InvocationTargetException e) {
+            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
+            return exception;
+        } catch (IllegalAccessException e) {
+            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
+            return exception;
+        } catch (NoSuchMethodException e) {
+            Timber.e(e, "Unable to Bankdroidify exception of type %s", exception.getClass());
+            return exception;
+        }
+
+        returnMe.initCause(exception);
+
+        returnMe.setStackTrace(bankdroidifiedStacktrace);
+
+        return returnMe;
+    }
+
+    /**
+     * Remove all initial non-Bankdroid frames from a stack.
+     *
+     * @return A copy of rawStack but with the initial non-Bankdroid frames removed
+     */
+    private static StackTraceElement[] bankdroidifyStacktrace(final StackTraceElement[] rawStack) {
+        for (int i = 0; i < rawStack.length; i++) {
+            StackTraceElement stackTraceElement = rawStack[i];
+            if (stackTraceElement.getClassName().startsWith(PREFIX)) {
+                return Arrays.copyOfRange(rawStack, i, rawStack.length);
+            }
+        }
+
+        // No Bankdroid stack frames found, never mind
+        return rawStack;
+    }
+}
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 2cc5e36..803be41 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -17,6 +17,7 @@
 package eu.nullbyte.android.urllib;
 
 import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.utils.ExceptionUtils;
 
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpEntity;
@@ -146,7 +147,11 @@ public class Urllib {
     }
 
     public String open(String url) throws ClientProtocolException, IOException {
-        return this.open(url, new ArrayList<NameValuePair>());
+        try {
+            return this.open(url, new ArrayList<NameValuePair>());
+        } catch (IOException e) {
+            throw ExceptionUtils.bankdroidifyException(e);
+        }
     }
 
     public String post(String url) throws ClientProtocolException, IOException {
@@ -155,7 +160,11 @@ public class Urllib {
 
     public String open(String url, List<NameValuePair> postData)
             throws ClientProtocolException, IOException {
-        return open(url, postData, false);
+        try {
+            return open(url, postData, false);
+        } catch (IOException e) {
+            throw ExceptionUtils.bankdroidifyException(e);
+        }
     }
 
     public String open(String url, List<NameValuePair> postData, boolean forcePost)
@@ -171,7 +180,11 @@ public class Urllib {
             boolean forcePost) throws ClientProtocolException, IOException {
         HttpEntity entity = (postData == null || postData.isEmpty()) && !forcePost ? null
                 : new UrlEncodedFormEntity(postData, this.charset);
-        return openAsHttpResponse(url, entity, forcePost);
+        try {
+            return openAsHttpResponse(url, entity, forcePost);
+        } catch (IOException e) {
+            throw ExceptionUtils.bankdroidifyException(e);
+        }
     }
 
     public HttpResponse openAsHttpResponse(String url, boolean forcePost)
@@ -181,10 +194,14 @@ public class Urllib {
 
     public HttpResponse openAsHttpResponse(String url, HttpEntity entity, boolean forcePost)
             throws ClientProtocolException, IOException {
-        if ((entity == null) && !forcePost) {
-            return openAsHttpResponse(url, entity, HttpMethod.GET);
-        } else {
-            return openAsHttpResponse(url, entity, HttpMethod.POST);
+        try {
+            if ((entity == null) && !forcePost) {
+                return openAsHttpResponse(url, entity, HttpMethod.GET);
+            } else {
+                return openAsHttpResponse(url, entity, HttpMethod.POST);
+            }
+        } catch (IOException e) {
+            throw ExceptionUtils.bankdroidifyException(e);
         }
     }
 
@@ -273,8 +290,12 @@ public class Urllib {
 
     public InputStream openStream(String url, String postData, boolean forcePost)
             throws ClientProtocolException, IOException {
-        return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null,
-                forcePost);
+        try {
+            return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null,
+                    forcePost);
+        } catch (IOException e) {
+            throw ExceptionUtils.bankdroidifyException(e);
+        }
     }
 
     public InputStream openStream(String url, HttpEntity postData, boolean forcePost)
diff --git bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
new file mode 100644
index 0000000..803dc5f
--- /dev/null
+++ bankdroid-legacy/src/test/java/com/liato/bankdroid/utils/ExceptionUtilsTest.java
@@ -0,0 +1,41 @@
+package com.liato.bankdroid.utils;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class ExceptionUtilsTest {
+    @Test
+    @SuppressWarnings("PMD") // This is for the stack trace printing, we really want to do it here
+    public void bankdroidifyException() throws Exception {
+        Exception raw = null;
+        try {
+            new Urllib(null);
+            Assert.fail("Exception expected");
+        } catch (NullPointerException e) {
+            raw = e;
+        }
+
+        // Print stack traces, useful if the tests fail
+        System.err.println("Before:");
+        raw.printStackTrace();
+
+        System.err.println();
+        System.err.println("After:");
+        Exception bankdroidified = ExceptionUtils.bankdroidifyException(raw);
+        bankdroidified.printStackTrace();
+
+        Assert.assertFalse("Test setup: Top frame of initial exception shouldn't be in Bankdroid",
+                raw.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+
+        Assert.assertTrue("Top frame of bankdroidified exception should be in Bankdroid",
+                bankdroidified.getStackTrace()[0].getClassName().startsWith("com.liato.bankdroid."));
+
+        // Verify that e is the cause of bankdroidified
+        Assert.assertSame(raw, bankdroidified.getCause());
+
+        // Verify that re-bankdroidifying is a no-op
+        Assert.assertSame(bankdroidified, ExceptionUtils.bankdroidifyException(bankdroidified));
+    }
+}

commit b75ce9788c33d9d6ef70bfe6fbb3fae8647f9232
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Oct 20 20:04:51 2016 +0200

    Show warning for disabled banks
    
    Before this change, in the banks list in the main UI, disabled banks
    were marked with a warning icon.
    
    This change adds to that warning icon a text describing what's actually
    going on and what the user can do about it.
    
    Before starting to work on this I fixed all Android Lint reported
    warnings in the .java and .xml files I had to change, and re-enabled
    those warnings.
    
    One of those warnings was about using sp rather than dp for text. I
    suppressed that warning for the widgets, but heeded it in all other
    places. This results in a UI that better adapts to the user's font size
    preferences.
    
    The UI changes I have tested with both "small" and "huge" font size,
    and it looks fine.

diff --git CHANGELOG CHANGELOG
index 858714a..5d85914 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 Not yet released
 * Warn about disabled banks in the transactions list
+* Show warning text about disabled banks in the main activity
 * Remove TrustBuddy since they're no longer in business
 * Remove unused class MobilbankenBase
 
diff --git app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
index af4e6ec..9413be0 100644
--- app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -25,6 +25,7 @@ import android.content.Context;
 import android.content.SharedPreferences;
 import android.graphics.Color;
 import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -42,50 +43,30 @@ public class AccountsAdapter extends BaseAdapter {
 
     public final static int VIEWTYPE_EMPTY = 2;
 
-    SharedPreferences prefs;
+    private final SharedPreferences prefs;
 
     private ArrayList<Bank> banks;
 
-    private Context context;
-
-    private LayoutInflater inflater;
+    private final LayoutInflater inflater;
 
     private boolean showHidden;
 
     public AccountsAdapter(Context context, boolean showHidden) {
-        this.context = context;
-        this.banks = new ArrayList<Bank>();
-        inflater = LayoutInflater.from(this.context);
+        this.banks = new ArrayList<>();
+        inflater = LayoutInflater.from(context);
         this.showHidden = showHidden;
         prefs = PreferenceManager.getDefaultSharedPreferences(context);
     }
 
-    public void addGroup(Bank bank) {
-        banks.add(bank);
-    }
-
     public void setGroups(ArrayList<Bank> banks) {
         this.banks = banks;
-                /*for (Bank b : this.banks) {
-                    ArrayList<Account> as = b.getAccounts();
-            for (Account a : as) {
-                if (a.isHidden() && !showHidden) {
-                    as.remove(a);
-                }
-
-            }
-        }*/
-    }
-
-    public boolean isShowHidden() {
-        return showHidden;
     }
 
     public void setShowHidden(boolean showHidden) {
         this.showHidden = showHidden;
     }
 
-    public View newBankView(Bank bank, ViewGroup parent, View convertView) {
+    private View newBankView(Bank bank, ViewGroup parent, View convertView) {
         if (convertView == null) {
             convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
         }
@@ -103,16 +84,16 @@ public class AccountsAdapter extends BaseAdapter {
                         bank.getDecimalFormatter(),
                         false));
         icon.setImageResource(bank.getImageResource());
-        ImageView warning = (ImageView) convertView.findViewById(R.id.imgWarning);
+        View warning = convertView.findViewById(R.id.txtDisabledWarningX);
         if (bank.isDisabled()) {
             warning.setVisibility(View.VISIBLE);
         } else {
-            warning.setVisibility(View.INVISIBLE);
+            warning.setVisibility(View.GONE);
         }
         return convertView;
     }
 
-    public View newAccountView(Account account, ViewGroup parent, View convertView) {
+    private View newAccountView(Account account, ViewGroup parent, View convertView) {
         if ((account.isHidden() && !showHidden) || account.getBank().getHideAccounts()) {
             return convertView == null ? inflater.inflate(R.layout.empty, parent, false)
                     : convertView;
@@ -158,6 +139,7 @@ public class AccountsAdapter extends BaseAdapter {
     }
 
     @Override
+    @Nullable
     public Object getItem(int position) {
         if (banks.size() == 0) {
             return null;
@@ -188,19 +170,21 @@ public class AccountsAdapter extends BaseAdapter {
     }
 
     @Override
+    @Nullable
     public View getView(int position, View convertView, ViewGroup parent) {
         Object item = getItem(position);
         if (item == null) {
             return null;
         }
         if (item instanceof Bank) {
-            return newBankView((Bank) item, parent, convertView);
+            return newBankView((Bank)item, parent, convertView);
         } else if (item instanceof Account) {
-            return newAccountView((Account) item, parent, convertView);
+            return newAccountView((Account)item, parent, convertView);
         }
         return null;
     }
 
+    @Override
     public boolean isEnabled(int position) {
         if (getItemViewType(position) == VIEWTYPE_EMPTY) {
             return false;
@@ -208,7 +192,6 @@ public class AccountsAdapter extends BaseAdapter {
         return true;
     }
 
-
     @Override
     public int getViewTypeCount() {
         return 3;
@@ -220,8 +203,9 @@ public class AccountsAdapter extends BaseAdapter {
         if (item instanceof Bank) {
             return VIEWTYPE_BANK;
         } else {
-            if ((((Account) item).isHidden() && !showHidden) ||
-                    ((Account) item).getBank().getHideAccounts()) {
+            final Account account = (Account)item;
+            if ((account.isHidden() && !showHidden) ||
+                    account.getBank().getHideAccounts()) {
                 return VIEWTYPE_EMPTY;
             }
         }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index fb3ddf2..17c19ae 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -166,7 +166,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
         //intent = new Intent(context, AccountsActivity.class);
         pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-        views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent);
+        views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
 
         intent = new Intent(context, WidgetService.class);
         intent.setAction(AutoRefreshService.BROADCAST_WIDGET_REFRESH);
diff --git app/src/main/res/layout-land/choose_lock_pattern.xml app/src/main/res/layout-land/choose_lock_pattern.xml
index e32dc0a..a98f3a9 100644
--- app/src/main/res/layout-land/choose_lock_pattern.xml
+++ app/src/main/res/layout-land/choose_lock_pattern.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project Licensed under the 
-	Apache License, Version 2.0 (the "License"); you may not use this file except 
-	in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
-	Unless required by applicable law or agreed to in writing, software distributed 
-	under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
-	OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+<!-- Copyright (C) 2008 The Android Open Source Project Licensed under the
+	Apache License, Version 2.0 (the "License"); you may not use this file except
+	in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+	Unless required by applicable law or agreed to in writing, software distributed
+	under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+	OR CONDITIONS OF ANY KIND, either express or implied. See the License for
 	the specific language governing permissions and limitations under the License. -->
 
 <com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient
@@ -44,10 +44,10 @@
 				android:layout_alignParentBottom="true"
 				android:layout_centerHorizontal="true"
 				android:ellipsize="marquee"
-				android:singleLine="true"
 				android:drawableRight="@drawable/ic_btn_next"
 				android:drawablePadding="3dip"
-				android:text="@string/lockpattern_confirm_button_text" />
+				android:text="@string/lockpattern_confirm_button_text"
+				android:maxLines="1"/>
 
 
 			<!-- left / top button: skip, or re-try -->
@@ -58,8 +58,8 @@
 				android:layout_above="@id/footerRightButton"
 				android:layout_centerHorizontal="true"
 				android:ellipsize="marquee"
-				android:singleLine="true"
-				android:text="@string/lockpattern_restart_button_text" />
+				android:text="@string/lockpattern_restart_button_text"
+				android:maxLines="1"/>
 
 
 			<!-- message above buttons -->
diff --git app/src/main/res/layout-land/dialog_color_picker.xml app/src/main/res/layout-land/dialog_color_picker.xml
index 7f63aff..fc0caa3 100644
--- app/src/main/res/layout-land/dialog_color_picker.xml
+++ app/src/main/res/layout-land/dialog_color_picker.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,30 +14,31 @@
      limitations under the License.
 -->
 
-<LinearLayout 
+<LinearLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
+	xmlns:tools="http://schemas.android.com/tools"
+	android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingRight="5dp"
     android:orientation="horizontal">
-		
+
 	<net.margaritov.preference.colorpicker.ColorPickerView
 		android:id="@+id/color_picker_view"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		android:tag="landscape"
 	/>
-		
+
 	<LinearLayout
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		android:orientation="vertical"
 		android:layout_marginBottom="10dp">
-		
+
 		<TextView
-			android:layout_width="wrap_content" 
-			android:layout_height="wrap_content"	
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
 			android:text="@string/press_color_to_apply"
 			android:gravity="center"
 			android:layout_marginTop="6dp"
@@ -53,24 +54,24 @@
 			android:layout_height="40dp"
 			android:layout_weight="0.5"
 		/>
-	
+
 		<TextView
 			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"	
+			android:layout_height="wrap_content"
 			android:text="↓"
 			android:textSize="20sp"
 			android:gravity="center"
 			android:layout_marginTop="10dp"
 			android:layout_marginBottom="10dp"
-		/>
-	
+			tools:ignore="HardcodedText"/>
+
 		<net.margaritov.preference.colorpicker.ColorPickerPanelView
 			android:id="@+id/new_color_panel"
 			android:layout_width="fill_parent"
 			android:layout_height="40dp"
 			android:layout_weight="0.5"
 		/>
-	
+
 	</LinearLayout>
-	
-</LinearLayout>
\ No newline at end of file
+
+</LinearLayout>
diff --git app/src/main/res/layout/about.xml app/src/main/res/layout/about.xml
index 82dda73..4faa0a1 100644
--- app/src/main/res/layout/about.xml
+++ app/src/main/res/layout/about.xml
@@ -26,14 +26,14 @@
 				android:id="@+id/imgTextLogo"
 				android:layout_marginTop="20dp" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_centerHorizontal="true"></ImageView>
 			<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imgTextLogo" android:id="@+id/imgNullbyteLogo" android:src="@drawable/nullbyte_logo" android:layout_alignRight="@+id/imgTextLogo" android:layout_alignBottom="@+id/txtVersion"></ImageView>
-			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtVersion" android:text="@string/version" android:textSize="15dp" android:layout_below="@+id/imgTextLogo" android:gravity="right" android:textColor="#78ffffff" android:layout_toLeftOf="@+id/imgNullbyteLogo" android:layout_marginRight="4dp"></TextView>
+			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtVersion" android:text="@string/version" android:textSize="15sp" android:layout_below="@+id/imgTextLogo" android:gravity="right" android:textColor="#78ffffff" android:layout_toLeftOf="@+id/imgNullbyteLogo" android:layout_marginRight="4dp"></TextView>
 </RelativeLayout>
 			<TextView
 					android:layout_height="wrap_content"
 				android:text="@string/thanks_to"
 				android:textStyle="bold"
 				android:layout_marginTop="10dp"
-				android:layout_width="fill_parent" android:textSize="20dp"></TextView>
+				android:layout_width="fill_parent" android:textSize="20sp"></TextView>
 			<TextView
 					android:layout_height="wrap_content"
 				android:text="@string/thanks"
diff --git app/src/main/res/layout/choose_lock_pattern.xml app/src/main/res/layout/choose_lock_pattern.xml
index 54e8888..1327760 100644
--- app/src/main/res/layout/choose_lock_pattern.xml
+++ app/src/main/res/layout/choose_lock_pattern.xml
@@ -54,11 +54,11 @@
 
         <!-- left button: skip, or retry -->
         <Button android:id="@+id/footerLeftButton"
-            android:layout_height="wrap_content"
-            android:layout_width="140dip"
-            android:ellipsize="marquee"
-            android:singleLine="true"
-            android:text="@string/lockpattern_restart_button_text"/>
+                android:layout_height="wrap_content"
+                android:layout_width="140dip"
+                android:ellipsize="marquee"
+                android:text="@string/lockpattern_restart_button_text"
+                android:maxLines="1"/>
 
         <!-- Placeholder to get blank space between the two buttons -->
         <View
@@ -69,13 +69,13 @@
 
         <!-- right button: confirm or ok -->
         <Button android:id="@+id/footerRightButton"
-            android:layout_height="wrap_content"
-            android:layout_width="140dip"
-            android:ellipsize="marquee"
-            android:singleLine="true"
-            android:drawableRight="@drawable/ic_btn_next"
-            android:drawablePadding="3dip"
-            android:text="@string/lockpattern_confirm_button_text"/>
+                android:layout_height="wrap_content"
+                android:layout_width="140dip"
+                android:ellipsize="marquee"
+                android:drawableRight="@drawable/ic_btn_next"
+                android:drawablePadding="3dip"
+                android:text="@string/lockpattern_confirm_button_text"
+                android:maxLines="1"/>
 
     </LinearLayout>
 
diff --git app/src/main/res/layout/choose_lock_pattern_example.xml app/src/main/res/layout/choose_lock_pattern_example.xml
index d1e816c..bf7297a 100644
--- app/src/main/res/layout/choose_lock_pattern_example.xml
+++ app/src/main/res/layout/choose_lock_pattern_example.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,18 +18,18 @@
     android:orientation="vertical"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent">
-    
-    <ScrollView 
+
+    <ScrollView
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:layout_weight="1">
-        
+
         <LinearLayout
             android:orientation="vertical"
             android:layout_height="fill_parent"
             android:layout_width="fill_parent"
             android:padding="5dip">
-            
+
             <TextView
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
@@ -37,7 +37,7 @@
                 android:gravity="center_horizontal"
                 style="?android:attr/textAppearanceLarge"
             />
-        
+
             <ImageView android:id="@+id/lock_anim"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
@@ -46,7 +46,7 @@
                 android:focusable="false"
                 android:clickable="false"
             />
-            
+
             <TextView
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
@@ -55,41 +55,39 @@
                 android:layout_gravity="left"
                 style="?android:attr/textAppearanceMedium"
             />
-            
+
         </LinearLayout>
 
     </ScrollView>
-    
+
     <LinearLayout style="@android:style/ButtonBar"
         android:orientation="horizontal"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content">
-        
+
         <Button android:id="@+id/skip_button"
             android:layout_height="wrap_content"
             android:layout_width="140dip"
             android:ellipsize="marquee"
-            android:singleLine="true"
-            android:text="@string/skip_button_label"
-        />
-      
+                android:text="@string/skip_button_label"
+                android:maxLines="1"/>
+
         <!-- Placeholder to get blank space between the two buttons -->
         <View
             android:visibility="invisible"
             android:layout_height="0dip"
             android:layout_width="1dip"
             android:layout_weight="1" />
-            
+
         <Button android:id="@+id/next_button"
             android:layout_height="wrap_content"
             android:layout_width="140dip"
             android:ellipsize="marquee"
-            android:singleLine="true"
-            android:drawableRight="@drawable/ic_btn_next"
+                android:drawableRight="@drawable/ic_btn_next"
             android:drawablePadding="3dip"
             android:text="@string/next_button_label"
-        />
-        
+                android:maxLines="1"/>
+
     </LinearLayout>
-    
+
 </LinearLayout>
diff --git app/src/main/res/layout/choose_lock_pattern_tutorial.xml app/src/main/res/layout/choose_lock_pattern_tutorial.xml
index 8eadc01..adb765f 100644
--- app/src/main/res/layout/choose_lock_pattern_tutorial.xml
+++ app/src/main/res/layout/choose_lock_pattern_tutorial.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,18 +18,18 @@
     android:orientation="vertical"
     android:layout_height="fill_parent"
     android:layout_width="fill_parent">
-    
-    <ScrollView 
+
+    <ScrollView
         android:layout_width="fill_parent"
         android:layout_height="0dip"
         android:layout_weight="1">
-        
+
         <LinearLayout
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical"
             android:padding="5dip">
-            
+
             <TextView
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
@@ -39,19 +39,19 @@
                 android:layout_marginTop="3dip"
                 style="?android:attr/textAppearanceLarge"
             />
-        
-            <TextView 
+
+            <TextView
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_marginTop="10dip"
                 android:text="@string/lock_intro_message"
             />
-            
+
         </LinearLayout>
-       
+
     </ScrollView>
-    
+
     <LinearLayout style="@android:style/ButtonBar"
         android:orientation="horizontal"
         android:layout_width="fill_parent"
@@ -61,27 +61,25 @@
             android:layout_height="wrap_content"
             android:layout_width="140dip"
             android:ellipsize="marquee"
-            android:singleLine="true"
-            android:text="@string/skip_button_label"
-        />
-        
+                android:text="@string/skip_button_label"
+                android:maxLines="1"/>
+
         <!-- Placeholder to get blank space between the two buttons -->
         <View
             android:visibility="invisible"
             android:layout_height="0dip"
             android:layout_width="1dip"
             android:layout_weight="1" />
-        
+
         <Button android:id="@+id/next_button"
             android:layout_height="wrap_content"
             android:layout_width="140dip"
             android:drawableRight="@drawable/ic_btn_next"
             android:drawablePadding="3dip"
             android:ellipsize="marquee"
-            android:singleLine="true"
-            android:text="@string/next_button_label"
-        />
-        
+                android:text="@string/next_button_label"
+                android:maxLines="1"/>
+
     </LinearLayout>
-    
+
 </LinearLayout >
diff --git app/src/main/res/layout/dialog_color_picker.xml app/src/main/res/layout/dialog_color_picker.xml
index 1196da5..e72a834 100644
--- app/src/main/res/layout/dialog_color_picker.xml
+++ app/src/main/res/layout/dialog_color_picker.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,13 +15,14 @@
 -->
 
 <LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android" 
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingRight="5dp"
     android:orientation="vertical">
-		
+
 	<net.margaritov.preference.colorpicker.ColorPickerView
 		android:id="@+id/color_picker_view"
 		android:layout_width="wrap_content"
@@ -29,10 +30,10 @@
 		android:layout_centerHorizontal="true"
 		android:tag="portrait"
 	/>
-	
+
 	<TextView
 		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"	
+		android:layout_height="wrap_content"
 		android:text="@string/press_color_to_apply"
 		android:gravity="left"
 		android:layout_marginLeft="6dp"
@@ -40,7 +41,7 @@
 		android:layout_marginBottom="5dp"
 		android:textAppearance="?android:attr/textAppearanceSmall"
 	/>
-	
+
 	<LinearLayout
 		android:layout_width="wrap_content"
 		android:layout_height="40dp"
@@ -54,24 +55,25 @@
 			android:layout_height="fill_parent"
 			android:layout_weight="0.5"
 		/>
-	
+
 		<TextView
+			tools:ignore="HardcodedText"
 			android:layout_width="wrap_content"
-			android:layout_height="fill_parent"	
+			android:layout_height="fill_parent"
 			android:text="→"
 			android:textSize="20sp"
 			android:gravity="center"
 			android:layout_marginLeft="10dp"
 			android:layout_marginRight="10dp"
 		/>
-	
+
 		<net.margaritov.preference.colorpicker.ColorPickerPanelView
 			android:id="@+id/new_color_panel"
 			android:layout_width="0px"
 			android:layout_height="wrap_content"
 			android:layout_weight="0.5"
 		/>
-	
+
 	</LinearLayout>
-	
-</LinearLayout>
\ No newline at end of file
+
+</LinearLayout>
diff --git app/src/main/res/layout/listitem_accounts_group.xml app/src/main/res/layout/listitem_accounts_group.xml
index f18d729..1df9da4 100644
--- app/src/main/res/layout/listitem_accounts_group.xml
+++ app/src/main/res/layout/listitem_accounts_group.xml
@@ -1,88 +1,107 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/layBankHeader"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:orientation="vertical"
     android:layout_width="fill_parent"
-    android:layout_height="62dp"
-    android:background="@drawable/group_bg"
-    android:paddingBottom="5dp"
-    android:paddingLeft="5dp"
-    android:paddingRight="10dp"
-    android:paddingTop="5dp" >
+    android:layout_height="wrap_content"
+    >
 
-    <ImageView
-        android:id="@+id/imgListitemAccountsGroup"
-        android:layout_width="48dp"
-        android:layout_height="fill_parent"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginLeft="0dp"
-        android:layout_marginRight="2dp"
-        android:maxHeight="48dp"
-        android:maxWidth="48dp"
-        android:minHeight="48dp"
-        android:minWidth="48dp"
-        android:padding="0dp"
-        android:src="@drawable/ic_launcher" />
+    <RelativeLayout
+        android:id="@+id/layBankHeader"
+        android:layout_width="fill_parent"
+        android:layout_height="62dp"
+        android:background="@drawable/group_bg"
+        android:paddingBottom="5dp"
+        android:paddingLeft="5dp"
+        android:paddingRight="10dp"
+        android:paddingTop="5dp"
+        >
 
-    <TextView
-        android:id="@+id/txtListitemAccountsGroupBankname"
-        android:layout_width="wrap_content"
-        android:layout_height="21dip"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="false"
-        android:layout_marginRight="4dp"
-        android:layout_toLeftOf="@+id/txtListitemAccountsGroupTotal"
-        android:layout_toRightOf="@id/imgListitemAccountsGroup"
-        android:ellipsize="marquee"
-        android:gravity="top"
-        android:singleLine="true"
-        android:text="Banknamn"
-        android:textColor="#000" />
+        <ImageView
+            android:id="@+id/imgListitemAccountsGroup"
+            android:layout_width="48dp"
+            android:layout_height="fill_parent"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginLeft="0dp"
+            android:layout_marginRight="2dp"
+            android:maxHeight="48dp"
+            android:maxWidth="48dp"
+            android:minHeight="48dp"
+            android:minWidth="48dp"
+            android:padding="0dp"
+            android:src="@drawable/ic_launcher"
+            />
 
-    <TextView
-        android:id="@+id/txtListitemAccountsGroupAccountname"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_above="@id/txtListitemAccountsGroupBankname"
-        android:layout_alignParentRight="false"
-        android:layout_alignParentTop="true"
-        android:layout_alignWithParentIfMissing="true"
-        android:layout_toRightOf="@id/imgListitemAccountsGroup"
-        android:ellipsize="marquee"
-        android:gravity="center_vertical"
-        android:includeFontPadding="true"
-        android:lines="1"
-        android:marqueeRepeatLimit="marquee_forever"
-        android:scrollHorizontally="true"
-        android:shadowColor="#78ffffff"
-        android:shadowDx="0"
-        android:shadowDy="1"
-        android:shadowRadius="2"
-        android:text="Personnummer"
-        android:textColor="#000"
-        android:textSize="23dp" />
+        <TextView
+            android:id="@+id/txtListitemAccountsGroupBankname"
+            android:layout_width="wrap_content"
+            android:layout_height="21dip"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="false"
+            android:layout_marginRight="4dp"
+            android:layout_toLeftOf="@+id/txtListitemAccountsGroupTotal"
+            android:layout_toRightOf="@id/imgListitemAccountsGroup"
+            android:ellipsize="marquee"
+            android:gravity="top"
+            android:text="Banknamn"
+            android:textColor="#000"
+            tools:ignore="HardcodedText"
+            android:maxLines="1"
+            />
 
-    <ImageView
-        android:id="@+id/imgWarning"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_above="@id/txtListitemAccountsGroupBankname"
-        android:layout_alignParentRight="true"
-        android:src="@drawable/indicator_input_error"
-        android:visibility="invisible" >
-    </ImageView>
+        <TextView
+            android:id="@+id/txtListitemAccountsGroupAccountname"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_above="@id/txtListitemAccountsGroupBankname"
+            android:layout_alignParentRight="false"
+            android:layout_alignParentTop="true"
+            android:layout_alignWithParentIfMissing="true"
+            android:layout_toRightOf="@id/imgListitemAccountsGroup"
+            android:ellipsize="marquee"
+            android:gravity="center_vertical"
+            android:includeFontPadding="true"
+            android:lines="1"
+            android:marqueeRepeatLimit="marquee_forever"
+            android:scrollHorizontally="true"
+            android:shadowColor="#78ffffff"
+            android:shadowDx="0"
+            android:shadowDy="1"
+            android:shadowRadius="2"
+            android:text="Personnummer"
+            android:textColor="#000"
+            android:textSize="23sp"
+            tools:ignore="HardcodedText"
+            />
+
+        <TextView
+            android:id="@+id/txtListitemAccountsGroupTotal"
+            android:layout_width="wrap_content"
+            android:layout_height="21dp"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="true"
+            android:ellipsize="marquee"
+            android:gravity="top"
+            android:text="00000 SEK"
+            android:textColor="#333"
+            tools:ignore="HardcodedText"
+            android:maxLines="1"
+            />
+
+    </RelativeLayout>
 
     <TextView
-        android:id="@+id/txtListitemAccountsGroupTotal"
-        android:layout_width="wrap_content"
-        android:layout_height="21dp"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
-        android:ellipsize="marquee"
-        android:gravity="top"
-        android:singleLine="true"
-        android:text="00000 SEK"
-        android:textColor="#333" />
+        android:id="@+id/txtDisabledWarningX"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="10dp"
+        android:drawableLeft="@drawable/indicator_input_error"
+        android:drawablePadding="10dp"
+        android:text="@string/disabled_refresh_or_edit"
+        android:visibility="visible"
+        />
 
-</RelativeLayout>
\ No newline at end of file
+</LinearLayout>
diff --git app/src/main/res/layout/listitem_accounts_item.xml app/src/main/res/layout/listitem_accounts_item.xml
index 4acad10..3164d5b 100644
--- app/src/main/res/layout/listitem_accounts_item.xml
+++ app/src/main/res/layout/listitem_accounts_item.xml
@@ -1,38 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="35dp"
-	android:layout_gravity="center_horizontal">
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="fill_parent"
+    android:layout_height="35dp"
+    android:layout_gravity="center_horizontal">
 
-	<TextView
-		android:layout_alignParentBottom="true"
-		android:ellipsize="marquee"
-		android:gravity="center_vertical"
-		android:layout_width="wrap_content"
-		android:layout_alignParentRight="false"
-		android:textColor="#fff"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentTop="true"
-		android:id="@+id/txtListitemAccountsItemAccountname"
-		android:inputType="none"
-		android:text="Kontonamn"
-		android:textStyle="bold"
-		android:layout_height="fill_parent" android:paddingLeft="15dp" android:layout_toLeftOf="@+id/txtListitemAccountsItemBalance"/>
+    <TextView
+        android:layout_alignParentBottom="true"
+        android:ellipsize="marquee"
+        android:gravity="center_vertical"
+        android:layout_width="wrap_content"
+        android:layout_alignParentRight="false"
+        android:textColor="#fff"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:id="@+id/txtListitemAccountsItemAccountname"
+        android:inputType="none"
+        android:text="Kontonamn"
+        android:textStyle="bold"
+        android:layout_height="fill_parent"
+        android:paddingLeft="15dp"
+        android:layout_toLeftOf="@+id/txtListitemAccountsItemBalance"
+        tools:ignore="HardcodedText"/>
 
+    <TextView
+        android:layout_alignParentBottom="true"
+        android:ellipsize="marquee"
+        android:text="00000 SEK"
+        android:layout_width="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:id="@+id/txtListitemAccountsItemBalance"
+        android:inputType="none"
+        android:gravity="right|center_vertical"
+        android:layout_height="fill_parent"
+        android:textColor="#fff"
+        android:paddingRight="10dp"
+        tools:ignore="HardcodedText"/>
 
-	<TextView
-		android:layout_alignParentBottom="true"
-		android:ellipsize="marquee"
-		android:text="00000 SEK"
-		android:layout_width="wrap_content"
-		android:layout_alignParentRight="true"
-		android:layout_alignParentTop="true"
-		android:id="@+id/txtListitemAccountsItemBalance"
-		android:inputType="none"
-		android:gravity="right|center_vertical"
-		android:layout_height="fill_parent" android:textColor="#fff" android:paddingRight="10dp"/>
-
-
-<RelativeLayout android:layout_width="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:minHeight="1dp" android:layout_height="wrap_content" android:layout_alignWithParentIfMissing="true" android:layout_alignParentTop="false" android:layout_alignParentBottom="true" android:id="@+id/divider"></RelativeLayout>
-</RelativeLayout>
\ No newline at end of file
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentRight="true"
+        android:minHeight="1dp"
+        android:layout_height="wrap_content"
+        android:layout_alignWithParentIfMissing="true"
+        android:layout_alignParentTop="false"
+        android:layout_alignParentBottom="true"
+        android:id="@+id/divider"></RelativeLayout>
+</RelativeLayout>
diff --git app/src/main/res/layout/transaction_date.xml app/src/main/res/layout/transaction_date.xml
index ceb30eb..0142a4c 100644
--- app/src/main/res/layout/transaction_date.xml
+++ app/src/main/res/layout/transaction_date.xml
@@ -1,26 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:paddingLeft="10dp"
-	android:paddingRight="0dp"
-	android:background="@drawable/date_bg"
-	android:layout_height="28dp"
-	android:gravity="center_vertical" android:clickable="false" android:focusable="false" android:focusableInTouchMode="false">
-	<TextView
-		android:inputType="none"
-		android:scrollHorizontally="true"
-		android:layout_width="fill_parent"
-		android:textStyle="bold"
-		android:text="2010-11-12"
-		android:typeface="sans"
-		android:shadowColor="#000"
-		android:id="@+id/txtDate"
-		android:shadowDx="0"
-		android:shadowDy="0"
-		android:shadowRadius="1"
-		android:textSize="16dp"
-		android:gravity="center_vertical"
-		android:textColor="#fff"
-		android:layout_height="fill_parent" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:focusable="false" android:clickable="false" android:focusableInTouchMode="false"/>
-</RelativeLayout>
\ No newline at end of file
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="fill_parent"
+    android:paddingLeft="10dp"
+    android:paddingRight="0dp"
+    android:background="@drawable/date_bg"
+    android:layout_height="wrap_content"
+    android:clickable="false"
+    android:focusable="false"
+    android:focusableInTouchMode="false"
+    >
+
+    <TextView
+        android:inputType="none"
+        android:scrollHorizontally="true"
+        android:layout_width="fill_parent"
+        android:textStyle="bold"
+        android:text="2010-11-12"
+        android:typeface="sans"
+        android:shadowColor="#000"
+        android:id="@+id/txtDate"
+        android:shadowDx="0"
+        android:shadowDy="0"
+        android:shadowRadius="1"
+        android:textSize="16sp"
+        android:gravity="center_vertical"
+        android:textColor="#fff"
+        android:layout_height="fill_parent"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentBottom="true"
+        android:focusable="false"
+        android:clickable="false"
+        android:focusableInTouchMode="false"
+        tools:ignore="HardcodedText"
+        />
+</RelativeLayout>
diff --git app/src/main/res/layout/transaction_item.xml app/src/main/res/layout/transaction_item.xml
index 2ec52d7..7c6415b 100644
--- app/src/main/res/layout/transaction_item.xml
+++ app/src/main/res/layout/transaction_item.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="fill_parent"
 	android:layout_height="35dp"
 	android:layout_gravity="center_horizontal"
@@ -28,7 +29,11 @@
 		android:inputType="none"
 		android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname"
 		android:gravity="right|center_vertical"
-		android:layout_height="fill_parent" android:layout_toLeftOf="@+id/imgColor" android:id="@+id/txtAmount" android:paddingLeft="5dp"/>
+		android:layout_height="fill_parent"
+		android:layout_toLeftOf="@+id/imgColor"
+        android:id="@+id/txtAmount"
+        android:paddingLeft="5dp"
+		tools:ignore="HardcodedText"/>
 
 <ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/imgColor" android:background="@drawable/transaction_negative" android:layout_alignParentRight="true" android:layout_marginLeft="5dp"></ImageView>
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git app/src/main/res/layout/widget.xml app/src/main/res/layout/widget.xml
index 8175975..b6bb7f5 100644
--- app/src/main/res/layout/widget.xml
+++ app/src/main/res/layout/widget.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_gravity="center_horizontal"
 	android:background="@drawable/widget_2x1"
 	android:layout_height="100dp"
@@ -36,8 +37,9 @@
 		android:inputType="none"
 		android:layout_marginLeft="2dp"
 		android:layout_marginRight="2dp"
-		android:text="Bankdroid"
-		android:lines="1"></TextView>
+		android:text="@string/app_name"
+		android:lines="1"
+		tools:ignore="SpUsage"></TextView>
 	<TextView
 		android:id="@+id/txtWidgetAccountnameBlur"
 		android:layout_height="wrap_content"
@@ -48,9 +50,10 @@
 		android:inputType="none"
 		android:layout_marginLeft="2dp"
 		android:layout_marginRight="2dp"
-		android:text="Bankdroid"
+		android:text="@string/app_name"
 		android:lines="1"
-		android:visibility="gone"></TextView>
+		android:visibility="gone"
+		tools:ignore="SpUsage"></TextView>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -78,7 +81,8 @@
 			android:textSize="15dp"
 			android:id="@+id/txtWidgetAccountbalance"
 			android:layout_height="fill_parent"
-			android:text="Loading..." />
+			android:text="@string/loading"
+			tools:ignore="SpUsage"/>
 	</LinearLayout>
 	<LinearLayout
 			android:layout_below="@+id/layWidgetRow02"
diff --git app/src/main/res/layout/widget_large.xml app/src/main/res/layout/widget_large.xml
index b9a11a5..9971290 100644
--- app/src/main/res/layout/widget_large.xml
+++ app/src/main/res/layout/widget_large.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_gravity="center_horizontal"
 	android:layout_height="100dp"
 	android:id="@+id/layWidgetContainer"
@@ -52,7 +53,8 @@
 				android:id="@+id/txtWidgetAccountnameBlur"
 				android:layout_alignRight="@+id/imgBalanceblur"
 				android:layout_alignTop="@+id/imgBalanceblur"
-				android:visibility="gone"></TextView>
+				android:visibility="gone"
+				tools:ignore="SpUsage"></TextView>
 			<TextView
 				android:textColor="#fff"
 				android:inputType="none"
@@ -65,10 +67,11 @@
 				android:layout_width="wrap_content"
 				android:layout_centerInParent="false"
 				android:layout_centerHorizontal="true"
-				android:text="Loading..."
+				android:text="@string/loading"
 				android:textSize="27dp"
 				android:paddingRight="1dp"
-				android:paddingTop="8dp" />
+				android:paddingTop="8dp"
+				tools:ignore="SpUsage"/>
 			<TextView
 				android:layout_height="wrap_content"
 				android:layout_width="wrap_content"
@@ -79,7 +82,8 @@
 				android:layout_alignRight="@+id/txtWidgetAccountbalance"
 				android:gravity="right"
 				android:layout_alignTop="@+id/txtWidgetAccountbalance"
-				android:paddingTop="37dp"></TextView>
+				android:paddingTop="37dp"
+				tools:ignore="SpUsage"></TextView>
 
 </RelativeLayout>
 	</RelativeLayout>
diff --git app/src/main/res/layout/widget_large_transparent.xml app/src/main/res/layout/widget_large_transparent.xml
index 9f69ffd..b44228c 100644
--- app/src/main/res/layout/widget_large_transparent.xml
+++ app/src/main/res/layout/widget_large_transparent.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_gravity="center_horizontal"
 	android:layout_height="100dp"
 	android:id="@+id/layWidgetContainer"
@@ -51,7 +52,8 @@
 				android:id="@+id/txtWidgetAccountnameBlur"
 				android:layout_alignRight="@+id/imgBalanceblur"
 				android:layout_alignTop="@+id/imgBalanceblur"
-				android:visibility="gone"></TextView>
+				android:visibility="gone"
+				tools:ignore="SpUsage"/>
 			<TextView
 				android:textColor="#fff"
 				android:inputType="none"
@@ -64,10 +66,11 @@
 				android:layout_width="wrap_content"
 				android:layout_centerInParent="false"
 				android:layout_centerHorizontal="true"
-				android:text="Loading..."
+				android:text="@string/loading"
 				android:textSize="27dp"
 				android:paddingRight="1dp"
-				android:paddingTop="8dp" />
+				android:paddingTop="8dp"
+				tools:ignore="SpUsage"/>
 			<TextView
 				android:layout_height="wrap_content"
 				android:layout_width="wrap_content"
@@ -78,7 +81,8 @@
 				android:layout_alignRight="@+id/txtWidgetAccountbalance"
 				android:gravity="right"
 				android:layout_alignTop="@+id/txtWidgetAccountbalance"
-				android:paddingTop="37dp"></TextView>
+				android:paddingTop="37dp"
+				tools:ignore="SpUsage"></TextView>
 		</RelativeLayout>
 	</RelativeLayout>
 	<RelativeLayout
diff --git app/src/main/res/layout/widget_transparent.xml app/src/main/res/layout/widget_transparent.xml
index 3c9e6e5..4ce1b8b 100644
--- app/src/main/res/layout/widget_transparent.xml
+++ app/src/main/res/layout/widget_transparent.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_gravity="center_horizontal"
 
 	android:layout_height="100dp"
@@ -40,8 +41,9 @@
 		android:inputType="none"
 		android:layout_marginLeft="2dp"
 		android:layout_marginRight="2dp"
-		android:text="Bankdroid"
-		android:lines="1"/>
+		android:text="@string/app_name"
+		android:lines="1"
+		tools:ignore="SpUsage"/>
 	<TextView
 		android:id="@+id/txtWidgetAccountnameBlur"
 		android:layout_height="wrap_content"
@@ -52,9 +54,10 @@
 		android:inputType="none"
 		android:layout_marginLeft="2dp"
 		android:layout_marginRight="2dp"
-		android:text="Bankdroid"
+		android:text="@string/app_name"
 		android:lines="1"
-		android:visibility="gone"/>
+		android:visibility="gone"
+		tools:ignore="SpUsage"/>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -83,7 +86,8 @@
 			android:textSize="15dp"
 			android:id="@+id/txtWidgetAccountbalance"
 			android:layout_height="fill_parent"
-			android:text="Loading..." />
+			android:text="@string/loading"
+			tools:ignore="SpUsage"/>
 	</LinearLayout>
 	<LinearLayout
 			android:layout_below="@+id/layWidgetRow02"
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 38f8f2b..6f0eb42 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -218,5 +218,6 @@
     <!-- Error messages -->
     <string name="error_bank_not_found">Den valda banken kunde inte hittas.</string>
     <string name="error_account_not_found">Det valda kontot kunde inte hittas.</string>
-	<string name="disabled_refresh_or_edit">Senaste uppdateringen misslyckades och vi har slutat uppdatera kontot automatiskt. Uppdatera kontot manuellt för att försöka igen eller ändra kontot och kontrollera dina inloggningsuppgifter.</string>
+	<string name="disabled_refresh_or_edit">Senaste anslutningsförsöket till den här banken misslyckades och vi har slutat uppdatera denna bank automatiskt. Uppdatera banken manuellt för att försöka igen eller öppna inställningarna för denna bank och kontrollera dina inloggningsuppgifter.</string>
+	<string name="loading">Laddar…</string>
 </resources>
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index 29c3f47..1f3171e 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -14,6 +14,7 @@
     <string name="settings">Settings</string>
     <string name="refresh">Refresh</string>
     <string name="add_account">Add account</string>
+	<string name="loading">Loading…</string>
 
 
     <string name="optional_field">(optional)</string>
@@ -132,10 +133,10 @@
     <string name="menu_hide_hidden">Hide hidden accounts</string>
 
     <string name="tran_desc">No transaction history available for this account.</string>
-	<string name="disabled_refresh_or_edit">The last update was unsuccessful and updates for this account have been disabled. Manually refresh the account to try again or edit the account and check your credentials.</string>
+	<string name="disabled_refresh_or_edit">Our last connection attempt to this bank failed and further updates for this bank have been disabled. Manually refresh the bank to try again or open the settings for this bank and check your credentials.</string>
 
     <string name="thanks_to">Thanks to</string>
-    <string name="thanks">
+    <string name="thanks" translatable="false">
     Wendell Fernandes (Icon)
     \nKingcool (ICA Banken &amp; SEB)
     \ngrief (Länsförsäkringar)
diff --git app/src/main/res/values/styles.xml app/src/main/res/values/styles.xml
index 2a94ef4..353ae66 100644
--- app/src/main/res/values/styles.xml
+++ app/src/main/res/values/styles.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
 	<style
 		name="Widget_Progress">
 		<item
@@ -32,7 +32,7 @@
 	<item name="android:paddingLeft">4dp</item>
 	<item name="android:paddingRight">4dp</item>
 	<item name="android:textColor">#fff</item>
-	<item name="android:textSize">12dp</item>
+	<item name="android:textSize">12sp</item>
 	<item name="android:minWidth">50dp</item>
 	<item name="android:background">@drawable/popup_button</item>
 	<item name="android:gravity">center_vertical|center_horizontal</item>
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
index 86c90a4..4bb2e20 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
@@ -65,15 +65,4 @@ public class CertificateReader {
         }
         return null;
     }
-
-    private static String byteArrayToHexString(byte[] b) {
-        int len = b.length;
-        String data = new String();
-
-        for (int i = 0; i < len; i++) {
-            data += Integer.toHexString((b[i] >> 4) & 0xf);
-            data += Integer.toHexString(b[i] & 0xf);
-        }
-        return data;
-    }
 }
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 81ee529..8f68763 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -9,13 +9,11 @@
     <issue id="ClickableViewAccessibility" severity="ignore" />
     <issue id="ContentDescription" severity="ignore" />
     <issue id="DefaultLocale" severity="ignore" />
-    <issue id="Deprecated" severity="ignore" />
     <issue id="ExportedReceiver" severity="ignore" />
     <issue id="GetInstance" severity="ignore" />
     <issue id="GoogleAppIndexingWarning" severity="ignore" />
     <issue id="GradleDependency" severity="ignore" />
     <issue id="GradleDynamicVersion" severity="ignore" />
-    <issue id="HardcodedText" severity="ignore" />
     <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
     <issue id="IconExpectedSize" severity="ignore" />
@@ -42,7 +40,6 @@
     <issue id="SelectableText" severity="ignore" />
     <issue id="SetJavaScriptEnabled" severity="ignore" />
     <issue id="SimpleDateFormat" severity="ignore" />
-    <issue id="SpUsage" severity="ignore" />
     <issue id="TrulyRandom" severity="ignore" />
     <issue id="UnknownIdInLayout" severity="ignore" />
     <issue id="UnusedAttribute" severity="ignore" />
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 4f92b80..9dbddb2 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -110,7 +110,6 @@
         <exclude name="SimplifyStartsWith" />
         <exclude name="SingularField" />
         <exclude name="StdCyclomaticComplexity" />
-        <exclude name="StringInstantiation" />
         <exclude name="SuspiciousConstantFieldName" />
         <exclude name="SwitchDensity" />
         <exclude name="SwitchStmtsShouldHaveDefault" />
@@ -125,7 +124,6 @@
         <exclude name="UnnecessaryWrapperObjectCreation" />
         <exclude name="UnsynchronizedStaticDateFormatter" />
         <exclude name="UnusedLocalVariable" />
-        <exclude name="UnusedPrivateMethod" />
         <exclude name="UseCollectionIsEmpty" />
         <exclude name="UseConcurrentHashMap" />
         <exclude name="UseEqualsToCompareStrings" />

commit 8fa69c401b0e7fb76116a18becdc6970ac0b0b83
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 20 20:12:43 2016 +0200

    Allow org.hamcrest and org.junit packages to be imported statically

diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 503f4cb..4f92b80 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -9,6 +9,22 @@
     <exclude-pattern>.*/R.java</exclude-pattern>
     <exclude-pattern>.*/gen/.*</exclude-pattern>
 
+    <rule ref="rulesets/internal/all-java.xml/TooManyStaticImports">
+        <properties>
+            <property name="legalPackages" type="String"
+              description="Allow static imports for following packages."
+              value="org.hamcrest.*|org.junit.*"/>
+            <property name="xpath">
+                <value><![CDATA[
+                    .[count(ImportDeclaration[@Static='true' and
+                    not(
+                        matches(@PackageName, $legalPackages)
+                    )]) > $maximumStaticImports]
+                ]]></value>
+            </property>
+        </properties>
+    </rule>
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
 
diff --git tools/update-suppressions.sh tools/update-suppressions.sh
index 62b338b..363091b 100755
--- tools/update-suppressions.sh
+++ tools/update-suppressions.sh
@@ -45,6 +45,22 @@ function set_pmd_suppressions() {
     <exclude-pattern>.*/R.java</exclude-pattern>
     <exclude-pattern>.*/gen/.*</exclude-pattern>
 
+    <rule ref="rulesets/internal/all-java.xml/TooManyStaticImports">
+        <properties>
+            <property name="legalPackages" type="String"
+              description="Allow static imports for following packages."
+              value="org.hamcrest.*|org.junit.*"/>
+            <property name="xpath">
+                <value><![CDATA[
+                    .[count(ImportDeclaration[@Static='true' and
+                    not(
+                        matches(@PackageName, \$legalPackages)
+                    )]) > \$maximumStaticImports]
+                ]]></value>
+            </property>
+        </properties>
+    </rule>
+
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
 

commit 148a694e9dce18b8963b60d301847235e49cdb03
Author: Johan Walles <johan.walles@gmail.com>
Date:   Wed Oct 19 20:26:58 2016 +0200

    Add bank-disabled warning to TransactionsActivity
    
    If a bank is disabled, and you click on the widget, with this change in
    place you now get a warning about the bank being disabled and what you
    can do about it.
    
    This is part of fixing #610.
    
    To be able to work on this I first fixed all warnings in the two files
    I had to change. To remove the suppressions for those warnings so that
    they don't come back, I fixed all other instances of those problems as
    well.

diff --git CHANGELOG CHANGELOG
index ff0a4dc..858714a 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,12 +1,13 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 Not yet released
+* Warn about disabled banks in the transactions list
 * Remove TrustBuddy since they're no longer in business
 * Remove unused class MobilbankenBase
 
 v1.9.10.10 (2016-10-17)
 * Fixes crash for Amex
-* Strikethrough balance in widget indicates update problems. 
+* Strikethrough balance in widget indicates update problems.
 
 v1.9.10.9 (2016-10-12)
 * Länsförsäkringar: Remove broken web links
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index c52f332..fce0bbe 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -81,8 +81,6 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
     @InjectView(R.id.txtErrorDesc)
     TextView mErrorDescription;
 
-    private final static String TAG = "BankEditActivity";
-
     private Bank SELECTED_BANK;
 
     private long BANKID = -1;
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index 5ff4724..b8145f3 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -45,8 +45,6 @@ import timber.log.Timber;
 
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
-    private final static String TAG = "DataRetrieverTask";
-
     private final ProgressDialog dialog;
 
     private final MainActivity parent;
diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index 64e5907..1b5720f 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -35,7 +35,6 @@ import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.support.v7.app.ActionBarActivity;
 import android.support.v7.widget.Toolbar;
-import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 
@@ -51,13 +50,6 @@ public class LockableActivity extends ActionBarActivity {
 
     private boolean mHasLoaded = false;
 
-    //    private LinearLayout mTitlebarButtons;
-    private LayoutInflater mInflater;
-//    private ProgressBar mProgressBar;
-
-//    private ImageView mHomeButton;
-//    private View mHomeButtonCont;
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
diff --git app/src/main/java/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
index 95d08cd..31b7963 100644
--- app/src/main/java/com/liato/bankdroid/SettingsActivity.java
+++ app/src/main/java/com/liato/bankdroid/SettingsActivity.java
@@ -42,8 +42,6 @@ import timber.log.Timber;
 public class SettingsActivity extends LockablePreferenceActivity
         implements OnPreferenceClickListener, OnPreferenceChangeListener {
 
-    private final static String TAG = "SettingsActivity";
-
     private final static int DISABLE_LOCKPATTERN = 1;
 
     private final static int ENABLE_LOCKPATTERN = 2;
diff --git app/src/main/java/com/liato/bankdroid/StartupReceiver.java app/src/main/java/com/liato/bankdroid/StartupReceiver.java
index b550441..f7a6e8c 100644
--- app/src/main/java/com/liato/bankdroid/StartupReceiver.java
+++ app/src/main/java/com/liato/bankdroid/StartupReceiver.java
@@ -30,8 +30,6 @@ import android.preference.PreferenceManager;
 
 public class StartupReceiver extends BroadcastReceiver {
 
-    private final static String TAG = "StartupReceiver";
-
     public static void setAlarm(Context context) {
         PendingIntent alarmSender;
         alarmSender = PendingIntent
diff --git app/src/main/java/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
index 1e0290b..f94df2c 100644
--- app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
+++ app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
@@ -24,6 +24,7 @@ import com.liato.bankdroid.banking.Transaction;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.annotation.Nullable;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -38,8 +39,6 @@ import java.util.List;
 
 public class TransactionsActivity extends LockableActivity {
 
-    final static String TAG = "TransactionActivity";
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -70,6 +69,10 @@ public class TransactionsActivity extends LockableActivity {
         icon.setImageResource(bank.getImageResource());
         List<Transaction> transactions = account.getTransactions();
 
+        if (bank.isDisabled()) {
+            findViewById(R.id.txtDisabledWarning).setVisibility(View.VISIBLE);
+        }
+
         if (!transactions.isEmpty()) {
             Collections.sort(transactions);
             findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
@@ -93,7 +96,7 @@ public class TransactionsActivity extends LockableActivity {
     private void redirectToMain(String errorMessage) {
         final Intent intent = new Intent(this, MainActivity.class);
         ((BankdroidApplication) getApplicationContext())
-                .setApplicationMessage(getString(R.string.error_bank_not_found));
+                .setApplicationMessage(errorMessage);
         startActivity(intent);
     }
 
@@ -101,7 +104,7 @@ public class TransactionsActivity extends LockableActivity {
 
         private LayoutInflater inflater;
 
-        private ArrayList<Object> items = new ArrayList<Object>();
+        private ArrayList<Object> items = new ArrayList<>();
 
         public TransactionsAdapter(List<Transaction> transactions) {
             inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -129,10 +132,10 @@ public class TransactionsActivity extends LockableActivity {
             ((TextView) convertView.findViewById(R.id.txtAmount)).setText(
                     Helpers.formatBalance(transaction.getAmount(), transaction.getCurrency()));
             if (transaction.getAmount().signum() == 1) {
-                ((ImageView) convertView.findViewById(R.id.imgColor))
+                convertView.findViewById(R.id.imgColor)
                         .setBackgroundResource(R.drawable.transaction_positive);
             } else {
-                ((ImageView) convertView.findViewById(R.id.imgColor))
+                convertView.findViewById(R.id.imgColor)
                         .setBackgroundResource(R.drawable.transaction_negative);
             }
             return convertView;
@@ -162,6 +165,7 @@ public class TransactionsActivity extends LockableActivity {
         }
 
         @Override
+        @Nullable
         public View getView(int position, View convertView, ViewGroup parent) {
             Object item = getItem(position);
             if (item == null) {
diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index bac0ab7..24fff3f 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -47,12 +47,8 @@ import static android.graphics.Color.WHITE;
 
 public class WebViewActivity extends LockableActivity implements OnClickListener {
 
-    private final static String TAG = "WebViewActivity";
-
     private WebView mWebView;
 
-    private final LockableActivity activity = this;
-
     private boolean mFirstPageLoaded = false;
 
     private Handler mMainThreadhandler = new Handler(Looper.getMainLooper());
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index b3aee41..7e26254 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -75,8 +75,6 @@ public class AutoRefreshService extends Service {
     public final static String BROADCAST_TRANSACTIONS_UPDATED
             = "com.liato.bankdroid.action.TRANSACTIONS";
 
-    private final static String TAG = "AutoRefreshService";
-
     public static void showNotification(final Bank bank, final Account account,
             final BigDecimal diff, Context context) {
 
@@ -189,16 +187,16 @@ public class AutoRefreshService extends Service {
     @Override
     public void onStart(Intent intent, int startId) {
         super.onStart(intent, startId);
-        handleStart(intent, startId);
+        handleStart();
     }
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        handleStart(intent, startId);
+        handleStart();
         return START_NOT_STICKY;
     }
 
-    private void handleStart(Intent intent, int startId) {
+    private void handleStart() {
         ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
         NetworkInfo ni = cm.getActiveNetworkInfo();
         if (ni != null &&
diff --git app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
index 6f0bec7..71fbaf2 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
@@ -40,8 +40,6 @@ public class WidgetConfigureActivity extends LockableActivity {
 
     private static final String WIDGET_PREFIX = "widget_";
 
-    private static final int LOGIN_ID = 1;
-
     int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
 
     private AccountsAdapter adapter;
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
index 115304d..96c3f8a 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
@@ -400,8 +400,8 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener
      * The states of the left footer button.
      */
     enum LeftButtonMode {
-        Cancel(R.string.lock_cancel, true),
-        CancelDisabled(R.string.lock_cancel, false),
+        Cancel(android.R.string.cancel, true),
+        CancelDisabled(android.R.string.cancel, false),
         Retry(R.string.lockpattern_retry_button_text, true),
         RetryDisabled(R.string.lockpattern_retry_button_text, false),
         Gone(ID_EMPTY_MESSAGE, false);
@@ -429,7 +429,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener
         ContinueDisabled(R.string.lockpattern_continue_button_text, false),
         Confirm(R.string.lockpattern_confirm_button_text, true),
         ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
-        Ok(R.string.lock_ok, true);
+        Ok(android.R.string.ok, true);
 
         final int text;
 
diff --git app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 4c0e444..3e16654 100644
--- app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -51,9 +51,6 @@ public class BankTransactionsProvider extends ContentProvider implements
 
     private static final String CONTENT_PROVIDER_API_KEY = "content_provider_api_key";
 
-    // Tags can be at most 23 characters, note the slight abbreviation
-    private final static String TAG = "BankTransactionsProvdr";
-
     private final static int TRANSACTIONS = 0;
 
     private final static int BANK_ACCOUNTS = 1;
diff --git app/src/main/res/layout/bank.xml app/src/main/res/layout/bank.xml
index d5186bc..c6f6ec5 100644
--- app/src/main/res/layout/bank.xml
+++ app/src/main/res/layout/bank.xml
@@ -74,7 +74,7 @@
                 android:id="@+id/btnSettingsCancel"
                 style="@style/Menu_Button"
                 android:drawableLeft="@drawable/button_cancel"
-                android:text="@string/cancel"></Button>
+                android:text="@android:string/cancel"></Button>
 
             <ImageView
                 android:layout_width="wrap_content"
diff --git app/src/main/res/layout/pair_applications_layout.xml app/src/main/res/layout/pair_applications_layout.xml
index a571a4c..60471ed 100644
--- app/src/main/res/layout/pair_applications_layout.xml
+++ app/src/main/res/layout/pair_applications_layout.xml
@@ -54,7 +54,7 @@
 			android:layout_width="fill_parent">
 			<Button
 				android:onClick="cancelPairing"
-				android:text="@string/cancel"
+				android:text="@android:string/cancel"
 				android:drawableLeft="@drawable/button_cancel"
 				android:id="@+id/btnSettingsCancel"
 				style="@style/Menu_Button"></Button>
diff --git app/src/main/res/layout/transactions.xml app/src/main/res/layout/transactions.xml
index 7510222..1c68f60 100644
--- app/src/main/res/layout/transactions.xml
+++ app/src/main/res/layout/transactions.xml
@@ -16,11 +16,22 @@
         android:layout_below="@id/toolbar" />
 
     <TextView
-        android:id="@+id/txtTranDesc"
+        android:id="@+id/txtDisabledWarning"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_below="@+id/layBankHeader"
         android:layout_margin="10dp"
+        android:drawableLeft="@drawable/indicator_input_error"
+        android:drawablePadding="10dp"
+        android:text="@string/disabled_refresh_or_edit"
+        android:visibility="gone" />
+
+    <TextView
+        android:id="@+id/txtTranDesc"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/txtDisabledWarning"
+        android:layout_margin="10dp"
         android:text="@string/tran_desc"
         android:visibility="visible" />
 
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index ff8a6f5..38f8f2b 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -1,15 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <string name="about">Om</string>
     <string name="version">Version $version av</string>
     <string name="widget_name_small">Bankdroid (Liten)</string>
     <string name="widget_name_large">Bankdroid (Stor)</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
-    <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
+    <string name="updating_account_balance">Uppdaterar saldoinformation…</string>
     <string name="errors_when_updating">Fel vid uppdatering</string>
-    <string name="logging_in">Loggar in...</string>
+    <string name="logging_in">Loggar in…</string>
     <string name="could_not_create_account">Kunde ej skapa konto</string>
 	<string name="transparent_background">Transparent bakgrund</string>
     <string name="settings">Inställningar</string>
@@ -20,7 +19,6 @@
     <string name="optional_field">(frivilligt)</string>
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
-    <string name="cancel">AVBRYT</string>
     <string name="save">SPARA</string>
 
 	<string name="add_new_account">LÄGG TILL BANK</string>
@@ -206,8 +204,6 @@
     <string name="lock_example_message">Anslut minst fyra punkter.
     \n\nVälj \u201CNästa\u201D när du vill rita ditt eget grafiska lösenord.
     </string>
-	<string name="lock_cancel">Avbryt</string>
-	<string name="lock_ok">Ok</string>
 
 	<string name="select_a_bank">Välj en bank</string>
 	<string name="invalid_integer">%1$s är inte ett giltigt positivt heltal, var god försök igen.</string>
@@ -222,4 +218,5 @@
     <!-- Error messages -->
     <string name="error_bank_not_found">Den valda banken kunde inte hittas.</string>
     <string name="error_account_not_found">Det valda kontot kunde inte hittas.</string>
+	<string name="disabled_refresh_or_edit">Senaste uppdateringen misslyckades och vi har slutat uppdatera kontot automatiskt. Uppdatera kontot manuellt för att försöka igen eller ändra kontot och kontrollera dina inloggningsuppgifter.</string>
 </resources>
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index 4770b58..29c3f47 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources  xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="version">Version $version by</string>
-    <string name="app_name">Bankdroid</string>
+    <string name="app_name" translatable="false">Bankdroid</string>
     <string name="widget_name_small">Bankdroid (Small)</string>
     <string name="widget_name_large">Bankdroid (Large)</string>
     <string name="about">About</string>
     <string name="accounts_were_not_updated">Balance for the following accounts could not be updated</string>
-    <string name="updating_account_balance">Refreshing account balance...</string>
+    <string name="updating_account_balance">Refreshing account balance…</string>
     <string name="errors_when_updating">Errors while refreshing</string>
-    <string name="logging_in">Signing in...</string>
+    <string name="logging_in">Signing in…</string>
     <string name="could_not_create_account">Could not create account</string>
 	<string name="transparent_background">Transparent background</string>
     <string name="settings">Settings</string>
@@ -21,12 +21,11 @@
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
 
-    <string name="cancel">CANCEL</string>
     <string name="save">SAVE</string>
 
 	<string name="add_new_account">ADD BANK</string>
 
-	<string name="main_instructions">You have not added any bank accounts yet, press the "Accounts" button in the menu to add a new account.</string>
+	<string name="main_instructions">You have not added any bank accounts yet, press the “Accounts” button in the menu to add a new account.</string>
 	<string name="refresh_balance">REFRESH</string>
 
 	<string name="choose_an_account">Choose an account</string>
@@ -133,6 +132,7 @@
     <string name="menu_hide_hidden">Hide hidden accounts</string>
 
     <string name="tran_desc">No transaction history available for this account.</string>
+	<string name="disabled_refresh_or_edit">The last update was unsuccessful and updates for this account have been disabled. Manually refresh the account to try again or edit the account and check your credentials.</string>
 
     <string name="thanks_to">Thanks to</string>
     <string name="thanks">
@@ -258,8 +258,6 @@
     <string name="lock_example_message">Connect at least four dots.\n
         \nSelect \u201CNext\u201D when you\u2019re ready to draw your own pattern.
     </string>
-	<string name="lock_cancel">Cancel</string>
-	<string name="lock_ok">Ok</string>
 
 	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
index 0b47ef7..444d8fd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
@@ -18,6 +18,8 @@ package com.liato.bankdroid.banking;
 
 import com.liato.bankdroid.provider.IAccountTypes;
 
+import android.support.annotation.Nullable;
+
 import java.math.BigDecimal;
 import java.util.List;
 
@@ -120,6 +122,7 @@ public class Account implements IAccountTypes {
         this.id = id;
     }
 
+    @Nullable
     public Bank getBank() {
         return bank;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
index 5bb5cbe..5b14d0e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
@@ -4,9 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class Account {
@@ -30,9 +28,7 @@ public class Account {
     private double creditLimit;
 
     @JsonProperty("Transactions")
-    private List<Transaction> transactions = new ArrayList<Transaction>();
-
-    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+    private List<Transaction> transactions = new ArrayList<>();
 
     @JsonProperty("Name")
     public String getName() {
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index 9b26a38..2a87b49 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -48,8 +48,6 @@ import javax.net.ssl.TrustManager;
 
 public class CertPinningSSLSocketFactory extends SSLSocketFactory {
 
-    private final static String TAG = CertPinningSSLSocketFactory.class.getSimpleName();
-
     private SSLContext sslcontext = null;
 
     private Certificate[] certificates;
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 3439326..81ee529 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -6,7 +6,6 @@
     <issue id="AlwaysShowAction" severity="ignore" />
     <issue id="AppCompatResource" severity="ignore" />
     <issue id="BatteryLife" severity="ignore" />
-    <issue id="ButtonCase" severity="ignore" />
     <issue id="ClickableViewAccessibility" severity="ignore" />
     <issue id="ContentDescription" severity="ignore" />
     <issue id="DefaultLocale" severity="ignore" />
@@ -19,6 +18,7 @@
     <issue id="HardcodedText" severity="ignore" />
     <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
+    <issue id="IconExpectedSize" severity="ignore" />
     <issue id="IconLocation" severity="ignore" />
     <issue id="IconMissingDensityFolder" severity="ignore" />
     <issue id="InefficientWeight" severity="ignore" />
@@ -28,6 +28,7 @@
     <issue id="MergeRootFrame" severity="ignore" />
     <issue id="MissingTranslation" severity="ignore" />
     <issue id="NewApi" severity="ignore" />
+    <issue id="NewerVersionAvailable" severity="ignore" />
     <issue id="NotSibling" severity="ignore" />
     <issue id="ObsoleteLayoutParam" severity="ignore" />
     <issue id="Orientation" severity="ignore" />
@@ -38,14 +39,14 @@
     <issue id="RtlHardcoded" severity="ignore" />
     <issue id="RtlSymmetry" severity="ignore" />
     <issue id="ScrollViewSize" severity="ignore" />
+    <issue id="SelectableText" severity="ignore" />
     <issue id="SetJavaScriptEnabled" severity="ignore" />
     <issue id="SimpleDateFormat" severity="ignore" />
     <issue id="SpUsage" severity="ignore" />
     <issue id="TrulyRandom" severity="ignore" />
-    <issue id="TypographyEllipsis" severity="ignore" />
-    <issue id="Typos" severity="ignore" />
     <issue id="UnknownIdInLayout" severity="ignore" />
     <issue id="UnusedAttribute" severity="ignore" />
+    <issue id="UnusedIds" severity="ignore" />
     <issue id="UnusedResources" severity="ignore" />
     <issue id="UseCompoundDrawables" severity="ignore" />
     <issue id="UselessParent" severity="ignore" />
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 12461c8..503f4cb 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -108,9 +108,7 @@
         <exclude name="UnnecessaryParentheses" />
         <exclude name="UnnecessaryWrapperObjectCreation" />
         <exclude name="UnsynchronizedStaticDateFormatter" />
-        <exclude name="UnusedFormalParameter" />
         <exclude name="UnusedLocalVariable" />
-        <exclude name="UnusedPrivateField" />
         <exclude name="UnusedPrivateMethod" />
         <exclude name="UseCollectionIsEmpty" />
         <exclude name="UseConcurrentHashMap" />
diff --git config/quality/quality.gradle config/quality/quality.gradle
index a69b301..bf2f1c6 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -71,6 +71,7 @@ if(plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) {
         lintOptions {
             abortOnError true
             warningsAsErrors true
+            checkAllWarnings true
 
             // FIXME: This file contains *far* too many disabled checks. Somebody think of the children!
             lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")

commit 505eb29969ea9ef78abbcf09ddb2f1469382c715
Merge: d3bb175 22ed6e5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 19:46:28 2016 +0200

    Merge pull request #651 from walles/walles/fix-popups
    
    Fix crashing popup windows

commit 22ed6e509728434484d142b3859915f2db733a93 (walles/walles/fix-popups, walles/fix-popups)
Author: Johan Walles <johan.walles@gmail.com>
Date:   Wed Oct 19 19:26:37 2016 +0200

    Fix crashing popup windows
    
    An earlier PR by myself is the source of these crashes. But at least I
    found them myself :/.

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index c545a83..48acb74 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -237,7 +237,7 @@ public class MainActivity extends LockableActivity {
                     (LayoutInflater) this.anchor.getContext()
                             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, this.parentView);
+            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, this.parentView, false);
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnWWW = (Button) root.findViewById(R.id.btnWWW);
@@ -351,7 +351,7 @@ public class MainActivity extends LockableActivity {
                     (LayoutInflater) this.anchor.getContext()
                             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, this.parentView);
+            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, this.parentView, false);
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnDisableNotifications = (Button) root
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
index 7a6533a..86f7136 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -65,7 +65,7 @@ public class ColorPickerDialog
         LayoutInflater inflater = (LayoutInflater) getContext()
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-        View layout = inflater.inflate(R.layout.dialog_color_picker, mParent);
+        View layout = inflater.inflate(R.layout.dialog_color_picker, mParent, false);
 
         setContentView(layout);
 

commit d3bb175aa131b79ef0c91b5145fa7c5580076cf5
Merge: 575e259 a03c711
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 18:28:37 2016 +0200

    Merge pull request #650 from walles/walles/fix-invisible-warning
    
    Fix overlapping layout

commit a03c7115e0cbad969cf4e9f7676c3a28f39bd54f (walles/walles/fix-invisible-warning, walles/fix-invisible-warning)
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Oct 17 21:38:36 2016 +0200

    Fix overlapping layout
    
    Also, boy-scout-principle update suppressions script to disable a PMD
    rule that needs configuration to work that we don't supply right now.

diff --git app/src/main/res/layout/transactions.xml app/src/main/res/layout/transactions.xml
index 15d0e4b..7510222 100644
--- app/src/main/res/layout/transactions.xml
+++ app/src/main/res/layout/transactions.xml
@@ -29,7 +29,7 @@
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:layout_alignParentBottom="true"
-        android:layout_below="@+id/layBankHeader"
+        android:layout_below="@+id/txtTranDesc"
         android:background="@drawable/background_repeat"
         android:cacheColorHint="#00000000"
         android:clickable="false"
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index b9bb166..12461c8 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -11,6 +11,10 @@
 
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
+
+        <!-- This check needs extra configuration to work, disable it for now -->
+        <exclude name="LoosePackageCoupling" />
+
         <exclude name="AbstractNaming" />
         <exclude name="AccessorClassGeneration" />
         <exclude name="AppendCharacterWithChar" />
diff --git tools/update-suppressions.sh tools/update-suppressions.sh
index 2b23a17..62b338b 100755
--- tools/update-suppressions.sh
+++ tools/update-suppressions.sh
@@ -47,6 +47,10 @@ function set_pmd_suppressions() {
 
     <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
+
+        <!-- This check needs extra configuration to work, disable it for now -->
+        <exclude name="LoosePackageCoupling" />
+
 EOF
 
   for RULE in $1; do

commit 575e2591d4640c02203fb8b613922da0173ef7a9
Merge: 5fdb7e3 3de82e2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 12:00:31 2016 +0200

    Merge pull request #649 from liato/feature/648-remove-broken-banks
    
    Removes banks that require BankId

commit 3de82e22503bf9c12d46341d76c4d788092895cc
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:45:24 2016 +0200

    Removes NordnetDirekt since they are now included in Nordnet

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 2b2b17e..d2a8b11 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -24,7 +24,6 @@ import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Meniga;
 import com.liato.bankdroid.banking.banks.MinPension;
 import com.liato.bankdroid.banking.banks.Nordnet;
-import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
@@ -106,8 +105,6 @@ public class LegacyBankFactory {
                 return new PlusGirot(context);
             case IBankTypes.IKEA:
                 return new IKEA(context);
-            case IBankTypes.NORDNETDIREKT:
-                return new Nordnetdirekt(context);
             case IBankTypes.DANSKEBANK:
                 return new DanskeBank(context);
             case IBankTypes.VASTTRAFIK:
@@ -176,7 +173,6 @@ public class LegacyBankFactory {
         banks.add(new McDonalds(context));
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
-        banks.add(new Nordnetdirekt(context));
         banks.add(new IKEA(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
deleted file mode 100644
index 2f78946..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Nordnetdirekt extends Bank {
-
-    private static final String NAME = "Nordnetdirekt";
-
-    private static final String NAME_SHORT = "nordnetdirekt";
-
-    private static final String URL
-            = "https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html";
-
-    private static final int BANKTYPE_ID = IBankTypes.NORDNETDIREKT;
-
-    private static final int INPUT_TITLETEXT_EXTRAS = R.string.nordnetdirekt_extras_title;
-
-    private static final int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT
-            | InputType.TYPE_TEXT_VARIATION_PASSWORD;
-
-    private static final boolean INPUT_HIDDEN_EXTRAS = false;
-
-    private Pattern reBalance = Pattern.compile(
-            "left\">\\s*<table[^>]+>\\s*<caption[^>]+>([^<]+)</caption>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>");
-
-    private String response = null;
-
-    public Nordnetdirekt(Context context) {
-        super(context, R.drawable.logo_nordnetdirekt);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TITLETEXT_EXTRAS = INPUT_TITLETEXT_EXTRAS;
-        super.INPUT_TYPE_EXTRAS = INPUT_TYPE_EXTRAS;
-        super.INPUT_HIDDEN_EXTRAS = INPUT_HIDDEN_EXTRAS;
-    }
-
-    public Nordnetdirekt(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        response = urlopen.open("https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html");
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("a4", "sv"));
-        postData.add(new BasicNameValuePair("a3", "ADSE"));
-        postData.add(new BasicNameValuePair("usa", "7"));
-        postData.add(new BasicNameValuePair("a1", getUsername()));
-        postData.add(new BasicNameValuePair("a2", getPassword()));
-        postData.add(new BasicNameValuePair("nyckel", getExtras()));
-        return new LoginPackage(urlopen, postData, response,
-                "https://www.nordnetdirekt.se/mux/inloggad/lib/login.html");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("fel vid inloggningen")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        Matcher matcher = reBalance.matcher(response);
-        if (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Currency          Dep&aring;v&auml;rde - SEK
-             * 2: Kontantsaldo      13 264,53
-             * 3: Värdepapper       111 909,05
-             *
-             */
-            accounts.add(new Account(
-                    "Kontosaldo",
-                    Helpers.parseBalance(matcher.group(2)),
-                    "1"));
-            accounts.add(new Account(
-                    "Värdepapper",
-                    Helpers.parseBalance(matcher.group(3)),
-                    "2"));
-            balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index e97231a..230dbd5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -44,7 +44,6 @@ public interface IBankTypes {
     int MCDONALDS = 32;
     int PLUSGIROT = 40;
     int IKEA = 47;
-    int NORDNETDIREKT = 50;
     int DANSKEBANK = 52;
     int VASTTRAFIK = 54;
     int EVERYDAYCARD = 55;
diff --git bankdroid-legacy/src/main/res/drawable/logo_nordnetdirekt.png bankdroid-legacy/src/main/res/drawable/logo_nordnetdirekt.png
deleted file mode 100644
index c2a26d1..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_nordnetdirekt.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
deleted file mode 100644
index 356b023..0000000
--- bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
+++ /dev/null
@@ -1,43 +0,0 @@
------BEGIN CERTIFICATE-----

-tuhEbaCLdLWID2yLn3NMtdkabXtgfWq+kE5lOCKGseEm
------END CERTIFICATE-----
-www.nordnetdirekt.se:443

commit d38b0759701867cf1618e76b8ffd625eba359b22
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:42:53 2016 +0200

    Removes ResursBank due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 5383ece..2b2b17e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -30,7 +30,6 @@ import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
-import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
@@ -99,8 +98,6 @@ public class LegacyBankFactory {
                 return new Osuuspankki(context);
             case IBankTypes.CSN:
                 return new CSN(context);
-            case IBankTypes.RESURSBANK:
-                return new ResursBank(context);
             case IBankTypes.AMERICANEXPRESS:
                 return new AmericanExpress(context);
             case IBankTypes.MCDONALDS:
@@ -176,7 +173,6 @@ public class LegacyBankFactory {
         banks.add(new SevenDay(context));
         banks.add(new Osuuspankki(context));
         banks.add(new CSN(context));
-        banks.add(new ResursBank(context));
         banks.add(new McDonalds(context));
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
deleted file mode 100644
index 116a1f8..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class ResursBank extends Bank {
-
-    private Pattern reAccounts = Pattern.compile(
-            "kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactions = Pattern.compile(
-            "<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</",
-            Pattern.CASE_INSENSITIVE);
-
-    private String response = null;
-
-    public ResursBank(Context context) {
-        super(context, R.drawable.logo_resursbank);
-        super.TAG = "ResursBank";
-        super.NAME = "Resurs Bank";
-        super.NAME_SHORT = "resursbank";
-        super.BANKTYPE_ID = IBankTypes.RESURSBANK;
-        super.URL = "https://secure.resurs.se/internetbank/default.jsp";
-    }
-
-    public ResursBank(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_resursbank));
-        response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("kontonummer", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        postData.add(new BasicNameValuePair("page", "privat"));
-        return new LoginPackage(urlopen, postData, response,
-                "https://secure.resurs.se/internetbank/login.jsp");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-        if (response.contains("vid inloggningen")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        Matcher matcher = reAccounts.matcher(response);
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Account number        0000000000000000
-             * 2: Beviljad kredit       0,00 kr
-             * 3: Utnyttjad kredit      0,00 kr
-             * 4: Reserverat  belopp    0,00 kr
-             * 5: Kvar att utnyttja     0,00 kr
-             *
-             */
-            String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll(
-                    "[^0-9]*", "");
-            accounts.add(new Account("Beviljad kredit",
-                    Helpers.parseBalance(matcher.group(2)),
-                    "b_" + accountId));
-
-            BigDecimal utnyttjad = Helpers.parseBalance(matcher.group(3));
-            utnyttjad = utnyttjad.add(Helpers.parseBalance(matcher.group(4)));
-            utnyttjad = utnyttjad.negate();
-            accounts.add(new Account("Utnyttjad kredit",
-                    utnyttjad,
-                    "u_" + accountId));
-
-            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-            balance = balance.add(utnyttjad);
-            accounts.add(new Account("Reserverat belopp",
-                    Helpers.parseBalance(matcher.group(4)),
-                    "r_" + accountId));
-            accounts.add(new Account("Disponibelt",
-                    Helpers.parseBalance(matcher.group(5)),
-                    "k_" + accountId));
-        }
-
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        // Only update transactions for the main account
-        if (!account.getId().startsWith("b_")) {
-            return;
-        }
-
-        response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
-        Matcher matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Date                  2010-04-17
-             * 2: Transaction           ONOFF L+äNNA
-             * 3: Currency              always null?
-             * 4: Amount                -95,00 kr
-             *
-             */
-            transactions.add(new Transaction(matcher.group(1),
-                    Html.fromHtml(matcher.group(2)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(4))));
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index d4272b1..e97231a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -40,7 +40,6 @@ public interface IBankTypes {
     int SEVENDAY = 26;
     int OSUUSPANKKI = 27;
     int CSN = 29;
-    int RESURSBANK = 30;
     int AMERICANEXPRESS = 31;
     int MCDONALDS = 32;
     int PLUSGIROT = 40;
diff --git bankdroid-legacy/src/main/res/drawable/logo_resursbank.png bankdroid-legacy/src/main/res/drawable/logo_resursbank.png
deleted file mode 100644
index 2ab7e88..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_resursbank.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_resursbank.pem bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
deleted file mode 100644
index 73c1371..0000000
--- bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
+++ /dev/null
@@ -1,32 +0,0 @@
------BEGIN CERTIFICATE-----

-W/XNhjLrhdvTh2RAciWb01s=
------END CERTIFICATE-----
-secure.resurs.se:443

commit a832c0bc7ac3dd76357f5a0a78af182815e8bc57
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:40:59 2016 +0200

    Removes Volkswagen due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 625c88e..5383ece 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -37,7 +37,6 @@ import com.liato.bankdroid.banking.banks.SvenskaSpel;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.TicketRikskortet;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
-import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
@@ -108,8 +107,6 @@ public class LegacyBankFactory {
                 return new McDonalds(context);
             case IBankTypes.PLUSGIROT:
                 return new PlusGirot(context);
-            case IBankTypes.VOLKSWAGEN:
-                return new Volkswagen(context);
             case IBankTypes.IKEA:
                 return new IKEA(context);
             case IBankTypes.NORDNETDIREKT:
@@ -184,7 +181,6 @@ public class LegacyBankFactory {
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));
-        banks.add(new Volkswagen(context));
         banks.add(new IKEA(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
deleted file mode 100644
index 3bb6edb..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Volkswagen extends AbsIkanoPartner {
-
-    private static final String NAME = "Volkswagenkortet";
-
-    private static final String NAME_SHORT = "volkswagen";
-
-    private static final String URL
-            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1319";
-
-    private static final int BANKTYPE_ID = Bank.VOLKSWAGEN;
-
-    public Volkswagen(Context context) {
-        super(context, R.drawable.logo_volkswagen);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        this.structId = "1319";
-    }
-
-    public Volkswagen(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index a174b89..d4272b1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -44,7 +44,6 @@ public interface IBankTypes {
     int AMERICANEXPRESS = 31;
     int MCDONALDS = 32;
     int PLUSGIROT = 40;
-    int VOLKSWAGEN = 42;
     int IKEA = 47;
     int NORDNETDIREKT = 50;
     int DANSKEBANK = 52;
@@ -63,7 +62,6 @@ public interface IBankTypes {
     int BETTERGLOBE = 69;
     int BITCOIN = 72;
     int SVEADIREKT = 74;
-    int SUPREMECARD = 75;
     int BLEKINGETRAFIKEN = 77;
     int OSTGOTATRAFIKEN = 78;
     int BREDBAND2VOIP = 79;
diff --git bankdroid-legacy/src/main/res/drawable/logo_volkswagen.png bankdroid-legacy/src/main/res/drawable/logo_volkswagen.png
deleted file mode 100644
index 77f603e..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_volkswagen.png and /dev/null differ

commit c8aa191dbbd8e81dad77c217f228239745400e72
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:39:14 2016 +0200

    Removes Villabanken due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 5338820..625c88e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -37,7 +37,6 @@ import com.liato.bankdroid.banking.banks.SvenskaSpel;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.TicketRikskortet;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
-import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
@@ -77,8 +76,6 @@ public class LegacyBankFactory {
                 return new ICA(context);
             case IBankTypes.AVANZA:
                 return new Avanza(context);
-            case IBankTypes.VILLABANKEN:
-                return new Villabanken(context);
             case IBankTypes.AVANZAMINI:
                 return new AvanzaMini(context);
             case IBankTypes.OKQ8:
@@ -170,7 +167,6 @@ public class LegacyBankFactory {
         banks.add(new Coop(context));
         banks.add(new ICA(context));
         banks.add(new Avanza(context));
-        banks.add(new Villabanken(context));
         banks.add(new AvanzaMini(context));
         banks.add(new OKQ8(context));
         banks.add(new FirstCard(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
deleted file mode 100644
index 2518cd4..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Villabanken extends Bank {
-
-    private static final String NAME = "Villabanken";
-
-    private static final String NAME_SHORT = "villabanken";
-
-    private static final String URL
-            = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
-
-    private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
-
-    private final Pattern reDisposableAmount = Pattern.compile(
-            "<[^>]+>((?:Kvar att utnyttja:)+)[^>]+>([^<]+)");
-
-    private final Pattern reBalance = Pattern.compile(
-            "<[^>]+>((?:Utnyttjad kredit:)+)[^>]+>([^<]+)");
-
-    private final Pattern reCreditLimit = Pattern.compile(
-            "<[^>]+>((?:Beviljad kredit:)+)[^>]+>([^<]+)");
-
-    private final Pattern reTransactions = Pattern.compile(
-            "<[^>]+>(\\d{4}-\\d{2}-\\d{2})[^>]+><[^>]*>+([^<]+)<[^>]*><[^>]*>([^<]+) SEK<");
-
-    private final Pattern reRequestDigest = Pattern.compile(
-            "__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
-
-    private final Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
-
-    private final Pattern reEventValidation = Pattern.compile(
-            "__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
-
-    private final Pattern reCtl00 = Pattern.compile("\"(ctl00.*?ctl00)\"");
-
-    private String accountUrl
-            = "https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx";
-
-    private String accountResponse = null;
-
-    public Villabanken(Context context) {
-        super(context, R.drawable.logo_villabanken);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-    }
-
-    public Villabanken(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_villabanken));
-        String preLoginResponse = urlopen.open(URL);
-        Matcher matcher = reRequestDigest.matcher(preLoginResponse);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " request digest.");
-        }
-        String requestDigest = matcher.group(1);
-
-        matcher = reCtl00.matcher(preLoginResponse);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl00");
-        }
-        String ctl00 = matcher.group(1);
-
-        matcher = reViewState.matcher(preLoginResponse);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " view state.");
-        }
-        String viewState = matcher.group(1);
-
-        matcher = reEventValidation.matcher(preLoginResponse);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " event validation.");
-        }
-        String eventValidation = matcher.group(1);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
-        postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
-        postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
-        postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
-        postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
-        postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
-        postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_ExitingDesignMode", "false"));
-        postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
-        postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
-        postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
-        postData.add(new BasicNameValuePair("_wpSelected", ""));
-        postData.add(new BasicNameValuePair("_wzSelected", ""));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
-        postData.add(
-                new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_EndWebPartEditing", "false"));
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "accountNumber"), getUsername()));
-        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "password"), getPassword()));
-        postData.add(new BasicNameValuePair(ctl00, "Logga in"));
-        postData.add(new BasicNameValuePair("__spDummyText1", ""));
-        postData.add(new BasicNameValuePair("__spDummyText2", ""));
-        postData.add(new BasicNameValuePair("_wpcmWpid", ""));
-        postData.add(new BasicNameValuePair("wpcmVal", ""));
-
-        return new LoginPackage(urlopen, postData, preLoginResponse, URL);
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        String loginResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (loginResponse.contains("misslyckades")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        this.accountResponse = urlopen.open(accountUrl);
-
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-
-        Matcher matcher;
-
-        matcher = reDisposableAmount.matcher(accountResponse);
-        if (matcher.find()) {
-            Account account = new Account("Disponibelt belopp",
-                    Helpers.parseBalance(matcher.group(2)), "0");
-            account.setType(Account.CCARD);
-            account.setCurrency(currency);
-            accounts.add(account);
-            balance = balance.add(account.getBalance());
-        }
-        matcher = reBalance.matcher(accountResponse);
-        if (matcher.find()) {
-            Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
-            account.setType(Account.OTHER);
-            account.setAliasfor("Saldo alias");
-            account.setCurrency(currency);
-            accounts.add(account);
-        }
-        matcher = reCreditLimit.matcher(accountResponse);
-        if (matcher.find()) {
-            Account account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
-            account.setType(Account.OTHER);
-            account.setAliasfor("Köpgräns alias");
-            account.setCurrency(currency);
-            accounts.add(account);
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        if (account.getType() != Account.CCARD) {
-            return;
-        }
-
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        Matcher matcher = reTransactions.matcher(accountResponse);
-        while (matcher.find()) {
-            transactions.add(new Transaction(matcher.group(1), matcher.group(2),
-                    Helpers.parseBalance(matcher.group(3)).negate(), account.getCurrency()));
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 245da17..a174b89 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -28,7 +28,6 @@ public interface IBankTypes {
     int COOP = 6;
     int ICA = 7;
     int AVANZA = 9;
-    int VILLABANKEN = 10;
     int AVANZAMINI = 11;
     int OKQ8 = 12;
     int FIRSTCARD = 14;
diff --git bankdroid-legacy/src/main/res/drawable/logo_villabanken.png bankdroid-legacy/src/main/res/drawable/logo_villabanken.png
deleted file mode 100644
index 4621d48..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_villabanken.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_villabanken.pem bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
deleted file mode 100644
index 0a1c6cb..0000000
--- bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-oUqagmah9/w06kPvE1LqLw5zhZvm0A==
------END CERTIFICATE-----
-kundportal.cerdo.se:443

commit 71f0c6066a7534f5c4a42ef813f57a5c25d5faef
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:36:58 2016 +0200

    Remove SupremeCard due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 423c966..5338820 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -32,7 +32,6 @@ import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.SevenDay;
-import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
 import com.liato.bankdroid.banking.banks.TestBank;
@@ -146,8 +145,6 @@ public class LegacyBankFactory {
                 return new Bitcoin(context);
             case IBankTypes.SVEADIREKT:
                 return new SveaDirekt(context);
-            case IBankTypes.SUPREMECARD:
-                return new SupremeCard(context);
             case IBankTypes.BLEKINGETRAFIKEN:
                 return new BlekingeTrafiken(context);
             case IBankTypes.OSTGOTATRAFIKEN:
@@ -205,7 +202,6 @@ public class LegacyBankFactory {
         banks.add(new BetterGlobe(context));
         banks.add(new Bitcoin(context));
         banks.add(new SveaDirekt(context));
-        banks.add(new SupremeCard(context));
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
         banks.add(new Bredband2VoIP(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
deleted file mode 100644
index 35216cd..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class SupremeCard extends ResursBank {
-
-    public SupremeCard(Context context) {
-        super(context);
-        super.TAG = "SupremeCard";
-        super.NAME = "Supreme Card";
-        super.NAME_SHORT = "supremecard";
-        super.INPUT_TITLETEXT_USERNAME = R.string.account_number;
-        super.INPUT_TITLETEXT_PASSWORD = R.string.control_code;
-        super.BANKTYPE_ID = IBankTypes.SUPREMECARD;
-    }
-
-    public SupremeCard(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context);
-    }
-}

commit abec66cb2a000b3741134d90804b280d5a407ff9
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:32:07 2016 +0200

    Removes Skoda due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 858a7eb..423c966 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -32,7 +32,6 @@ import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.SevenDay;
-import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
@@ -115,8 +114,6 @@ public class LegacyBankFactory {
                 return new PlusGirot(context);
             case IBankTypes.VOLKSWAGEN:
                 return new Volkswagen(context);
-            case IBankTypes.SKODA:
-                return new Skoda(context);
             case IBankTypes.IKEA:
                 return new IKEA(context);
             case IBankTypes.NORDNETDIREKT:
@@ -195,7 +192,6 @@ public class LegacyBankFactory {
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));
         banks.add(new Volkswagen(context));
-        banks.add(new Skoda(context));
         banks.add(new IKEA(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
deleted file mode 100644
index 51429a7..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Skoda extends AbsIkanoPartner {
-
-    private static final String NAME = "Skodakortet";
-
-    private static final String NAME_SHORT = "skoda";
-
-    private static final String URL
-            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2461";
-
-    private static final int BANKTYPE_ID = Bank.SKODA;
-
-    public Skoda(Context context) {
-        super(context, R.drawable.logo_skoda);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        this.structId = "2461";
-    }
-
-    public Skoda(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index cbf8e1f..245da17 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -46,7 +46,6 @@ public interface IBankTypes {
     int MCDONALDS = 32;
     int PLUSGIROT = 40;
     int VOLKSWAGEN = 42;
-    int SKODA = 46;
     int IKEA = 47;
     int NORDNETDIREKT = 50;
     int DANSKEBANK = 52;
diff --git bankdroid-legacy/src/main/res/drawable/logo_skoda.png bankdroid-legacy/src/main/res/drawable/logo_skoda.png
deleted file mode 100644
index 44417e2..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_skoda.png and /dev/null differ

commit 18b282b1e9ae817adb3cad82ab40bbfdbf961aca
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:30:37 2016 +0200

    Remove shell due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 7102d78..858a7eb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -32,7 +32,6 @@ import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.SevenDay;
-import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
@@ -114,8 +113,6 @@ public class LegacyBankFactory {
                 return new McDonalds(context);
             case IBankTypes.PLUSGIROT:
                 return new PlusGirot(context);
-            case IBankTypes.SHELL:
-                return new Shell(context);
             case IBankTypes.VOLKSWAGEN:
                 return new Volkswagen(context);
             case IBankTypes.SKODA:
@@ -197,7 +194,6 @@ public class LegacyBankFactory {
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));
-        banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
deleted file mode 100644
index 768275f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Shell extends AbsIkanoPartner {
-
-    private static final String NAME = "Shell MasterCard";
-
-    private static final String NAME_SHORT = "shell";
-
-    private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
-
-    private static final int BANKTYPE_ID = Bank.SHELL;
-
-    public Shell(Context context) {
-        super(context, R.drawable.logo_shell);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        this.structId = "2035";
-    }
-
-    public Shell(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 71a6933..cbf8e1f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -45,10 +45,7 @@ public interface IBankTypes {
     int AMERICANEXPRESS = 31;
     int MCDONALDS = 32;
     int PLUSGIROT = 40;
-    int SHELL = 41;
     int VOLKSWAGEN = 42;
-    int PREEM = 44;
-    int SEAT = 45;
     int SKODA = 46;
     int IKEA = 47;
     int NORDNETDIREKT = 50;
diff --git bankdroid-legacy/src/main/res/drawable/logo_shell.png bankdroid-legacy/src/main/res/drawable/logo_shell.png
deleted file mode 100644
index 688b52a..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_shell.png and /dev/null differ

commit b49d29f849d8667221068ded496869204560473b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:28:49 2016 +0200

    Removes Seat due to bankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 4a14c96..7102d78 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -31,7 +31,6 @@ import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skoda;
@@ -119,8 +118,6 @@ public class LegacyBankFactory {
                 return new Shell(context);
             case IBankTypes.VOLKSWAGEN:
                 return new Volkswagen(context);
-            case IBankTypes.SEAT:
-                return new Seat(context);
             case IBankTypes.SKODA:
                 return new Skoda(context);
             case IBankTypes.IKEA:
@@ -202,7 +199,6 @@ public class LegacyBankFactory {
         banks.add(new Nordnetdirekt(context));
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
-        banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
         banks.add(new Vasttrafik(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
deleted file mode 100644
index 17e1006..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Seat extends AbsIkanoPartner {
-
-    private static final String NAME = "Seatkortet";
-
-    private static final String NAME_SHORT = "seat";
-
-    private static final String URL
-            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1301";
-
-    private static final int BANKTYPE_ID = Bank.SEAT;
-
-    public Seat(Context context) {
-        super(context, R.drawable.logo_seat);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        this.structId = "1301";
-    }
-
-    public Seat(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-}
diff --git bankdroid-legacy/src/main/res/drawable/logo_seat.png bankdroid-legacy/src/main/res/drawable/logo_seat.png
deleted file mode 100644
index 5c33abc..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_seat.png and /dev/null differ

commit 54ca0d5576ab7fde8ff30f6980c27c9fe51aa850
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:26:43 2016 +0200

    Remove Preem due to BankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 48dcce0..4a14c96 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -30,7 +30,6 @@ import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
-import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
@@ -120,8 +119,6 @@ public class LegacyBankFactory {
                 return new Shell(context);
             case IBankTypes.VOLKSWAGEN:
                 return new Volkswagen(context);
-            case IBankTypes.PREEM:
-                return new Preem(context);
             case IBankTypes.SEAT:
                 return new Seat(context);
             case IBankTypes.SKODA:
@@ -205,7 +202,6 @@ public class LegacyBankFactory {
         banks.add(new Nordnetdirekt(context));
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
-        banks.add(new Preem(context));
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
deleted file mode 100644
index b780868..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Preem extends AbsIkanoPartner {
-
-    private static final String NAME = "Preem Privatkort";
-
-    private static final String NAME_SHORT = "preem";
-
-    private static final String URL
-            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
-
-    private static final int BANKTYPE_ID = Bank.PREEM;
-
-    public Preem(Context context) {
-        super(context, R.drawable.logo_preem);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        this.structId = "1437";
-    }
-
-    public Preem(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-}
diff --git bankdroid-legacy/src/main/res/drawable/logo_preem.png bankdroid-legacy/src/main/res/drawable/logo_preem.png
deleted file mode 100644
index 9443e37..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_preem.png and /dev/null differ

commit c308f755ca081d62b607c23906e5336f28edbefd
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:02:58 2016 +0200

    Removes EasyCard due to BankID requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index a276416..48dcce0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -13,7 +13,6 @@ import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.DanskeBank;
-import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.Hemkop;
@@ -147,8 +146,6 @@ public class LegacyBankFactory {
                 return new Chalmrest(context);
             case IBankTypes.SVENSKASPEL:
                 return new SvenskaSpel(context);
-            case IBankTypes.EASYCARD:
-                return new EasyCard(context);
             case IBankTypes.APPEAKPOKER:
                 return new AppeakPoker(context);
             case IBankTypes.BRUMMER_KF:
@@ -219,7 +216,6 @@ public class LegacyBankFactory {
         banks.add(new Bioklubben(context));
         banks.add(new Chalmrest(context));
         banks.add(new SvenskaSpel(context));
-        banks.add(new EasyCard(context));
         banks.add(new AppeakPoker(context));
         banks.add(new Zidisha(context));
         banks.add(new BetterGlobe(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
deleted file mode 100644
index d3ff765..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class EasyCard extends Bank {
-
-    private static final String NAME = "EasyCard";
-
-    private static final String NAME_SHORT = "easycard";
-
-    private static final String URL = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
-
-    private static final int BANKTYPE_ID = IBankTypes.EASYCARD;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
-
-    private static final String INPUT_HINT_USERNAME = "XXXXXXXXX";
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_NUMBER;
-
-    private Pattern reAccounts = Pattern.compile(
-            "<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private Pattern reTransactions = Pattern.compile(
-            "<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern rePostData = Pattern.compile(
-            "<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>",
-            Pattern.CASE_INSENSITIVE);
-
-    private String response = null;
-
-    public EasyCard(Context context) {
-        super(context, R.drawable.logo_easycard);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-    }
-
-    public EasyCard(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_easycard));
-        response = urlopen.open(EasyCard.URL);
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-
-        // Find hidden required fields.
-        Matcher matcher = rePostData.matcher(response);
-
-        // Populate hidden fields
-        while (matcher.find()) {
-            // 1 == name, 2 == value
-            postData.add(new BasicNameValuePair(matcher.group(1).toString(),
-                    matcher.group(2).toString()));
-        }
-
-        // Our data + button value
-        postData.add(new BasicNameValuePair(
-                "ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", getUsername()));
-        postData.add(
-                new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$password",
-                        getPassword()));
-        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$ctl00",
-                "Logga in"));
-
-        return new LoginPackage(urlopen, postData, response, EasyCard.URL);
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-        // The string "Valuta" is always present on successful login.
-        if (response.contains("Inloggningen misslyckades")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        } else if (response.contains("sedan du") || !response.contains("Valuta")) {
-            throw new BankException(res.getText(R.string.unable_to_login).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-
-        super.update();
-
-        if (getPassword().isEmpty() || getUsername().length() != 9) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-
-        // Find account info
-        Matcher matcher = reAccounts.matcher(response);
-
-        if (matcher.find()) {
-            // Our data!
-            String account_number = matcher.group(1).toString().trim(); // 123123123
-
-            if (!account_number.equalsIgnoreCase(getUsername())) {
-                throw new BankException(res.getText(R.string.unable_to_login).toString());
-            }
-
-            BigDecimal credit_left_amount = Helpers.parseBalance(
-                    matcher.group(2).toString().trim()); // 3 748,87
-            BigDecimal credit_amount = Helpers.parseBalance(
-                    matcher.group(4).toString().trim()); // 30 000,00
-            BigDecimal credit_spent_amount = credit_amount.subtract(credit_left_amount)
-                    .negate(); // 26 251,13
-
-            // Construct accounts
-            Account credit_spent = new Account("Saldo", credit_spent_amount,
-                    getUsername() + ":saldo", Account.CCARD);
-            Account credit_left = new Account("Kredit", credit_left_amount,
-                    getUsername() + ":kredit", Account.OTHER);
-
-            accounts.add(credit_spent);
-            accounts.add(credit_left);
-        }
-
-        // No accounts found no profit...
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-
-        // Find transactions
-        Matcher matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-        while (matcher.find()) {
-            String date = matcher.group(1).toString().trim(); // 2013-01-15
-            String transaction = matcher.group(2).toString().trim(); // EBG HOSPITALITY
-            BigDecimal amount = Helpers.parseBalance(matcher.group(3).toString()); // 214,00
-
-            transactions.add(new Transaction(date, transaction, amount.negate()));
-        }
-
-        account.setTransactions(transactions);
-    }
-
-    @Override
-    public void closeConnection() {
-        super.closeConnection();
-        response = null;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index a2d86df..71a6933 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -62,7 +62,6 @@ public interface IBankTypes {
     int CHALMREST = 60;
     int AKELIUSSPAR = 62;
     int SVENSKASPEL = 63;
-    int EASYCARD = 64;
     int APPEAKPOKER = 65;
     int BRUMMER_KF = 67;
     int ZIDISHA = 68;
diff --git bankdroid-legacy/src/main/res/drawable/logo_easycard.png bankdroid-legacy/src/main/res/drawable/logo_easycard.png
deleted file mode 100644
index ee00936..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_easycard.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_easycard.pem bankdroid-legacy/src/main/res/raw/cert_easycard.pem
deleted file mode 100644
index 0a1c6cb..0000000
--- bankdroid-legacy/src/main/res/raw/cert_easycard.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-oUqagmah9/w06kPvE1LqLw5zhZvm0A==
------END CERTIFICATE-----
-kundportal.cerdo.se:443

commit 69a0f231eda54b608fb165a03d90821e8197e122
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 11:01:02 2016 +0200

    Removes Audi due to BankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index dfd4284..a276416 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -4,7 +4,6 @@ import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.americanexpress.AmericanExpress;
 import com.liato.bankdroid.banking.banks.AppeakPoker;
-import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
@@ -122,8 +121,6 @@ public class LegacyBankFactory {
                 return new Shell(context);
             case IBankTypes.VOLKSWAGEN:
                 return new Volkswagen(context);
-            case IBankTypes.AUDI:
-                return new Audi(context);
             case IBankTypes.PREEM:
                 return new Preem(context);
             case IBankTypes.SEAT:
@@ -211,7 +208,6 @@ public class LegacyBankFactory {
         banks.add(new Nordnetdirekt(context));
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
-        banks.add(new Audi(context));
         banks.add(new Preem(context));
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
deleted file mode 100644
index 678fcfa..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Audi extends AbsIkanoPartner {
-
-    private static final String NAME = "AudiKortet";
-
-    private static final String NAME_SHORT = "audi";
-
-    private static final String URL
-            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2177";
-
-    private static final int BANKTYPE_ID = Bank.AUDI;
-
-    public Audi(Context context) {
-        super(context, R.drawable.logo_audi);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        this.structId = "2177";
-    }
-
-    public Audi(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index b202a2e..a2d86df 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -47,7 +47,6 @@ public interface IBankTypes {
     int PLUSGIROT = 40;
     int SHELL = 41;
     int VOLKSWAGEN = 42;
-    int AUDI = 43;
     int PREEM = 44;
     int SEAT = 45;
     int SKODA = 46;
diff --git bankdroid-legacy/src/main/res/drawable/logo_audi.png bankdroid-legacy/src/main/res/drawable/logo_audi.png
deleted file mode 100644
index ae81cae..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_audi.png and /dev/null differ

commit bc7d5228b2e91cd49db0f33f1b45d68895ad258d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 19 10:57:06 2016 +0200

    Removes Volvofinans due to BankId requirement

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index aa15071..dfd4284 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -46,7 +46,6 @@ import com.liato.bankdroid.banking.banks.TicketRikskortet;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
 import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
-import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
@@ -109,8 +108,6 @@ public class LegacyBankFactory {
                 return new SevenDay(context);
             case IBankTypes.OSUUSPANKKI:
                 return new Osuuspankki(context);
-            case IBankTypes.VOLVOFINANS:
-                return new Volvofinans(context);
             case IBankTypes.CSN:
                 return new CSN(context);
             case IBankTypes.RESURSBANK:
@@ -206,7 +203,6 @@ public class LegacyBankFactory {
         banks.add(new Nordnet(context));
         banks.add(new SevenDay(context));
         banks.add(new Osuuspankki(context));
-        banks.add(new Volvofinans(context));
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
         banks.add(new McDonalds(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
deleted file mode 100644
index 4d76637..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-
-import android.content.Context;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-import timber.log.Timber;
-
-public class Volvofinans extends Bank {
-
-    private static final String NAME = "Volvofinans";
-
-    private static final String NAME_SHORT = "volvofinans";
-
-    private static final String URL
-            = "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html";
-
-    private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-
-    private static SimpleDateFormat DATE_PARSER = new SimpleDateFormat(
-            "EEE MMM d HH:mm:ss zzz yyyy", Locale.UK);
-
-    private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd",
-            new Locale("sv_SE"));
-
-    private HashMap<String, String> mAccountUrlMappings = new HashMap<String, String>();
-
-    public Volvofinans(Context context) {
-        super(context, R.drawable.logo_volvofinans);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-    }
-
-    public Volvofinans(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
-                R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        postData.add(new BasicNameValuePair("TARGET",
-                "https://inloggad.volvofinans.se/privat/inloggning/redirect.html"));
-        postData.add(new BasicNameValuePair("REFERER",
-                "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html"));
-        return new LoginPackage(urlopen, postData, null,
-                "https://secure.volvofinans.se/neas/KodAuth");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-        if (response.contains("Fel personr/organisationsnr och/eller lösenord.")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        if (response.contains(
-                "Internetbanken är stängd för tillfället och beräknas vara tillgänglig")) {
-            throw new LoginException(res.getText(R.string.bank_closed).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        String response = urlopen.open(
-                "https://inloggad.volvofinans.se/privat/kund/kortkonto/oversikt/kortkonton.html");
-        try {
-            JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
-            JSONArray data = object.getJSONArray("data");
-
-            int length = data.length();
-            for (int index = 0; index < length; index++) {
-                JSONObject account = data.getJSONObject(index);
-                Document d = Jsoup.parse(account.getString("namnUrl"));
-                Element e = d.getElementsByTag("a").first();
-                if (e != null && e.attr("href") != null) {
-                    mAccountUrlMappings.put(account.getString("kontonummer"),
-                            e.attr("href").replace("/info.html", "/info/kontoutdrag.html"));
-                }
-                accounts.add(new Account(String.format("%s (%s)", account.getString("namn"),
-                        account.getString("kontonummer")),
-                        Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(
-                                Helpers.parseBalance(account.getString("limit"))),
-                        account.getString("kontonummer")));
-            }
-        } catch (JSONException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        String response = null;
-        String url = mAccountUrlMappings.get(account.getId());
-        if (url != null) {
-            try {
-                response = urlopen.open("https://inloggad.volvofinans.se" + url);
-                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                account.setTransactions(transactions);
-                JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
-                JSONArray data = object.getJSONArray("data");
-
-                int length = data.length();
-                for (int index = 0; index < length; index++) {
-                    JSONObject acc = data.getJSONObject(index);
-                    String date = acc.getString("datum");
-                    try {
-                        Date d = DATE_PARSER.parse(date);
-                        date = DATE_FORMATTER.format(d);
-                    } catch (ParseException e) {
-                        Timber.w(e, "Volvofinans: Date parsing failed");
-                    }
-
-                    transactions.add(new Transaction(date, acc.getString("text"), Helpers
-                            .parseBalance(acc.getString("belopp")).negate()));
-                }
-                account.setTransactions(transactions);
-                if (accounts.isEmpty()) {
-                    throw new BankException(res.getText(R.string.no_accounts_found).toString());
-                }
-
-            } catch (JSONException e) {
-                throw new BankException(e.getMessage(), e);
-            }
-        }
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 9ca70ba..b202a2e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -40,7 +40,6 @@ public interface IBankTypes {
     int NORDNET = 25;
     int SEVENDAY = 26;
     int OSUUSPANKKI = 27;
-    int VOLVOFINANS = 28;
     int CSN = 29;
     int RESURSBANK = 30;
     int AMERICANEXPRESS = 31;
diff --git bankdroid-legacy/src/main/res/drawable/logo_volvofinans.png bankdroid-legacy/src/main/res/drawable/logo_volvofinans.png
deleted file mode 100644
index 60a8c19..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_volvofinans.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
deleted file mode 100644
index 85c5676..0000000
--- bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
+++ /dev/null
@@ -1,32 +0,0 @@
------BEGIN CERTIFICATE-----

-0o5EzaTpvLKP25NYUQA7pjdUyGhu/8+xMT+oPA==
------END CERTIFICATE-----
-secure.volvofinans.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
deleted file mode 100644
index 87e5e5e..0000000
--- bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
+++ /dev/null
@@ -1,43 +0,0 @@
------BEGIN CERTIFICATE-----

-wxPKg50QQRw8a0rHZ3EISw==
------END CERTIFICATE-----
-inloggad.volvofinans.se:443

commit 5fdb7e3aa25df54efa3e383c7846674c57c3b6e8
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Oct 17 22:12:51 2016 +0200

    Fix Instant Run
    
    This change fixes Instant Run in Android Studio 2.2.1 by upgrading the
    Android Build Tools Gradle dependency (as suggested by Android Studio)
    and by not storing Contexts in static variables (as suggested by
    Android Lint).
    
    I ran into this linter bug developing this...
    https://code.google.com/p/android/issues/detail?id=225515
    ... which I tried to work around in various ways by fixing various
    linter problems. That didn't help however, and the only thing I found
    that did help was to disable the UnusedResources lint check :(.

diff --git .travis.yml .travis.yml
index ba6f24b..6c53f33 100644
--- .travis.yml
+++ .travis.yml
@@ -16,7 +16,7 @@ android:
   components:
     - tools
     - platform-tools
-    - build-tools-24.0.1
+    - build-tools-24.0.3
     - android-24
     - extra-android-m2repository
 
diff --git app/build.gradle app/build.gradle
index 20d8d89..da46be5 100644
--- app/build.gradle
+++ app/build.gradle
@@ -35,7 +35,7 @@ ext {
 
 android {
     compileSdkVersion 24
-    buildToolsVersion "24.0.1"
+    buildToolsVersion "24.0.3"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
diff --git app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
index 3ba1a09..b72492a 100644
--- app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
+++ app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
@@ -9,6 +9,7 @@ import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 import android.widget.PopupWindow;
@@ -20,6 +21,7 @@ import android.widget.PopupWindow;
  */
 public class BetterPopupWindow {
 
+    protected final ViewGroup parentView;
     protected final View anchor;
 
     private final PopupWindow window;
@@ -35,8 +37,9 @@ public class BetterPopupWindow {
      *
      * @param anchor the view that the BetterPopupWindow will be displaying 'from'
      */
-    public BetterPopupWindow(View anchor) {
+    public BetterPopupWindow(ViewGroup parentView, View anchor) {
         this.anchor = anchor;
+        this.parentView = parentView;
         this.window = new PopupWindow(anchor.getContext());
 
         // when a touch even happens outside of the window
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index ab70eb9..5ff4724 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -149,7 +149,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
                 if (NetworkUtils.isInternetAvailable()) {
-                    Timber.e(e);
+                    Timber.e(e, "IO error talking to bank");
                 }
             }
 
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 77be2eb..c545a83 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -31,7 +31,6 @@ import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
@@ -58,8 +57,6 @@ public class MainActivity extends LockableActivity {
     @InjectView(R.id.txtAccountsDesc)
     TextView mAccountsDescription;
 
-    private final static String TAG = "MainActivity";
-
     protected static boolean showHidden = false;
 
     private static Bank selected_bank = null;
@@ -85,16 +82,17 @@ public class MainActivity extends LockableActivity {
         ButterKnife.inject(this);
 
         adapter = new AccountsAdapter(this, showHidden);
-        final ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
+        final ArrayList<Bank> banks = new ArrayList<>();
         adapter.setGroups(banks);
         final ListView lv = (ListView) findViewById(R.id.lstAccountsList);
         lv.setAdapter(adapter);
         lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+            @Override
             public boolean onItemLongClick(final AdapterView<?> parent, final View view,
                     final int position, final long id) {
                 if (adapter.getItem(position) instanceof Account) {
                     selected_account = (Account) adapter.getItem(position);
-                    final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
+                    final PopupMenuAccount pmenu = new PopupMenuAccount(parent, view, MainActivity.this);
                     pmenu.showLikeQuickAction(0, 12);
                     return true;
                 } else if (adapter.getItem(position) instanceof Bank) {
@@ -108,11 +106,12 @@ public class MainActivity extends LockableActivity {
             }
         });
         lv.setOnItemClickListener(new OnItemClickListener() {
+            @Override
             public void onItemClick(final AdapterView<?> parent, final View view,
                     final int position, final long id) {
                 if (adapter.getItem(position) instanceof Bank) {
                     selected_bank = (Bank) adapter.getItem(position);
-                    final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
+                    final PopupMenuBank pmenu = new PopupMenuBank(parent, view, MainActivity.this);
                     pmenu.showLikeQuickAction(0, 12);
                 } else {
                     final Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
@@ -173,7 +172,6 @@ public class MainActivity extends LockableActivity {
         final Dialog dialog = new Dialog(this);
         dialog.setContentView(R.layout.about);
         dialog.setTitle(getString(R.string.about));
-        PackageInfo pInfo;
         String version = BuildConfig.VERSION_NAME;
         ((TextView) dialog.findViewById(R.id.txtVersion))
                 .setText(getText(R.string.version).toString().replace("$version", version));
@@ -227,8 +225,8 @@ public class MainActivity extends LockableActivity {
 
         MainActivity parent = null;
 
-        public PopupMenuBank(final View anchor, final MainActivity parent) {
-            super(anchor);
+        public PopupMenuBank(final ViewGroup parentView, final View anchor, final MainActivity parent) {
+            super(parentView, anchor);
             this.parent = parent;
         }
 
@@ -239,7 +237,7 @@ public class MainActivity extends LockableActivity {
                     (LayoutInflater) this.anchor.getContext()
                             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
+            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, this.parentView);
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnWWW = (Button) root.findViewById(R.id.btnWWW);
@@ -305,6 +303,7 @@ public class MainActivity extends LockableActivity {
                             .setIcon(android.R.drawable.ic_dialog_alert)
                             .setPositiveButton(context.getText(R.string.yes),
                                     new DialogInterface.OnClickListener() {
+                                        @Override
                                         public void onClick(final DialogInterface dialog,
                                                 final int id) {
                                             final DBAdapter db = new DBAdapter(context);
@@ -315,6 +314,7 @@ public class MainActivity extends LockableActivity {
                                     })
                             .setNegativeButton(context.getText(R.string.no),
                                     new DialogInterface.OnClickListener() {
+                                        @Override
                                         public void onClick(final DialogInterface dialog,
                                                 final int id) {
                                             dialog.cancel();
@@ -340,8 +340,8 @@ public class MainActivity extends LockableActivity {
 
         MainActivity parent = null;
 
-        public PopupMenuAccount(final View anchor, final MainActivity parent) {
-            super(anchor);
+        public PopupMenuAccount(final ViewGroup parentView, final View anchor, final MainActivity parent) {
+            super(parentView, anchor);
             this.parent = parent;
         }
 
@@ -351,7 +351,7 @@ public class MainActivity extends LockableActivity {
                     (LayoutInflater) this.anchor.getContext()
                             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, null);
+            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, this.parentView);
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnDisableNotifications = (Button) root
diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index 1f6a153..bac0ab7 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -49,7 +49,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
 
     private final static String TAG = "WebViewActivity";
 
-    private static WebView mWebView;
+    private WebView mWebView;
 
     private final LockableActivity activity = this;
 
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
index 3bc7c6a..7a6533a 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -24,6 +24,7 @@ import android.content.Context;
 import android.graphics.PixelFormat;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 public class ColorPickerDialog
@@ -41,9 +42,13 @@ public class ColorPickerDialog
 
     private OnColorChangedListener mListener;
 
-    public ColorPickerDialog(Context context, int initialColor) {
+    private final ViewGroup mParent;
+
+    public ColorPickerDialog(ViewGroup parent, Context context, int initialColor) {
         super(context);
 
+        this.mParent = parent;
+
         init(initialColor);
     }
 
@@ -60,7 +65,7 @@ public class ColorPickerDialog
         LayoutInflater inflater = (LayoutInflater) getContext()
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-        View layout = inflater.inflate(R.layout.dialog_color_picker, null);
+        View layout = inflater.inflate(R.layout.dialog_color_picker, mParent);
 
         setContentView(layout);
 
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
index 7166e8a..2de42b7 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -23,6 +23,7 @@ import android.graphics.Color;
 import android.preference.Preference;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
@@ -42,6 +43,8 @@ public class ColorPickerPreference
 
     private static final String androidns = "http://schemas.android.com/apk/res/android";
 
+    private ViewGroup parent;
+
     View mView;
 
     int mDefaultValue = Color.BLACK;
@@ -154,6 +157,12 @@ public class ColorPickerPreference
         mValue = mDefaultValue;
     }
 
+    @Override
+    protected View onCreateView(ViewGroup parent) {
+        this.parent = parent;
+        return super.onCreateView(parent);
+    }
+
     @Override
     protected void onBindView(View view) {
         super.onBindView(view);
@@ -234,8 +243,9 @@ public class ColorPickerPreference
         }
     }
 
+    @Override
     public boolean onPreferenceClick(Preference preference) {
-        ColorPickerDialog picker = new ColorPickerDialog(getContext(), getValue());
+        ColorPickerDialog picker = new ColorPickerDialog(parent, getContext(), getValue());
         picker.setOnColorChangedListener(this);
         if (mAlphaSliderEnabled) {
             picker.setAlphaSliderVisible(true);
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index 03007ed..a5dd3f4 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -3,7 +3,7 @@ apply from: '../config/quality/quality.gradle'
 
 android {
     compileSdkVersion 24
-    buildToolsVersion "24.0.1"
+    buildToolsVersion "24.0.3"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index a86e341..ceca10f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -27,7 +27,6 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.CookieStore;
 
 import android.content.Context;
@@ -452,12 +451,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
             CookieStore cookies = urlopen.getHttpclient().getCookieStore();
             return new SessionPackage(html, cookies);
-        } catch (ClientProtocolException e) {
-            Timber.e(e);
-        } catch (IOException e) {
-            Timber.e(e);
-        } catch (BankException e) {
-            Timber.e(e);
+        } catch (IOException | BankException e) {
+            Timber.e(e, "Error getting session package");
         }
         String html = String.format(preloader,
                 String.format("function go(){window.location=\"%s\" }", this.URL),
diff --git build.gradle build.gradle
index bb0898c..8f0f520 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.2.0'
+        classpath 'com.android.tools.build:gradle:2.2.1'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 37f0cd0..3439326 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -22,7 +22,6 @@
     <issue id="IconLocation" severity="ignore" />
     <issue id="IconMissingDensityFolder" severity="ignore" />
     <issue id="InefficientWeight" severity="ignore" />
-    <issue id="InflateParams" severity="ignore" />
     <issue id="InlinedApi" severity="ignore" />
     <issue id="InvalidPackage" severity="ignore" />
     <issue id="ManifestOrder" severity="ignore" />
@@ -42,14 +41,13 @@
     <issue id="SetJavaScriptEnabled" severity="ignore" />
     <issue id="SimpleDateFormat" severity="ignore" />
     <issue id="SpUsage" severity="ignore" />
-    <issue id="StaticFieldLeak" severity="ignore" />
     <issue id="TrulyRandom" severity="ignore" />
     <issue id="TypographyEllipsis" severity="ignore" />
     <issue id="Typos" severity="ignore" />
     <issue id="UnknownIdInLayout" severity="ignore" />
     <issue id="UnusedAttribute" severity="ignore" />
+    <issue id="UnusedResources" severity="ignore" />
     <issue id="UseCompoundDrawables" severity="ignore" />
-    <issue id="UseValueOf" severity="ignore" />
     <issue id="UselessParent" severity="ignore" />
     <issue id="WorldReadableFiles" severity="ignore" />
 </lint>
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index cdb0e97..b9bb166 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -99,7 +99,6 @@
         <exclude name="TooManyMethods" />
         <exclude name="UncommentedEmptyMethodBody" />
         <exclude name="UnnecessaryConstructor" />
-        <exclude name="UnnecessaryConversionTemporary" />
         <exclude name="UnnecessaryFullyQualifiedName" />
         <exclude name="UnnecessaryLocalBeforeReturn" />
         <exclude name="UnnecessaryParentheses" />

commit a5d94f0bc414e51dab12587c316179d8e63d3694
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Tue Oct 18 22:07:50 2016 +0200

    Remove unused class MobilbankenBase
    
    MobilbankenBase was used by SparbankenOresund and SparbankenSyd, but
    these banks were removed in 3991e4d647cf9b97923dc622230d0939b68d1d63,
    leaving the base class unused.

diff --git CHANGELOG CHANGELOG
index 7b0ce94..ff0a4dc 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 Not yet released
 * Remove TrustBuddy since they're no longer in business
+* Remove unused class MobilbankenBase
 
 v1.9.10.10 (2016-10-17)
 * Fixes crash for Amex
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
deleted file mode 100644
index 0d6ab45..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.support.annotation.DrawableRes;
-import android.text.Html;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public abstract class MobilbankenBase extends Bank {
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-
-    protected String targetId;
-
-    private Pattern reTimestamp = Pattern.compile("name=\"user(\\d{1,})\"");
-
-    private Pattern reMsisdn = Pattern.compile("name=\"msisdn\"\\s*value=\"([^\"]+)\" />");
-
-    private Pattern reAccounts = Pattern.compile(
-            "accountmovement\\.html\\?account_no=([^\"]+)\">([^<]+)</a></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+><span[^>]+>([^<]+)</span></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>[^<]+<span[^>]+>([^<]+)</");
-
-    private Pattern reTransactions = Pattern.compile(
-            "<a[^>]+>([^<]+)</a>\\s*</div>\\s*<table[^>]+>\\s*<tr>\\s*<td[^>]+>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>([^<]+)</span>\\s*</td>\\s*</tr>\\s*</table>\\s*<div[^>]+>\\s*(\\d{4}\\.\\d{2}\\.\\d{2})\\s*</div>\\s*");
-
-    private String response = null;
-
-
-    public MobilbankenBase(Context context, @DrawableRes int logoResource) {
-        super(context , logoResource);
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-    }
-
-    public MobilbankenBase(String username, String password, Context context, @DrawableRes int logoResource) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context, logoResource);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
-        urlopen.setAllowCircularRedirects(true);
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        String postUrl = String.format("https://mobil-banken.se/%s/login.html", targetId);
-        response = urlopen.open(postUrl);
-        Matcher matcher = reMsisdn.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " msisdn.");
-        }
-        String msisdn = matcher.group(1);
-        matcher = reTimestamp.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " timestamp.");
-        }
-        String timestamp = matcher.group(1);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("msisdn", msisdn));
-        postData.add(new BasicNameValuePair("user" + timestamp, getUsername()));
-        postData.add(new BasicNameValuePair("password" + timestamp, getPassword()));
-        return new LoginPackage(urlopen, postData, response, postUrl);
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-        if (response.contains("eller pinkod")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        Matcher matcher = reAccounts.matcher(response);
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: ID                ?
-             * 2: Name              Sparkonto
-             * 3: Account number    9570 012.345.678-9 SEK
-             * 4: ?                 xxxxxxxxxxx
-             * 5: Amount            ?
-             *
-             */
-            accounts.add(new Account(
-                    Html.fromHtml(matcher.group(2)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(5)),
-                    matcher.group(1).trim()));
-            balance = balance.add(Helpers.parseBalance(matcher.group(5)));
-        }
-
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-
-        Matcher matcher;
-        response = urlopen.open(String
-                .format("https://mobil-banken.se/%s/accountmovement.html?account_no=%s", targetId,
-                        account.getId()));
-        matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Transaction           Kortköp QPARKSTOCKHOLM,  STOCKHOLM
-             * 2: Amount                -40,00
-             * 3: Date                  2010.12.23
-             *
-             */
-            transactions.add(new Transaction(
-                    matcher.group(3).trim().replace(".", "-"),
-                    Html.fromHtml(matcher.group(1)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(2))));
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
deleted file mode 100644
index fd7c6ee..0000000
--- bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----

-9E2iMPGN
------END CERTIFICATE-----
-mobil-banken.se:443

commit 5187e9cd472a70e54ee29f05daa678d824d8f280
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Tue Oct 18 21:24:42 2016 +0200

    Remove TrustBuddy since they're no longer in business

diff --git CHANGELOG CHANGELOG
index c4aa6e4..7b0ce94 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+Not yet released
+* Remove TrustBuddy since they're no longer in business
+
 v1.9.10.10 (2016-10-17)
 * Fixes crash for Amex
 * Strikethrough balance in widget indicates update problems. 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index f2b41b1..aa15071 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -43,7 +43,6 @@ import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.TicketRikskortet;
-import com.liato.bankdroid.banking.banks.TrustBuddy;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
 import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
@@ -158,8 +157,6 @@ public class LegacyBankFactory {
                 return new EasyCard(context);
             case IBankTypes.APPEAKPOKER:
                 return new AppeakPoker(context);
-            case IBankTypes.TRUSTBUDDY:
-                return new TrustBuddy(context);
             case IBankTypes.BRUMMER_KF:
                 return new BrummerKF(context);
             case IBankTypes.ZIDISHA:
@@ -191,7 +188,6 @@ public class LegacyBankFactory {
         List<Bank> banks = new ArrayList<>();
         banks.add(new AkeliusInvest(context));
         banks.add(new AkeliusSpar(context));
-        banks.add(new TrustBuddy(context));
         banks.add(new BrummerKF(context));
         banks.add(new Nordea(context));
         banks.add(new Lansforsakringar(context));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
deleted file mode 100644
index c19925a..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>, first version by Snah@Swedroid 2012-01-06
- * Modified for TrustBuddy by Per Wigren <per.wigren@gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class TrustBuddy extends Bank {
-
-    private static final String NAME = "TrustBuddy";
-
-    private static final String NAME_SHORT = "trustbuddy";
-
-    private static final String URL = "https://www.trustbuddy.com/";
-
-    private static final int BANKTYPE_ID = IBankTypes.TRUSTBUDDY;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
-
-    private static final String INPUT_HINT_USERNAME = "Your email";
-
-    private static final boolean STATIC_BALANCE = true;
-
-    private Pattern reError = Pattern.compile("<h3>error\\s*:\\s*</h3>\\s*<p>\\s*(.*?)\\s*</p>",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private Pattern reAccounts = Pattern.compile(
-            "<h1>\\s*([^<]+).*?>Balans: ([0-9, ]+) ([A-Z]{3})<",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    public TrustBuddy(Context context) {
-        super(context, R.drawable.logo_trustbuddy);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public TrustBuddy(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
-        urlopen.setAllowCircularRedirects(true);
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        postData.add(new BasicNameValuePair("logon", "Logga in"));
-        return new LoginPackage(urlopen, postData, null, "https://trustbuddy.com/se/logga_in/");
-    }
-
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        Matcher matcher = reError.matcher(response);
-        if (matcher.find()) {
-            String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-            if (errormsg.contains("Felaktigt")) {
-                throw new LoginException(errormsg);
-            } else {
-                throw new BankException(errormsg);
-            }
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        String response = urlopen.open("https://trustbuddy.com/se/din_sida/");
-        Matcher matcher = reAccounts.matcher(response);
-
-        while (matcher.find()) {
-            /*
-             * 1: Land
-             * 2: Saldo
-             * 3: Valuta
-             */
-            Account temp = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(2).trim()), matcher.group(1).toLowerCase());
-            temp.setCurrency(matcher.group(3));
-            accounts.add(temp);
-
-            balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 24258c3..9ca70ba 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -66,7 +66,6 @@ public interface IBankTypes {
     int SVENSKASPEL = 63;
     int EASYCARD = 64;
     int APPEAKPOKER = 65;
-    int TRUSTBUDDY = 66;
     int BRUMMER_KF = 67;
     int ZIDISHA = 68;
     int BETTERGLOBE = 69;
diff --git bankdroid-legacy/src/main/res/drawable/logo_trustbuddy.png bankdroid-legacy/src/main/res/drawable/logo_trustbuddy.png
deleted file mode 100644
index 9ef035c..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_trustbuddy.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
deleted file mode 100644
index 6a8a9c4..0000000
--- bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
+++ /dev/null
@@ -1,43 +0,0 @@
------BEGIN CERTIFICATE-----

-NkPZyQ==
------END CERTIFICATE-----
-trustbuddy.com:443

commit 530fa103baa21fff8286e75ee1e87b29958edb71
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Oct 18 17:38:25 2016 +0200

    Fixes failing quality checks

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index 3bd978d..ad41c8f 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -82,7 +82,7 @@ public class FieldBuilder {
         return this;
     }
 
-    private class BasicField implements Field {
+    private static class BasicField implements Field {
 
         private ResourceBundle resourceBundle;
 
@@ -148,7 +148,7 @@ public class FieldBuilder {
         public List<Entry> getValues() {
             if(values == null) {
                 values = Collections.emptyList();
-            };
+            }
             return values;
         }
 
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java
index d1bf8b8..07c7cfc 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java
@@ -1,7 +1,6 @@
 package com.liato.bankdroid.api.domain.account;
 
 import java.math.BigDecimal;
-import java.util.Collection;
 import java.util.Map;
 
 /**
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
index 92ed3ac..bd1a3e8 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
@@ -47,7 +47,7 @@ public class EquityBuilder {
     }
 
 
-    private class BasicEquity implements Equity {
+    private static class BasicEquity implements Equity {
 
         private String mName;
 
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
index 658b8fa..d99e715 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
@@ -47,7 +47,7 @@ public class LiabilityAccountBuilder extends AbstractAccountBuilder<LiabilityAcc
                 mInterest, mPayments);
     }
 
-    private class BasicLiabilityAccount extends BasicAccount implements LiabilityAccount {
+    private static class BasicLiabilityAccount extends BasicAccount implements LiabilityAccount {
 
         private double mInterest;
         private Collection<Payment> mPayments;
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
index 4310d90..641fd7e 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
@@ -36,7 +36,7 @@ public class PrePaidCardAccountBuilder extends AbstractAccountBuilder<PrePaidCar
                 mExpirationDate, mValidFrom);
     }
 
-    private class BasicPrePaidCardAccount extends BasicAccount implements PrePaidCardAccount {
+    private static class BasicPrePaidCardAccount extends BasicAccount implements PrePaidCardAccount {
 
         private DateTime mExpirationDate;
         private DateTime mValidFrom;
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
index e42d107..00e1e2f 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
@@ -41,7 +41,7 @@ public class TransactionAccountBuilder extends AbstractAccountBuilder<Transactio
                 mTransactions);
     }
 
-    private class BasicTransactionAccount extends BasicAccount implements TransactionAccount {
+    private static class BasicTransactionAccount extends BasicAccount implements TransactionAccount {
 
         private Collection<Transaction> mTransactions;
 
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java
index 194dfe3..377f3c3 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java
@@ -29,7 +29,7 @@ public class TransactionBuilder {
         return mTransaction;
     }
 
-    private class BasicTransaction implements Transaction {
+    private static class BasicTransaction implements Transaction {
 
         private BigDecimal amount;
         private String description;

commit 100411273bc1ad46cd244b57eef31ba4b024cb69
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Oct 18 17:37:56 2016 +0200

    Enable quality checks for all modules

diff --git bankdroid-core/build.gradle bankdroid-core/build.gradle
index e31a6ba..4238b1f 100644
--- bankdroid-core/build.gradle
+++ bankdroid-core/build.gradle
@@ -1,5 +1,5 @@
 apply plugin: 'java'
-
+apply from: '../config/quality/quality.gradle'
 sourceCompatibility = JavaVersion.VERSION_1_7
 targetCompatibility = JavaVersion.VERSION_1_7
 
diff --git bankdroid-interface/build.gradle bankdroid-interface/build.gradle
index 248d29c..a63f037 100644
--- bankdroid-interface/build.gradle
+++ bankdroid-interface/build.gradle
@@ -1,5 +1,5 @@
 apply plugin: 'java'
-
+apply from: '../config/quality/quality.gradle'
 sourceCompatibility = JavaVersion.VERSION_1_7
 targetCompatibility = JavaVersion.VERSION_1_7
 
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 6e053f2..a69b301 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -3,12 +3,9 @@ apply plugin: 'findbugs'
 apply plugin: 'pmd'
 
 // Add checkstyle, findbugs and lint to the check task.
-check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'lint'
+check.dependsOn 'checkstyle', 'findbugs', 'pmd'
 
 task checkstyle(type: Checkstyle) {
-    configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
-    configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
-
     source 'src'
     include '**/*.java'
     classpath = files()
@@ -17,30 +14,14 @@ task checkstyle(type: Checkstyle) {
 checkstyle {
     toolVersion '6.1.1' // TODO https://github.com/jshiell/checkstyle-idea/blob/dbe595028c3488400790e6caed2f122fba0bded1/README#L13-19
     ignoreFailures false
+    configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
+    configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
 }
 
-android {
-    lintOptions {
-        abortOnError true
-        warningsAsErrors true
-
-        // FIXME: This file contains *far* too many disabled checks. Somebody think of the children!
-        lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
-
-        textOutput "stdout"
-        textReport true
-
-        htmlReport true
-        // optional path to report (default will be lint-results.html in the builddir)
-        htmlOutput file("$project.buildDir/reports/lint/lint.html")
-    }
-}
-
-task findbugs(type: FindBugs, dependsOn: 'compileDebugSources') {
+task findbugs(type: FindBugs) {
     effort = "max"
     reportLevel = "high"
     excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")
-    classes = files("$project.buildDir/intermediates/classes")
 
     source 'src'
     include '**/*.java'
@@ -81,3 +62,29 @@ task pmd(type: Pmd) {
         }
     }
 }
+
+if(plugins.hasPlugin('android') || plugins.hasPlugin('com.android.library')) {
+    check.dependsOn 'lint'
+    tasks.getByName("findbugs").dependsOn 'compileDebugSources'
+    tasks.getByName('findbugs').classes = files("$project.buildDir/intermediates/classes")
+    android {
+        lintOptions {
+            abortOnError true
+            warningsAsErrors true
+
+            // FIXME: This file contains *far* too many disabled checks. Somebody think of the children!
+            lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
+
+            textOutput "stdout"
+            textReport true
+
+            htmlReport true
+            // optional path to report (default will be lint-results.html in the builddir)
+            htmlOutput file("$project.buildDir/reports/lint/lint.html")
+        }
+    }
+}
+if(plugins.hasPlugin('java')) {
+    tasks.getByName('findbugs').classes = files("$project.buildDir/classes")
+    tasks.getByName('findbugs').dependsOn 'classes'
+}

commit 760611e10a3be4bf63affbd618c363bdc365e9d9 (tag: v1.9.10.10)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 17 22:07:13 2016 +0200

    Create release v1.9.10.10

diff --git CHANGELOG CHANGELOG
index fe5edba..c4aa6e4 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.10 (2016-10-17)
+* Fixes crash for Amex
+* Strikethrough balance in widget indicates update problems. 
+
 v1.9.10.9 (2016-10-12)
 * Länsförsäkringar: Remove broken web links
 * Improve Javadocs in the Bank class

commit 90ab0728e0b8b53899241c72dd0ee63874ed3939
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 17 21:52:48 2016 +0200

    Update ignore list for PMD and lint checks

diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 22f5563..37f0cd0 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -17,7 +17,6 @@
     <issue id="GradleDependency" severity="ignore" />
     <issue id="GradleDynamicVersion" severity="ignore" />
     <issue id="HardcodedText" severity="ignore" />
-    <issue id="HardwareIds" severity="ignore" />
     <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
     <issue id="IconLocation" severity="ignore" />
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index f065d55..cdb0e97 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -13,7 +13,6 @@
     <rule ref="rulesets/internal/all-java.xml">
         <exclude name="AbstractNaming" />
         <exclude name="AccessorClassGeneration" />
-        <exclude name="AddEmptyString" />
         <exclude name="AppendCharacterWithChar" />
         <exclude name="ArrayIsStoredDirectly" />
         <exclude name="AssignmentInOperand" />
@@ -49,19 +48,16 @@
         <exclude name="CyclomaticComplexity" />
         <exclude name="DataflowAnomalyAnalysis" />
         <exclude name="DefaultPackage" />
-        <exclude name="DoNotThrowExceptionInFinally" />
         <exclude name="DoNotUseThreads" />
         <exclude name="EmptyCatchBlock" />
         <exclude name="EmptyIfStmt" />
         <exclude name="EmptyMethodInAbstractClassShouldBeAbstract" />
-        <exclude name="ExceptionAsFlowControl" />
         <exclude name="ExcessiveClassLength" />
         <exclude name="ExcessiveImports" />
         <exclude name="ExcessiveMethodLength" />
         <exclude name="ExcessiveParameterList" />
         <exclude name="ExcessivePublicCount" />
         <exclude name="FieldDeclarationsShouldBeAtStartOfClass" />
-        <exclude name="FinalFieldCouldBeStatic" />
         <exclude name="GodClass" />
         <exclude name="ImmutableField" />
         <exclude name="InefficientStringBuffering" />
@@ -72,11 +68,9 @@
         <exclude name="LocalVariableCouldBeFinal" />
         <exclude name="LongVariable" />
         <exclude name="LooseCoupling" />
-        <exclude name="LoosePackageCoupling" />
         <exclude name="MethodArgumentCouldBeFinal" />
         <exclude name="MethodNamingConventions" />
         <exclude name="MissingBreakInSwitch" />
-        <exclude name="MissingSerialVersionUID" />
         <exclude name="ModifiedCyclomaticComplexity" />
         <exclude name="NPathComplexity" />
         <exclude name="NcssMethodCount" />
@@ -103,7 +97,6 @@
         <exclude name="TooFewBranchesForASwitchStatement" />
         <exclude name="TooManyFields" />
         <exclude name="TooManyMethods" />
-        <exclude name="UncommentedEmptyConstructor" />
         <exclude name="UncommentedEmptyMethodBody" />
         <exclude name="UnnecessaryConstructor" />
         <exclude name="UnnecessaryConversionTemporary" />

commit 3991e4d647cf9b97923dc622230d0939b68d1d63
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 17 21:49:54 2016 +0200

    Remove unused banks

diff --git app/src/main/java/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
index 2e54b30..95d08cd 100644
--- app/src/main/java/com/liato/bankdroid/SettingsActivity.java
+++ app/src/main/java/com/liato/bankdroid/SettingsActivity.java
@@ -19,8 +19,8 @@ package com.liato.bankdroid;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
-import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
 import com.liato.bankdroid.lockpattern.ChooseLockPattern;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
@@ -127,7 +127,7 @@ public class SettingsActivity extends LockablePreferenceActivity
         } else if ("test_notification".equals(prefKey)) {
             Timber.d("Sending test notification.");
             Account account1 = new Account("Personkonto", new BigDecimal(8351.00), "22");
-            Bank bank1 = new Swedbank(this);
+            Bank bank1 = new TestBank(this);
             bank1.setDbid(21);
             bank1.setCustomName("800416-0001");
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 2e610f1..f2b41b1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -76,22 +76,14 @@ public class LegacyBankFactory {
                 return new AkeliusInvest(context);
             case IBankTypes.AKELIUSSPAR:
                 return new AkeliusSpar(context);
-            // case IBankTypes.SWEDBANK:
-            //     return new Swedbank(context);
             case IBankTypes.NORDEA:
                 return new Nordea(context);
             case IBankTypes.LANSFORSAKRINGAR:
                 return new Lansforsakringar(context);
-            // case IBankTypes.ICABANKEN:
-            //    return new ICABanken(context);
-            // case IBankTypes.HANDELSBANKEN:
-            //     return new Handelsbanken(context);
             case IBankTypes.COOP:
                 return new Coop(context);
             case IBankTypes.ICA:
                 return new ICA(context);
-            // case IBankTypes.STATOIL:
-            //    return new Statoil(context);
             case IBankTypes.AVANZA:
                 return new Avanza(context);
             case IBankTypes.VILLABANKEN:
@@ -100,34 +92,18 @@ public class LegacyBankFactory {
                 return new AvanzaMini(context);
             case IBankTypes.OKQ8:
                 return new OKQ8(context);
-            // case IBankTypes.EUROCARD:
-            //     return new Eurocard(context);
             case IBankTypes.FIRSTCARD:
                 return new FirstCard(context);
-            // case IBankTypes.PAYPAL:
-            //     return new PayPal(context);
             case IBankTypes.PAYSON:
                 return new Payson(context);
             case IBankTypes.JOJO:
                 return new Jojo(context);
-            // case IBankTypes.STEAM:
-            //    return new Steam(context);
-            // case IBankTypes.DINERSCLUB:
-            //    return new DinersClub(context);
             case IBankTypes.IKANOBANK:
                 return new IkanoBank(context);
-            //  case IBankTypes.SASEUROBONUSMASTERCARD:
-            //      return new EurobonusMastercard(context);
-            //  case IBankTypes.SASEUROBONUSMASTERCARD_NO:
-            //      return new EurobonusMastercardNo(context);
-            //  case IBankTypes.SASEUROBONUSMASTERCARD_DK:
-            //      return new EurobonusMastercardDk(context);
             case IBankTypes.RIKSLUNCHEN:
                 return new Rikslunchen(context);
             case IBankTypes.HEMKOP:
                 return new Hemkop(context);
-            // case IBankTypes.SEB:
-            //     return new SEB(context);
             case IBankTypes.NORDNET:
                 return new Nordnet(context);
             case IBankTypes.SEVENDAY:
@@ -144,20 +120,6 @@ public class LegacyBankFactory {
                 return new AmericanExpress(context);
             case IBankTypes.MCDONALDS:
                 return new McDonalds(context);
-            // case IBankTypes.SAAB:
-            //     return new Saab(context);
-            // case IBankTypes.WALLET:
-            //     return new Wallet(context);
-            //  case IBankTypes.CHEVROLET:
-            //      return new Chevrolet(context);
-            //  case IBankTypes.SJPRIO:
-            //      return new SJPrio(context);
-            //  case IBankTypes.OPEL:
-            //      return new Opel(context);
-            // case IBankTypes.DJURGARDEN:
-            //     return new Djurgarden(context);
-            //   case IBankTypes.QUINTESSENTIALLY:
-            //       return new Quintessentially(context);
             case IBankTypes.PLUSGIROT:
                 return new PlusGirot(context);
             case IBankTypes.SHELL:
@@ -174,18 +136,10 @@ public class LegacyBankFactory {
                 return new Skoda(context);
             case IBankTypes.IKEA:
                 return new IKEA(context);
-            // case IBankTypes.SPARBANKEN_SYD:
-            //     return new SparbankenSyd(context);
-            // case IBankTypes.SPARBANKEN_ORESUND:
-            //    return new SparbankenOresund(context);
             case IBankTypes.NORDNETDIREKT:
                 return new Nordnetdirekt(context);
-            // case IBankTypes.SKANDIABANKEN:
-            //    return new Skandiabanken(context);
             case IBankTypes.DANSKEBANK:
                 return new DanskeBank(context);
-            // case IBankTypes.NORDEA_DK:
-            //     return new NordeaDK(context);
             case IBankTypes.VASTTRAFIK:
                 return new Vasttrafik(context);
             case IBankTypes.EVERYDAYCARD:
@@ -198,8 +152,6 @@ public class LegacyBankFactory {
                 return new Bioklubben(context);
             case IBankTypes.CHALMREST:
                 return new Chalmrest(context);
-            // case IBankTypes.MARGINALEN:
-            //     return new Marginalen(context);
             case IBankTypes.SVENSKASPEL:
                 return new SvenskaSpel(context);
             case IBankTypes.EASYCARD:
@@ -214,34 +166,20 @@ public class LegacyBankFactory {
                 return new Zidisha(context);
             case IBankTypes.BETTERGLOBE:
                 return new BetterGlobe(context);
-           // case IBankTypes.FOREX:
-           //     return new ForexBank(context);
             case IBankTypes.BITCOIN:
                 return new Bitcoin(context);
             case IBankTypes.SVEADIREKT:
                 return new SveaDirekt(context);
             case IBankTypes.SUPREMECARD:
                 return new SupremeCard(context);
-            // case IBankTypes.SPARBANKERNA:
-            //     return new Sparbankerna(context);
             case IBankTypes.BLEKINGETRAFIKEN:
                 return new BlekingeTrafiken(context);
             case IBankTypes.OSTGOTATRAFIKEN:
                 return new Ostgotatrafiken(context);
             case IBankTypes.BREDBAND2VOIP:
                 return new Bredband2VoIP(context);
-            // case IBankTypes.ESPRESSOHOUSE:
-            //    return new EspressoHouse(context);
             case IBankTypes.MINPENSION:
                 return new MinPension(context);
-            // case IBankTypes.SPARBANKERNA_CORPORATE:
-            //    return new SparbankernaCorporate(context);
-            // case IBankTypes.SPARBANKERNA_YOUTH:
-            //    return new SparbankernaYouth(context);
-            // case IBankTypes.SWEDBANK_CORPORATE:
-            //    return new SwedbankCorporate(context);
-            // case IBankTypes.SWEDBANK_YOUTH:
-            //    return new SwedbankYouth(context);
             case IBankTypes.HORS:
                 return new Hors(context);
             default:
@@ -255,30 +193,20 @@ public class LegacyBankFactory {
         banks.add(new AkeliusSpar(context));
         banks.add(new TrustBuddy(context));
         banks.add(new BrummerKF(context));
-        // banks.add(new Swedbank(context));
         banks.add(new Nordea(context));
-        // banks.add(new ICABanken(context));
         banks.add(new Lansforsakringar(context));
-        // banks.add(new Handelsbanken(context));
         banks.add(new Coop(context));
         banks.add(new ICA(context));
-        // banks.add(new Statoil(context));
         banks.add(new Avanza(context));
         banks.add(new Villabanken(context));
         banks.add(new AvanzaMini(context));
         banks.add(new OKQ8(context));
-        // banks.add(new Eurocard(context));
         banks.add(new FirstCard(context));
-        // banks.add(new PayPal(context));
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
-        // banks.add(new Steam(context));
-        // banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
-        // banks.add(new EurobonusMastercard(context));
         banks.add(new Rikslunchen(context));
         banks.add(new Hemkop(context));
-        // banks.add(new SEB(context));
         banks.add(new Nordnet(context));
         banks.add(new SevenDay(context));
         banks.add(new Osuuspankki(context));
@@ -286,19 +214,9 @@ public class LegacyBankFactory {
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
         banks.add(new McDonalds(context));
-        // banks.add(new SJPrio(context));
-        // banks.add(new SparbankenSyd(context));
-        // banks.add(new SparbankenOresund(context));
-        // banks.add(new Opel(context));
-        // banks.add(new Skandiabanken(context));
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));
-        // banks.add(new Saab(context));
-        // banks.add(new Wallet(context));
-        // banks.add(new Chevrolet(context));
-        // banks.add(new Djurgarden(context));
-        // banks.add(new Quintessentially(context));
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
         banks.add(new Audi(context));
@@ -306,36 +224,24 @@ public class LegacyBankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
-        // banks.add(new DanskeBank(context));
-        // banks.add(new NordeaDK(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
         banks.add(new Meniga(context));
         banks.add(new TicketRikskortet(context));
         banks.add(new Bioklubben(context));
         banks.add(new Chalmrest(context));
-        // banks.add(new Marginalen(context));
         banks.add(new SvenskaSpel(context));
         banks.add(new EasyCard(context));
         banks.add(new AppeakPoker(context));
         banks.add(new Zidisha(context));
         banks.add(new BetterGlobe(context));
-        //banks.add(new ForexBank(context));
-        // banks.add(new EurobonusMastercardNo(context));
         banks.add(new Bitcoin(context));
-        // banks.add(new EurobonusMastercardDk(context));
         banks.add(new SveaDirekt(context));
         banks.add(new SupremeCard(context));
-        // banks.add(new Sparbankerna(context));
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
         banks.add(new Bredband2VoIP(context));
-        // banks.add(new EspressoHouse(context));
         banks.add(new MinPension(context));
-        // banks.add(new SparbankernaCorporate(context));
-        // banks.add(new SparbankernaYouth(context));
-        // banks.add(new SwedbankCorporate(context));
-        // banks.add(new SwedbankYouth(context));
         banks.add(new Hors(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
deleted file mode 100644
index de3abd3..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Chevrolet extends SEBKortBase {
-
-    private static final String NAME = "Chevrolet Big Plus Card";
-
-    private static final String NAME_SHORT = "chevrolet";
-
-    private static final int BANKTYPE_ID = Bank.CHEVROLET;
-
-    public Chevrolet(Context context) {
-        super(context, "chse", "0086", R.drawable.logo_chevrolet);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Chevrolet(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "chse", "0086", R.drawable.logo_chevrolet);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
deleted file mode 100644
index 1baec10..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class DinersClub extends Bank {
-
-    private static final String NAME = "Diners Club";
-
-    private static final String NAME_SHORT = "dinersclub";
-
-    private static final String URL = "https://secure.dinersclub.se/dcs/login.aspx";
-
-    private static final int BANKTYPE_ID = IBankTypes.DINERSCLUB;
-
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-
-    private Pattern reEventValidation = Pattern
-            .compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-
-    private Pattern reBalance = Pattern.compile(
-            "class=\"card\"[^>]+>\\s*<div[^>]+>\\s*<b>([^<]+)</b>\\s*<br ?/>\\s*<span[^>]+>([^<]+)</span>\\s*</div>\\s*<div[^>]+>\\s*<strong[^>]+>[^<]+</strong>([^<]+)</div>",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reInvoices = Pattern.compile(
-            "<tr[^>]+>\\s*<td class=\"right\">\\s*<a href='((Invoice|Nonbilled).aspx\\?card=\\d+&bdate=[\\d-]+)'>",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactions = Pattern.compile(
-            "<tr[^>]+>\\s*<td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*([\\d-]+)\\s*</a>\\s*</td><td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td><td class=\"right\">\\s*(?:<span[^>]+>\\s*<a[^>]+>([^<]+)</a></span>\\s*)?</td><td class=\"right\">\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td>\\s*</tr>",
-            Pattern.CASE_INSENSITIVE);
-
-    private String response = null;
-
-    private String invoiceUrl;
-
-    public DinersClub(Context context) {
-        super(context, R.drawable.logo_dinersclub);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-    }
-
-    public DinersClub(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
-        response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
-
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
-        }
-        String viewState = matcher.group(1);
-
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
-        }
-        String eventValidation = matcher.group(1);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$UserName", getUsername()));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", getPassword()));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
-
-        return new LoginPackage(urlopen, postData, response,
-                "https://secure.dinersclub.se/dcs/login.aspx");
-    }
-
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("Har du glömt ditt lösenord")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        if (!"https://secure.dinersclub.se/dcs/eSaldo/Default.aspx".equalsIgnoreCase(
-                urlopen.getCurrentURI())) {
-            try {
-                response = urlopen.open("https://secure.dinersclub.se/dcs/eSaldo/Default.aspx");
-            } catch (ClientProtocolException e) {
-                throw new BankException(e.getMessage(), e);
-            } catch (IOException e) {
-                throw new BankException(e.getMessage(), e);
-            }
-        }
-
-        Matcher matcher = reBalance.matcher(response);
-        if (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Name              Privatkort
-             * 2: Card number       1234 789456 741
-             * 3: Balance           3.331,79 kr
-             *
-             */
-            accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(3)), "1"));
-            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-
-        /* Detect invoice dates - needed to find the transactions */
-        matcher = reInvoices.matcher(response);
-        if (matcher.find()) {
-            invoiceUrl = matcher.group(1);
-        } else {
-            invoiceUrl = null;
-        }
-
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        String response = null;
-        Matcher matcher;
-
-        /* We're going to look at all the pages until we find one that has transactions on it */
-        response = urlopen.open(
-                String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
-        matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-        while (matcher.find()) {
-                        /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Trans. date        2010-10-06
-             * 2: Specifications    Skyways Express Ab
-             * 3: Foreign amount    30,30 EUR
-             * 4: Amount            2.462,00 kr
-             */
-
-            transactions.add(new Transaction(matcher.group(1), matcher.group(2),
-                    Helpers.parseBalance(matcher.group(4))));
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
deleted file mode 100644
index 6440247..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Djurgarden extends SEBKortBase {
-
-    private static final String NAME = "Djurgårdskortet MasterCard";
-
-    private static final String NAME_SHORT = "djurgarden";
-
-    private static final int BANKTYPE_ID = Bank.DJURGARDEN;
-
-    public Djurgarden(Context context) {
-        super(context, "djse", "0116", R.drawable.logo_djurgarden);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Djurgarden(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "djse", "0116", R.drawable.logo_djurgarden);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
deleted file mode 100644
index e1c4468..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-
-import android.content.Context;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import eu.nullbyte.android.urllib.Urllib;
-
-public class EspressoHouse extends Bank {
-
-    private static final String API_URL = "http://www.espressohouse.com/coffee-card/min-sida/";
-
-    private Document dResponse = null;
-
-    public EspressoHouse(Context context) {
-        super(context, R.drawable.logo_espressohouse);
-        NAME = "Espresso House";
-        NAME_SHORT = "espressohouse";
-        BANKTYPE_ID = IBankTypes.ESPRESSOHOUSE;
-        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
-                | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-        INPUT_TITLETEXT_USERNAME = R.string.email;
-    }
-
-    public EspressoHouse(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            IOException {
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        urlopen = new Urllib(context);
-        urlopen.setFollowRedirects(false);
-        postData.add(new BasicNameValuePair("__EVENTTARGET",
-                "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$LoginButton"));
-        postData.add(new BasicNameValuePair(
-                "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$UserName",
-                getUsername()));
-        postData.add(new BasicNameValuePair(
-                "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$Password",
-                getPassword()));
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(
-                "http://www.espressohouse.com/coffee-card/logga-inladda/", postData, true);
-        LoginPackage lp = new LoginPackage(urlopen, postData, null, API_URL);
-        if (httpResponse.getStatusLine().getStatusCode() == 302) {
-            lp.setIsLoggedIn(true);
-        }
-        return lp;
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        if (!lp.isLoggedIn()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        String response = urlopen.open(API_URL);
-        dResponse = Jsoup.parse(response);
-        String card = dResponse.select(".transactionCardNumber").first().text().trim();
-        String cardNo = card.split(":")[1].trim();
-        String balance = dResponse.select(".balanceAmount").first().text();
-        balance = balance.substring(0, balance.length() - 2);
-        accounts.add(new Account(card,
-                Helpers.parseBalance(balance),
-                cardNo, Account.REGULAR, "SEK"));
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen)
-            throws LoginException, BankException {
-        List<Element> eBalance = dResponse.select(".lineTotalAmount");
-        List<Element> eTransaction = dResponse.select(".lineTime");
-        List<Transaction> transactions = new ArrayList<>();
-        for (int i = 0; i < eTransaction.size() && i < eBalance.size(); i++) {
-            String s = eTransaction.get(i).text();
-            String balance = eBalance.get(i).text();
-            if (balance.length() >= 4 && s.length() >= 16) {
-                transactions.add(new Transaction(s.substring(s.length() - 16, s.length() - 6),
-                        s.substring(0, s.length() - 16),
-                        Helpers.parseBalance(balance.substring(2, balance.length() - 2))));
-            }
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
deleted file mode 100644
index 5722bed..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class EurobonusMastercard extends SEBKortBase {
-
-    private static final String NAME = "SAS EuroBonus MasterCard (Sweden)";
-
-    private static final String NAME_SHORT = "ebmaster";
-
-    private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
-
-    public EurobonusMastercard(Context context) {
-        super(context, "sase", "0102", R.drawable.logo_ebmaster);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public EurobonusMastercard(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sase", "0102", R.drawable.logo_ebmaster);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
deleted file mode 100644
index 397d768..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class EurobonusMastercardDk extends SEBKortBase {
-
-    private static final String NAME = "SAS EuroBonus MasterCard (Denmark)";
-
-    private static final String NAME_SHORT = "ebmaster_dk";
-
-    private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_DK;
-
-    public EurobonusMastercardDk(Context context) {
-        super(context, "sadk", "0101", R.drawable.logo_ebmaster_dk);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.currency = "DKK";
-    }
-
-    public EurobonusMastercardDk(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sadk", "0101", R.drawable.logo_ebmaster_dk);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
deleted file mode 100644
index 9463db1..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class EurobonusMastercardNo extends SEBKortBase {
-
-    private static final String NAME = "SAS EuroBonus MasterCard (Norway)";
-
-    private static final String NAME_SHORT = "ebmaster_no";
-
-    private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_NO;
-
-    public EurobonusMastercardNo(Context context) {
-        super(context, "sano", "0117", R.drawable.logo_ebmaster_no);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.currency = "NOK";
-    }
-
-    public EurobonusMastercardNo(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sano", "0117", R.drawable.logo_ebmaster_no);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
deleted file mode 100644
index 4699a9f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class Eurocard extends SEBKortBase {
-
-    private static final String NAME = "Eurocard";
-
-    private static final String NAME_SHORT = "eurocard";
-
-    private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
-
-    public Eurocard(Context context) {
-        super(context, "ecse", "0005", "secure.eurocard.se", new int[]{R.raw.cert_eurocard}, R.drawable.logo_eurocard);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Eurocard(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "ecse", "0005", "secure.eurocard.se",
-                new int[]{R.raw.cert_eurocard}, R.drawable.logo_eurocard);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
deleted file mode 100644
index 03f2f30..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.util.EntityUtils;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class ForexBank extends Bank {
-
-    private static final String NAME = "Forex Bank";
-
-    private static final String NAME_SHORT = "forex";
-
-    private static final String URL = "https://www.forex.se/";
-
-    private static final int BANKTYPE_ID = IBankTypes.FOREX;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-
-    private static final boolean STATIC_BALANCE = false;
-
-    private static final String BASE_URL = "https://nettbank.edb.com";
-
-    private Pattern reFormAction = Pattern.compile("form action=\"(.*)\"\\s", Pattern.MULTILINE);
-
-    private Pattern reTranId = Pattern.compile("p_tranid\" value=\"(\\d+)\"", Pattern.MULTILINE);
-
-    private Pattern reFallbackQuery = Pattern.compile("fallbackQuery\"\\svalue=\"(.*)\"",
-            Pattern.MULTILINE);
-
-    private Pattern reAccountIds = Pattern.compile("ransactions\\?cvokey=(.\\d+)",
-            Pattern.MULTILINE);
-
-    private Pattern reAccountNumbers = Pattern.compile("account_number.*\\>(\\d+)",
-            Pattern.MULTILINE);
-
-    private Pattern reAccountName = Pattern.compile("account_name.*\\>(.+)<", Pattern.MULTILINE);
-
-    private Pattern reAccountBalance = Pattern.compile("balance.*\\>(\\d+,\\d\\d)",
-            Pattern.MULTILINE);
-
-    private Pattern reDisposable = Pattern.compile("disposable.*\\>(\\d+,\\d\\d)",
-            Pattern.MULTILINE);
-
-    private Pattern reTransactions = Pattern.compile(
-            "item\\stransaction.+?(\\d{4}-\\d{2}-\\d{2}?).+?(-?\\d+,\\d{2}).*?left\">\\s+(.+?)\\s+</div>",
-            Pattern.MULTILINE | Pattern.DOTALL);
-
-    public ForexBank(Context context) {
-        super(context, R.drawable.logo_forex);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public ForexBank(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_forexbank));
-        String baseUrl = "https://nettbank.edb.com";
-        String res = urlopen.open(
-                baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
-        String formAction = "";
-        String tranId = "";
-        String fallbackQuery = "";
-
-        // Get post action
-        Matcher mFormAction = reFormAction.matcher(res);
-        if (mFormAction.find()) {
-            formAction = mFormAction.group(1);
-            //System.err.println(mFormAction.group(1));
-        }
-
-        // Get transaction id hidden param
-        Matcher mTranId = reTranId.matcher(res);
-        if (mTranId.find()) {
-            tranId = mTranId.group(1);
-            //System.err.println(mTranId.group(1));
-        }
-
-        // Weird param, lets include it!
-        Matcher mFallbackQuery = reFallbackQuery.matcher(res);
-        if (mFallbackQuery.find()) {
-            fallbackQuery = mFallbackQuery.group(1);
-            //System.err.println(mTranId.group(1));
-        }
-
-        // Assemble param table
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("p_tranid", tranId));
-        postData.add(new BasicNameValuePair("user_id", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        postData.add(new BasicNameValuePair("submitButton", "Logga in"));
-        postData.add(new BasicNameValuePair("forcelayout", "touch"));
-        postData.add(new BasicNameValuePair("fallbackQuery", fallbackQuery));
-        postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
-
-        return new LoginPackage(urlopen, postData, null, formAction);
-    }
-
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-
-        // Post
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(BASE_URL + lp.getLoginTarget(),
-                lp.getPostData(), false);
-
-        String result = EntityUtils.toString(httpResponse.getEntity());
-
-        if (!result.contains("/mobilepayment/transigo/logon/logout")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        /*
-        "account_number.*\\>(\\d+)"; // Kontonummer
-        "account_name.*\\>(.+)<" // Kontonamn
-        "balance.*\>(\d+,\d\d)" // Saldo
-        "disposable.*\>(\d+,\d\d)" // Disponibelt
-
-        System.err.println("Kontonummer " + mAccountNumbers.group(i+1));
-        System.err.println("Kontonamn " + mAccountNames.group(i+1));
-        System.err.println("Saldo " + mAccountBalances.group(i+1));
-        System.err.println("Disponibelt " + mDisposables.group(i+1));
-         */
-        urlopen = login();
-
-        // Go to main menu
-        String result = urlopen.open("https://nettbank.edb.com/mobilepayment/transigo/menu/menu1");
-        result = result.replace("&nbsp;", ""); // Remove non-breaking spaces, they fuck up balances
-
-        Matcher mAccountIds = reAccountIds.matcher(result);
-        Matcher mAccountNumbers = reAccountNumbers.matcher(result);
-        Matcher mAccountNames = reAccountName.matcher(result);
-        Matcher mAccountBalances = reAccountBalance.matcher(result);
-        Matcher mDisposables = reDisposable.matcher(result);
-
-        while (mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find()
-                && mAccountBalances.find()) {
-            if (!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
-                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(),
-                        Helpers.parseBalance(mDisposables.group(1).trim()),
-                        mAccountIds.group(1))); //Disponibelt
-            } else {
-                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(),
-                        Helpers.parseBalance(mAccountBalances.group(1).trim()),
-                        mAccountIds.group(1)));
-            }
-
-            balance = balance.add(Helpers.parseBalance(mAccountBalances.group(1)));
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        String accountId = account.getId();
-        Matcher matcher;
-        String response = urlopen.open(BASE_URL
-                + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey="
-                + accountId);
-        response = response.replace("&nbsp;", "");
-        matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        while (matcher.find()) {
-            transactions.add(new Transaction(matcher.group(1).trim(), matcher.group(3).trim(),
-                    Helpers.parseBalance(matcher.group(2))));
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
deleted file mode 100644
index c825370..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: DEGE
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Handelsbanken extends Bank {
-
-    private static final String NAME = "Handelsbanken";
-
-    private static final String NAME_SHORT = "handelsbanken";
-
-    private static final String URL = "https://m.handelsbanken.se/";
-
-    private static final int BANKTYPE_ID = IBankTypes.HANDELSBANKEN;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-
-    private Pattern reBalance = Pattern.compile(
-            "block-link\\s*\"\\s*href=\"[^\"]*?/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK(?:&nbsp;|\\s*)?([0-9\\s.,-ÃÂ]+)",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private Pattern reAccountsUrl = Pattern
-            .compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Konton<",
-                    Pattern.CASE_INSENSITIVE);
-
-    private Pattern reLoginUrl = Pattern
-            .compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Logga",
-                    Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactions = Pattern.compile(
-            "padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<",
-            Pattern.CASE_INSENSITIVE);
-
-    private ArrayList<String> accountIds = new ArrayList<String>();
-
-    private String response = null;
-
-    public Handelsbanken(Context context) {
-        super(context, R.drawable.logo_handelsbanken);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-    }
-
-    public Handelsbanken(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
-        response = urlopen.open("https://m.handelsbanken.se/primary/");
-        Matcher matcher = reLoginUrl.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " login url.");
-        }
-        String strLoginUrl = "https://m.handelsbanken.se/primary/_-" + matcher.group(1);
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", getUsername()));
-        postData.add(new BasicNameValuePair("pin", getPassword()));
-        postData.add(new BasicNameValuePair("execute", "true"));
-        return new LoginPackage(urlopen, postData, response, strLoginUrl);
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("ontrollera dina uppgifter")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-
-        Matcher matcher = reAccountsUrl.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " accounts url.");
-        }
-        String strAccountsUrl = "https://m.handelsbanken.se/primary/_-" + matcher.group(1);
-        response = urlopen.open(strAccountsUrl);
-        matcher = reBalance.matcher(response);
-        Integer accountId = 0;
-        while (matcher.find()) {
-            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
-            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-            accountIds.add(matcher.group(1));
-            accountId += 1;
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        Matcher matcher;
-        String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-        response = urlopen.open("https://m.handelsbanken.se/primary/_-" + accountWebId);
-        matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        while (matcher.find()) {
-            transactions.add(new Transaction(matcher.group(1).trim(),
-                    Html.fromHtml(matcher.group(2)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(3))));
-        }
-
-        // Sort transactions by date
-        Collections.sort(transactions, new Comparator<Transaction>() {
-            public int compare(Transaction t1, Transaction t2) {
-                return t2.compareTo(t1);
-            }
-        });
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
deleted file mode 100644
index 6c564d8..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Marginalen extends Bank {
-
-    private static final String NAME = "Marginalen Bank";
-
-    private static final String NAME_SHORT = "marginalen";
-
-    private static final String BASE_URL = "https://secure1.marginalen.se/marginalen/";
-
-    private static final int BANKTYPE_ID = IBankTypes.MARGINALEN;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-
-    String response;
-
-    private Pattern reLoginLink = Pattern
-            .compile("href=\"(engine\\?usecase=pin&[a-zA-Z0-9;=&._]+)");
-
-    private Pattern reHash = Pattern.compile("name=\"hash\" value=\"([a-zA-Z0-9]+)\"");
-
-    private Pattern reGuid = Pattern.compile("name=\"guid\" value=\"([a-zA-Z0-9]+)\"");
-
-    private Pattern reAccountLink = Pattern
-            .compile("href=\"(engine\\?[a-zA-Z0-9;=&._]+menuid=15[a-zA-Z0-9;=&._]+)\"");
-
-    private Pattern reAccounts = Pattern.compile(
-            "<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td>\\s*<a href=\"(engine\\?usecase=account[a-zA-Z0-9;=&._]+)\">([0-9]+)</a>\\s*</td>\\s*<td class=\"aright\">\\s*([0-9.,]+)\\s*[a-zA-Z&;]+\\s*</td>");
-
-    private Pattern reTransactions = Pattern.compile(
-            "href=\"engine\\?usecase=transactiondetails.*tabindex=\"4\">([0-9\\-]+)</a>\\s*</td>\\s*<td>\\s*(.*?)\\s*</td>\\s*<td class=\"aright\">\\s*([\\-0-9\\.,]+)&nbsp;");
-
-    private String accountUrl = "";
-
-    public Marginalen(Context context) {
-        super(context, R.drawable.logo_marginalen);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-    }
-
-    public Marginalen(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader
-                .getCertificates(context, R.raw.cert_marginalen));
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        Matcher matcher;
-        response = urlopen.open(BASE_URL + "engine");
-        matcher = reLoginLink.matcher(response);
-
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " login link.");
-        }
-        String url = BASE_URL + matcher.group(1);
-        url = url.replaceAll("&amp;", "&");
-        response = urlopen.open(url);
-
-        matcher = reHash.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " hash value.");
-        }
-
-        String hash = matcher.group(1);
-
-        matcher = reGuid.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " GUID value.");
-        }
-
-        String guid = matcher.group(1);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("usecase", "base"));
-        postData.add(new BasicNameValuePair("command", "formcommand"));
-        postData.add(new BasicNameValuePair("commandorigin", "0.pin_logon_step1_view_handler"));
-        postData.add(new BasicNameValuePair("guid", guid));
-        postData.add(new BasicNameValuePair("hash", hash));
-        postData.add(new BasicNameValuePair("userId", getUsername()));
-        postData.add(new BasicNameValuePair("pin", getPassword()));
-
-        return new LoginPackage(urlopen, postData, response, BASE_URL + "engine");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-        if (response.contains("Felmeddelande")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        Matcher matcher;
-        matcher = reAccountLink.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " accounts link.");
-        }
-        accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
-
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        response = urlopen.open(accountUrl);
-        Matcher matcher = reAccounts.matcher(response);
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Name              Högräntekonto
-             * 2: URL               engine?usecase=account&amp;command=transactions&amp;guid=mCmupGvnAAJuC76MGuuRnwCC&amp;commandorigin=0.account_private_viewhandler&amp;account_table=0&amp;hash=Be2HxFargpk2m0BI2tShAACC
-             * 3: ID                92351124972
-             * 4: Amount            100.000,00
-             *
-             */
-            Account account = new Account(Html.fromHtml(matcher.group(1)).toString(),
-                    Helpers.parseBalance(matcher.group(4)), matcher.group(2),
-                    Long.parseLong(matcher.group(3)));
-            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-            accounts.add(account);
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        Matcher matcher;
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        response = urlopen.open(BASE_URL + account.getId().replaceAll("&amp;", "&"));
-
-        matcher = reTransactions.matcher(response);
-        while (matcher.find()) {
-                /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Date                  2011-04-06
-             * 2: Specification         Pressbyran
-             * 3: Amount                -20
-             *
-             */
-            transactions.add(new Transaction(matcher.group(1).trim(),
-                    Html.fromHtml(matcher.group(2)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(3))));
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
deleted file mode 100644
index 0afc6f4..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class NordeaDK extends Bank {
-
-    private static final String NAME = "Nordea DK";
-
-    private static final String NAME_SHORT = "nordea_dk";
-
-    private static final String URL = "https://m.nordea.dk/";
-
-    private static final int BANKTYPE_ID = IBankTypes.NORDEA_DK;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "DDMMÅÅ-XXXX";
-
-    private final String currency = "DKK";
-
-    private String prefix;
-
-    private String referer;
-
-    private Pattern reLoginUrl = Pattern.compile(
-            "<input.*?name=\"prefix\".*?value=\"([^\"]+)\"",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reAccounts = Pattern
-            .compile(
-                    "<a.*?href=\"(.*?AccountTransactions.*?productidx=([0-9]+).*?)[^>]+>\\s*<span[^>]+>(.*?)</span>\\s*<span[^>]+>\\s*(.*?)</span>",
-                    Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactions = Pattern
-            .compile(
-                    "<tr [^>]+>\\s*<td.*?[^>]+>\\s*(.*?)[.]{1}\\s*</td>\\s*<td[^>]*>\\s*(.*?)\\s*</td>\\s*<td[^>]+>\\s*(.*?)\\s*</td>\\s*</tr>",
-                    Pattern.CASE_INSENSITIVE);
-
-    private Pattern rePrefix = Pattern.compile(
-            "<a id=\"logout\" href=.*?prefix=([0-9-]+)",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reOldTransactions = Pattern
-            .compile("<a.*?class=\".*?prev_btn.*?\".*?href=\".*?AccountTransactions",
-                    Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactionYear = Pattern
-            .compile("<h3[^>]+>.*?([0-9]{4})</h3>", Pattern.CASE_INSENSITIVE);
-
-    private String response;
-
-    public NordeaDK(Context context) {
-        super(context, R.drawable.logo_nordea_dk);
-
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.currency = "DKK";
-        this.response = null;
-        this.prefix = "";
-    }
-
-    public NordeaDK(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        if (urlopen == null) {
-            urlopen = new Urllib(context,
-                    CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
-        }
-        response = urlopen
-                .open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
-        response = urlopen.open("https://www.netbank.nordea.dk/mnetbank/logon.jsp");
-        Matcher matcher = reLoginUrl.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find)
-                    .toString() + " login url.");
-        }
-        String strLoginUrl = "https://www.netbank.nordea.dk/mnetbank/servlet/Logon";
-        this.referer = strLoginUrl;
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("user_id", getUsername()));
-        postData.add(new BasicNameValuePair("logon_code", getPassword()));
-        postData.add(new BasicNameValuePair("command", "1"));
-        this.prefix = matcher.group(1);
-        postData.add(new BasicNameValuePair("prefix", matcher.group(1)));
-        return new LoginPackage(urlopen, postData, response, strLoginUrl);
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("class=\"icon error_icon\"")) {
-            throw new LoginException(res.getText(
-                    R.string.invalid_username_password).toString());
-        }
-        this.updatePrefix();
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException,
-            BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(
-                    R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        Matcher matcher = reAccounts.matcher(response);
-
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find)
-                    .toString() + " accounts url.");
-        }
-        matcher.reset();
-        while (matcher.find()) {
-                        /*
-             * Capture groups:
-             * GROUP         EXAMPLE DATA
-             * 1: Link        https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
-             * 2: ID         0
-             * 3: Name         Check-in-konto
-             * 4: Amount    1.234,56
-             */
-            String name = Html.fromHtml(matcher.group(3)).toString().trim();
-            String id = matcher.group(2).toString().trim();
-            BigDecimal amount = Helpers.parseBalance(matcher.group(4));
-
-            accounts.add(new Account(name, amount, id, Account.REGULAR,
-                    this.currency));
-            balance = balance.add(amount);
-
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found)
-                    .toString());
-        }
-        this.updatePrefix();
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen)
-            throws LoginException, BankException, IOException {
-        super.updateTransactions(account, urlopen);
-
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-        transactions.addAll(updateMonthTransactions(account, urlopen, false));
-
-        //Get last months' transactions
-        Matcher oldTransactionMatcher = reOldTransactions.matcher(response);
-        if (oldTransactionMatcher.find()) {
-            transactions.addAll(updateMonthTransactions(account, urlopen, true));
-        }
-
-        account.setTransactions(transactions);
-
-    }
-
-    private ArrayList<Transaction> updateMonthTransactions(Account account,
-            Urllib urlopen, boolean oldTransactions) throws BankException, IOException {
-        String command = "command=";
-        command += (oldTransactions) ? "1" : "0";
-        String url =
-                "https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions?productidx="
-                        + account.getId() + "&prefix=" + this.prefix + "&" + command;
-
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-        Matcher matcher;
-        urlopen.addHeader("referer", this.referer);
-        this.response = urlopen.open(url);
-        this.updatePrefix();
-        this.referer = url;
-
-        Matcher transYear = reTransactionYear.matcher(response);
-        String year = "";
-        if (transYear.find()) {
-            year = Html.fromHtml(transYear.group(1)).toString().trim();
-        }
-
-        matcher = reTransactions.matcher(response);
-        /*
-         * Capture groups:
-         * GROUP     EXAMPLE     DATA
-         * 1:         Date         29.07
-         * 2:         Transaction    Bgs Check-in-konto
-         * 3:         Amount         906.56
-         */
-
-        while (matcher.find()) {
-            String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
-            String text = Html.fromHtml(matcher.group(2)).toString().trim();
-            BigDecimal amount = Helpers.parseBalance(matcher.group(3));
-            String date = year + "-" + monthDate.substring(3, 5) + "-" + monthDate.substring(0, 2);
-
-            Transaction transaction = new Transaction(date, text, amount,
-                    super.currency);
-            transactions.add(transaction);
-        }
-        return transactions;
-    }
-
-    private void updatePrefix() throws BankException {
-        Matcher matcher = rePrefix.matcher(this.response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find)
-                    .toString());
-        }
-        this.prefix = Html.fromHtml(matcher.group(1)).toString().trim();
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
deleted file mode 100644
index 45a5bb1..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Opel extends SEBKortBase {
-
-    private static final String NAME = "OpelKortet";
-
-    private static final String NAME_SHORT = "opel";
-
-    private static final int BANKTYPE_ID = Bank.OPEL;
-
-    public Opel(Context context) {
-        super(context, "opse", "0107", R.drawable.logo_opel);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Opel(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "opse", "0107", R.drawable.logo_opel);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
deleted file mode 100644
index e2261ff..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-
-import android.content.Context;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class PayPal extends Bank {
-    private static final String NAME = "PayPal";
-    private static final String NAME_SHORT = "paypal";
-    private static final String ORIGIN_URL =  "https://www.paypal.com";
-    private static final String REFERER_URL ="https://www.paypal.com/se/webapps/mpp/home";
-    private static final String OVERVIEW_URL = "https://www.paypal.com/myaccount/home";
-    private static final String LOGIN_URL = "https://www.paypal.com/signin/intent/";
-    private static final String BALANCE_URL = "https://www.paypal.com/myaccount/wallet/balance";
-
-    private static final int BANKTYPE_ID = IBankTypes.PAYPAL;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
-            | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-    private static final boolean STATIC_BALANCE = true;
-    private String response = null;
-
-    public PayPal(Context context) {
-        super(context, R.drawable.logo_paypal);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public PayPal(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        try {
-            urlopen = login();
-            LoginPackage lp = new LoginPackage(urlopen, null,
-                    response, OVERVIEW_URL);
-            lp.setIsLoggedIn(true);
-            return lp;
-        } catch (LoginException e) {
-            return null;
-        }
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_paypal));
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("email", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        postData.add(new BasicNameValuePair("ul-submit-cookied", "Logga in"));
-        urlopen.addHeader("Origin",ORIGIN_URL);
-        urlopen.addHeader("Referer", REFERER_URL);
-        response = urlopen.open(LOGIN_URL, postData, true);
-        if (response.contains("Some information you entered isn't right.")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        /* TODO find a reliable way to verify that the user has logged in successfully.
-        if (!response.contains("cgi-bin/webscr?cmd=_logout\" class=\"btn btn-small btn-secondary logout\">")) {
-            throw new BankException("Error logging in to PayPal");
-        }
-        */
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-
-        /* Start by parsing the data in "response" (containing transactions) */
-        List<Transaction> transactions = new ArrayList<>();
-        Document trans = Jsoup.parse(response);
-        try {
-            for (Element e : trans.select(".transactionItem .row")) {
-                String date = e.select(".dateParts").first().text(); //"Mar 17 2015"
-                date = new SimpleDateFormat("yyyy-MM-dd").format(
-                        new SimpleDateFormat("MMM dd yyyy").parse(date));
-                String description = e.select(".transactionDescription").first().text(); //"Unovation Inc."
-                String type = e.select(".transactionType").first().text(); //"Recurring Payment "
-                String amount = e.select(".transactionAmount").first().text(); //"-negative $3.00 USD"
-                Transaction t = new Transaction(date,
-                        description + "\n— " + type, Helpers.parseBalance(amount));
-                t.setCurrency(amount.substring(amount.length() - 3));
-                transactions.add(t);
-            }
-        } catch (ParseException | NullPointerException e) {
-            //Ignore parsing errors of transactions (for now).
-            //TODO handle parsing errors gracefully.
-        }
-
-        try {
-            //Set bank balance from first page balance.
-            String bal = trans.select(".balanceNumeral.nemo_balanceNumeral .h2").text();
-            this.balance = Helpers.parseBalance(bal);
-            this.setCurrency(bal.substring(bal.length() - 3));
-
-            //Get all currencies and create separate accounts for each.
-            response = urlopen.open(BALANCE_URL);
-            Document doc = Jsoup.parse(response);
-            Element wallet = doc.getElementById("wallet");
-            bal = wallet.attr("data-balance").replace("&quot;", "\"");
-            JSONObject acc = new JSONObject(bal);
-            this.balance = Helpers.parseBalance(
-                    acc.getJSONObject("totalAvailable").getString("unformattedAmount"));
-            this.setCurrency(acc.getString("primaryCurrency"));
-
-            JSONArray accArr = acc.getJSONArray("balanceDetails");
-            for (int i = 0; i < accArr.length(); i++) {
-                try {
-                    JSONObject a = accArr.getJSONObject(i);
-                    String accountName = a.getString("currency");
-                    String displayName = accountName;
-                    if (accountName.equals(this.getCurrency())) {
-                        displayName = accountName + " (Primary)";
-                    }
-                    Double amount = a.getJSONObject("available")
-                            .getDouble("unformattedAmount");
-                    Account account = new Account(displayName,
-                            Helpers.parseBalance(amount.toString()),
-                            accountName,
-                            Account.REGULAR,
-                            accountName);
-                    account.setTransactions(transactions);
-                    accounts.add(account);
-                } catch (JSONException e) {
-                    //Ignore if we can't add a new account..
-                }
-            }
-        } catch (JSONException e) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString(), e);
-        }
-        super.updateComplete();
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
deleted file mode 100644
index 15a3e99..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Quintessentially extends SEBKortBase {
-
-    private static final String NAME = "Quintessentially Credit Card";
-
-    private static final String NAME_SHORT = "quintessentially";
-
-    private static final int BANKTYPE_ID = Bank.QUINTESSENTIALLY;
-
-    public Quintessentially(Context context) {
-        super(context, "quse", "0119", R.drawable.logo_quintessentially);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Quintessentially(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "quse", "0119", R.drawable.logo_quintessentially);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
deleted file mode 100644
index dea7bd5..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class SJPrio extends SEBKortBase {
-
-    private static final String NAME = "SJ Prio MasterCard";
-
-    private static final String NAME_SHORT = "sj_prio";
-
-    private static final int BANKTYPE_ID = Bank.SJPRIO;
-
-    public SJPrio(Context context) {
-        super(context, "sjse", "0104", R.drawable.logo_sj_prio);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public SJPrio(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sjse", "0104", R.drawable.logo_sj_prio);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
deleted file mode 100644
index f65816f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Saab extends SEBKortBase {
-
-    private static final String NAME = "SaabKortet";
-
-    private static final String NAME_SHORT = "saab";
-
-    private static final int BANKTYPE_ID = Bank.SAAB;
-
-    public Saab(Context context) {
-        super(context, "sbse", "0106", R.drawable.logo_saab);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Saab(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sbse", "0106", R.drawable.logo_saab);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
deleted file mode 100644
index bad3a38..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ /dev/null
@@ -1,271 +0,0 @@
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpResponseException;
-import org.apache.http.message.BasicNameValuePair;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.content.Context;
-import android.provider.Settings.Secure;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Skandiabanken extends Bank {
-
-    private static final String NAME = "Skandiabanken";
-
-    private static final String NAME_SHORT = "skandiabanken";
-
-    private static final int BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
-
-    private static final String URL = "http://www.skandiabanken.se/hem/";
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-
-    private static final String BASE_URL = "https://smartrefill.se/BankServices";
-
-    private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_ID
-            = "x-smartrefill-application";
-
-    private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION
-            = "x-smartrefill-version";
-
-    private static final String HTTP_HEADER_SMARTREFILL_COUNTRY_CODE = "x-smartrefill-country-code";
-
-    private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER
-            = "x-smartrefill-customer-owner";
-
-    private static final String HTTP_HEADER_SMARTREFILL_DEVICE_ID = "x-smartrefill-device";
-
-    private static final String HTTP_HEADER_SMARTREFILL_INFLOW = "x-smartrefill-inflow";
-
-    private static final String INFLOW_ANDROID = "Android";
-
-    private final static String customerOwner = "SKANDIABANKEN";
-
-    private final static String countryCode = "SE";
-
-    private final static String SERVICE_NAME = "bank";
-
-    private int customerId = 0;
-
-    public Skandiabanken(Context context) {
-        super(context, R.drawable.logo_skandiabanken);
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-    }
-
-    public Skandiabanken(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
-
-        HashMap<String, String> headers = urlopen.getHeaders();
-        headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID,
-                "se.skandiabanken.android.wallet");
-        headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION, "9");
-        headers.put(HTTP_HEADER_SMARTREFILL_COUNTRY_CODE, countryCode);
-        headers.put(HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER, customerOwner);
-        headers.put(HTTP_HEADER_SMARTREFILL_DEVICE_ID, getDeviceId());
-        headers.put(HTTP_HEADER_SMARTREFILL_INFLOW, INFLOW_ANDROID);
-
-        urlopen.setUserAgent(null);
-
-        String loginUrl = getBaseUrlWithCustomerOwner() + "/login";
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-
-        try {
-            String loginResponse = urlopen.open(loginUrl, postData);
-            JSONObject obj = new JSONObject(loginResponse);
-            customerId = (int) obj.getLong("id");
-            urlopen.addHeader("x-smartrefill-customer", "" + customerId);
-        } catch (HttpResponseException e) {
-            if (e.getStatusCode() == 401) {
-                throw new LoginException(
-                        "Inloggning misslyckad fel användarnamn eller lösenord");
-            } else {
-                throw new BankException("Http fel (" + e.getStatusCode() + ") "
-                        + e.getMessage(), e);
-            }
-        } catch (JSONException e) {
-            throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
-        }
-
-        return urlopen;
-    }
-
-    private String getBaseUrlWithCustomerOwner() {
-        return BASE_URL + "/rest/" + SERVICE_NAME + "/" + countryCode + "/"
-                + customerOwner;
-    }
-
-    private void logout() {
-        String logoutUrl = getBaseUrlWithCustomerOwner() + "/customer/"
-                + customerId + "/logout";
-        try {
-            urlopen.post(logoutUrl);
-        } catch (IOException e) {
-        }
-    }
-
-    @Override
-    public void update() throws BankException, LoginException,
-            BankChoiceException, IOException {
-        super.update();
-
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(
-                    R.string.invalid_username_password).toString());
-        }
-
-        login();
-
-        String accountsUrl = getBaseUrlWithCustomerOwner() + "/customer/"
-                + customerId + "/accounts";
-        try {
-            String accountsJsonString = urlopen.open(accountsUrl);
-            JSONArray json = new JSONArray(accountsJsonString);
-            for (int i = 0; i < json.length(); i++) {
-                JSONObject acountJsonObj = json.getJSONObject(i);
-
-                String name = acountJsonObj.optString("alias");
-
-                if (name.length() != 0) {
-                    name += " - ";
-                }
-
-                name += acountJsonObj.getString("accountNumber");
-
-                // disposableAmount also exists in JSON
-                String balanceString = acountJsonObj.getString("amount");
-                String id = acountJsonObj.getString("id");
-                int type = Account.REGULAR; // accountType exists in JSON
-                Account account = new Account(name, Helpers.parseBalance(balanceString), id, type);
-                accounts.add(account);
-            }
-        } catch (JSONException e) {
-            throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen)
-            throws LoginException, BankException, IOException {
-        super.updateTransactions(account, urlopen);
-
-        if (customerId == 0) {
-            login();
-        }
-
-        try {
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-            String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
-                    + "/customer/" + customerId + "/account/" + account.getId();
-
-            String accountJsonString = urlopen.open(accountTransactionsUrl);
-            JSONObject accountJSONObj = new JSONObject(accountJsonString);
-            JSONArray transactionsJSONArray = accountJSONObj.optJSONArray("transactions");
-            if (transactionsJSONArray != null) {
-                for (int i = 0; i < transactionsJSONArray.length(); i++) {
-                    JSONObject transactionJsonObj = transactionsJSONArray.getJSONObject(i);
-                    String date = transactionJsonObj
-                            .getString("date"); // time and timestamp also exists in JSON
-                    String ammountString = transactionJsonObj.getString("amount");
-                    String description = transactionJsonObj.getString("merchant");
-                    Transaction transaction = new Transaction(date, description,
-                            Helpers.parseBalance(ammountString));
-                    transactions.add(transaction);
-                }
-
-                // Sort transactions by date
-                Collections.sort(transactions, new Comparator<Transaction>() {
-                    public int compare(Transaction t1, Transaction t2) {
-                        return t2.compareTo(t1);
-                    }
-                });
-
-                account.setTransactions(transactions);
-            }
-
-        } catch (JSONException e) {
-            throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public void closeConnection() {
-        logout();
-        super.closeConnection();
-    }
-
-    public String getDeviceId() {
-        // TelephonyManager localTelephonyManager =
-        // (TelephonyManager)context.getSystemService("phone");
-        // if (localTelephonyManager.getDeviceId() != null) // null for emulator
-        // return localTelephonyManager.getDeviceId();
-        // else
-        // return "000000000000000";
-        // We should return the imei of the phone (se code above)
-        // As we would need permission to read imei we use something else that
-        // is unique and constant
-        // Bankdroid should have as less permissions as possible...
-        String test = Secure.getString(context.getContentResolver(),
-                Secure.ANDROID_ID);
-
-        if (test == null) {
-            // null for emulator
-            test = "0";
-        }
-
-        // convert to decimal string (imei is decimal)
-        try {
-            test = String.valueOf(Integer.parseInt(test, 16));
-        } catch (NumberFormatException e) {
-        }
-
-        while (test.length() < 16) {
-            test += "0";
-        }
-
-        return test.substring(0, 15);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
deleted file mode 100644
index b722e42..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class SparbankenOresund extends MobilbankenBase {
-
-    private static final String NAME = "Sparbanken Öresund";
-
-    private static final String NAME_SHORT = "sparbanken_oresund";
-
-    private static final String URL = "https://mobil-banken.se/0003/login.html";
-
-    private static final int BANKTYPE_ID = Bank.SPARBANKEN_ORESUND;
-
-    public SparbankenOresund(Context context) {
-        super(context, R.drawable.logo_sparbanken_oresund);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.BROKEN = true;
-        this.targetId = "0003";
-    }
-
-    public SparbankenOresund(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
deleted file mode 100644
index f4f6777..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class SparbankenSyd extends MobilbankenBase {
-
-    private static final String NAME = "Sparbanken Syd";
-
-    private static final String NAME_SHORT = "sparbanken_syd";
-
-    private static final String URL = "https://mobil-banken.se/0004/login.html";
-
-    private static final int BANKTYPE_ID = Bank.SPARBANKEN_SYD;
-
-    public SparbankenSyd(Context context) {
-        super(context, R.drawable.logo_sparbanken_syd);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.BROKEN = true;
-        this.targetId = "0004";
-    }
-
-    public SparbankenSyd(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
deleted file mode 100644
index f883912..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Statoil extends SEBKortBase {
-
-    private static final String NAME = "Statoil Mastercard";
-
-    private static final String NAME_SHORT = "statoil";
-
-    private static final int BANKTYPE_ID = IBankTypes.STATOIL;
-
-    public Statoil(Context context) {
-        super(context, "stse", "0122", R.drawable.logo_statoil);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Statoil(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "stse", "0122", R.drawable.logo_statoil);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
deleted file mode 100644
index d53ffcc..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-import timber.log.Timber;
-
-public class Steam extends Bank {
-
-    private static final String NAME = "Steam Wallet";
-
-    private static final String NAME_SHORT = "steam";
-
-    private static final String URL = "https://store.steampowered.com/login/?redir=account";
-
-    private static final int BANKTYPE_ID = IBankTypes.STEAM;
-
-    private static final boolean STATIC_BALANCE = true;
-
-    private Pattern reBalance = Pattern.compile("accountBalance\">\\s*<div[^>]+>([^<]+)</div>",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactions = Pattern.compile(
-            "(?:even|odd)\">\\s*<div\\s*class=\"transactionRowDate\">([^<]+)</div>\\s*<div.*?RowPrice\">([^<]+)</div>\\s*<div.*?RowEvent\">([^<]+)</div>.*?RowTitle\">([^<]+)</div>\\s*<span[^>]+>([^<]*)<",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private String response = null;
-
-    public Steam(Context context) {
-        super(context, R.drawable.logo_steam);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public Steam(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_steam));
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("redir", "account"));
-        postData.add(new BasicNameValuePair("username", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        return new LoginPackage(urlopen, postData, null, "https://store.steampowered.com/login/");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("Enter the characters above")) {
-            throw new LoginException(
-                    "You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
-        }
-        if (response.contains("Incorrect login.")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        Matcher matcher = reBalance.matcher(response);
-        if (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Amount            0,--&#8364;
-             *
-             */
-            String amount = Html.fromHtml(matcher.group(1)).toString().trim().replace("--", "00");
-            Account account = new Account("Wallet", Helpers.parseBalance(amount), "1");
-            String currency = Helpers.parseCurrency(amount, "USD");
-            this.setCurrency(currency);
-            account.setCurrency(currency);
-            balance = balance.add(Helpers.parseBalance(amount));
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            matcher = reTransactions.matcher(response);
-            while (matcher.find()) {
-                    /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Date              18 Oct 2007
-                 * 2: Amount            0,99&#8364;
-                 * 3: Event             Purchase
-                 * 4: Item              Team Fortress 2&nbsp;
-                 * 5: Sub item          Mann Co. Supply Crate Key
-                 *
-                 */
-                SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
-                SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
-                Date transactionDate;
-                try {
-                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
-                    String strDate = sdfTo.format(transactionDate);
-                    BigDecimal price = Helpers.parseBalance(
-                            Html.fromHtml(matcher.group(2)).toString().trim().replace("--", "00"));
-                    if ("Purchase".equalsIgnoreCase(matcher.group(3).trim())) {
-                        price = price.negate();
-                    }
-                    transactions.add(new Transaction(strDate,
-                            Html.fromHtml(matcher.group(4)).toString().trim() + (
-                                    Html.fromHtml(matcher.group(5)).toString().trim().length() > 1 ?
-                                            " (" + Html.fromHtml(matcher.group(5)).toString().trim()
-                                                    + ")" : ""),
-                            price,
-                            Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(),
-                                    "USD")));
-                } catch (ParseException e) {
-                    Timber.e(e, "Unable to parse date: %s", matcher.group(1).trim());
-                }
-            }
-            Collections.sort(transactions, Collections.reverseOrder());
-            account.setTransactions(transactions);
-            accounts.add(account);
-        }
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
deleted file mode 100644
index 49831f0..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-
-public class Wallet extends SEBKortBase {
-
-    private static final String NAME = "wallet MasterCard";
-
-    private static final String NAME_SHORT = "wallet";
-
-    private static final int BANKTYPE_ID = Bank.WALLET;
-
-    public Wallet(Context context) {
-        super(context, "wase", "0121", R.drawable.logo_wallet);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-    }
-
-    public Wallet(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        super(username, password, context, "wase", "0121", R.drawable.logo_wallet);
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
deleted file mode 100644
index 80a09a2..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks.icabanken;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccount;
-import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccountList;
-import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenTransaction;
-import com.liato.bankdroid.banking.banks.icabanken.model.response.LoginResponse;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-import android.os.Build;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class ICABanken extends Bank {
-
-    private static final String NAME = "ICA Banken";
-
-    private static final String NAME_SHORT = "icabanken";
-
-    private static final String URL = "https://mobil.icabanken.se/";
-
-    private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
-
-    private static final boolean STATIC_BALANCE = false;
-
-    private static final String API_KEY = "8987B80B-A708-4C61-B8CF-350D4BA289F0";
-
-    private static final String API_URL = "https://appserver.icabanken.se";
-
-    private static final String API_VERSION = "1.0";
-
-    public ICABanken(Context context) {
-        super(context, R.drawable.logo_icabanken);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public ICABanken(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_icabanken));
-        urlopen.addHeader("ApiVersion", API_VERSION);
-        urlopen.addHeader("Accept", "application/json");
-        urlopen.addHeader("ApiKey", API_KEY);
-        urlopen.addHeader("ClientHardware", Build.MODEL);
-        urlopen.addHeader("ClientOS", "Android");
-        urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
-        urlopen.addHeader("ClientAppVersion", "777");
-
-        String response = urlopen.open(String.format(
-                "%s/login/passwordlogin?customerId=%s&password=%s", API_URL, getUsername(), getPassword()));
-        if (response == null || "".equals(response)) {
-            throw new LoginException(res.getText(
-                    R.string.invalid_username_password).toString());
-        }
-        ObjectMapper vObjectMapper = new ObjectMapper();
-        vObjectMapper.setDateFormat(new SimpleDateFormat(
-                "yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
-        LoginResponse loginResponse = vObjectMapper.readValue(response,
-                LoginResponse.class);
-
-        addAccounts(loginResponse.getAccountList());
-
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException,
-            BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(
-                    R.string.invalid_username_password).toString());
-        }
-        login();
-
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found)
-                    .toString());
-        }
-        super.updateComplete();
-
-    }
-
-    private void addAccounts(IcaBankenAccountList pAccountList) {
-        for (IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
-            Account account = new Account(icaAccount.getName()
-                    + " (Disponibelt)", icaAccount.getAvailableAmount(),
-                    icaAccount.getAccountId());
-            account.setTransactions(mapTransactions(icaAccount));
-            Account alias = new Account(icaAccount.getName() + " (Saldo)",
-                    icaAccount.getCurrentAmount(), "a:"
-                    + icaAccount.getAccountId());
-            alias.setAliasfor(icaAccount.getAccountId());
-            accounts.add(account);
-            accounts.add(alias);
-            balance = balance.add(account.getBalance());
-        }
-    }
-
-    private ArrayList<Transaction> mapTransactions(IcaBankenAccount pAccount) {
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd",
-                Locale.getDefault());
-        for (IcaBankenTransaction icaTransaction : pAccount.getTransactions()) {
-            String date = dateFormatter.format(icaTransaction.getPostedDate());
-            Transaction transaction = new Transaction(date,
-                    icaTransaction.getMemoText(), icaTransaction.getAmount());
-            transactions.add(transaction);
-        }
-        return transactions;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
deleted file mode 100644
index 0b20126..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package com.liato.bankdroid.banking.banks.icabanken.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class IcaBankenAccount {
-
-    private String mAccountId;
-
-    private String mAccountNumber;
-
-    private String mAddress;
-
-    private BigDecimal mAvailableAmount;
-
-    private String mBic;
-
-    private BigDecimal mCurrentAmount;
-
-    private String mGroup;
-
-    private String mHolder;
-
-    private String mIban;
-
-    private String mName;
-
-    private BigDecimal mOutstandingAmount;
-
-    private List<String> mServices;
-
-    private List<IcaBankenTransaction> mTransactions;
-
-    private List<String> mValidFor;
-
-    @JsonProperty("AccountId")
-    public String getAccountId() {
-        return mAccountId;
-    }
-
-    public void setAccountId(String pAccountId) {
-        this.mAccountId = pAccountId;
-    }
-
-    @JsonProperty("AccountNumber")
-    public String getAccountNumber() {
-        return mAccountNumber;
-    }
-
-    public void setAccountNumber(String pAccountNumber) {
-        this.mAccountNumber = pAccountNumber;
-    }
-
-    @JsonProperty("Address")
-    public String getAddress() {
-        return mAddress;
-    }
-
-    public void setAddress(String pAddress) {
-        this.mAddress = pAddress;
-    }
-
-    @JsonProperty("AvailableAmount")
-    public BigDecimal getAvailableAmount() {
-        return mAvailableAmount;
-    }
-
-    public void setAvailableAmount(BigDecimal pAvailableAmount) {
-        this.mAvailableAmount = pAvailableAmount;
-    }
-
-    @JsonProperty("BIC")
-    public String getBic() {
-        return mBic;
-    }
-
-    public void setBic(String pBic) {
-        this.mBic = pBic;
-    }
-
-    @JsonProperty("CurrentAmount")
-    public BigDecimal getCurrentAmount() {
-        return mCurrentAmount;
-    }
-
-    public void setCurrentAmount(BigDecimal pCurrentAmount) {
-        this.mCurrentAmount = pCurrentAmount;
-    }
-
-    @JsonProperty("Group")
-    public String getGroup() {
-        return mGroup;
-    }
-
-    public void setGroup(String pGroup) {
-        this.mGroup = pGroup;
-    }
-
-    @JsonProperty("Holder")
-    public String getHolder() {
-        return mHolder;
-    }
-
-    public void setHolder(String pHolder) {
-        this.mHolder = pHolder;
-    }
-
-    @JsonProperty("IBAN")
-    public String getIban() {
-        return mIban;
-    }
-
-    public void setIban(String pIban) {
-        this.mIban = pIban;
-    }
-
-    @JsonProperty("Name")
-    public String getName() {
-        return mName;
-    }
-
-    public void setName(String pName) {
-        this.mName = pName;
-    }
-
-    @JsonProperty("OutstandingAmount")
-    public BigDecimal getOutstandingAmount() {
-        return mOutstandingAmount;
-    }
-
-    public void setOutstandingAmount(BigDecimal pOutstandingAmount) {
-        this.mOutstandingAmount = pOutstandingAmount;
-    }
-
-    @JsonProperty("Services")
-    public List<String> getServices() {
-        return mServices;
-    }
-
-    public void setServices(List<String> pServices) {
-        this.mServices = pServices;
-    }
-
-    @JsonProperty("Transactions")
-    public List<IcaBankenTransaction> getTransactions() {
-        return mTransactions;
-    }
-
-    public void setTransactions(List<IcaBankenTransaction> pTransactions) {
-        this.mTransactions = pTransactions;
-    }
-
-    @JsonProperty("ValidFor")
-    public List<String> getValidFor() {
-        return mValidFor;
-    }
-
-    public void setValidFor(List<String> pValidFor) {
-        this.mValidFor = pValidFor;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
deleted file mode 100644
index cfb4dd4..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.liato.bankdroid.banking.banks.icabanken.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class IcaBankenAccountList {
-
-    private List<IcaBankenAccount> mAccounts;
-
-    private String mDefaultAccountIdForEgiros;
-
-    private String mDefaultAccountIdForPayments;
-
-    private String mDefaultAccountIdForTransfers;
-
-    private BigDecimal mJointAccountsTotalAvailableAmount;
-
-    private BigDecimal mJointAccountsTotalCurrentAmount;
-
-    private BigDecimal mMinorsAccountsTotalAvailableAmount;
-
-    private BigDecimal mMinorsAccountsTotalCurrentAmount;
-
-    private BigDecimal mOwnAccountsTotalAvailableAmount;
-
-    private BigDecimal mOwnAccountsTotalCurrentAmount;
-
-    @JsonProperty("Accounts")
-    public List<IcaBankenAccount> getAccounts() {
-        return mAccounts;
-    }
-
-    public void setAccounts(List<IcaBankenAccount> pAccounts) {
-        this.mAccounts = pAccounts;
-    }
-
-    @JsonProperty("DefaultAccountIdForEgiros")
-    public String getDefaultAccountIdForEgiros() {
-        return mDefaultAccountIdForEgiros;
-    }
-
-    public void setDefaultAccountIdForEgiros(String pDefaultAccountIdForEgiros) {
-        this.mDefaultAccountIdForEgiros = pDefaultAccountIdForEgiros;
-    }
-
-    @JsonProperty("DefaultAccountIdForPayments")
-    public String getDefaultAccountIdForPayments() {
-        return mDefaultAccountIdForPayments;
-    }
-
-    public void setDefaultAccountIdForPayments(
-            String pDefaultAccountIdForPayments) {
-        this.mDefaultAccountIdForPayments = pDefaultAccountIdForPayments;
-    }
-
-    @JsonProperty("DefaultAccountIdForTransfers")
-    public String getDefaultAccountIdForTransfers() {
-        return mDefaultAccountIdForTransfers;
-    }
-
-    public void setDefaultAccountIdForTransfers(
-            String pDefaultAccountIdForTransfers) {
-        this.mDefaultAccountIdForTransfers = pDefaultAccountIdForTransfers;
-    }
-
-    @JsonProperty("JointAccountsTotalAvailableAmount")
-    public BigDecimal getJointAccountsTotalAvailableAmount() {
-        return mJointAccountsTotalAvailableAmount;
-    }
-
-    public void setJointAccountsTotalAvailableAmount(
-            BigDecimal pJointAccountsTotalAvailableAmount) {
-        this.mJointAccountsTotalAvailableAmount = pJointAccountsTotalAvailableAmount;
-    }
-
-    @JsonProperty("JointAccountsTotalCurrentAmount")
-    public BigDecimal getJointAccountsTotalCurrentAmount() {
-        return mJointAccountsTotalCurrentAmount;
-    }
-
-    public void setJointAccountsTotalCurrentAmount(
-            BigDecimal pJointAccountsTotalCurrentAmount) {
-        this.mJointAccountsTotalCurrentAmount = pJointAccountsTotalCurrentAmount;
-    }
-
-    @JsonProperty("MinorsAccountsTotalAvailableAmount")
-    public BigDecimal getMinorsAccountsTotalAvailableAmount() {
-        return mMinorsAccountsTotalAvailableAmount;
-    }
-
-    public void setMinorsAccountsTotalAvailableAmount(
-            BigDecimal pMinorsAccountsTotalAvailableAmount) {
-        this.mMinorsAccountsTotalAvailableAmount = pMinorsAccountsTotalAvailableAmount;
-    }
-
-    @JsonProperty("MinorsAccountsTotalCurrentAmount")
-    public BigDecimal getMinorsAccountsTotalCurrentAmount() {
-        return mMinorsAccountsTotalCurrentAmount;
-    }
-
-    public void setMinorsAccountsTotalCurrentAmount(
-            BigDecimal pMinorsAccountsTotalCurrentAmount) {
-        this.mMinorsAccountsTotalCurrentAmount = pMinorsAccountsTotalCurrentAmount;
-    }
-
-    @JsonProperty("OwnAccountsTotalAvailableAmount")
-    public BigDecimal getOwnAccountsTotalAvailableAmount() {
-        return mOwnAccountsTotalAvailableAmount;
-    }
-
-    public void setOwnAccountsTotalAvailableAmount(
-            BigDecimal pOwnAccountsTotalAvailableAmount) {
-        this.mOwnAccountsTotalAvailableAmount = pOwnAccountsTotalAvailableAmount;
-    }
-
-    @JsonProperty("OwnAccountsTotalCurrentAmount")
-    public BigDecimal getOwnAccountsTotalCurrentAmount() {
-        return mOwnAccountsTotalCurrentAmount;
-    }
-
-    public void setOwnAccountsTotalCurrentAmount(
-            BigDecimal pOwnAccountsTotalCurrentAmount) {
-        this.mOwnAccountsTotalCurrentAmount = pOwnAccountsTotalCurrentAmount;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
deleted file mode 100644
index c356b91..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.liato.bankdroid.banking.banks.icabanken.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-import java.util.Date;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class IcaBankenTransaction {
-
-    private BigDecimal mAccountBalance;
-
-    private BigDecimal mAmount;
-
-    private String mMemoText;
-
-    private Date mPostedDate;
-
-    @JsonProperty("AccountBalance")
-    public BigDecimal getAccountBalance() {
-        return mAccountBalance;
-    }
-
-    public void setAccountBalance(BigDecimal pAccountBalance) {
-        this.mAccountBalance = pAccountBalance;
-    }
-
-    @JsonProperty("Amount")
-    public BigDecimal getAmount() {
-        return mAmount;
-    }
-
-    public void setAmount(BigDecimal pAmount) {
-        this.mAmount = pAmount;
-    }
-
-    @JsonProperty("MemoText")
-    public String getMemoText() {
-        return mMemoText;
-    }
-
-    public void setMemoText(String pMemoText) {
-        this.mMemoText = pMemoText;
-    }
-
-    @JsonProperty("PostedDate")
-    public Date getPostedDate() {
-        return mPostedDate;
-    }
-
-    public void setPostedDate(Date pPostedDate) {
-        this.mPostedDate = pPostedDate;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
deleted file mode 100644
index e6ec565..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.icabanken.model.response;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccountList;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class LoginResponse {
-
-    private String mABCustomerId;
-
-    private IcaBankenAccountList mAccountList;
-
-    private String mSessionId;
-
-    @JsonProperty("ABCustomerId")
-    public String getABCustomerId() {
-        return mABCustomerId;
-    }
-
-    public void setABCustomerId(String pABCustomerId) {
-        this.mABCustomerId = pABCustomerId;
-    }
-
-    @JsonProperty("AccountList")
-    public IcaBankenAccountList getAccountList() {
-        return mAccountList;
-    }
-
-    public void setAccountList(IcaBankenAccountList pAccountList) {
-        this.mAccountList = pAccountList;
-    }
-
-    @JsonProperty("SessionId")
-    public String getSessionId() {
-        return mSessionId;
-    }
-
-    public void setSessionId(String pSessionId) {
-        this.mSessionId = pSessionId;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
deleted file mode 100644
index fb070a8..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class DEVID implements Serializable {
-
-    private static final long serialVersionUID = -8706994448508325149L;
-
-    @JsonProperty("APPLICATION_VERSION")
-    private String applicationVersion;
-
-    @JsonProperty("OS_NAME")
-    private String osName;
-
-    @JsonProperty("MODEL")
-    private String model;
-
-    @JsonProperty("MANUFACTURER")
-    private String manufacturer;
-
-    @JsonProperty("OS_VERSION")
-    private String osVersion;
-
-    @JsonProperty("APPLICATION_NAME")
-    private String applicationName;
-
-
-    public DEVID() {
-
-    }
-
-    public DEVID(String model, String applicationName, String applicationVersion, String osName,
-            String osVersion, String manufacturer) {
-        this.model = model;
-        this.applicationName = applicationName;
-        this.osVersion = osVersion;
-        this.manufacturer = manufacturer;
-        this.applicationVersion = applicationVersion;
-        this.osName = osName;
-    }
-
-    public static DEVID createDefault() {
-        return new DEVID("45", "MASP", "6.0.0", "Android", "5", "Apple");
-    }
-
-    @JsonProperty("APPLICATION_VERSION")
-    public String getApplicationVersion() {
-        return applicationVersion;
-    }
-
-    @JsonProperty("APPLICATION_VERSION")
-    public void setApplicationVersion(String applicationVersion) {
-        this.applicationVersion = applicationVersion;
-    }
-
-    @JsonProperty("OS_NAME")
-    public String getOsName() {
-        return osName;
-    }
-
-    @JsonProperty("OS_NAME")
-    public void setOsName(String osName) {
-        this.osName = osName;
-    }
-
-    @JsonProperty("MODEL")
-    public String getModel() {
-        return model;
-    }
-
-    @JsonProperty("MODEL")
-    public void setModel(String model) {
-        this.model = model;
-    }
-
-    @JsonProperty("MANUFACTURER")
-    public String getManufacturer() {
-        return manufacturer;
-    }
-
-    @JsonProperty("MANUFACTURER")
-    public void setManufacturer(String manufacturer) {
-        this.manufacturer = manufacturer;
-    }
-
-    @JsonProperty("OS_VERSION")
-    public String getOsVersion() {
-        return osVersion;
-    }
-
-    @JsonProperty("OS_VERSION")
-    public void setOsVersion(String osVersion) {
-        this.osVersion = osVersion;
-    }
-
-    @JsonProperty("APPLICATION_NAME")
-    public String getApplicationName() {
-        return applicationName;
-    }
-
-    @JsonProperty("APPLICATION_NAME")
-    public void setApplicationName(String applicationName) {
-        this.applicationName = applicationName;
-    }
-
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
deleted file mode 100644
index 38a42f4..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class HWINFO implements Serializable {
-
-    @JsonProperty("LONGITUDE_DECIMAL")
-    private String longitudeDecimal;
-
-    @JsonProperty("LATITUDE_DECIMAL")
-    private String latitudeDecimal;
-
-    @JsonProperty("COUNTRY_PREFIX")
-    private long countryPrefix;
-
-    public HWINFO() {
-
-    }
-
-    public HWINFO(long countryPrefix, String latitudeDecimal, String longitudeDecimal) {
-        this.countryPrefix = countryPrefix;
-        this.latitudeDecimal = latitudeDecimal;
-        this.longitudeDecimal = longitudeDecimal;
-    }
-
-    public static HWINFO createDefault() {
-        return new HWINFO(0, "0", "0");
-    }
-
-    @JsonProperty("LONGITUDE_DECIMAL")
-    public String getLongitudeDecimal() {
-        return longitudeDecimal;
-    }
-
-    @JsonProperty("LONGITUDE_DECIMAL")
-    public void setLongitudeDecimal(String longitudeDecimal) {
-        this.longitudeDecimal = longitudeDecimal;
-    }
-
-    @JsonProperty("LATITUDE_DECIMAL")
-    public String getLatitudeDecimal() {
-        return latitudeDecimal;
-    }
-
-    @JsonProperty("LATITUDE_DECIMAL")
-    public void setLatitudeDecimal(String latitudeDecimal) {
-        this.latitudeDecimal = latitudeDecimal;
-    }
-
-    @JsonProperty("COUNTRY_PREFIX")
-    public long getCountryPrefix() {
-        return countryPrefix;
-    }
-
-    @JsonProperty("COUNTRY_PREFIX")
-    public void setCountryPrefix(long countryPrefix) {
-        this.countryPrefix = countryPrefix;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
deleted file mode 100644
index 4294369..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Request implements Serializable {
-
-    @JsonProperty("ResultInfo")
-    private Object resultInfo;
-
-    @JsonProperty("VODB")
-    private VODB vODB;
-
-    @JsonProperty("ServiceInput")
-    private List<ServiceInput> serviceInput = new ArrayList<ServiceInput>();
-
-    @JsonProperty("UserCredentials")
-    private UserCredentials userCredentials;
-
-    @JsonProperty("ServiceInfo")
-    private Object serviceInfo;
-
-    @JsonProperty("ResultInfo")
-    public Object getResultInfo() {
-        return resultInfo;
-    }
-
-    @JsonProperty("ResultInfo")
-    public void setResultInfo(Object resultInfo) {
-        this.resultInfo = resultInfo;
-    }
-
-    @JsonProperty("VODB")
-    public VODB getVODB() {
-        return vODB;
-    }
-
-    @JsonProperty("VODB")
-    public void setVODB(VODB vODB) {
-        this.vODB = vODB;
-    }
-
-    @JsonProperty("ServiceInput")
-    public List<ServiceInput> getServiceInput() {
-        return serviceInput;
-    }
-
-    @JsonProperty("ServiceInput")
-    public void setServiceInput(List<ServiceInput> serviceInput) {
-        this.serviceInput = serviceInput;
-    }
-
-    @JsonProperty("UserCredentials")
-    public UserCredentials getUserCredentials() {
-        return userCredentials;
-    }
-
-    @JsonProperty("UserCredentials")
-    public void setUserCredentials(UserCredentials userCredentials) {
-        this.userCredentials = userCredentials;
-    }
-
-    @JsonProperty("ServiceInfo")
-    public Object getServiceInfo() {
-        return serviceInfo;
-    }
-
-    @JsonProperty("ServiceInfo")
-    public void setServiceInfo(Object serviceInfo) {
-        this.serviceInfo = serviceInfo;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
deleted file mode 100644
index 639c23f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class SEBRequest implements Serializable {
-
-    @JsonProperty("request")
-    private Request request;
-
-    @JsonProperty("request")
-    public Request getRequest() {
-        return request;
-    }
-
-    @JsonProperty("request")
-    public void setRequest(Request request) {
-        this.request = request;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
deleted file mode 100644
index 6516f9f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ServiceInput implements Serializable {
-
-    @JsonProperty("Condition")
-    private String condition;
-
-    @JsonProperty("VariableNamePossibleValues")
-    private List<Object> variableNamePossibleValues = new ArrayList<Object>();
-
-    @JsonProperty("VariableName")
-    private String variableName;
-
-    @JsonProperty("VariableValue")
-    private String variableValue;
-
-    @JsonProperty("Condition")
-    public String getCondition() {
-        return condition;
-    }
-
-    @JsonProperty("Condition")
-    public void setCondition(String condition) {
-        this.condition = condition;
-    }
-
-    @JsonProperty("VariableNamePossibleValues")
-    public List<Object> getVariableNamePossibleValues() {
-        return variableNamePossibleValues;
-    }
-
-    @JsonProperty("VariableNamePossibleValues")
-    public void setVariableNamePossibleValues(List<Object> variableNamePossibleValues) {
-        this.variableNamePossibleValues = variableNamePossibleValues;
-    }
-
-    @JsonProperty("VariableName")
-    public String getVariableName() {
-        return variableName;
-    }
-
-    @JsonProperty("VariableName")
-    public void setVariableName(String variableName) {
-        this.variableName = variableName;
-    }
-
-    @JsonProperty("VariableValue")
-    public String getVariableValue() {
-        return variableValue;
-    }
-
-    @JsonProperty("VariableValue")
-    public void setVariableValue(String variableValue) {
-        this.variableValue = variableValue;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
deleted file mode 100644
index ad181f3..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class UserCredentials implements Serializable {
-
-    @JsonProperty("ApplicationName")
-    private String applicationName;
-
-    @JsonProperty("WorkstationID")
-    private String workstationID;
-
-    @JsonProperty("LoggedOnUser")
-    private String loggedOnUser;
-
-    @JsonProperty("AuthMethod")
-    private String authMethod;
-
-    @JsonProperty("UserId")
-    private String userId;
-
-    @JsonProperty("Password")
-    private String password;
-
-    public UserCredentials() {
-
-    }
-
-    public UserCredentials(String userId, String password) {
-        this.userId = userId;
-        this.password = password;
-        this.applicationName = "RFO";
-        this.loggedOnUser = "Mobile";
-        this.workstationID = "";
-        this.authMethod = "0";
-    }
-
-    @JsonProperty("ApplicationName")
-    public String getApplicationName() {
-        return applicationName;
-    }
-
-    @JsonProperty("ApplicationName")
-    public void setApplicationName(String applicationName) {
-        this.applicationName = applicationName;
-    }
-
-    @JsonProperty("WorkstationID")
-    public String getWorkstationID() {
-        return workstationID;
-    }
-
-    @JsonProperty("WorkstationID")
-    public void setWorkstationID(String workstationID) {
-        this.workstationID = workstationID;
-    }
-
-    @JsonProperty("LoggedOnUser")
-    public String getLoggedOnUser() {
-        return loggedOnUser;
-    }
-
-    @JsonProperty("LoggedOnUser")
-    public void setLoggedOnUser(String loggedOnUser) {
-        this.loggedOnUser = loggedOnUser;
-    }
-
-    @JsonProperty("AuthMethod")
-    public String getAuthMethod() {
-        return authMethod;
-    }
-
-    @JsonProperty("AuthMethod")
-    public void setAuthMethod(String authMethod) {
-        this.authMethod = authMethod;
-    }
-
-    @JsonProperty("UserId")
-    public String getUserId() {
-        return userId;
-    }
-
-    @JsonProperty("UserId")
-    public void setUserId(String userId) {
-        this.userId = userId;
-    }
-
-    @JsonProperty("Password")
-    public String getPassword() {
-        return password;
-    }
-
-    @JsonProperty("Password")
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
deleted file mode 100644
index 2ddceff..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.liato.bankdroid.banking.banks.seb.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class VODB implements Serializable {
-
-    private static final long serialVersionUID = 6084093222386932965L;
-
-    @JsonProperty("USRINF01")
-    private Object usrinf01;
-
-    @JsonProperty("DBZV160")
-    private List<Object> dbzv160 = new ArrayList<Object>();
-
-    @JsonProperty("DEVID01")
-    private DEVID devid01;
-
-    @JsonProperty("HWINFO01")
-    private HWINFO hWINFO01;
-
-    @JsonProperty("CBEW501")
-    private List<Object> cbew501 = new ArrayList<Object>();
-
-    @JsonProperty("DBZV170")
-    private List<Object> dbzv170 = new ArrayList<Object>();
-
-    @JsonProperty("CBEW502")
-    private List<Object> cbew502 = new ArrayList<Object>();
-
-    @JsonProperty("USRINF01")
-    public Object getUSRINF01() {
-        return usrinf01;
-    }
-
-    @JsonProperty("USRINF01")
-    public void setUSRINF01(Object uSRINF01) {
-        this.usrinf01 = uSRINF01;
-    }
-
-    @JsonProperty("DBZV160")
-    public List<Object> getDBZV160() {
-        return dbzv160;
-    }
-
-    @JsonProperty("DBZV160")
-    public void setDBZV160(List<Object> dBZV160) {
-        this.dbzv160 = dBZV160;
-    }
-
-    @JsonProperty("DEVID01")
-    public DEVID getDEVID01() {
-        return devid01;
-    }
-
-    @JsonProperty("DEVID01")
-    public void setDEVID01(DEVID dEVID01) {
-        this.devid01 = dEVID01;
-    }
-
-    @JsonProperty("HWINFO01")
-    public HWINFO getHWINFO01() {
-        return hWINFO01;
-    }
-
-    @JsonProperty("HWINFO01")
-    public void setHWINFO01(HWINFO hWINFO01) {
-        this.hWINFO01 = hWINFO01;
-    }
-
-    @JsonProperty("CBEW501")
-    public List<Object> getCBEW501() {
-        return cbew501;
-    }
-
-    @JsonProperty("CBEW501")
-    public void setCBEW501(List<Object> cBEW501) {
-        this.cbew501 = cBEW501;
-    }
-
-    @JsonProperty("DBZV170")
-    public List<Object> getDBZV170() {
-        return dbzv170;
-    }
-
-    @JsonProperty("DBZV170")
-    public void setDBZV170(List<Object> dBZV170) {
-        this.dbzv170 = dBZV170;
-    }
-
-    @JsonProperty("CBEW502")
-    public List<Object> getCBEW502() {
-        return cbew502;
-    }
-
-    @JsonProperty("CBEW502")
-    public void setCBEW502(List<Object> cBEW502) {
-        this.cbew502 = cBEW502;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
deleted file mode 100644
index 7e5486d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks.sebkort;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.banks.sebkort.model.BillingUnit;
-import com.liato.bankdroid.banking.banks.sebkort.model.CardGroup;
-import com.liato.bankdroid.banking.banks.sebkort.model.TransactionGroup;
-import com.liato.bankdroid.banking.banks.sebkort.model.response.BillingUnitsResponse;
-import com.liato.bankdroid.banking.banks.sebkort.model.response.LoginResponse;
-import com.liato.bankdroid.banking.banks.sebkort.model.response.PendingTransactionsResponse;
-import com.liato.bankdroid.banking.banks.sebkort.model.response.UserResponse;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.support.annotation.DrawableRes;
-import android.text.Html;
-import android.text.InputType;
-import android.text.TextUtils;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public abstract class SEBKortBase extends Bank {
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-
-    private static final boolean STATIC_BALANCE = true;
-
-    private ObjectMapper mObjectMapper = new ObjectMapper();
-
-    private String response = null;
-
-    private String mProviderPart;
-
-    private String mProdgroup;
-
-    private String mApiBase;
-
-    private int[] mCertificates;
-
-    private BasicNameValuePair mParamsTarget;
-
-    private BasicNameValuePair mParamsErrorTarget;
-
-    private Map<Account, String> mBillingUnitIds = new HashMap<Account, String>();
-
-
-    public SEBKortBase(Context context, String providerPart, String prodgroup, @DrawableRes int logoResource) {
-        this(context, providerPart, prodgroup, "secure.sebkort.com", new int[]{R.raw.cert_sebkort}, logoResource);
-    }
-
-    public SEBKortBase(Context context, String providerPart, String prodgroup, String apiBase,
-            int[] certificates, @DrawableRes int logoResource) {
-        super(context, logoResource);
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-        super.URL = String
-                .format("https://%s/nis/m/%s/external/t/login/index", apiBase, providerPart);
-        mProviderPart = providerPart;
-        mProdgroup = prodgroup;
-        mApiBase = apiBase;
-        mCertificates = certificates;
-        mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
-        mParamsTarget = new BasicNameValuePair("target", URL);
-        mParamsErrorTarget = new BasicNameValuePair("errorTarget", URL);
-    }
-
-    public SEBKortBase(String username, String password, Context context, String url,
-            String prodgroup, @DrawableRes int logoResource)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context, url, prodgroup, logoResource);
-        this.update(username, password);
-    }
-
-    public SEBKortBase(String username, String password, Context context, String url,
-            String prodgroup, String apiBase, int[] certificates, @DrawableRes int logoResource)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context, url, prodgroup, apiBase, certificates, logoResource);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, mCertificates));
-        //Get required cookies
-        response = urlopen.open(String
-                .format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.clear();
-        postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
-        postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
-        postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
-        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        postData.add(new BasicNameValuePair("UID", mProdgroup + getUsername().toUpperCase()));
-        postData.add(new BasicNameValuePair("PASSWORD", getPassword()));
-        postData.add(new BasicNameValuePair("mProdgroup", mProdgroup));
-        postData.add(mParamsTarget);
-        postData.add(mParamsErrorTarget);
-        return new LoginPackage(urlopen, postData, response,
-                String.format("https://%s/auth4/Authentication/select.jsp", mApiBase));
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        urlopen.addHeader("Origin", String.format("https://%s", mApiBase));
-        urlopen.addHeader("Referer",
-                String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase,
-                        mProviderPart));
-        urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
-        List<NameValuePair> postData = lp.getPostData();
-        postData.remove(mParamsTarget);
-        postData.remove(mParamsErrorTarget);
-        postData.add(new BasicNameValuePair("target",
-                String.format("/nis/m/%s/login/loginSuccess", mProviderPart)));
-        postData.add(new BasicNameValuePair("errorTarget",
-                String.format("/nis/m/%s/external/login/loginError", mProviderPart)));
-
-        LoginResponse r = mObjectMapper
-                .readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
-                        LoginResponse.class);
-        if ("Failure".equalsIgnoreCase(r.getReturnCode())) {
-            throw new LoginException(
-                    !TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString()
-                            : res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-        UserResponse ur = mObjectMapper.readValue(urlopen.openStream(
-                String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)),
-                UserResponse.class);
-        BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(
-                String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)),
-                BillingUnitsResponse.class);
-
-        boolean multipleAccounts = br.getBody().size() > 1;
-        for (BillingUnit bu : br.getBody()) {
-            Account account = new Account(
-                    formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp",
-                            multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()),
-                    bu.getArrangementNumber());
-            account.setType(Account.CCARD);
-            account.setCurrency(currency);
-            mBillingUnitIds.put(account, bu.getBillingUnitId());
-            accounts.add(account);
-            balance = balance.add(account.getBalance());
-            account = new Account(
-                    formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts),
-                    Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
-            account.setType(Account.OTHER);
-            account.setAliasfor(bu.getArrangementNumber());
-            account.setCurrency(currency);
-            accounts.add(account);
-            account = new Account(
-                    formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts),
-                    Helpers.parseBalance(bu.getCreditAmountNumber()),
-                    bu.getArrangementNumber() + "_3");
-            account.setType(Account.OTHER);
-            account.setAliasfor(bu.getArrangementNumber());
-            account.setCurrency(currency);
-            accounts.add(account);
-        }
-
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    private String formatAccountName(String accountNumber, String name,
-            boolean includeAccountNnumber) {
-        return includeAccountNnumber ? String.format("%s (%s)", accountNumber, name) : name;
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        if (account.getType() != Account.CCARD) {
-            return;
-        }
-
-        PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(
-                String.format("https://%s/nis/m/%s/a/pendingTransactions/%s", mApiBase,
-                        mProviderPart, mBillingUnitIds.get(account))),
-                PendingTransactionsResponse.class);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        for (CardGroup cg : r.getBody().getCardGroups()) {
-            for (TransactionGroup tg : cg.getTransactionGroups()) {
-                for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg
-                        .getTransactions()) {
-                    transactions.add(new Transaction(
-                            Helpers.formatDate(new Date(t.getOriginalAmountDateDate())),
-                            t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate(),
-                            account.getCurrency()));
-                }
-            }
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
deleted file mode 100644
index 31568d7..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
+++ /dev/null
@@ -1,229 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-
-public class BillingUnit implements Serializable {
-
-    private static final long serialVersionUID = 335801680600207389L;
-
-    private String mUnInvoicedAmount;
-
-    private boolean mShowCreditAmount;
-
-    private String mArrangementId;
-
-    private ArrayList<Contract> mContracts = new ArrayList<Contract>();
-
-    private String mCutOffDate;
-
-    private String mInterestPercentage;
-
-    private String mCreditAmount;
-
-    private String mLatestPaymentDate;
-
-    private boolean mShowInvoices;
-
-    private String mCreditAmountNumber;
-
-    private String mBillingUnitName;
-
-    private String mBillingUnitId;
-
-    private String mDisposableAmount;
-
-    private String mBalance;
-
-    private boolean mFinanceServiceAllowed;
-
-    private String mLatestPaymentAmount;
-
-    private String mArrangementNumber;
-
-    private String mNextInvoiceDate;
-
-    @JsonProperty("unInvoicedAmount")
-    public String getUnInvoicedAmount() {
-        return mUnInvoicedAmount;
-    }
-
-    @JsonSetter("unInvoicedAmount")
-    public void setUnInvoicedAmount(String u) {
-        mUnInvoicedAmount = u;
-    }
-
-    @JsonProperty("showCreditAmount")
-    public boolean getShowCreditAmount() {
-        return mShowCreditAmount;
-    }
-
-    @JsonSetter("showCreditAmount")
-    public void setShowCreditAmount(boolean s) {
-        mShowCreditAmount = s;
-    }
-
-    @JsonProperty("arrangementId")
-    public String getArrangementId() {
-        return mArrangementId;
-    }
-
-    @JsonSetter("arrangementId")
-    public void setArrangementId(String a) {
-        mArrangementId = a;
-    }
-
-    @JsonProperty("contracts")
-    public ArrayList<Contract> getContracts() {
-        return mContracts;
-    }
-
-    @JsonSetter("contracts")
-    public void setContracts(ArrayList<Contract> c) {
-        mContracts = c;
-    }
-
-    @JsonProperty("cutOffDate")
-    public String getCutOffDate() {
-        return mCutOffDate;
-    }
-
-    @JsonSetter("cutOffDate")
-    public void setCutOffDate(String c) {
-        mCutOffDate = c;
-    }
-
-    @JsonProperty("interestPercentage")
-    public String getInterestPercentage() {
-        return mInterestPercentage;
-    }
-
-    @JsonSetter("interestPercentage")
-    public void setInterestPercentage(String i) {
-        mInterestPercentage = i;
-    }
-
-    @JsonProperty("creditAmount")
-    public String getCreditAmount() {
-        return mCreditAmount;
-    }
-
-    @JsonSetter("creditAmount")
-    public void setCreditAmount(String c) {
-        mCreditAmount = c;
-    }
-
-    @JsonProperty("latestPaymentDate")
-    public String getLatestPaymentDate() {
-        return mLatestPaymentDate;
-    }
-
-    @JsonSetter("latestPaymentDate")
-    public void setLatestPaymentDate(String l) {
-        mLatestPaymentDate = l;
-    }
-
-    @JsonProperty("showInvoices")
-    public boolean getShowInvoices() {
-        return mShowInvoices;
-    }
-
-    @JsonSetter("showInvoices")
-    public void setShowInvoices(boolean s) {
-        mShowInvoices = s;
-    }
-
-    @JsonProperty("creditAmountNumber")
-    public String getCreditAmountNumber() {
-        return mCreditAmountNumber;
-    }
-
-    @JsonSetter("creditAmountNumber")
-    public void setCreditAmountNumber(String c) {
-        mCreditAmountNumber = c;
-    }
-
-    @JsonProperty("billingUnitName")
-    public String getBillingUnitName() {
-        return mBillingUnitName;
-    }
-
-    @JsonSetter("billingUnitName")
-    public void setBillingUnitName(String b) {
-        mBillingUnitName = b;
-    }
-
-    @JsonProperty("billingUnitId")
-    public String getBillingUnitId() {
-        return mBillingUnitId;
-    }
-
-    @JsonSetter("billingUnitId")
-    public void setBillingUnitId(String b) {
-        mBillingUnitId = b;
-    }
-
-    @JsonProperty("disposableAmount")
-    public String getDisposableAmount() {
-        return mDisposableAmount;
-    }
-
-    @JsonSetter("disposableAmount")
-    public void setDisposableAmount(String d) {
-        mDisposableAmount = d;
-    }
-
-    @JsonProperty("balance")
-    public String getBalance() {
-        return mBalance;
-    }
-
-    @JsonSetter("balance")
-    public void setBalance(String b) {
-        mBalance = b;
-    }
-
-    @JsonProperty("financeServiceAllowed")
-    public boolean getFinanceServiceAllowed() {
-        return mFinanceServiceAllowed;
-    }
-
-    @JsonSetter("financeServiceAllowed")
-    public void setFinanceServiceAllowed(boolean f) {
-        mFinanceServiceAllowed = f;
-    }
-
-    @JsonProperty("latestPaymentAmount")
-    public String getLatestPaymentAmount() {
-        return mLatestPaymentAmount;
-    }
-
-    @JsonSetter("latestPaymentAmount")
-    public void setLatestPaymentAmount(String l) {
-        mLatestPaymentAmount = l;
-    }
-
-    @JsonProperty("arrangementNumber")
-    public String getArrangementNumber() {
-        return mArrangementNumber;
-    }
-
-    @JsonSetter("arrangementNumber")
-    public void setArrangementNumber(String a) {
-        mArrangementNumber = a;
-    }
-
-    @JsonProperty("nextInvoiceDate")
-    public String getNextInvoiceDate() {
-        return mNextInvoiceDate;
-    }
-
-    @JsonSetter("nextInvoiceDate")
-    public void setNextInvoiceDate(String n) {
-        mNextInvoiceDate = n;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
deleted file mode 100644
index 0f9edfc..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CardGroup implements Serializable {
-
-    private static final long serialVersionUID = 4603347903479018508L;
-
-    private List<TransactionGroup> mTransactionGroups = new ArrayList<TransactionGroup>();
-
-    private double mTotalNumber;
-
-    private String mTotal;
-
-    private String mMaskedCardNumber;
-
-    private String mNameOnCard;
-
-    @JsonProperty("transactionGroups")
-    public List<TransactionGroup> getTransactionGroups() {
-        return mTransactionGroups;
-    }
-
-    @JsonSetter("transactionGroups")
-    public void setTransactionGroups(List<TransactionGroup> t) {
-        mTransactionGroups = t;
-    }
-
-    @JsonProperty("totalNumber")
-    public double getTotalNumber() {
-        return mTotalNumber;
-    }
-
-    @JsonSetter("totalNumber")
-    public void setTotalNumber(double t) {
-        mTotalNumber = t;
-    }
-
-    @JsonProperty("total")
-    public String getTotal() {
-        return mTotal;
-    }
-
-    @JsonSetter("total")
-    public void setTotal(String t) {
-        mTotal = t;
-    }
-
-    @JsonProperty("maskedCardNumber")
-    public String getMaskedCardNumber() {
-        return mMaskedCardNumber;
-    }
-
-    @JsonSetter("maskedCardNumber")
-    public void setMaskedCardNumber(String m) {
-        mMaskedCardNumber = m;
-    }
-
-    @JsonProperty("nameOnCard")
-    public String getNameOnCard() {
-        return mNameOnCard;
-    }
-
-    @JsonSetter("nameOnCard")
-    public void setNameOnCard(String n) {
-        mNameOnCard = n;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
deleted file mode 100644
index ab4fcf4..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-
-public class Contract implements Serializable {
-
-    private static final long serialVersionUID = 9210413430068677151L;
-
-    private String mUnInvoicedAmount;
-
-    private String mContractName;
-
-    private String mCreditAmount;
-
-    private String mContractId;
-
-    @JsonProperty("unInvoicedAmount")
-    public String getUnInvoicedAmount() {
-        return mUnInvoicedAmount;
-    }
-
-    @JsonSetter("unInvoicedAmount")
-    public void setUnInvoicedAmount(String u) {
-        mUnInvoicedAmount = u;
-    }
-
-    @JsonProperty("contractName")
-    public String getContractName() {
-        return mContractName;
-    }
-
-    @JsonSetter("contractName")
-    public void setContractName(String c) {
-        mContractName = c;
-    }
-
-    @JsonProperty("creditAmount")
-    public String getCreditAmount() {
-        return mCreditAmount;
-    }
-
-    @JsonSetter("creditAmount")
-    public void setCreditAmount(String c) {
-        mCreditAmount = c;
-    }
-
-    @JsonProperty("contractId")
-    public String getContractId() {
-        return mContractId;
-    }
-
-    @JsonSetter("contractId")
-    public void setContractId(String c) {
-        mContractId = c;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
deleted file mode 100644
index 2f71e1d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class PendingTransactions implements Serializable {
-
-    private static final long serialVersionUID = 8675073239578979403L;
-
-    private double mTotalNumber;
-
-    private boolean mMoreDataExists;
-
-    private List<CardGroup> mCobrandCardGroups = new ArrayList<CardGroup>();
-
-    private String mReservedAmount;
-
-    private String mReservedAmountNumber;
-
-    private List<CardGroup> mCardGroups = new ArrayList<CardGroup>();
-
-    private List<TransactionGroup> mTransactionGroups = new ArrayList<TransactionGroup>();
-
-    private String mTotal;
-
-    @JsonProperty("totalNumber")
-    public double getTotalNumber() {
-        return mTotalNumber;
-    }
-
-    @JsonSetter("totalNumber")
-    public void setTotalNumber(double t) {
-        mTotalNumber = t;
-    }
-
-    @JsonProperty("moreDataExists")
-    public boolean getMoreDataExists() {
-        return mMoreDataExists;
-    }
-
-    @JsonSetter("moreDataExists")
-    public void setMoreDataExists(boolean m) {
-        mMoreDataExists = m;
-    }
-
-    @JsonProperty("cobrandCardGroups")
-    public List<CardGroup> getCobrandCardGroups() {
-        return mCobrandCardGroups;
-    }
-
-    @JsonSetter("cobrandCardGroups")
-    public void setCobrandCardGroups(List<CardGroup> c) {
-        mCobrandCardGroups = c;
-    }
-
-    @JsonProperty("reservedAmount")
-    public String getReservedAmount() {
-        return mReservedAmount;
-    }
-
-    @JsonSetter("reservedAmount")
-    public void setReservedAmount(String r) {
-        mReservedAmount = r;
-    }
-
-    @JsonProperty("reservedAmountNumber")
-    public String getReservedAmountNumber() {
-        return mReservedAmountNumber;
-    }
-
-    @JsonSetter("reservedAmountNumber")
-    public void setReservedAmountNumber(String r) {
-        mReservedAmountNumber = r;
-    }
-
-    @JsonProperty("cardGroups")
-    public List<CardGroup> getCardGroups() {
-        return mCardGroups;
-    }
-
-    @JsonSetter("cardGroups")
-    public void setCardGroups(List<CardGroup> c) {
-        mCardGroups = c;
-    }
-
-    @JsonProperty("transactionGroups")
-    public List<TransactionGroup> getTransactionGroups() {
-        return mTransactionGroups;
-    }
-
-    @JsonSetter("transactionGroups")
-    public void setTransactionGroups(List<TransactionGroup> t) {
-        mTransactionGroups = t;
-    }
-
-    @JsonProperty("total")
-    public String getTotal() {
-        return mTotal;
-    }
-
-    @JsonSetter("total")
-    public void setTotal(String t) {
-        mTotal = t;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
deleted file mode 100644
index a9da3af..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-
-public class Transaction implements Serializable {
-
-    private static final long serialVersionUID = 2810644466680342679L;
-
-    private String mCity;
-
-    private String mRefTransactionId;
-
-    private String mDescription;
-
-    private String mExchangeRateDescription;
-
-    private String mOriginalAmountDate;
-
-    private String mOriginalAmountOrVat;
-
-    private String mPostingDate;
-
-    private long mPostingDateDate;
-
-    private String mCurrency;
-
-    private String mAmount;
-
-    private double mAmountNumber;
-
-    private long mTransactionId;
-
-    private String mOriginalAmountOrVatNumber;
-
-    private long mOriginalAmountDateDate;
-
-    @JsonProperty("city")
-    public String getCity() {
-        return mCity;
-    }
-
-    @JsonSetter("city")
-    public void setCity(String c) {
-        mCity = c;
-    }
-
-    @JsonProperty("refTransactionId")
-    public String getRefTransactionId() {
-        return mRefTransactionId;
-    }
-
-    @JsonSetter("refTransactionId")
-    public void setRefTransactionId(String r) {
-        mRefTransactionId = r;
-    }
-
-    @JsonProperty("description")
-    public String getDescription() {
-        return mDescription;
-    }
-
-    @JsonSetter("description")
-    public void setDescription(String d) {
-        mDescription = d;
-    }
-
-    @JsonProperty("exchangeRateDescription")
-    public String getExchangeRateDescription() {
-        return mExchangeRateDescription;
-    }
-
-    @JsonSetter("exchangeRateDescription")
-    public void setExchangeRateDescription(String e) {
-        mExchangeRateDescription = e;
-    }
-
-    @JsonProperty("originalAmountDate")
-    public String getOriginalAmountDate() {
-        return mOriginalAmountDate;
-    }
-
-    @JsonSetter("originalAmountDate")
-    public void setOriginalAmountDate(String o) {
-        mOriginalAmountDate = o;
-    }
-
-    @JsonProperty("originalAmountOrVat")
-    public String getOriginalAmountOrVat() {
-        return mOriginalAmountOrVat;
-    }
-
-    @JsonSetter("originalAmountOrVat")
-    public void setOriginalAmountOrVat(String o) {
-        mOriginalAmountOrVat = o;
-    }
-
-    @JsonProperty("postingDate")
-    public String getPostingDate() {
-        return mPostingDate;
-    }
-
-    @JsonSetter("postingDate")
-    public void setPostingDate(String p) {
-        mPostingDate = p;
-    }
-
-    @JsonProperty("postingDateDate")
-    public long getPostingDateDate() {
-        return mPostingDateDate;
-    }
-
-    @JsonSetter("postingDateDate")
-    public void setPostingDateDate(long p) {
-        mPostingDateDate = p;
-    }
-
-    @JsonProperty("currency")
-    public String getCurrency() {
-        return mCurrency;
-    }
-
-    @JsonSetter("currency")
-    public void setCurrency(String c) {
-        mCurrency = c;
-    }
-
-    @JsonProperty("amount")
-    public String getAmount() {
-        return mAmount;
-    }
-
-    @JsonSetter("amount")
-    public void setAmount(String a) {
-        mAmount = a;
-    }
-
-    @JsonProperty("amountNumber")
-    public double getAmountNumber() {
-        return mAmountNumber;
-    }
-
-    @JsonSetter("amountNumber")
-    public void setAmountNumber(double a) {
-        mAmountNumber = a;
-    }
-
-    @JsonProperty("transactionId")
-    public long getTransactionId() {
-        return mTransactionId;
-    }
-
-    @JsonSetter("transactionId")
-    public void setTransactionId(long t) {
-        mTransactionId = t;
-    }
-
-    @JsonProperty("originalAmountOrVatNumber")
-    public String getOriginalAmountOrVatNumber() {
-        return mOriginalAmountOrVatNumber;
-    }
-
-    @JsonSetter("originalAmountOrVatNumber")
-    public void setOriginalAmountOrVatNumber(String o) {
-        mOriginalAmountOrVatNumber = o;
-    }
-
-    @JsonProperty("originalAmountDateDate")
-    public long getOriginalAmountDateDate() {
-        return mOriginalAmountDateDate;
-    }
-
-    @JsonSetter("originalAmountDateDate")
-    public void setOriginalAmountDateDate(long o) {
-        mOriginalAmountDateDate = o;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
deleted file mode 100644
index 73a9a2a..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class TransactionGroup implements Serializable {
-
-    private static final long serialVersionUID = 5011424262690542196L;
-
-    private String mTotal;
-
-    private String mType;
-
-    private double mTotalNumber;
-
-    private List<Transaction> mTransactions = new ArrayList<Transaction>();
-
-    private String mTitle;
-
-    @JsonProperty("total")
-    public String getTotal() {
-        return mTotal;
-    }
-
-    @JsonSetter("total")
-    public void setTotal(String t) {
-        mTotal = t;
-    }
-
-    @JsonProperty("type")
-    public String getType() {
-        return mType;
-    }
-
-    @JsonSetter("type")
-    public void setType(String t) {
-        mType = t;
-    }
-
-    @JsonProperty("totalNumber")
-    public double getTotalNumber() {
-        return mTotalNumber;
-    }
-
-    @JsonSetter("totalNumber")
-    public void setTotalNumber(double t) {
-        mTotalNumber = t;
-    }
-
-    @JsonProperty("transactions")
-    public List<Transaction> getTransactions() {
-        return mTransactions;
-    }
-
-    @JsonSetter("transactions")
-    public void setTransactions(List<Transaction> t) {
-        mTransactions = t;
-    }
-
-    @JsonProperty("title")
-    public String getTitle() {
-        return mTitle;
-    }
-
-    @JsonSetter("title")
-    public void setTitle(String t) {
-        mTitle = t;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
deleted file mode 100644
index e433d55..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-
-public class User implements Serializable {
-
-    private static final long serialVersionUID = -6588506336066035322L;
-
-    private String mSurName;
-
-    private String mFirstName;
-
-    private boolean mPasswordAuthentication;
-
-    private boolean mCoBrowse;
-
-    private int mAuthenticationTypeId;
-
-    private String mPhone;
-
-    private boolean mHsu;
-
-    private String mEmail;
-
-    private boolean mOtpAuthentication;
-
-    @JsonProperty("surName")
-    public String getSurName() {
-        return mSurName;
-    }
-
-    @JsonSetter("surName")
-    public void setSurName(String s) {
-        mSurName = s;
-    }
-
-    @JsonProperty("firstName")
-    public String getFirstName() {
-        return mFirstName;
-    }
-
-    @JsonSetter("firstName")
-    public void setFirstName(String f) {
-        mFirstName = f;
-    }
-
-    @JsonProperty("passwordAuthentication")
-    public boolean getPasswordAuthentication() {
-        return mPasswordAuthentication;
-    }
-
-    @JsonSetter("passwordAuthentication")
-    public void setPasswordAuthentication(boolean p) {
-        mPasswordAuthentication = p;
-    }
-
-    @JsonProperty("coBrowse")
-    public boolean getCoBrowse() {
-        return mCoBrowse;
-    }
-
-    @JsonSetter("coBrowse")
-    public void setCoBrowse(boolean c) {
-        mCoBrowse = c;
-    }
-
-    @JsonProperty("authenticationTypeId")
-    public int getAuthenticationTypeId() {
-        return mAuthenticationTypeId;
-    }
-
-    @JsonSetter("authenticationTypeId")
-    public void setAuthenticationTypeId(int a) {
-        mAuthenticationTypeId = a;
-    }
-
-    @JsonProperty("phone")
-    public String getPhone() {
-        return mPhone;
-    }
-
-    @JsonSetter("phone")
-    public void setPhone(String p) {
-        mPhone = p;
-    }
-
-    @JsonProperty("hsu")
-    public boolean getHsu() {
-        return mHsu;
-    }
-
-    @JsonSetter("hsu")
-    public void setHsu(boolean h) {
-        mHsu = h;
-    }
-
-    @JsonProperty("email")
-    public String getEmail() {
-        return mEmail;
-    }
-
-    @JsonSetter("email")
-    public void setEmail(String e) {
-        mEmail = e;
-    }
-
-    @JsonProperty("otpAuthentication")
-    public boolean getOtpAuthentication() {
-        return mOtpAuthentication;
-    }
-
-    @JsonSetter("otpAuthentication")
-    public void setOtpAuthentication(boolean o) {
-        mOtpAuthentication = o;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
deleted file mode 100644
index 95a074f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model.response;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSetter;
-
-import java.io.Serializable;
-
-public abstract class BaseResponse<T> implements Serializable {
-
-    private static final long serialVersionUID = 2771913870986291964L;
-
-    private String mErrorCode;
-
-    private String mMessage;
-
-    private String mReturnCode;
-
-    private T mBody;
-
-    @JsonProperty("errorCode")
-    public String getErrorCode() {
-        return mErrorCode;
-    }
-
-    @JsonSetter("errorCode")
-    public void setErrorCode(String e) {
-        mErrorCode = e;
-    }
-
-    @JsonProperty("body")
-    public T getBody() {
-        return mBody;
-    }
-
-    @JsonSetter("body")
-    public void setBody(T b) {
-        mBody = b;
-    }
-
-    @JsonProperty("message")
-    public String getMessage() {
-        return mMessage;
-    }
-
-    @JsonSetter("message")
-    public void setMessage(String m) {
-        mMessage = m;
-    }
-
-    @JsonProperty("returnCode")
-    public String getReturnCode() {
-        return mReturnCode;
-    }
-
-    @JsonSetter("returnCode")
-    public void setReturnCode(String r) {
-        mReturnCode = r;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
deleted file mode 100644
index 5e14eb1..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model.response;
-
-import com.liato.bankdroid.banking.banks.sebkort.model.BillingUnit;
-
-import java.util.ArrayList;
-
-public class BillingUnitsResponse extends BaseResponse<ArrayList<BillingUnit>> {
-
-    private static final long serialVersionUID = 2004033024178420458L;
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
deleted file mode 100644
index f3d6977..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model.response;
-
-public class LoginResponse extends BaseResponse<Object> {
-
-    private static final long serialVersionUID = -5831397352860729105L;
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
deleted file mode 100644
index ed9b9e7..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model.response;
-
-import com.liato.bankdroid.banking.banks.sebkort.model.PendingTransactions;
-
-public class PendingTransactionsResponse extends BaseResponse<PendingTransactions> {
-
-    private static final long serialVersionUID = 3753708966368822328L;
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
deleted file mode 100644
index 705c27c..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.liato.bankdroid.banking.banks.sebkort.model.response;
-
-import com.liato.bankdroid.banking.banks.sebkort.model.User;
-
-
-public class UserResponse extends BaseResponse<User> {
-
-    private static final long serialVersionUID = -7005608413740529742L;
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
deleted file mode 100644
index 38f511d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ /dev/null
@@ -1,359 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankChoice;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
-import com.liato.bankdroid.banking.banks.swedbank.model.CardTransaction;
-import com.liato.bankdroid.banking.banks.swedbank.model.ErrorMessage;
-import com.liato.bankdroid.banking.banks.swedbank.model.ErrorResponse;
-import com.liato.bankdroid.banking.banks.swedbank.model.engagement.CardAccountResponse;
-import com.liato.bankdroid.banking.banks.swedbank.model.engagement.OverviewResponse;
-import com.liato.bankdroid.banking.banks.swedbank.model.engagement.TransactionsResponse;
-import com.liato.bankdroid.banking.banks.swedbank.model.identification.PersonalCodeRequest;
-import com.liato.bankdroid.banking.banks.swedbank.model.profile.ProfileResponse;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.utils.Installation;
-import com.liato.bankdroid.utils.StringUtils;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.support.annotation.DrawableRes;
-import android.text.Html;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.Base64;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.HttpMethod;
-import eu.nullbyte.android.urllib.Urllib;
-import timber.log.Timber;
-
-public abstract class AbstractSwedbank extends Bank {
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-
-    private static final boolean WEB_VIEW_ENABLED = false;
-
-    private static final String API_BASE
-            = "https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/";
-
-    private ObjectMapper mObjectMapper = new ObjectMapper();
-
-    private Map<String, String> mIdMap = new HashMap<String, String>();
-
-    public AbstractSwedbank(Context context, @DrawableRes int logoResource) {
-        super(context, logoResource);
-        SimpleModule module = new SimpleModule();
-        module.addDeserializer(BigDecimal.class, new BalanceDeserializer());
-        mObjectMapper.registerModule(module);
-
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.WEB_VIEW_ENABLED = WEB_VIEW_ENABLED;
-    }
-
-    public AbstractSwedbank(String username, String password, Context context, @DrawableRes int logoResource) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context, logoResource);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_swedbank));
-        urlopen.addHeader("Authorization", getAuthenticationHeader());
-        urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
-        urlopen.addHeader("Accept", "application/json");
-        return new LoginPackage(urlopen, null, null, getResourceUri("identification/personalcode"));
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        HttpResponse httpResponse = null;
-        try {
-            LoginPackage lp = preLogin();
-            httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(),
-                    new StringEntity(objectAsJson(new PersonalCodeRequest(getUsername(), getPassword())),
-                            HTTP.UTF_8), true);
-            int responseCode = httpResponse.getStatusLine().getStatusCode();
-            if (responseCode == 201) {
-                return urlopen;
-            } else if (responseCode == 401 || responseCode == 400) {
-                throw new LoginException(res.getText(
-                        R.string.invalid_username_password).toString());
-            } else if (responseCode == 503) {
-                String errorMessage = null;
-                try {
-                    ErrorResponse er = readJsonValue(httpResponse.getEntity().getContent(),
-                            ErrorResponse.class);
-                    StringBuilder sb = new StringBuilder();
-                    for (List<ErrorMessage> ems : er.getErrorMessages().values()) {
-                        for (ErrorMessage em : ems) {
-                            sb.append(Html.fromHtml(em.getMessage()).toString()).append("\n");
-                        }
-                    }
-                    errorMessage = sb.toString().trim();
-                } catch (BankException e) {
-                    //Ignore json parse errors and show generic server error message
-                }
-                throw new BankException(TextUtils.isEmpty(errorMessage) ? context
-                        .getString(R.string.server_error_try_again) : errorMessage);
-            } else {
-                throw new BankException("");
-            }
-        } finally {
-            if (httpResponse != null) {
-                HttpEntity httpEntity = httpResponse.getEntity();
-                if (httpEntity != null) {
-                    try {
-                        httpEntity.consumeContent();
-                    } catch (IOException e) {
-                        throw new BankException(e.getMessage(), e);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-
-        ProfileResponse profileResponse = getAvailableProfiles();
-        setDefaultProfile(getBankId(profileResponse.getBanks()));
-
-        HttpResponse httpResponse = urlopen
-                .openAsHttpResponse(getResourceUri("engagement/overview"), false);
-        if (httpResponse.getStatusLine().getStatusCode() != 200) {
-            throw new BankException(httpResponse.getStatusLine().toString());
-        }
-
-        OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),
-                OverviewResponse.class);
-        addAccounts(overviewResponse.getTransactionAccounts(), Account.REGULAR);
-        addAccounts(overviewResponse.getSavingAccounts(), Account.REGULAR);
-        addAccounts(overviewResponse.getTransactionDisposalAccounts(), Account.REGULAR);
-        addAccounts(overviewResponse.getSavingDisposalAccounts(), Account.REGULAR);
-        addCardAccounts(overviewResponse.getCardAccounts());
-        addAccounts(overviewResponse.getLoanAccounts(), Account.LOANS);
-        if (this.accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-        if (account.getType() == Account.CCARD) {
-            updateCreditCardTransactions(account, urlopen);
-            return;
-        } else if (account.getType() != Account.REGULAR) {
-            return;
-        } else if (mIdMap.get(account.getId()) == null) {
-            return;
-        }
-
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(
-                getResourceUri("engagement/transactions/" + mIdMap.get(account.getId())), false);
-
-        TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(),
-                TransactionsResponse.class);
-        List<Transaction> transactions = new ArrayList<Transaction>();
-        transactions.addAll(transformTransactions(response.getTransactions()));
-        transactions.addAll(transformTransactions(response.getReservedTransactions()));
-        account.setTransactions(transactions);
-    }
-
-    @Override
-    public void closeConnection() {
-        try {
-            HttpResponse response = urlopen
-                    .openAsHttpResponse(getResourceUri("identification/logout"), HttpMethod.PUT);
-        } catch (IOException e) {
-            //Ignore logout exceptions
-        } finally {
-            super.closeConnection();
-        }
-    }
-
-    private void updateCreditCardTransactions(Account account, Urllib urlopen) throws BankException,
-            IOException {
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(
-                getResourceUri("engagement/cardaccount/" + mIdMap.get(account.getId())), false);
-        int responseCode = httpResponse.getStatusLine().getStatusCode();
-        if (responseCode != 200) {
-            Timber.i(
-                    "Couldn't find transactions for creditcard. Got response code %d",
-                    responseCode);
-            account.setTransactions(Collections.<Transaction>emptyList());
-            return;
-        }
-        CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),
-                CardAccountResponse.class);
-        List<Transaction> transactions = new ArrayList<Transaction>();
-        transactions.addAll(transformCardTransactions(response.getTransactions()));
-        transactions.addAll(transformCardTransactions(response.getReservedTransactions()));
-        account.setTransactions(transactions);
-    }
-
-    private List<Transaction> transformTransactions(
-            List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {
-        List<Transaction> transactionList = new ArrayList<Transaction>();
-        for (com.liato.bankdroid.banking.banks.swedbank.model.Transaction transaction : transactions) {
-            transactionList.add(new Transaction(transaction.getDate(), transaction.getDescription(),
-                    transaction.getAmount(), transaction.getCurrency()));
-        }
-        return transactionList;
-    }
-
-    private List<Transaction> transformCardTransactions(List<CardTransaction> transactions) {
-        List<Transaction> transactionList = new ArrayList<Transaction>();
-        for (CardTransaction transaction : transactions) {
-            transactionList.add(new Transaction(transaction.getDate(),
-                    transaction.getDescription(),
-                    transaction.getLocalAmount().getAmount(),
-                    transaction.getLocalAmount().getCurrencyCode()));
-        }
-        return transactionList;
-    }
-
-    private ProfileResponse getAvailableProfiles()
-            throws IOException, BankException, LoginException {
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/"), false);
-        if (httpResponse.getStatusLine().getStatusCode() == 200) {
-            ProfileResponse response = readJsonValue(httpResponse.getEntity().getContent(),
-                    ProfileResponse.class);
-            if (response.getBanks().isEmpty()) {
-                String provider = response.isSwedbankProfile() ? "Swedbank"
-                        : response.isSavingbankProfile() ? "Sparbankerna" : null;
-                if (provider != null) {
-                    throw new LoginException(
-                            "You are trying to connect an account from " + provider + " to the "
-                                    + NAME + " bank. Please use the " + provider
-                                    + " bank instead.");
-                } else {
-                    throw new BankException("No profiles available.");
-                }
-            }
-            return response;
-        }
-        throw new BankException("Could not fetch available profiles.");
-    }
-
-    private void setDefaultProfile(String bankId) throws IOException, BankException {
-        HttpResponse httpResponse = urlopen
-                .openAsHttpResponse(getResourceUri("profile/private/" + bankId), true);
-        httpResponse.getEntity().consumeContent();
-        if (httpResponse.getStatusLine().getStatusCode() != 201) {
-            throw new BankException("Could not set the default profile.");
-        }
-    }
-
-    private String getBankId(List<com.liato.bankdroid.banking.banks.swedbank.model.Bank> bankList)
-            throws BankChoiceException {
-        String bankId = getExtras();
-        if (bankId != null && !bankId.isEmpty()) {
-            return bankId;
-        }
-        if (bankList.size() > 1) {
-            ArrayList<BankChoice> banks = new ArrayList<BankChoice>();
-            for (com.liato.bankdroid.banking.banks.swedbank.model.Bank bank : bankList) {
-                banks.add(new BankChoice(bank.getName(), bank.getBankId()));
-            }
-            throw new BankChoiceException("Select a bank.", banks);
-        }
-        return bankList.get(0).getBankId();
-    }
-
-    private void addAccounts(
-            List<com.liato.bankdroid.banking.banks.swedbank.model.Account> accountList,
-            int accountType) {
-        for (com.liato.bankdroid.banking.banks.swedbank.model.Account account : accountList) {
-            Account bankdroidAccount = new Account(account.getName(), account.getBalance(),
-                    account.getFullyFormattedNumber(), accountType, account.getCurrency());
-            mIdMap.put(bankdroidAccount.getId(), account.getId());
-            this.accounts.add(bankdroidAccount);
-        }
-    }
-
-    private void addCardAccounts(List<CardAccount> accountList) {
-        for (CardAccount account : accountList) {
-            String currency = account.getCurrency() == null ? "SEK" : account.getCurrency();
-            Account bankdroidAccount = new Account(account.getName(), account.getAvailableAmount(),
-                    account.getCardNumber(), Account.CCARD, currency);
-            mIdMap.put(bankdroidAccount.getId(), account.getId());
-            this.accounts.add(bankdroidAccount);
-        }
-    }
-
-    private String getAuthenticationHeader() {
-        byte[] data = StringUtils.getBytes(getAppId() +
-                ':' +
-                Installation.id(context));
-        return Base64.encodeToString(data, Base64.NO_WRAP);
-    }
-
-    private String getResourceUri(String resource) {
-        String dsid = "dsid=" + UUID.randomUUID().toString();
-        urlopen.addHeader("Cookie", dsid);
-        return API_BASE + resource + '?' + dsid;
-    }
-
-    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException, IOException {
-        try {
-            return mObjectMapper.readValue(is, valueType);
-        } catch(JsonParseException | JsonMappingException e) {
-            throw new BankException(e.getMessage(), e);
-        } finally {
-            try {
-                is.close();
-            } catch (IOException e) {
-                //Ignore
-            }
-        }
-
-    }
-
-    public String objectAsJson(Object value) throws BankException {
-        try {
-            return mObjectMapper.writeValueAsString(value);
-        } catch (JsonProcessingException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-    }
-
-    protected abstract String getAppId();
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
deleted file mode 100644
index c8bbb5d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonDeserializer;
-import com.liato.bankdroid.Helpers;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-
-
-public class BalanceDeserializer extends JsonDeserializer<BigDecimal> {
-
-    @Override
-    public BigDecimal deserialize(JsonParser jp, DeserializationContext ctxt)
-            throws IOException, JsonProcessingException {
-        return Helpers.parseBalance(jp.getValueAsString());
-
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
deleted file mode 100644
index e7924e9..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class Sparbankerna extends AbstractSwedbank {
-
-    protected static final String NAME_SHORT = "sparbankerna";
-
-    private static final String NAME = "Sparbankerna";
-
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
-
-    private static final String APP_ID = "qdorTi1mqZ09Zcyc";
-
-    public Sparbankerna(Context context) {
-        super(context, R.drawable.logo_sparbankerna);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-
-    }
-
-    public Sparbankerna(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected String getAppId() {
-        return APP_ID;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
deleted file mode 100644
index 06466d3..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class SparbankernaCorporate extends AbstractSwedbank {
-
-    private static final String NAME = "Sparbankerna Företag";
-
-    private static final String NAME_SHORT = "sparbankerna-corporate";
-
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA_CORPORATE;
-
-    private static final String APP_ID = "qdorTi1mqZ09Zcyc";
-
-    public SparbankernaCorporate(Context context) {
-        super(context, R.drawable.logo_sparbankerna);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-
-    }
-
-    public SparbankernaCorporate(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected String getAppId() {
-        return APP_ID;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
deleted file mode 100644
index 10eaaca..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class SparbankernaYouth extends AbstractSwedbank {
-
-    private static final String NAME = "Sparbankerna Ung";
-
-    private static final String NAME_SHORT = "sparbankerna-youth";
-
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA_YOUTH;
-
-    private static final String APP_ID = "QtDHyRnJvEuET2vU";
-
-    public SparbankernaYouth(Context context) {
-        super(context, R.drawable.logo_sparbankerna);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-
-    }
-
-    public SparbankernaYouth(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected String getAppId() {
-        return APP_ID;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
deleted file mode 100644
index c73dc9d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class Swedbank extends AbstractSwedbank {
-
-    protected static final String NAME_SHORT = "swedbank";
-
-    private static final String NAME = "Swedbank";
-
-    private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
-
-    private static final String APP_ID = "vgmYRMelBJ0Yzujs";
-
-    public Swedbank(Context context) {
-        super(context, R.drawable.logo_swedbank);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-
-    }
-
-    public Swedbank(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected String getAppId() {
-        return APP_ID;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
deleted file mode 100644
index ea492a3..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class SwedbankCorporate extends AbstractSwedbank {
-
-    private static final String NAME = "Swedbank Företag";
-
-    private static final String NAME_SHORT = "swedbank-corporate";
-
-    private static final int BANKTYPE_ID = IBankTypes.SWEDBANK_CORPORATE;
-
-    private static final String APP_ID = "Our91qzclXdNmpdE";
-
-    public SwedbankCorporate(Context context) {
-        super(context, R.drawable.logo_swedbank);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-
-    }
-
-    public SwedbankCorporate(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected String getAppId() {
-        return APP_ID;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
deleted file mode 100644
index c0ed666..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank;
-
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import android.content.Context;
-
-import java.io.IOException;
-
-public class SwedbankYouth extends AbstractSwedbank {
-
-    private static final String NAME = "Swedbank Ung";
-
-    private static final String NAME_SHORT = "swedbank-youth";
-
-    private static final int BANKTYPE_ID = IBankTypes.SWEDBANK_YOUTH;
-
-    private static final String APP_ID = "19AaEzp0jQJDt3vO";
-
-    public SwedbankYouth(Context context) {
-        super(context, R.drawable.logo_swedbank);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-
-    }
-
-    public SwedbankYouth(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected String getAppId() {
-        return APP_ID;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
deleted file mode 100644
index d89d625..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Account {
-
-    @JsonProperty
-    private boolean selectedForQuickBalance;
-
-    @JsonProperty
-    private String id;
-
-    @JsonProperty
-    private String name;
-
-    @JsonProperty
-    private BigDecimal balance;
-
-    @JsonProperty
-    private String currency;
-
-    @JsonProperty
-    private String fullyFormattedNumber;
-
-    @JsonProperty
-    private String accountNumber;
-
-    @JsonProperty
-    private String clearingNumber;
-
-    public boolean isSelectedForQuickBalance() {
-        return selectedForQuickBalance;
-    }
-
-    public void setSelectedForQuickBalance(boolean selectedForQuickBalance) {
-        this.selectedForQuickBalance = selectedForQuickBalance;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public BigDecimal getBalance() {
-        return balance != null ? balance : BigDecimal.ZERO;
-    }
-
-    public void setBalance(BigDecimal balance) {
-        this.balance = balance;
-    }
-
-    public String getCurrency() {
-        return currency != null ? currency : "";
-    }
-
-    public void setCurrency(String currency) {
-        this.currency = currency;
-    }
-
-    public String getFullyFormattedNumber() {
-        return fullyFormattedNumber;
-    }
-
-    public String getAccountNumber() {
-        return accountNumber;
-    }
-
-    public String getClearingNumber() {
-        return clearingNumber;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
deleted file mode 100644
index 26e973e..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-
-public class Amount {
-
-    @JsonProperty
-    private BigDecimal amount;
-
-    @JsonProperty
-    private String currencyCode;
-
-    public BigDecimal getAmount() {
-        return amount;
-    }
-
-    public void setAmount(BigDecimal amount) {
-        this.amount = amount;
-    }
-
-    public String getCurrencyCode() {
-        return currencyCode;
-    }
-
-    public void setCurrencyCode(String currencyCode) {
-        this.currencyCode = currencyCode;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
deleted file mode 100644
index 8c6408e..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Bank {
-
-    @JsonProperty
-    private String name;
-
-    @JsonProperty
-    private String bankId;
-
-    @JsonProperty
-    private Profile privateProfile;
-
-    @JsonProperty
-    private List<CorporateProfile> corporateProfiles;
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getBankId() {
-        return bankId;
-    }
-
-    public void setBankId(String bankId) {
-        this.bankId = bankId;
-    }
-
-    public Profile getPrivateProfile() {
-        return privateProfile;
-    }
-
-    public void setPrivateProfile(Profile privateProfile) {
-        this.privateProfile = privateProfile;
-    }
-
-    public List<CorporateProfile> getCorporateProfiles() {
-        if (corporateProfiles == null) {
-            corporateProfiles = new ArrayList<CorporateProfile>();
-        }
-        return corporateProfiles;
-    }
-
-    public void setCorporateProfiles(List<CorporateProfile> corporateProfiles) {
-        this.corporateProfiles = corporateProfiles;
-    }
-}
-
-
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
deleted file mode 100644
index 0fa5982..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CardAccount {
-
-    @JsonProperty
-    private String id;
-
-    @JsonProperty
-    private String name;
-
-    @JsonProperty
-    private BigDecimal creditLimit;
-
-    @JsonProperty
-    private BigDecimal currentBalance;
-
-    @JsonProperty
-    private BigDecimal reservedAmount;
-
-    @JsonProperty
-    private BigDecimal availableAmount;
-
-    @JsonProperty
-    private String currency;
-
-    @JsonProperty
-    private String cardNumber;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public BigDecimal getCreditLimit() {
-        return creditLimit;
-    }
-
-    public void setCreditLimit(BigDecimal creditLimit) {
-        this.creditLimit = creditLimit;
-    }
-
-    public BigDecimal getCurrentBalance() {
-        return currentBalance;
-    }
-
-    public void setCurrentBalance(BigDecimal currentBalance) {
-        this.currentBalance = currentBalance;
-    }
-
-    public BigDecimal getReservedAmount() {
-        return reservedAmount;
-    }
-
-    public void setReservedAmount(BigDecimal reservedAmount) {
-        this.reservedAmount = reservedAmount;
-    }
-
-    public BigDecimal getAvailableAmount() {
-        return availableAmount;
-    }
-
-    public void setAvailableAmount(BigDecimal availableAmount) {
-        this.availableAmount = availableAmount;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getCurrency() {
-        return currency;
-    }
-
-    public void setCurrency(String currency) {
-        this.currency = currency;
-    }
-
-    public String getCardNumber() {
-        return cardNumber;
-    }
-
-    public void setCardNumber(String cardNumber) {
-        this.cardNumber = cardNumber;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
deleted file mode 100644
index 283e2f8..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CardTransaction {
-
-    @JsonProperty
-    private String date;
-
-    @JsonProperty
-    private String description;
-
-    @JsonProperty
-    private Amount foreignAmount;
-
-    @JsonProperty
-    private Amount localAmount;
-
-    public String getDate() {
-        return date;
-    }
-
-    public void setDate(String date) {
-        this.date = date;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public Amount getForeignAmount() {
-        return foreignAmount;
-    }
-
-    public void setForeignAmount(Amount foreignAmount) {
-        this.foreignAmount = foreignAmount;
-    }
-
-    public Amount getLocalAmount() {
-        return localAmount;
-    }
-
-    public void setLocalAmount(Amount localAmount) {
-        this.localAmount = localAmount;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
deleted file mode 100644
index 0a7a3ef..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CorporateProfile extends Profile {
-
-    @JsonProperty
-    private String activeProfileName;
-
-    public String getActiveProfileName() {
-        return activeProfileName;
-    }
-
-    public void setActiveProfileName(String activeProfileName) {
-        this.activeProfileName = activeProfileName;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
deleted file mode 100644
index 68e5c8e..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CreditCard {
-
-    @JsonProperty
-    private String currency;
-
-    @JsonProperty
-    private String name;
-
-    @JsonProperty
-    private String balance;
-
-    @JsonProperty
-    private List<String> cardNumbers;
-
-    public String getCurrency() {
-        return currency;
-    }
-
-    public void setCurrency(String currency) {
-        this.currency = currency;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getBalance() {
-        return balance;
-    }
-
-    public void setBalance(String balance) {
-        this.balance = balance;
-    }
-
-    public List<String> getCardNumbers() {
-        if (cardNumbers == null) {
-            cardNumbers = new ArrayList<String>();
-        }
-        return cardNumbers;
-    }
-
-    public void setCardNumbers(List<String> cardNumbers) {
-        this.cardNumbers = cardNumbers;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
deleted file mode 100644
index 95c5a3d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2014 Nullbyte
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-
-public class ErrorMessage implements Serializable {
-
-    private static final long serialVersionUID = 7228754028321179052L;
-
-    @JsonProperty
-    String title;
-
-    @JsonProperty
-    String code;
-
-    @JsonProperty
-    String message;
-
-    public String getTitle() {
-        return title;
-    }
-
-    public String getCode() {
-        return code;
-    }
-
-    public String getMessage() {
-        return message;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
deleted file mode 100644
index fac0869..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2014 Nullbyte
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-
-/*
-{
-    "errorMessages": {
-        "general": [{
-            "title": "Mobilbanken ej tillg&auml;nglig",
-            "code": "SERVICE_UNAVAILABLE",
-            "message": "F&ouml;r n&auml;rvarande &auml;r Mobil- och iPad-apparna otillg&auml;ngliga. V&auml;nligen f&ouml;rs&ouml;k igen senare."
-        }]
-    }
-}
- */
-//@JsonIgnoreProperties(ignoreUnknown = true)
-public class ErrorResponse implements Serializable {
-
-    private static final long serialVersionUID = 1971937841087070779L;
-
-    @JsonProperty
-    Map<String, ArrayList<ErrorMessage>> errorMessages = Collections.emptyMap();
-
-    public Map<String, ArrayList<ErrorMessage>> getErrorMessages() {
-        return errorMessages;
-    }
-
-}
-
-
-
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
deleted file mode 100644
index e07cd43..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class OperationalMessages {
-
-    @JsonProperty
-    private String title;
-
-    @JsonProperty
-    private String message;
-
-    public String getMessage() {
-        return message;
-    }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
deleted file mode 100644
index 97aa94a..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Profile {
-
-    @JsonProperty
-    private String customerName;
-
-    @JsonProperty
-    private String customerNumber;
-
-    @JsonProperty
-    private String id;
-
-    public String getCustomerName() {
-        return customerName;
-    }
-
-    public void setCustomerName(String customerName) {
-        this.customerName = customerName;
-    }
-
-    public String getCustomerNumber() {
-        return customerNumber;
-    }
-
-    public void setCustomerNumber(String customerNumber) {
-        this.customerNumber = customerNumber;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-}
-
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
deleted file mode 100644
index d2c862f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.math.BigDecimal;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Transaction {
-
-    @JsonProperty
-    private String date;
-
-    @JsonProperty
-    private BigDecimal amount;
-
-    @JsonProperty
-    private String description;
-
-    @JsonProperty
-    private String currency;
-
-    public String getDate() {
-        return date;
-    }
-
-    public void setDate(String date) {
-        this.date = date;
-    }
-
-    public BigDecimal getAmount() {
-        return amount;
-    }
-
-    public void setAmount(BigDecimal amount) {
-        this.amount = amount;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getCurrency() {
-        return currency;
-    }
-
-    public void setCurrency(String currency) {
-        this.currency = currency;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
deleted file mode 100644
index 7396285..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
-import com.liato.bankdroid.banking.banks.swedbank.model.CardTransaction;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CardAccountResponse {
-
-    @JsonProperty
-    private CardAccount cardAccount;
-
-    @JsonProperty
-    private List<CardTransaction> transactions;
-
-    @JsonProperty
-    private List<CardTransaction> reservedTransactions;
-
-    public CardAccount getCardAccount() {
-        return cardAccount;
-    }
-
-    public void setCardAccount(CardAccount cardAccount) {
-        this.cardAccount = cardAccount;
-    }
-
-    public List<CardTransaction> getTransactions() {
-        if (transactions == null) {
-            transactions = new ArrayList<CardTransaction>();
-        }
-        return transactions;
-    }
-
-    public void setTransactions(List<CardTransaction> transactions) {
-        this.transactions = transactions;
-    }
-
-    public List<CardTransaction> getReservedTransactions() {
-        if (reservedTransactions == null) {
-            reservedTransactions = new ArrayList<CardTransaction>();
-        }
-        return reservedTransactions;
-    }
-
-    public void setReservedTransactions(List<CardTransaction> reservedTransactions) {
-        this.reservedTransactions = reservedTransactions;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
deleted file mode 100644
index c5133d9..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.liato.bankdroid.banking.banks.swedbank.model.Account;
-import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
-import com.liato.bankdroid.banking.banks.swedbank.model.CreditCard;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class OverviewResponse {
-
-    @JsonProperty
-    private CreditCard creditCard;
-
-    @JsonProperty
-    private List<Account> transactionAccounts;
-
-    @JsonProperty
-    private List<Account> savingAccounts;
-
-    @JsonProperty("loanAccounts")
-    private List<Account> loanAccounts;
-
-    @JsonProperty
-    private List<Account> transactionDisposalAccounts;
-
-    @JsonProperty
-    private List<Account> savingDisposalAccounts;
-
-    @JsonProperty
-    private List<CardAccount> cardAccounts;
-
-    public CreditCard getCreditCard() {
-        return creditCard;
-    }
-
-    public void setCreditCard(CreditCard creditCard) {
-        this.creditCard = creditCard;
-    }
-
-    public List<Account> getTransactionAccounts() {
-        if (transactionAccounts == null) {
-            transactionAccounts = new ArrayList<Account>();
-        }
-        return transactionAccounts;
-    }
-
-    public void setTransactionAccounts(List<Account> transactionAccounts) {
-        this.transactionAccounts = transactionAccounts;
-    }
-
-    public List<Account> getSavingAccounts() {
-        if (savingAccounts == null) {
-            savingAccounts = new ArrayList<Account>();
-        }
-        return savingAccounts;
-    }
-
-    public void setSavingAccounts(List<Account> savingAccounts) {
-        this.savingAccounts = savingAccounts;
-    }
-
-    public List<Account> getLoanAccounts() {
-        if (loanAccounts == null) {
-            loanAccounts = new ArrayList<Account>();
-        }
-        return loanAccounts;
-    }
-
-    public void setLoanAccounts(List<Account> loanAccounts) {
-        this.loanAccounts = loanAccounts;
-    }
-
-    public List<Account> getTransactionDisposalAccounts() {
-        if (transactionDisposalAccounts == null) {
-            transactionDisposalAccounts = new ArrayList<Account>();
-        }
-        return transactionDisposalAccounts;
-    }
-
-    public void setTransactionDisposalAccounts(List<Account> transactionDisposalAccounts) {
-        this.transactionDisposalAccounts = transactionDisposalAccounts;
-    }
-
-    public List<Account> getSavingDisposalAccounts() {
-        if (savingDisposalAccounts == null) {
-            savingDisposalAccounts = new ArrayList<Account>();
-        }
-        return savingDisposalAccounts;
-    }
-
-    public void setSavingDisposalAccounts(List<Account> savingDisposalAccounts) {
-        this.savingDisposalAccounts = savingDisposalAccounts;
-    }
-
-    public List<CardAccount> getCardAccounts() {
-        if (cardAccounts == null) {
-            cardAccounts = new ArrayList<CardAccount>();
-        }
-        return cardAccounts;
-    }
-
-    public void setCardAccounts(List<CardAccount> cardAccounts) {
-        this.cardAccounts = cardAccounts;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
deleted file mode 100644
index ce7c84f..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.liato.bankdroid.banking.banks.swedbank.model.Transaction;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class TransactionsResponse {
-
-    @JsonProperty
-    private List<Transaction> transactions;
-
-    @JsonProperty
-    private List<Transaction> reservedTransactions;
-
-    public List<Transaction> getTransactions() {
-        if (transactions == null) {
-            transactions = new ArrayList<Transaction>();
-        }
-        return transactions;
-    }
-
-    public void setTransactions(List<Transaction> transactions) {
-        this.transactions = transactions;
-    }
-
-    public List<Transaction> getReservedTransactions() {
-        if (reservedTransactions == null) {
-            reservedTransactions = new ArrayList<Transaction>();
-        }
-        return reservedTransactions;
-    }
-
-    public void setReservedTransactions(List<Transaction> reservedTransactions) {
-        this.reservedTransactions = reservedTransactions;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
deleted file mode 100644
index 67748c7..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model.identification;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class PersonalCodeRequest {
-
-    /**
-     * May be a personal number or a fictive personal number. Format YYYYMMDD-NNNN.
-     */
-    @JsonProperty
-    private String userId;
-
-    @JsonProperty
-    private String password;
-
-    public PersonalCodeRequest(String userId, String password) {
-        this.userId = userId;
-        this.password = password;
-    }
-
-    public String getUserId() {
-        return userId;
-    }
-
-    public void setUserId(String userId) {
-        this.userId = userId;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
deleted file mode 100644
index e20c3ce..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model.identification;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.liato.bankdroid.banking.banks.swedbank.model.OperationalMessages;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class PersonalCodeResponse {
-
-    @JsonProperty
-    private boolean personalCodeChangeRequired;
-
-    @JsonProperty
-    private List<OperationalMessages> operationalMessages;
-
-    public boolean getPersonalCodeChangeRequired() {
-        return personalCodeChangeRequired;
-    }
-
-    public void setPersonalCodeChangeRequired(boolean personalCodeChangeRequired) {
-        this.personalCodeChangeRequired = personalCodeChangeRequired;
-    }
-
-    public List<OperationalMessages> getOperationalMessages() {
-        if (operationalMessages == null) {
-            operationalMessages = new ArrayList<OperationalMessages>();
-        }
-        return operationalMessages;
-    }
-
-    public void setOperationalMessages(List<OperationalMessages> operationalMessages) {
-        this.operationalMessages = operationalMessages;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
deleted file mode 100644
index 6900058..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.liato.bankdroid.banking.banks.swedbank.model.profile;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.liato.bankdroid.banking.banks.swedbank.model.Bank;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ProfileResponse {
-
-    @JsonProperty("hasSwedbankProfile")
-    private boolean swedbankProfile;
-
-    @JsonProperty("hasSavingbankProfile")
-    private boolean savingbankProfile;
-
-    @JsonProperty
-    private List<Bank> banks;
-
-    public boolean isSwedbankProfile() {
-        return swedbankProfile;
-    }
-
-    public void setSwedbankProfile(boolean swedbankProfile) {
-        this.swedbankProfile = swedbankProfile;
-    }
-
-    public boolean isSavingbankProfile() {
-        return savingbankProfile;
-    }
-
-    public void setSavingbankProfile(boolean savingbankProfile) {
-        this.savingbankProfile = savingbankProfile;
-    }
-
-    public List<Bank> getBanks() {
-        if (banks == null) {
-            banks = new ArrayList<Bank>();
-        }
-        return banks;
-    }
-
-    public void setBanks(List<Bank> banks) {
-        this.banks = banks;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index cc75877..24258c3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -23,30 +23,20 @@ package com.liato.bankdroid.provider;
 public interface IBankTypes {
 
     int TESTBANK = 0;
-    int SWEDBANK = 1;
     int NORDEA = 2;
-    int ICABANKEN = 3;
     int LANSFORSAKRINGAR = 4;
-    int HANDELSBANKEN = 5;
     int COOP = 6;
     int ICA = 7;
-    int STATOIL = 8;
     int AVANZA = 9;
     int VILLABANKEN = 10;
     int AVANZAMINI = 11;
     int OKQ8 = 12;
-    int EUROCARD = 13;
     int FIRSTCARD = 14;
-    int PAYPAL = 15;
     int PAYSON = 16;
     int JOJO = 17;
     int IKANOBANK = 18;
-    int STEAM = 19;
-    int DINERSCLUB = 20;
-    int SASEUROBONUSMASTERCARD = 21;
     int RIKSLUNCHEN = 22;
     int HEMKOP = 23;
-    int SEB = 24;
     int NORDNET = 25;
     int SEVENDAY = 26;
     int OSUUSPANKKI = 27;
@@ -55,13 +45,6 @@ public interface IBankTypes {
     int RESURSBANK = 30;
     int AMERICANEXPRESS = 31;
     int MCDONALDS = 32;
-    int SAAB = 33;
-    int WALLET = 34;
-    int CHEVROLET = 35;
-    int SJPRIO = 36;
-    int OPEL = 37;
-    int DJURGARDEN = 38;
-    int QUINTESSENTIALLY = 39;
     int PLUSGIROT = 40;
     int SHELL = 41;
     int VOLKSWAGEN = 42;
@@ -70,12 +53,8 @@ public interface IBankTypes {
     int SEAT = 45;
     int SKODA = 46;
     int IKEA = 47;
-    int SPARBANKEN_SYD = 48;
-    int SPARBANKEN_ORESUND = 49;
     int NORDNETDIREKT = 50;
-    int SKANDIABANKEN = 51;
     int DANSKEBANK = 52;
-    int NORDEA_DK = 53;
     int VASTTRAFIK = 54;
     int EVERYDAYCARD = 55;
     int AKELIUSINVEST = 56;
@@ -83,7 +62,6 @@ public interface IBankTypes {
     int RIKSKORTET = 58;
     int BIOKLUBBEN = 59;
     int CHALMREST = 60;
-    int MARGINALEN = 61;
     int AKELIUSSPAR = 62;
     int SVENSKASPEL = 63;
     int EASYCARD = 64;
@@ -92,21 +70,12 @@ public interface IBankTypes {
     int BRUMMER_KF = 67;
     int ZIDISHA = 68;
     int BETTERGLOBE = 69;
-    int FOREX = 70;
-    int SASEUROBONUSMASTERCARD_NO = 71;
     int BITCOIN = 72;
-    int SASEUROBONUSMASTERCARD_DK = 73;
     int SVEADIREKT = 74;
     int SUPREMECARD = 75;
-    int SPARBANKERNA = 76;
     int BLEKINGETRAFIKEN = 77;
     int OSTGOTATRAFIKEN = 78;
     int BREDBAND2VOIP = 79;
-    int ESPRESSOHOUSE = 80;
     int MINPENSION = 81;
-    int SWEDBANK_YOUTH = 82;
-    int SWEDBANK_CORPORATE = 83;
-    int SPARBANKERNA_YOUTH = 84;
-    int SPARBANKERNA_CORPORATE = 85;
     int HORS = 86;
 }
diff --git bankdroid-legacy/src/main/res/drawable/logo_chevrolet.png bankdroid-legacy/src/main/res/drawable/logo_chevrolet.png
deleted file mode 100644
index 929ff78..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_chevrolet.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_dinersclub.png bankdroid-legacy/src/main/res/drawable/logo_dinersclub.png
deleted file mode 100644
index 3b3d916..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_dinersclub.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_djurgarden.png bankdroid-legacy/src/main/res/drawable/logo_djurgarden.png
deleted file mode 100644
index 7285764..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_djurgarden.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_ebmaster.png bankdroid-legacy/src/main/res/drawable/logo_ebmaster.png
deleted file mode 100644
index 0354e55..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_ebmaster.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_ebmaster_dk.png bankdroid-legacy/src/main/res/drawable/logo_ebmaster_dk.png
deleted file mode 100644
index 0354e55..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_ebmaster_dk.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_ebmaster_no.png bankdroid-legacy/src/main/res/drawable/logo_ebmaster_no.png
deleted file mode 100644
index 0354e55..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_ebmaster_no.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_espressohouse.png bankdroid-legacy/src/main/res/drawable/logo_espressohouse.png
deleted file mode 100644
index ccea1ed..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_espressohouse.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_eurocard.png bankdroid-legacy/src/main/res/drawable/logo_eurocard.png
deleted file mode 100644
index eb38336..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_eurocard.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_forex.png bankdroid-legacy/src/main/res/drawable/logo_forex.png
deleted file mode 100644
index 7aaaadc..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_forex.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_handelsbanken.png bankdroid-legacy/src/main/res/drawable/logo_handelsbanken.png
deleted file mode 100644
index 6f2313c..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_handelsbanken.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_icabanken.png bankdroid-legacy/src/main/res/drawable/logo_icabanken.png
deleted file mode 100644
index 798be0c..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_icabanken.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_marginalen.png bankdroid-legacy/src/main/res/drawable/logo_marginalen.png
deleted file mode 100644
index 5573a3b..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_marginalen.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_nordea_dk.png bankdroid-legacy/src/main/res/drawable/logo_nordea_dk.png
deleted file mode 100644
index 7b5d539..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_nordea_dk.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_opel.png bankdroid-legacy/src/main/res/drawable/logo_opel.png
deleted file mode 100644
index cb7626a..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_opel.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_paypal.png bankdroid-legacy/src/main/res/drawable/logo_paypal.png
deleted file mode 100644
index e5d5252..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_paypal.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_quintessentially.png bankdroid-legacy/src/main/res/drawable/logo_quintessentially.png
deleted file mode 100644
index ba38bef..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_quintessentially.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_saab.png bankdroid-legacy/src/main/res/drawable/logo_saab.png
deleted file mode 100644
index 4af4ca5..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_saab.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_sj_prio.png bankdroid-legacy/src/main/res/drawable/logo_sj_prio.png
deleted file mode 100644
index 1595331..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_sj_prio.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_skandiabanken.png bankdroid-legacy/src/main/res/drawable/logo_skandiabanken.png
deleted file mode 100644
index 561b3ed..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_skandiabanken.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_sparbanken_oresund.png bankdroid-legacy/src/main/res/drawable/logo_sparbanken_oresund.png
deleted file mode 100644
index 983273e..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_sparbanken_oresund.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_sparbanken_syd.png bankdroid-legacy/src/main/res/drawable/logo_sparbanken_syd.png
deleted file mode 100644
index d5e85ca..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_sparbanken_syd.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_sparbankerna.png bankdroid-legacy/src/main/res/drawable/logo_sparbankerna.png
deleted file mode 100644
index e7cb3e2..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_sparbankerna.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_statoil.png bankdroid-legacy/src/main/res/drawable/logo_statoil.png
deleted file mode 100644
index b1f7415..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_statoil.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_steam.png bankdroid-legacy/src/main/res/drawable/logo_steam.png
deleted file mode 100644
index 5dac35c..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_steam.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_swedbank.png bankdroid-legacy/src/main/res/drawable/logo_swedbank.png
deleted file mode 100644
index e7cb3e2..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_swedbank.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_wallet.png bankdroid-legacy/src/main/res/drawable/logo_wallet.png
deleted file mode 100644
index 3b80a87..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_wallet.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
deleted file mode 100644
index ec3b3d7..0000000
--- bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----

-JEoC5a8o3g==
------END CERTIFICATE-----
-secure.dinersclub.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_eurocard.pem bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
deleted file mode 100644
index 73f9ab7..0000000
--- bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-retcxhIyl4nBN1O84LH6XwuqSfCe/mmYIIZPV9xmU40Z
------END CERTIFICATE-----
-secure.eurocard.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_forexbank.pem bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
deleted file mode 100644
index 49ff36a..0000000
--- bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN CERTIFICATE-----

-hldUTZe6PNFogJtLQ49aehfHDSOCNLM4xrE=
------END CERTIFICATE-----
-nettbank.edb.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
deleted file mode 100644
index fc5c10d..0000000
--- bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-blFMqDEj/1eo3DvuDjonVoCOPtMitBUDAKb2ia9pcA==
------END CERTIFICATE-----
-m.handelsbanken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_icabanken.pem bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
deleted file mode 100644
index d87afbb..0000000
--- bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-5b5dbNyAM/HjoZ09ARu3cBJN
------END CERTIFICATE-----
-appserver.icabanken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_marginalen.pem bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
deleted file mode 100644
index ac9c03f..0000000
--- bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----

-Qed25gfl
------END CERTIFICATE-----
-secure1.marginalen.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
deleted file mode 100644
index 218e2f3..0000000
--- bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
+++ /dev/null
@@ -1,41 +0,0 @@
------BEGIN CERTIFICATE-----

-qh6i9DDaCOeqbWj8ZNfvIAa9VCQ=
------END CERTIFICATE-----
-www.netbank.nordea.dk:443
diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
deleted file mode 100644
index 53c5c43..0000000
--- bankdroid-legacy/src/main/res/raw/cert_paypal.pem
+++ /dev/null
@@ -1,43 +0,0 @@
------BEGIN CERTIFICATE-----

-NeQitYiySDIepHGnng==
------END CERTIFICATE-----
-www.paypal.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_sebkort.pem bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
deleted file mode 100644
index b167f07..0000000
--- bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-retcxhIyl4nBN1O84LH6XwuqSfCe/mmYIIZPV9xmU40Z
------END CERTIFICATE-----
-secure.sebkort.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
deleted file mode 100644
index 22ac4ac..0000000
--- bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
+++ /dev/null
@@ -1,32 +0,0 @@
------BEGIN CERTIFICATE-----

-xdCATkln5Q==
------END CERTIFICATE-----
-smartrefill.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_steam.pem bankdroid-legacy/src/main/res/raw/cert_steam.pem
deleted file mode 100644
index 0e381dc..0000000
--- bankdroid-legacy/src/main/res/raw/cert_steam.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----

-PEm1FqE12j/eVQpWpnubOHsPp3pc5q+n0RyCaBzTH1yMvykr
------END CERTIFICATE-----
-store.steampowered.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_swedbank.pem bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
deleted file mode 100644
index e16225a..0000000
--- bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----

-wg==
------END CERTIFICATE-----
-auth.api.swedbank.se:443

commit 26cfc388679d968e7f745c36af31448057c7c879
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 17 21:08:26 2016 +0200

    Make sure that transaction model for amex never return null, but an empty list if no transactions are available.
    
    Fixes #637

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java
index ab4e0c9..3a68e06 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java
@@ -2,6 +2,7 @@ package com.liato.bankdroid.banking.banks.americanexpress.model;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
+import java.util.Collections;
 import java.util.List;
 
 @JsonIgnoreProperties(ignoreUnknown = true)
@@ -9,7 +10,8 @@ public class AccountActivity {
     List<Transaction> transactionList;
 
     public List<Transaction> getTransactionList() {
-        return transactionList;
+        return transactionList == null ?
+                Collections.<Transaction>emptyList() : transactionList;
     }
 
     public void setTransactionList(List<Transaction> transactionList) {

commit 3fb3edb7fb026a19f4a1f64f23368102fe6bf66d
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sun Oct 16 19:50:57 2016 +0200

    Widget: Replace warning symbol with strikethrough

diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index 07bfccf..64e5907 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -47,8 +47,6 @@ public class LockableActivity extends ActionBarActivity {
 
     private SharedPreferences mPrefs;
 
-    private Editor mEditor;
-
     private LockPatternUtils mLockPatternUtils;
 
     private boolean mHasLoaded = false;
@@ -240,9 +238,9 @@ public class LockableActivity extends ActionBarActivity {
     }
 
     private void writeLockTime(long time) {
-        mEditor = mPrefs.edit();
-        mEditor.putLong("locked_at", time);
-        mEditor.commit();
+        Editor editor = mPrefs.edit();
+        editor.putLong("locked_at", time);
+        editor.apply();
     }
 
     protected void onActivityResult(int requestCode, int resultCode,
diff --git app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
index 87a459d..ffa55f5 100644
--- app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -35,8 +35,6 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 
     private SharedPreferences mPrefs;
 
-    private Editor mEditor;
-
     private LockPatternUtils mLockPatternUtils;
 
     private boolean mHasLoaded = false;
@@ -67,7 +65,7 @@ public class LockablePreferenceActivity extends PreferenceActivity {
         If this activity never loaded set the lock time to
         10 seconds ago.
         This is to prevent the following scenario:
-            1. Activity Starts 
+            1. Activity Starts
             2. Lock screen is displayed
             3. User presses the home button
             4. "lock time" is set in onPause to when the home button was pressed
@@ -111,9 +109,9 @@ public class LockablePreferenceActivity extends PreferenceActivity {
     }
 
     private void writeLockTime(long time) {
-        mEditor = mPrefs.edit();
-        mEditor.putLong("locked_at", time);
-        mEditor.commit();
+        Editor editor = mPrefs.edit();
+        editor.putLong("locked_at", time);
+        editor.apply();
     }
 
     protected boolean isLockEnabled() {
@@ -121,9 +119,9 @@ public class LockablePreferenceActivity extends PreferenceActivity {
     }
 
     protected void setLockEnabled(boolean enabled) {
-        mEditor = mPrefs.edit();
-        mEditor.putBoolean("lock_enabled", enabled);
-        mEditor.commit();
+        Editor editor = mPrefs.edit();
+        editor.putBoolean("lock_enabled", enabled);
+        editor.apply();
     }
 
     protected void onActivityResult(int requestCode, int resultCode,
diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index eeb67f0..f2af3c9 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -51,7 +51,7 @@ public class PairApplicationsActivity extends LockableActivity {
 
             // Commit to preferences
             editor.putString("content_provider_api_key", genKey.toUpperCase());
-            editor.commit();
+            editor.apply();
         }
     }
 
@@ -112,7 +112,7 @@ public class PairApplicationsActivity extends LockableActivity {
         SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx);
         Editor editor = pref.edit();
         editor.putBoolean("content_provider_enabled", true);
-        editor.commit();
+        editor.apply();
         String apiKey;
 
         try {
diff --git app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
index a4169f5..af4e6ec 100644
--- app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -100,7 +100,8 @@ public class AccountsAdapter extends BaseAdapter {
                 .setText(Helpers.formatBalance(bank.getBalance(),
                         bank.getCurrency(),
                         prefs.getBoolean("round_balance", false) || !bank.getDisplayDecimals(),
-                        bank.getDecimalFormatter()));
+                        bank.getDecimalFormatter(),
+                        false));
         icon.setImageResource(bank.getImageResource());
         ImageView warning = (ImageView) convertView.findViewById(R.id.imgWarning);
         if (bank.isDisabled()) {
@@ -131,7 +132,8 @@ public class AccountsAdapter extends BaseAdapter {
                         account.getCurrency(),
                         prefs.getBoolean("round_balance", false) || !account.getBank()
                                 .getDisplayDecimals(),
-                        account.getBank().getDecimalFormatter()));
+                        account.getBank().getDecimalFormatter(),
+                        false));
         if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
             txtBalance.setTextColor(Color.argb(255, 191, 191, 191));
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 81a0208..b3aee41 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -424,7 +424,7 @@ public class AutoRefreshService extends Service {
             }
             Editor edit = prefs.edit();
             edit.putLong("autoupdates_last_update", System.currentTimeMillis());
-            edit.commit();
+            edit.apply();
             autoRefreshService.stopSelf();
         }
     }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 141fed9..fb3ddf2 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -78,7 +78,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
         Editor e = prefs.edit();
         e.putBoolean("widget_unblurred_" + appWidgetId, true);
-        e.commit();
+        e.apply();
 
         RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
         if (views != null) {
@@ -95,7 +95,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
         Editor e = prefs.edit();
         e.remove("widget_unblurred_" + appWidgetId);
-        e.commit();
+        e.apply();
         RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
         if (views != null) {
             views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
@@ -158,13 +158,9 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         views.setTextViewText(R.id.txtWidgetAccountbalance,
                 Helpers.formatBalance(account.getBalance(), account.getCurrency(),
                         defprefs.getBoolean("round_widget_balance", false),
-                        bank.getDecimalFormatter()));
+                        bank.getDecimalFormatter(),
+                        bank.isDisabled()));
         views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
-        if (bank.isDisabled()) {
-            views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
-        } else {
-            views.setViewVisibility(R.id.frmWarning, View.INVISIBLE);
-        }
         Intent intent = new Intent(context, MainActivity.class);
         PendingIntent pendingIntent;
 
@@ -236,7 +232,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         views.setTextViewText(R.id.txtWidgetAccountname, "");
         views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR");
         views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
-        views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
 
         Intent intent = new Intent(context, MainActivity.class);
         PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
@@ -379,7 +374,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
                     return null;
                 }
                 long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
-                Bank bank = BankFactory.bankFromDb(new Long(bankId), context, true);
+                Bank bank = BankFactory.bankFromDb(bankId, context, true);
                 if (bank == null) {
                     return null;
                 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
index 973e62d..6f0bec7 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
@@ -56,7 +56,7 @@ public class WidgetConfigureActivity extends LockableActivity {
         SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
         prefs.putString(WIDGET_PREFIX + appWidgetId, accountId);
         prefs.putLong(WIDGET_PREFIX + appWidgetId + "_bankid", bankId);
-        prefs.commit();
+        prefs.apply();
     }
 
     public static String getAccountId(Context context, int appWidgetId) {
@@ -73,7 +73,7 @@ public class WidgetConfigureActivity extends LockableActivity {
         SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
         prefs.remove(WIDGET_PREFIX + appWidgetId);
         prefs.remove(WIDGET_PREFIX + appWidgetId + "_bankid");
-        prefs.commit();
+        prefs.apply();
     }
 
     @Override
@@ -114,7 +114,7 @@ public class WidgetConfigureActivity extends LockableActivity {
                         .edit();
                 prefs.putBoolean("transperant_background" + mAppWidgetId,
                         ((CheckBox) findViewById(R.id.chkTransperantBackground)).isChecked());
-                prefs.commit();
+                prefs.apply();
                 // Push widget update to surface with newly set prefix
                 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                 BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 483fa81..240669b 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -190,7 +190,7 @@ public class DBAdapter {
                 vals.put("bankid", bankId);
                 vals.put("balance", acc.getBalance().toPlainString());
                 vals.put("name", acc.getName());
-                vals.put("id", new Long(bankId).toString() + "_" + acc.getId());
+                vals.put("id", bankId + "_" + acc.getId());
                 vals.put("hidden", acc.isHidden() ? 1 : 0);
                 vals.put("notify", acc.isNotify() ? 1 : 0);
                 vals.put("currency", acc.getCurrency());
@@ -200,14 +200,14 @@ public class DBAdapter {
                 if (acc.getAliasfor() == null || acc.getAliasfor().length() == 0) {
                     List<Transaction> transactions = acc.getTransactions();
                     if (transactions != null && !transactions.isEmpty()) {
-                        deleteTransactions(new Long(bankId).toString() + "_" + acc.getId());
+                        deleteTransactions(bankId + "_" + acc.getId());
                         for (Transaction transaction : transactions) {
                             ContentValues transvals = new ContentValues();
                             transvals.put("transdate", transaction.getDate());
                             transvals.put("btransaction", transaction.getTransaction());
                             transvals.put("amount", transaction.getAmount().toPlainString());
                             transvals.put("account",
-                                    new Long(bankId).toString() + "_" + acc.getId());
+                                    bankId + "_" + acc.getId());
                             transvals.put("currency", transaction.getCurrency());
                             mDb.insert("transactions", null, transvals);
                         }
@@ -239,7 +239,7 @@ public class DBAdapter {
     }
 
     public Cursor getBank(long bankId) {
-        return getBank(new Long(bankId).toString());
+        return getBank(Long.toString(bankId));
     }
 
     public Cursor getAccount(String id) {
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index d092b42..584db70 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -372,7 +372,7 @@ public class LockPatternUtils {
     private void setBoolean(String systemSettingKey, boolean enabled) {
         Editor editor = mPrefs.edit();
         editor.putBoolean(systemSettingKey, enabled);
-        editor.commit();
+        editor.apply();
     }
 
     private long getLong(String systemSettingKey, long def) {
@@ -382,6 +382,6 @@ public class LockPatternUtils {
     private void setLong(String systemSettingKey, long value) {
         Editor editor = mPrefs.edit();
         editor.putLong(systemSettingKey, value);
-        editor.commit();
+        editor.apply();
     }
 }
diff --git app/src/main/res/layout/widget.xml app/src/main/res/layout/widget.xml
index 9216f02..8175975 100644
--- app/src/main/res/layout/widget.xml
+++ app/src/main/res/layout/widget.xml
@@ -105,21 +105,5 @@
 				android:minWidth="17dp"
 				android:visibility="visible"></ProgressBar>
 		</FrameLayout>
-
-
-		<FrameLayout
-			android:layout_height="wrap_content"
-			android:id="@+id/frmWarning"
-			android:layout_width="fill_parent"
-			android:visibility="invisible">
-			<ImageView
-				android:id="@+id/imgWarning"
-				android:adjustViewBounds="true"
-				android:layout_gravity="bottom|right"
-				android:layout_height="fill_parent"
-				android:src="@drawable/indicator_input_error"
-				android:scaleType="fitXY"
-				android:layout_width="wrap_content"></ImageView>
-		</FrameLayout>
 	</LinearLayout>
 </RelativeLayout>
diff --git app/src/main/res/layout/widget_large.xml app/src/main/res/layout/widget_large.xml
index ff2a059..b9a11a5 100644
--- app/src/main/res/layout/widget_large.xml
+++ app/src/main/res/layout/widget_large.xml
@@ -83,31 +83,6 @@
 
 </RelativeLayout>
 	</RelativeLayout>
-	<RelativeLayout
-			android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_alignParentRight="true"
-		android:paddingTop="15dp"
-		android:paddingRight="11dp">
-		<FrameLayout
-			android:layout_height="wrap_content"
-			android:id="@+id/frmWarning"
-			android:layout_width="wrap_content"
-			android:visibility="invisible">
-			<ImageView
-				android:id="@+id/imgWarning"
-				android:adjustViewBounds="true"
-				android:layout_height="fill_parent"
-				android:src="@drawable/indicator_input_error"
-				android:scaleType="fitXY"
-				android:layout_width="wrap_content"
-				android:layout_gravity="top|right"
-				android:maxWidth="17dp"
-				android:maxHeight="17dp"
-				android:minHeight="17dp"
-				android:minWidth="17dp"></ImageView>
-		</FrameLayout>
-	</RelativeLayout>
 	<RelativeLayout
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
diff --git app/src/main/res/layout/widget_large_transparent.xml app/src/main/res/layout/widget_large_transparent.xml
index c23f5e5..9f69ffd 100644
--- app/src/main/res/layout/widget_large_transparent.xml
+++ app/src/main/res/layout/widget_large_transparent.xml
@@ -81,31 +81,6 @@
 				android:paddingTop="37dp"></TextView>
 		</RelativeLayout>
 	</RelativeLayout>
-	<RelativeLayout
-			android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_alignParentRight="true"
-		android:paddingTop="15dp"
-		android:paddingRight="11dp">
-		<FrameLayout
-			android:layout_height="wrap_content"
-			android:id="@+id/frmWarning"
-			android:layout_width="wrap_content"
-			android:visibility="invisible">
-			<ImageView
-				android:id="@+id/imgWarning"
-				android:adjustViewBounds="true"
-				android:layout_height="fill_parent"
-				android:src="@drawable/indicator_input_error"
-				android:scaleType="fitXY"
-				android:layout_width="wrap_content"
-				android:layout_gravity="top|right"
-				android:maxWidth="17dp"
-				android:maxHeight="17dp"
-				android:minHeight="17dp"
-				android:minWidth="17dp"></ImageView>
-		</FrameLayout>
-	</RelativeLayout>
 	<RelativeLayout
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
diff --git app/src/main/res/layout/widget_transparent.xml app/src/main/res/layout/widget_transparent.xml
index bc7b30b..3c9e6e5 100644
--- app/src/main/res/layout/widget_transparent.xml
+++ app/src/main/res/layout/widget_transparent.xml
@@ -15,7 +15,7 @@
 		android:layout_height="22dp"
 		android:layout_width="fill_parent"
 		android:id="@+id/hitBox"
-		android:focusable="true"></FrameLayout>
+		android:focusable="true"/>
 	<LinearLayout
 		android:layout_height="wrap_content"
 		android:layout_width="wrap_content"
@@ -29,7 +29,7 @@
 			android:layout_gravity="center_vertical"
 			android:baselineAlignBottom="true"
 			android:src="@drawable/ic_launcher"
-			android:scaleType="fitXY"></ImageView>
+			android:scaleType="fitXY"/>
 	<TextView
 		android:id="@+id/txtWidgetAccountname"
 		android:layout_height="wrap_content"
@@ -41,7 +41,7 @@
 		android:layout_marginLeft="2dp"
 		android:layout_marginRight="2dp"
 		android:text="Bankdroid"
-		android:lines="1"></TextView>
+		android:lines="1"/>
 	<TextView
 		android:id="@+id/txtWidgetAccountnameBlur"
 		android:layout_height="wrap_content"
@@ -54,7 +54,7 @@
 		android:layout_marginRight="2dp"
 		android:text="Bankdroid"
 		android:lines="1"
-		android:visibility="gone"></TextView>
+		android:visibility="gone"/>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -71,8 +71,9 @@
 			android:scaleType="centerInside"
 			android:adjustViewBounds="false"
 			android:paddingTop="5dp"
-			android:visibility="gone"></ImageView>
+			android:visibility="gone"/>
 		<TextView
+
 			android:textColor="#fff"
 			android:inputType="none"
 			android:layout_gravity="center_vertical|center_horizontal"
@@ -107,26 +108,7 @@
 				android:maxHeight="2dp"
 				android:minHeight="2dp"
 				android:minWidth="17dp"
-				android:visibility="visible"></ProgressBar>
-		</FrameLayout>
-
-
-		<FrameLayout
-			android:layout_height="wrap_content"
-			android:id="@+id/frmWarning"
-			android:layout_width="fill_parent"
-			android:visibility="invisible">
-			<ImageView
-				android:id="@+id/imgWarning"
-				android:adjustViewBounds="true"
-				android:layout_gravity="bottom|right"
-				android:layout_height="fill_parent"
-				android:src="@drawable/indicator_input_error"
-				android:scaleType="fitXY"
-				android:layout_width="wrap_content"></ImageView>
+				android:visibility="visible"/>
 		</FrameLayout>
 	</LinearLayout>
-
-
-
 </RelativeLayout>
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
index f746ff3..2c2e4ce 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
@@ -16,17 +16,13 @@
 
 package com.liato.bankdroid;
 
-import com.liato.bankdroid.legacy.R;
-
 import org.apache.http.NameValuePair;
 
 import android.app.Activity;
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.util.DisplayMetrics;
+import android.support.annotation.Nullable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.style.StrikethroughSpan;
 
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
@@ -40,6 +36,7 @@ import java.util.List;
 import timber.log.Timber;
 
 public class Helpers {
+    private static final StrikethroughSpan STRIKE_THROUGH_SPAN = new StrikethroughSpan();
 
     private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS",
             "AUD",
@@ -90,8 +87,6 @@ public class Helpers {
 
     private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
-    private static String USER_AGENT;
-
     public static BigDecimal parseBalance(String balance) {
         if (balance == null) {
             return new BigDecimal(0);
@@ -114,8 +109,8 @@ public class Helpers {
         return ret;
     }
 
-    public static String formatBalance(BigDecimal balance, String curr, boolean round,
-            DecimalFormat format) {
+    public static CharSequence formatBalance(BigDecimal balance, String curr, boolean round,
+                                             @Nullable DecimalFormat format, boolean strikethrough) {
         DecimalFormatSymbols dfs = new DecimalFormatSymbols();
         dfs.setDecimalSeparator(',');
         dfs.setGroupingSeparator(' ');
@@ -128,21 +123,23 @@ public class Helpers {
             }
         }
         currency.setDecimalFormatSymbols(dfs);
-        return currency.format(balance.doubleValue()) + curr;
-    }
 
-    public static String formatBalance(BigDecimal balance, String curr) {
-        return formatBalance(balance, curr, false, null);
+        SpannableString returnMe = new SpannableString(currency.format(balance.doubleValue()) + curr);
+        if (strikethrough) {
+            returnMe.setSpan(STRIKE_THROUGH_SPAN, 0, returnMe.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
+
+        return returnMe;
     }
 
-    public static String formatBalance(Double balance, String curr) {
-        return formatBalance(new BigDecimal(balance), curr);
+    public static CharSequence formatBalance(BigDecimal balance, String curr) {
+        return formatBalance(balance, curr, false, null, false);
     }
 
     static public void setActivityAnimation(Activity activity, int in, int out) {
         try {
             Method method = Activity.class
-                    .getMethod("overridePendingTransition", new Class[]{int.class, int.class});
+                    .getMethod("overridePendingTransition", int.class, int.class);
             method.invoke(activity, in, out);
         } catch (Exception e) {
             // Can't change animation, so do nothing
@@ -233,50 +230,4 @@ public class Helpers {
         return DATE_FORMAT.format(date);
     }
 
-    public static String getAppUserAgentString(Context context) {
-        if (USER_AGENT != null) {
-            return USER_AGENT;
-        }
-        String appName = context.getResources().getString(R.string.app_name);
-        String appVersion = "";
-        int height = 0;
-        int width = 0;
-        DisplayMetrics display = context.getResources().getDisplayMetrics();
-        Configuration config = context.getResources().getConfiguration();
-
-        // Always send screen dimension for portrait mode
-        if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
-            height = display.widthPixels;
-            width = display.heightPixels;
-        } else {
-            width = display.widthPixels;
-            height = display.heightPixels;
-        }
-
-        try {
-            PackageInfo packageInfo = context.getPackageManager()
-                    .getPackageInfo(context.getPackageName(), PackageManager.GET_CONFIGURATIONS);
-            appVersion = packageInfo.versionName;
-        } catch (PackageManager.NameNotFoundException ignore) {
-            // this should never happen, we are looking up ourself
-        }
-
-        // Tries to conform to default android UA string without the Safari / webkit noise, plus adds the screen dimensions
-        USER_AGENT = String
-                .format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %12$s Build/%7$s; %8$s) %9$dX%10$d %11$s %12$s"
-                        , appName
-                        , appVersion
-                        , System.getProperty("os.name", "Linux")
-                        , Build.VERSION.RELEASE
-                        , config.locale.getLanguage().toLowerCase()
-                        , config.locale.getCountry().toLowerCase()
-                        , Build.ID
-                        , Build.BRAND
-                        , width
-                        , height
-                        , Build.MANUFACTURER
-                        , Build.MODEL);
-        return USER_AGENT;
-    }
-
 }
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 3d6c857..22f5563 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -8,7 +8,6 @@
     <issue id="BatteryLife" severity="ignore" />
     <issue id="ButtonCase" severity="ignore" />
     <issue id="ClickableViewAccessibility" severity="ignore" />
-    <issue id="CommitPrefEdits" severity="ignore" />
     <issue id="ContentDescription" severity="ignore" />
     <issue id="DefaultLocale" severity="ignore" />
     <issue id="Deprecated" severity="ignore" />
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 6b32309..f065d55 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -70,7 +70,6 @@
         <exclude name="JUnitTestsShouldIncludeAssert" />
         <exclude name="LawOfDemeter" />
         <exclude name="LocalVariableCouldBeFinal" />
-        <exclude name="LongInstantiation" />
         <exclude name="LongVariable" />
         <exclude name="LooseCoupling" />
         <exclude name="LoosePackageCoupling" />

commit 7a8bdd3ec2ed5e675f9b22f03968769700e2ba18
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Oct 17 19:34:17 2016 +0200

    Merge PMD and Lint suppressions generation scripts
    
    And move the result into the tools directory.

diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 2348b8f..3d6c857 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
-    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
+    <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
 
     <issue id="AllowBackup" severity="ignore" />
     <issue id="AlwaysShowAction" severity="ignore" />
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index c94b5e5..6b32309 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -4,12 +4,12 @@
     xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
     xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
 
-    <description>Custom ruleset for Bankdroid, created by create-pmd-suppressions.sh</description>
+    <description>Custom ruleset for Bankdroid, created by update-suppressions.sh</description>
 
     <exclude-pattern>.*/R.java</exclude-pattern>
     <exclude-pattern>.*/gen/.*</exclude-pattern>
 
-    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
+    <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
     <rule ref="rulesets/internal/all-java.xml">
         <exclude name="AbstractNaming" />
         <exclude name="AccessorClassGeneration" />
diff --git create-lint-suppressions.sh create-lint-suppressions.sh
deleted file mode 100755
index 65d3802..0000000
--- create-lint-suppressions.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-# Create an Android Lint suppressions file with a list of all
-# failing Lint checks. Store in config/quality/lint/lint.xml.
-
-LINT_XML='config/quality/lint/lint.xml'
-
-# From: https://sipb.mit.edu/doc/safe-shell/
-set -euf -o pipefail
-
-# List failing lint checks (with no suppressions)
-echo '<lint></lint>' > ${LINT_XML}
-./gradlew clean check --continue || true
-RESULTSFILES=$(find . -name 'lint-results*.xml')
-
-cat << EOF
-
-Here's an Android Lint config file with suppressions for
-everything we're violating.
-
-For great success, store in ${LINT_XML}.
-
-Or just fix all issues and skip the suppressions file entirely.
-
-<?xml version="1.0" encoding="UTF-8"?>
-<lint>
-    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
-
-EOF
-
-for RULE in $(egrep -h ' *id=".*"$' ${RESULTSFILES} | cut '-d"' -f2 | sort | uniq) ; do
-    echo "    <issue id=\"${RULE}\" severity=\"ignore\" />"
-done
-
-cat << EOF
-</lint>
-EOF
diff --git create-pmd-suppressions.sh create-pmd-suppressions.sh
deleted file mode 100755
index 9df5ec5..0000000
--- create-pmd-suppressions.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/bash
-
-# Create a PMD suppressions file with a list of all failing
-# PMD checks. Store in config/quality/pmd/pmd-ruleset.xml.
-
-PMD_XML='config/quality/pmd/pmd-ruleset.xml'
-
-# From: https://sipb.mit.edu/doc/safe-shell/
-set -euf -o pipefail
-
-# List failing PMD checks (with no suppressions)
-cat > ${PMD_XML} << EOF
-<?xml version="1.0"?>
-<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="All Java Rules"
-    xmlns="http://pmd.sf.net/ruleset/1.0.0"
-    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
-    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
-
-    <description>All Java rules, $(basename $0) running...</description>
-
-    <exclude-pattern>.*/R.java</exclude-pattern>
-    <exclude-pattern>.*/gen/.*</exclude-pattern>
-
-    <rule ref="rulesets/internal/all-java.xml" />
-</ruleset>
-EOF
-./gradlew clean check --continue || true
-RESULTSFILES=$(find . -name 'pmd.xml')
-
-cat << EOF
-
-Here's a PMD config file with suppressions for everything we're violating.
-
-For great success, store in ${PMD_XML}.
-
-Or just fix all issues and skip the suppressions file entirely.
-
-<?xml version="1.0"?>
-<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Bankdroid Rules"
-    xmlns="http://pmd.sf.net/ruleset/1.0.0"
-    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
-    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
-
-    <description>Custom ruleset for Bankdroid, created by $(basename $0)</description>
-
-    <exclude-pattern>.*/R.java</exclude-pattern>
-    <exclude-pattern>.*/gen/.*</exclude-pattern>
-
-    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
-    <rule ref="rulesets/internal/all-java.xml">
-EOF
-
-for RULE in $(grep externalInfoUrl= ${RESULTSFILES} | sed 's/.*rule="//' | cut '-d"' -f1 | sort | uniq) ; do
-    echo "        <exclude name=\"${RULE}\" />"
-done
-
-cat << EOF
-    </rule>
-</ruleset>
-EOF
diff --git tools/update-suppressions.sh tools/update-suppressions.sh
new file mode 100755
index 0000000..2b23a17
--- /dev/null
+++ tools/update-suppressions.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+# This script generates suppressions files for PMD and Android Lint.
+# The suppressions files list all rules that we violate.
+#
+# Before committing the result of running this script, make sure no
+# new suppressions have been added. We want to get rid of them, not
+# introduce more problems.
+#
+# Note that this script will do a build with all suppressions
+# disabled. That will print a lot of error messages, but that's OK.
+
+ROOTDIR=$(cd $(dirname "$0") ; cd .. ; pwd)
+LINT_XML="${ROOTDIR}/config/quality/lint/lint.xml"
+PMD_XML="${ROOTDIR}/config/quality/pmd/pmd-ruleset.xml"
+
+# From: https://sipb.mit.edu/doc/safe-shell/
+set -euf -o pipefail
+
+function set_lint_suppressions() {
+  cat > ${LINT_XML} << EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+    <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
+
+EOF
+
+  for RULE in $1 ; do
+    echo "    <issue id=\"${RULE}\" severity=\"ignore\" />" >> ${LINT_XML}
+  done
+
+  echo '</lint>' >> ${LINT_XML}
+}
+
+function set_pmd_suppressions() {
+  cat > ${PMD_XML} << EOF
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Bankdroid Rules"
+    xmlns="http://pmd.sf.net/ruleset/1.0.0"
+    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
+    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
+
+    <description>Custom ruleset for Bankdroid, created by $(basename $0)</description>
+
+    <exclude-pattern>.*/R.java</exclude-pattern>
+    <exclude-pattern>.*/gen/.*</exclude-pattern>
+
+    <!-- FIXME: This file should be empty and all violations fixed. Then we will all hug. -->
+    <rule ref="rulesets/internal/all-java.xml">
+EOF
+
+  for RULE in $1; do
+    echo "        <exclude name=\"${RULE}\" />" >> ${PMD_XML}
+  done
+
+  cat >> ${PMD_XML} << EOF
+    </rule>
+</ruleset>
+EOF
+}
+
+set_lint_suppressions ""
+set_pmd_suppressions ""
+
+./gradlew clean check --continue || true
+
+LINT_RESULTFILES=$(find ${ROOTDIR} -name 'lint-results*.xml')
+LINT_VIOLATIONS=$(egrep -h ' *id=".*"$' ${LINT_RESULTFILES} | cut '-d"' -f2 | sort | uniq)
+set_lint_suppressions "$LINT_VIOLATIONS"
+
+PMD_RESULTFILES=$(find ${ROOTDIR} -name 'pmd.xml')
+PMD_VIOLATIONS=$(grep externalInfoUrl= ${PMD_RESULTFILES} | sed 's/.*rule="//' | cut '-d"' -f1 | sort | uniq)
+set_pmd_suppressions "$PMD_VIOLATIONS"
+
+git diff ${ROOTDIR}/config

commit d5f60a7e53bdb4d64f1e2cef73d4cafe4e3f0062
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sat Oct 15 18:29:22 2016 +0200

    Enable all non-violated PMD rules
    
    And add a script for updating the list.
    
    Note that I haven't actually fixed anything in here, and there are some
    kind-of-scary-looking suppressions (like "EmptyIfStmt").
    
    Fixing those would be another exercise though, the only point of this
    change is really to document what we're violating and make sure we don't
    add to that list.

diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 3ccf593..c94b5e5 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -1,26 +1,134 @@
 <?xml version="1.0"?>
-<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Android Application Rules"
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Bankdroid Rules"
     xmlns="http://pmd.sf.net/ruleset/1.0.0"
     xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
     xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
 
-    <description>Custom ruleset for Android application</description>
+    <description>Custom ruleset for Bankdroid, created by create-pmd-suppressions.sh</description>
 
     <exclude-pattern>.*/R.java</exclude-pattern>
     <exclude-pattern>.*/gen/.*</exclude-pattern>
 
-    <!--
-    FIXME: This file needs a lot more rules.
-
-    To add more, first decide on one from here:
-    https://github.com/pmd/pmd/tree/master/pmd-java/src/main/resources/rulesets/java
-
-    Then add it just like android.xml has been added (below).
-
-    Do "./gradlew check" to test your newly added rule. If there are violations, check
-    the console output or the HTML report and remedy them until the build passes.
-    -->
-    <rule ref="rulesets/java/android.xml" />
-
-    <rule ref="rulesets/java/logging-java.xml" />
+    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
+    <rule ref="rulesets/internal/all-java.xml">
+        <exclude name="AbstractNaming" />
+        <exclude name="AccessorClassGeneration" />
+        <exclude name="AddEmptyString" />
+        <exclude name="AppendCharacterWithChar" />
+        <exclude name="ArrayIsStoredDirectly" />
+        <exclude name="AssignmentInOperand" />
+        <exclude name="AssignmentToNonFinalStatic" />
+        <exclude name="AtLeastOneConstructor" />
+        <exclude name="AvoidCatchingGenericException" />
+        <exclude name="AvoidCatchingNPE" />
+        <exclude name="AvoidConstantsInterface" />
+        <exclude name="AvoidDecimalLiteralsInBigDecimalConstructor" />
+        <exclude name="AvoidDeeplyNestedIfStmts" />
+        <exclude name="AvoidDuplicateLiterals" />
+        <exclude name="AvoidFieldNameMatchingMethodName" />
+        <exclude name="AvoidFieldNameMatchingTypeName" />
+        <exclude name="AvoidInstantiatingObjectsInLoops" />
+        <exclude name="AvoidLiteralsInIfCondition" />
+        <exclude name="AvoidPrefixingMethodParameters" />
+        <exclude name="AvoidReassigningParameters" />
+        <exclude name="AvoidSynchronizedAtMethodLevel" />
+        <exclude name="AvoidThrowingRawExceptionTypes" />
+        <exclude name="BeanMembersShouldSerialize" />
+        <exclude name="BigIntegerInstantiation" />
+        <exclude name="BooleanGetMethodName" />
+        <exclude name="CallSuperInConstructor" />
+        <exclude name="ClassWithOnlyPrivateConstructorsShouldBeFinal" />
+        <exclude name="CollapsibleIfStatements" />
+        <exclude name="CommentDefaultAccessModifier" />
+        <exclude name="CommentRequired" />
+        <exclude name="CommentSize" />
+        <exclude name="CompareObjectsWithEquals" />
+        <exclude name="ConfusingTernary" />
+        <exclude name="ConstantsInInterface" />
+        <exclude name="ConstructorCallsOverridableMethod" />
+        <exclude name="CyclomaticComplexity" />
+        <exclude name="DataflowAnomalyAnalysis" />
+        <exclude name="DefaultPackage" />
+        <exclude name="DoNotThrowExceptionInFinally" />
+        <exclude name="DoNotUseThreads" />
+        <exclude name="EmptyCatchBlock" />
+        <exclude name="EmptyIfStmt" />
+        <exclude name="EmptyMethodInAbstractClassShouldBeAbstract" />
+        <exclude name="ExceptionAsFlowControl" />
+        <exclude name="ExcessiveClassLength" />
+        <exclude name="ExcessiveImports" />
+        <exclude name="ExcessiveMethodLength" />
+        <exclude name="ExcessiveParameterList" />
+        <exclude name="ExcessivePublicCount" />
+        <exclude name="FieldDeclarationsShouldBeAtStartOfClass" />
+        <exclude name="FinalFieldCouldBeStatic" />
+        <exclude name="GodClass" />
+        <exclude name="ImmutableField" />
+        <exclude name="InefficientStringBuffering" />
+        <exclude name="InsufficientStringBufferDeclaration" />
+        <exclude name="JUnit4TestShouldUseBeforeAnnotation" />
+        <exclude name="JUnitTestsShouldIncludeAssert" />
+        <exclude name="LawOfDemeter" />
+        <exclude name="LocalVariableCouldBeFinal" />
+        <exclude name="LongInstantiation" />
+        <exclude name="LongVariable" />
+        <exclude name="LooseCoupling" />
+        <exclude name="LoosePackageCoupling" />
+        <exclude name="MethodArgumentCouldBeFinal" />
+        <exclude name="MethodNamingConventions" />
+        <exclude name="MissingBreakInSwitch" />
+        <exclude name="MissingSerialVersionUID" />
+        <exclude name="ModifiedCyclomaticComplexity" />
+        <exclude name="NPathComplexity" />
+        <exclude name="NcssMethodCount" />
+        <exclude name="NullAssignment" />
+        <exclude name="OneDeclarationPerLine" />
+        <exclude name="OnlyOneReturn" />
+        <exclude name="PositionLiteralsFirstInComparisons" />
+        <exclude name="PrematureDeclaration" />
+        <exclude name="PreserveStackTrace" />
+        <exclude name="RedundantFieldInitializer" />
+        <exclude name="ShortClassName" />
+        <exclude name="ShortMethodName" />
+        <exclude name="ShortVariable" />
+        <exclude name="SignatureDeclareThrowsException" />
+        <exclude name="SimpleDateFormatNeedsLocale" />
+        <exclude name="SimplifyBooleanReturns" />
+        <exclude name="SimplifyStartsWith" />
+        <exclude name="SingularField" />
+        <exclude name="StdCyclomaticComplexity" />
+        <exclude name="StringInstantiation" />
+        <exclude name="SuspiciousConstantFieldName" />
+        <exclude name="SwitchDensity" />
+        <exclude name="SwitchStmtsShouldHaveDefault" />
+        <exclude name="TooFewBranchesForASwitchStatement" />
+        <exclude name="TooManyFields" />
+        <exclude name="TooManyMethods" />
+        <exclude name="UncommentedEmptyConstructor" />
+        <exclude name="UncommentedEmptyMethodBody" />
+        <exclude name="UnnecessaryConstructor" />
+        <exclude name="UnnecessaryConversionTemporary" />
+        <exclude name="UnnecessaryFullyQualifiedName" />
+        <exclude name="UnnecessaryLocalBeforeReturn" />
+        <exclude name="UnnecessaryParentheses" />
+        <exclude name="UnnecessaryWrapperObjectCreation" />
+        <exclude name="UnsynchronizedStaticDateFormatter" />
+        <exclude name="UnusedFormalParameter" />
+        <exclude name="UnusedLocalVariable" />
+        <exclude name="UnusedPrivateField" />
+        <exclude name="UnusedPrivateMethod" />
+        <exclude name="UseCollectionIsEmpty" />
+        <exclude name="UseConcurrentHashMap" />
+        <exclude name="UseEqualsToCompareStrings" />
+        <exclude name="UseIndexOfChar" />
+        <exclude name="UseLocaleWithCaseConversions" />
+        <exclude name="UseObjectForClearerAPI" />
+        <exclude name="UseStringBufferForStringAppends" />
+        <exclude name="UseUtilityClass" />
+        <exclude name="UseVarargs" />
+        <exclude name="UselessOverridingMethod" />
+        <exclude name="UselessParentheses" />
+        <exclude name="UselessQualifiedThis" />
+        <exclude name="VariableNamingConventions" />
+    </rule>
 </ruleset>
diff --git config/quality/quality.gradle config/quality/quality.gradle
index bd0e0b1..6e053f2 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -71,7 +71,7 @@ task pmd(type: Pmd) {
     exclude '**/generated/**'
 
     reports {
-        xml.enabled = false
+        xml.enabled = true
         html.enabled = true
         xml {
             destination "$project.buildDir/reports/pmd/pmd.xml"
diff --git create-pmd-suppressions.sh create-pmd-suppressions.sh
new file mode 100755
index 0000000..9df5ec5
--- /dev/null
+++ create-pmd-suppressions.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+# Create a PMD suppressions file with a list of all failing
+# PMD checks. Store in config/quality/pmd/pmd-ruleset.xml.
+
+PMD_XML='config/quality/pmd/pmd-ruleset.xml'
+
+# From: https://sipb.mit.edu/doc/safe-shell/
+set -euf -o pipefail
+
+# List failing PMD checks (with no suppressions)
+cat > ${PMD_XML} << EOF
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="All Java Rules"
+    xmlns="http://pmd.sf.net/ruleset/1.0.0"
+    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
+    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
+
+    <description>All Java rules, $(basename $0) running...</description>
+
+    <exclude-pattern>.*/R.java</exclude-pattern>
+    <exclude-pattern>.*/gen/.*</exclude-pattern>
+
+    <rule ref="rulesets/internal/all-java.xml" />
+</ruleset>
+EOF
+./gradlew clean check --continue || true
+RESULTSFILES=$(find . -name 'pmd.xml')
+
+cat << EOF
+
+Here's a PMD config file with suppressions for everything we're violating.
+
+For great success, store in ${PMD_XML}.
+
+Or just fix all issues and skip the suppressions file entirely.
+
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Bankdroid Rules"
+    xmlns="http://pmd.sf.net/ruleset/1.0.0"
+    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
+    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
+
+    <description>Custom ruleset for Bankdroid, created by $(basename $0)</description>
+
+    <exclude-pattern>.*/R.java</exclude-pattern>
+    <exclude-pattern>.*/gen/.*</exclude-pattern>
+
+    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
+    <rule ref="rulesets/internal/all-java.xml">
+EOF
+
+for RULE in $(grep externalInfoUrl= ${RESULTSFILES} | sed 's/.*rule="//' | cut '-d"' -f1 | sort | uniq) ; do
+    echo "        <exclude name=\"${RULE}\" />"
+done
+
+cat << EOF
+    </rule>
+</ruleset>
+EOF

commit 463d5a6895a8f55c4d00279e882565614c5ab906
Merge: 91c8194 57244db
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Oct 14 12:22:10 2016 +0200

    Merge pull request #636 from walles/walles/fix-printstacktrace
    
    Fix all instances of e.printStackTrace()

commit 57244db351d6a4cfd116520d0041bffb3a0a592d (walles/walles/fix-printstacktrace, walles/fix-printstacktrace)
Author: Johan Walles <johan.walles@gmail.com>
Date:   Wed Oct 12 23:42:32 2016 +0200

    Fix all instances of e.printStackTrace()
    
    Not terribly important, but low hanging fruit now that Timber is in
    place.
    
    Note for reviewers: I'm not sure we want all of those in Crashlytics,
    please consider that. But maybe too much data in Crashlytics is better
    than too little? In that case these should probably be dealt with on a
    case-by-case basis.

diff --git app/src/main/java/com/liato/bankdroid/AboutActivity.java app/src/main/java/com/liato/bankdroid/AboutActivity.java
index 203fda9..a1f17de 100644
--- app/src/main/java/com/liato/bankdroid/AboutActivity.java
+++ app/src/main/java/com/liato/bankdroid/AboutActivity.java
@@ -18,8 +18,6 @@ package com.liato.bankdroid;
 
 import android.content.Intent;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
 import android.view.Menu;
@@ -41,14 +39,7 @@ public class AboutActivity extends LockableActivity {
         setContentView(R.layout.about);
         ButterKnife.inject(this);
         PackageInfo pInfo;
-        String version = "v1.x.x";
-        try {
-            pInfo = getPackageManager().getPackageInfo(getPackageName(),
-                    PackageManager.GET_META_DATA);
-            version = pInfo.versionName;
-        } catch (final NameNotFoundException e) {
-            e.printStackTrace();
-        }
+        String version = BuildConfig.VERSION_NAME;
         mVersion.setText(
                 getText(R.string.version).toString().replace("$version", version));
 
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index d05721a..c52f332 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -68,6 +68,7 @@ import java.util.Map;
 import butterknife.ButterKnife;
 import butterknife.InjectView;
 import butterknife.OnClick;
+import timber.log.Timber;
 
 public class BankEditActivity extends LockableActivity implements OnItemSelectedListener {
 
@@ -363,7 +364,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
                         }
                     });
                 } else {
-                    exc.printStackTrace();
+                    Timber.w(exc, "Failed getting info from bank");
                     builder.setMessage(this.exc.getMessage())
                             .setTitle(res.getText(R.string.could_not_create_account))
                             .setIcon(android.R.drawable.ic_dialog_alert)
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 8ffa910..77be2eb 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -32,8 +32,6 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
@@ -176,14 +174,7 @@ public class MainActivity extends LockableActivity {
         dialog.setContentView(R.layout.about);
         dialog.setTitle(getString(R.string.about));
         PackageInfo pInfo;
-        String version = "v1.x.x";
-        try {
-            pInfo = getPackageManager()
-                    .getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
-            version = pInfo.versionName;
-        } catch (final NameNotFoundException e) {
-            e.printStackTrace();
-        }
+        String version = BuildConfig.VERSION_NAME;
         ((TextView) dialog.findViewById(R.id.txtVersion))
                 .setText(getText(R.string.version).toString().replace("$version", version));
         return dialog;
diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index d2584f1..1f6a153 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -41,6 +41,7 @@ import android.webkit.WebViewClient;
 import java.io.IOException;
 
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 import static android.graphics.Color.WHITE;
 
@@ -106,12 +107,8 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                     "", // Javascript function
                     "" // HTML
             );
-        } catch (NotFoundException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+        } catch (NotFoundException | IOException e) {
+            Timber.w(e, "Error loading loading.html");
         }
         mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", preloader, "text/html", "utf-8",
                 null);
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 67ca09d..b1a8888 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -25,6 +25,7 @@ import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 
 import android.content.Context;
 import android.database.Cursor;
+import android.support.annotation.Nullable;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -32,6 +33,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import timber.log.Timber;
+
 public class BankFactory {
 
     public static Bank fromBanktypeId(int id, Context context) throws BankException {
@@ -43,6 +46,7 @@ public class BankFactory {
         return LegacyBankFactory.listBanks(context);
     }
 
+    @Nullable
     public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
         Bank bank = null;
         DBAdapter db = new DBAdapter(context);
@@ -63,8 +67,7 @@ public class BankFactory {
                     bank.setAccounts(accountsFromDb(context, bank.getDbId()));
                 }
             } catch (BankException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
+                Timber.w(e, "Failed getting bank from database");
             } finally {
                 c.close();
             }
@@ -187,8 +190,7 @@ public class BankFactory {
                 try {
                     value = SimpleCrypto.decrypt(Crypto.getKey(), value);
                 } catch (Exception e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
+                    Timber.w(e, "Failed decrypting bank properties");
                 }
             }
             properties.put(key, value);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 30c0536..a86e341 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -421,12 +421,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         String preloader = "Error...";
         try {
             preloader = IOUtils.toString(context.getResources().openRawResource(R.raw.loading));
-        } catch (NotFoundException e1) {
-            // TODO Auto-generated catch block
-            e1.printStackTrace();
-        } catch (IOException e1) {
-            // TODO Auto-generated catch block
-            e1.printStackTrace();
+        } catch (NotFoundException | IOException e1) {
+            Timber.w(e1, "Error getting session package");
         }
 
         try {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index ba28ae1..4d76637 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -51,6 +51,7 @@ import java.util.Locale;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public class Volvofinans extends Bank {
 
@@ -183,7 +184,7 @@ public class Volvofinans extends Bank {
                         Date d = DATE_PARSER.parse(date);
                         date = DATE_FORMATTER.format(d);
                     } catch (ParseException e) {
-                        e.printStackTrace();
+                        Timber.w(e, "Volvofinans: Date parsing failed");
                     }
 
                     transactions.add(new Transaction(date, acc.getString("text"), Helpers
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 2f19c0c..d1ece28 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.provider.IBankTypes;
 import com.liato.bankdroid.utils.StringUtils;
 
 import android.content.Context;
+import android.support.annotation.Nullable;
 import android.text.InputType;
 
 import java.io.IOException;
@@ -57,6 +58,7 @@ import java.util.UUID;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public class Lansforsakringar extends Bank {
 
@@ -139,11 +141,12 @@ public class Lansforsakringar extends Bank {
         return readJsonValue(urlopen.openStream(url, postData, false), valueType);
     }
 
+    @Nullable
     private String objectAsJson(Object value) {
         try {
             return mObjectMapper.writeValueAsString(value);
         } catch (JsonProcessingException e) {
-            e.printStackTrace();
+            Timber.w(e, "Failed converting Object to JSON");
         }
         return null;
     }
@@ -161,8 +164,7 @@ public class Lansforsakringar extends Bank {
             }
             return md5;
         } catch (NoSuchAlgorithmException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            Timber.w(e, "Länsförsäkringar: Error generating challenge");
         }
         return "";
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
deleted file mode 100644
index b389213..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks.seb;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.seb.model.DEVID;
-import com.liato.bankdroid.banking.banks.seb.model.HWINFO;
-import com.liato.bankdroid.banking.banks.seb.model.Request;
-import com.liato.bankdroid.banking.banks.seb.model.SEBRequest;
-import com.liato.bankdroid.banking.banks.seb.model.ServiceInput;
-import com.liato.bankdroid.banking.banks.seb.model.UserCredentials;
-import com.liato.bankdroid.banking.banks.seb.model.VODB;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.InputType;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class SEB extends Bank {
-
-    private static final String NAME = "SEB";
-
-    private static final String NAME_SHORT = "seb";
-
-    private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx";
-
-    private static final int BANKTYPE_ID = IBankTypes.SEB;
-
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-
-    private Pattern reAccounts = Pattern.compile(
-            "/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reTransactions = Pattern.compile(
-            "(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>",
-            Pattern.CASE_INSENSITIVE);
-
-    private String response = null;
-
-    private ObjectMapper mObjectMapper;
-
-    public SEB(Context context) {
-        super(context, R.drawable.logo_seb);
-
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-    }
-
-    public SEB(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_seb_web));
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        urlopen.addHeader("Referer", "https://m.seb.se/");
-        urlopen.setKeepAliveTimeout(5);
-        //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("A1", getUsername()));
-        postData.add(new BasicNameValuePair("A2", getPassword()));
-        postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response,
-                "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader
-                .getClientCertificate(context, R.raw.cert_client_seb, "openbankdata"),
-                CertificateReader.getCertificates(context, R.raw.cert_seb));
-        urlopen.setFollowRedirects(false);
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("A1", getUsername()));
-        postData.add(new BasicNameValuePair("A2", getPassword()));
-        HttpResponse hr = urlopen.openAsHttpResponse(
-                "https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw",
-                postData, true);
-        if (hr.getStatusLine().getStatusCode() == 200) {
-            throw new LoginException(res.getString(R.string.invalid_username_password));
-        } else if (hr.getStatusLine().getStatusCode() != 302) {
-            throw new BankException(res.getString(R.string.unable_to_login));
-        }
-        urlopen.setFollowRedirects(true);
-
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
-        urlopen.addHeader("Accept", "application/json");
-
-        SEBRequest sessionRequest = new SEBRequest();
-        Request r = new Request();
-        r.setUserCredentials(new UserCredentials(getUsername(), getPassword()));
-        ServiceInput serviceInput = new ServiceInput();
-        serviceInput.setCondition("EQ");
-        serviceInput.setVariableName("CUSTOMERTYPE");
-        serviceInput.setVariableValue("P");
-        r.getServiceInput().add(serviceInput);
-        VODB vodb = new VODB();
-        vodb.setHWINFO01(HWINFO.createDefault());
-        vodb.setDEVID01(DEVID.createDefault());
-        r.setVODB(vodb);
-        sessionRequest.setRequest(r);
-
-        try {
-            HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(sessionRequest));
-            HttpResponse hr = urlopen.openAsHttpResponse(
-                    "https://mP.seb.se/1000/ServiceFactory/PC_BANK/PC_BankAktivera01Session01.asmx/Execute",
-                    e, true);
-            hr.getEntity().getContent();
-
-        } catch (UnsupportedEncodingException e1) {
-            e1.printStackTrace();
-        } catch (JsonProcessingException e1) {
-            e1.printStackTrace();
-        }
-
-//        {
-//            "request": {
-//            "ResultInfo": null,
-//                    "VODB": {
-//                "USRINF01": null,
-//                        "DBZV160": [],
-//                "DEVID01": {
-//                    "APPLICATION_VERSION": "6.0.0",
-//                            "OS_NAME": "Android",
-//                            "MODEL": "4S",
-//                            "MANUFACTURER": "Apple",
-//                            "OS_VERSION": "5",
-//                            "APPLICATION_NAME": "MASP"
-//                },
-//                "HWINFO01": {
-//                    "LONGITUDE_DECIMAL": "0",
-//                            "LATITUDE_DECIMAL": "0",
-//                            "COUNTRY_PREFIX": 0
-//                },
-//                "CBEW501": [],
-//                "DBZV170": [],
-//                "CBEW502": []
-//            },
-//            "ServiceInput": [{
-//                "Condition": "EQ",
-//                        "VariableNamePossibleValues": [],
-//                "VariableName": "CUSTOMERTYPE",
-//                        "VariableValue": "P"
-//            }],
-//            "UserCredentials": {
-//                "ApplicationName": "RFO",
-//                        "WorkstationID": "",
-//                        "LoggedOnUser": "Mobile",
-//                        "AuthMethod": "0",
-//                        "UserId": "8001019999",
-//                        "Password": "123password"
-//            },
-//            "ServiceInfo": null
-//        }
-//        }
-
-//        Matcher matcher;
-//        try {
-//            response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=digipassAppl1");
-//            matcher = reAccounts.matcher(response);
-//            while (matcher.find()) {
-//                /*
-//                 * Capture groups:
-//                 * GROUP                    EXAMPLE DATA
-//                 * 1: ID                    GJmQRqlrOPmM++1zf50d6Q==
-//                 * 2: Name                  Personkonto
-//                 * 3: Amount                2.208,03
-//                 *
-//                 */
-//                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-//                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-//            }
-//
-//            if (accounts.isEmpty()) {
-//                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-//            }
-//        }
-//        catch (ClientProtocolException e) {
-//            throw new BankException(e.getMessage());
-//        }
-//        catch (IOException e) {
-//            throw new BankException(e.getMessage());
-//        }
-//        finally {
-//            super.updateComplete();
-//        }
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-
-        //No transaction history for loans, funds and credit cards.
-        int accType = account.getType();
-        if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) {
-            return;
-        }
-
-//        Matcher matcher;
-//        try {
-//            response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1102.aspx?M1=show&P2=1&P4=1&P1=" + account.getId());
-//            matcher = reTransactions.matcher(response);
-//            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-//            while (matcher.find()) {
-//                /*
-//                 * Capture groups:
-//                 * GROUP                    EXAMPLE DATA
-//                 * 1: Book. date            101214
-//                 * 2: Transaction           St1
-//                 * 3: Trans. date           10-12-11
-//                 * 4: Amount                -200,07
-//                 *
-//                 */
-//                String date;
-//                if (matcher.group(3) == null || matcher.group(3).length() == 0) {
-//                    date = Html.fromHtml(matcher.group(1)).toString().trim();
-//                    date = String.format("%s-%s-%s", date.substring(0,2), date.substring(2,4), date.substring(4,6));
-//                }
-//                else {
-//                    date = Html.fromHtml(matcher.group(3)).toString().trim();
-//                }
-//                transactions.add(new Transaction("20"+date, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4))));
-//            }
-//            Collections.sort(transactions, Collections.reverseOrder());
-//            account.setTransactions(transactions);
-//        } catch (ClientProtocolException e) {
-//            // TODO Auto-generated catch block
-//            e.printStackTrace();
-//        } catch (IOException e) {
-//            // TODO Auto-generated catch block
-//            e.printStackTrace();
-//        }
-    }
-
-
-    private ObjectMapper getObjectmapper() {
-        if (mObjectMapper == null) {
-            mObjectMapper = new ObjectMapper();
-            mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-            mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
-        }
-        return mObjectMapper;
-    }
-
-    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
-        try {
-            return getObjectmapper().readValue(is, valueType);
-        } catch (Exception e) {
-            throw new BankException(e.getMessage(), e);
-        }
-    }
-}
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
index 5c1ceb4..86c90a4 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
@@ -7,7 +7,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
-import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
@@ -16,6 +15,8 @@ import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
 
+import timber.log.Timber;
+
 public class CertificateReader {
 
     public static Certificate[] getCertificates(Context context,
@@ -33,12 +34,12 @@ public class CertificateReader {
                     try {
                         is.close();
                     } catch (IOException e) {
-                        e.printStackTrace();
+                        Timber.w(e, "Failed to close input stream");
                     }
                 }
             }
-        } catch (CertificateException e1) {
-            e1.printStackTrace();
+        } catch (CertificateException e) {
+            Timber.w(e, "Generating certificate failed");
         }
         return certificates.toArray(new Certificate[certificates.size()]);
     }
@@ -51,14 +52,8 @@ public class CertificateReader {
             is = new BufferedInputStream(context.getResources().openRawResource(rawResCert));
             keyStore.load(is, password.toCharArray());
             return new ClientCertificate(keyStore, password);
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-        } catch (CertificateException e) {
-            e.printStackTrace();
-        } catch (KeyStoreException e) {
-            e.printStackTrace();
+        } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException e) {
+            Timber.w(e, "Failed to get client certificate");
         } finally {
             if (is != null) {
                 try {
@@ -71,29 +66,6 @@ public class CertificateReader {
         return null;
     }
 
-
-    public static String[] getPins(Context context, int... rawResCerts) {
-        Certificate[] certs = getCertificates(context, rawResCerts);
-        if (certs != null && certs.length > 0) {
-            String[] pins = new String[certs.length];
-            for (int i = 0; i < certs.length; i++) {
-                Certificate cert = certs[i];
-                String hash = getCertificateHash(cert);
-                pins[i] = hash;
-                try {
-                    MessageDigest digest = MessageDigest.getInstance("SHA1");
-                    byte[] publicKey = cert.getPublicKey().getEncoded();
-                    byte[] pin = digest.digest(publicKey);
-                    pins[i] = CertificateReader.byteArrayToHexString(pin);
-                } catch (NoSuchAlgorithmException e) {
-                    e.printStackTrace();
-                }
-            }
-            return pins;
-        }
-        return null;
-    }
-
     private static String byteArrayToHexString(byte[] b) {
         int len = b.length;
         String data = new String();
@@ -104,16 +76,4 @@ public class CertificateReader {
         }
         return data;
     }
-
-    public static String getCertificateHash(Certificate cert) {
-        try {
-            MessageDigest digest = MessageDigest.getInstance("SHA1");
-            byte[] publicKey = cert.getPublicKey().getEncoded();
-            byte[] pin = digest.digest(publicKey);
-            return CertificateReader.byteArrayToHexString(pin);
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-        }
-        return null;
-    }
 }
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 099fb17..2cc5e36 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -84,6 +84,8 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
+import timber.log.Timber;
+
 public class Urllib {
 
     private static int MAX_RETRIES = 5;
@@ -134,14 +136,8 @@ public class Urllib {
             registry.register(new Scheme("https",
                     pins != null && !trustSystemKeystore ? mSSLSocketFactory
                             : SSLSocketFactory.getSocketFactory(), 443));
-        } catch (UnrecoverableKeyException e) {
-            e.printStackTrace();
-        } catch (KeyManagementException e) {
-            e.printStackTrace();
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-        } catch (KeyStoreException e) {
-            e.printStackTrace();
+        } catch (UnrecoverableKeyException | KeyManagementException | KeyStoreException | NoSuchAlgorithmException e) {
+            Timber.w(e, "Urllib: SSLSocketFactory error");
         }
         ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
         httpclient = new BankdroidHttpClient(manager, params);
@@ -264,7 +260,7 @@ public class Urllib {
             try {
                 return new UrlEncodedFormEntity(postData, this.charset);
             } catch (UnsupportedEncodingException e) {
-                e.printStackTrace();
+                Timber.w(e, "Error converting NameValuePair list to HttpEntity");
             }
         }
         return null;
diff --git bankdroid-legacy/src/main/res/drawable/logo_seb.png bankdroid-legacy/src/main/res/drawable/logo_seb.png
deleted file mode 100644
index bdae10f..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_seb.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_client_seb.p12 bankdroid-legacy/src/main/res/raw/cert_client_seb.p12
deleted file mode 100644
index f12d074..0000000
Binary files bankdroid-legacy/src/main/res/raw/cert_client_seb.p12 and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/cert_seb.pem bankdroid-legacy/src/main/res/raw/cert_seb.pem
deleted file mode 100644
index 915fe13..0000000
--- bankdroid-legacy/src/main/res/raw/cert_seb.pem
+++ /dev/null
@@ -1,41 +0,0 @@
------BEGIN CERTIFICATE-----

-HMyRgKehX5A=
------END CERTIFICATE-----
-mP.seb.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_seb_web.pem bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
deleted file mode 100644
index 5f8fa9e..0000000
--- bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----

-e4+R3di3uW33Agbv9Mgdh4m6gencdR5343WmT8LnIw==
------END CERTIFICATE-----
-m.seb.se:443
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index caf5f2b..3ccf593 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -19,14 +19,8 @@
 
     Do "./gradlew check" to test your newly added rule. If there are violations, check
     the console output or the HTML report and remedy them until the build passes.
-
-    If you can't / won't fix a specific violation, you can exclude rules like in the
-    logging-java.xml example below.
     -->
     <rule ref="rulesets/java/android.xml" />
 
-    <rule ref="rulesets/java/logging-java.xml">
-        <!-- FIXME: Re-enable this rule and fix all instances -->
-        <exclude name="AvoidPrintStackTrace" />
-    </rule>
+    <rule ref="rulesets/java/logging-java.xml" />
 </ruleset>

commit 91c8194761e74f71008956a9473b9d35f9a1c454 (tag: v1.9.10.9)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 12 21:14:05 2016 +0200

    Creates release 1.9.10.9

diff --git CHANGELOG CHANGELOG
index 7a93dc1..fe5edba 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,6 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-v1.9.10.9
+v1.9.10.9 (2016-10-12)
 * Länsförsäkringar: Remove broken web links
 * Improve Javadocs in the Bank class
 * Make successfully refreshing a disabled bank re-enable it
@@ -11,6 +11,7 @@ v1.9.10.9
 * Removes IcaBanken since they now require BankID
 * SveaDirekt: Adapt to changed web page
 * Rikslunchen: Adapt to new web service
+* AmericanExpress: Use their mobile API
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git app/build.gradle app/build.gradle
index eeaeac4..20d8d89 100644
--- app/build.gradle
+++ app/build.gradle
@@ -1,14 +1,19 @@
 buildscript {
     repositories {
         maven { url 'https://maven.fabric.io/public' }
+        maven {
+            url "https://plugins.gradle.org/m2/"
+        }
     }
 
     dependencies {
         classpath 'io.fabric.tools:gradle:1.+'
+        classpath "org.ajoberstar:gradle-git:1.5.1"
     }
 }
 apply plugin: 'com.android.application'
 apply from: '../config/quality/quality.gradle'
+apply plugin: "org.ajoberstar.grgit"
 
 if(new File('app/crashlytics.properties').exists()) {
     apply plugin: 'io.fabric'
@@ -22,6 +27,12 @@ def keystorePropertiesFile = project.file("keystore.properties")
 def keystoreProperties = new Properties()
 keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
 
+ext {
+    git = org.ajoberstar.grgit.Grgit.open()
+    gitVersionCode = git.tag.list().size()
+    gitVersionName = "${git.describe()}"
+}
+
 android {
     compileSdkVersion 24
     buildToolsVersion "24.0.1"
@@ -31,8 +42,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 24
-        versionCode 224
-        versionName "1.9.10.8"
+        versionCode 224 + gitVersionCode
+        versionName gitVersionName
     }
 
     signingConfigs {

commit 6bfab24e597a66b7087b7a5fbb1abca23da4d4d4
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Oct 11 20:43:39 2016 +0200

    Refactor logging creation

diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index e4154e6..735c472 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -1,37 +1,18 @@
 package com.liato.bankdroid;
 
-import com.crashlytics.android.Crashlytics;
-import com.crashlytics.android.core.CrashlyticsCore;
+import com.liato.bankdroid.utils.LoggingUtils;
 
 import android.app.Application;
-import android.support.annotation.Nullable;
-import android.util.Log;
 import android.widget.Toast;
 
-import io.fabric.sdk.android.Fabric;
-import timber.log.Timber;
-
 public class BankdroidApplication extends Application {
 
-    public static final String LOG_KEY_LOCALE = "locale";
-
-    public static final String LOG_KEY_BANKS = "banks";
-
     private String message = "";
 
     @Override
     public void onCreate() {
         super.onCreate();
-
-        CrashlyticsCore core = new CrashlyticsCore.Builder()
-                .disabled(BuildConfig.DEBUG)
-                .build();
-        Fabric.with(this, new Crashlytics.Builder().core(core).build());
-
-        if (BuildConfig.DEBUG) {
-            Timber.plant(new Timber.DebugTree());
-        }
-        Timber.plant(new CrashlyticsTree());
+        LoggingUtils.createLogger(this);
     }
 
     public void setApplicationMessage(String messageText) {
@@ -45,27 +26,4 @@ public class BankdroidApplication extends Application {
             toast.show();
         }
     }
-
-    public class CrashlyticsTree extends Timber.Tree {
-        private static final String CRASHLYTICS_KEY_PRIORITY = "priority";
-        private static final String CRASHLYTICS_KEY_TAG = "tag";
-        private static final String CRASHLYTICS_KEY_MESSAGE = "message";
-
-        @Override
-        protected void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable t) {
-            if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO) {
-                return;
-            }
-
-            Crashlytics.setInt(CRASHLYTICS_KEY_PRIORITY, priority);
-            Crashlytics.setString(CRASHLYTICS_KEY_TAG, tag);
-            Crashlytics.setString(CRASHLYTICS_KEY_MESSAGE, message);
-
-            if (t == null) {
-                Crashlytics.logException(new Exception(message));
-            } else {
-                Crashlytics.logException(t);
-            }
-        }
-    }
 }
diff --git app/src/main/java/com/liato/bankdroid/utils/EmulatorUtils.java app/src/main/java/com/liato/bankdroid/utils/EmulatorUtils.java
new file mode 100644
index 0000000..46fdb94
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/utils/EmulatorUtils.java
@@ -0,0 +1,48 @@
+package com.liato.bankdroid.utils;
+
+import android.os.Build;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+class EmulatorUtils {
+    static final boolean RUNNING_ON_EMULATOR = isRunningOnEmulator();
+    static final boolean RUNNING_ON_ANDROID = isRunningOnAndroid();
+
+    private EmulatorUtils() {
+    }
+
+    private static boolean isRunningOnEmulator() {
+        // Inspired by
+        // http://stackoverflow.com/questions/2799097/how-can-i-detect-when-an-android-application-is-running-in>
+        if (Build.PRODUCT == null) {
+            return false;
+        }
+
+        Set<String> parts = new HashSet<>(Arrays.asList(Build.PRODUCT.split("_")));
+        if (parts.size() == 0) {
+            return false;
+        }
+
+        parts.remove("sdk");
+        parts.remove("google");
+        parts.remove("x86");
+        parts.remove("64");
+        parts.remove("phone");
+
+        // If the build identifier contains only the above keywords in some order, then we're
+        // in an emulator
+        return parts.isEmpty();
+    }
+
+    private static boolean isRunningOnAndroid() {
+        // Inspired by:
+        // https://developer.android.com/reference/java/lang/System.html#getProperties()
+        // Developed using trial and error...
+        final Properties properties = System.getProperties();
+        final String httpAgent = (String) properties.get("http.agent");
+        return httpAgent != null && httpAgent.contains("Android");
+    }
+}
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
new file mode 100644
index 0000000..4867459
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/utils/LoggingUtils.java
@@ -0,0 +1,77 @@
+package com.liato.bankdroid.utils;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.BuildConfig;
+
+import io.fabric.sdk.android.Fabric;
+import timber.log.Timber;
+
+public class LoggingUtils {
+
+    private static final boolean IS_CRASHLYTICS_ENABLED = isCrashlyticsEnabled();
+    private static final String DEFAULT_TAG = "Bankdroid";
+
+    private static Class<Timber> initializedLoggingClass = null;
+
+    private LoggingUtils() {
+    }
+
+    public static void createLogger(Context context) {
+       Timber.Tree tree =  IS_CRASHLYTICS_ENABLED ?
+               new CrashlyticsTree(context) :
+               new LocalTree();
+
+        if (initializedLoggingClass != Timber.class) {
+            initializedLoggingClass = Timber.class;
+            Timber.plant(tree);
+            Timber.v("Logging tree planted: %s", tree.getClass());
+        }
+    }
+
+    private static boolean isCrashlyticsEnabled() {
+        return EmulatorUtils.RUNNING_ON_ANDROID &&
+                !EmulatorUtils.RUNNING_ON_EMULATOR;
+    }
+
+    private static class CrashlyticsTree extends Timber.Tree {
+        CrashlyticsTree(Context context) {
+            Fabric.with(context, new Crashlytics());
+        }
+
+        @Override
+        protected void log(int priority, String tag, String message, Throwable t) {
+            if (BuildConfig.DEBUG) {
+                tag = "DEBUG";
+            } else if (TextUtils.isEmpty(tag)) {
+                tag = DEFAULT_TAG;
+            }
+
+            // This call logs to *both* Crashlytics and LogCat, and will log the Exception backtrace
+            // to LogCat on exceptions.
+            Crashlytics.log(priority, tag, message);
+
+            if (t != null) {
+                Crashlytics.logException(t);
+            }
+        }
+    }
+
+    private static class LocalTree extends Timber.Tree {
+        @Override
+        protected void log(int priority, String tag, String message, Throwable t) {
+            if (BuildConfig.DEBUG) {
+                tag = "DEBUG";
+            } else if (TextUtils.isEmpty(tag)) {
+                tag = DEFAULT_TAG;
+            }
+
+            // Empirical evidence shows any exception stack trace is already part of the message, so
+            // no need to print the exception explicitly here.
+            Log.println(priority, tag, message);
+        }
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
index 2602ff1..988e29e 100644
--- app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
+++ app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
@@ -15,7 +15,7 @@ public class NetworkUtils {
     }
 
 
-    public static boolean ping(byte[] ipAddress, int timeout) {
+    private static boolean ping(byte[] ipAddress, int timeout) {
         DatagramSocket datagramSocket = null;
         try {
             datagramSocket = new DatagramSocket();

commit dd9dd7438b5f911f3afc3677c25f40cf5c1e231e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 10 22:00:29 2016 +0200

    Removes unused TAG constants

diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index 645a4a4..eeb67f0 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -38,11 +38,6 @@ import timber.log.Timber;
  */
 public class PairApplicationsActivity extends LockableActivity {
 
-    /**
-     *
-     */
-    private static final String TAG = "Pair Application";
-
     private static final String PAIR_APP_NAME = "com.liato.bankdroid.PAIR_APP_NAME";
 
     public static void initialSetupApiKey(Context ctx) {
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index aada78c..483fa81 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -39,8 +39,6 @@ import timber.log.Timber;
 
 public class DBAdapter {
 
-    static final String TAG = "DBAdapter";
-
     private DatabaseHelper mDbHelper;
 
     private SQLiteDatabase mDb;
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
index 6b17998..0e7502e 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
@@ -28,8 +28,6 @@ import android.widget.ImageView;
 
 public class ChooseLockPatternExample extends Activity implements View.OnClickListener {
 
-    protected static final String TAG = "Settings";
-
     private static final int REQUESTCODE_CHOOSE = 1;
 
     private static final long START_DELAY = 1000;
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index 15e14b3..d092b42 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -79,8 +79,6 @@ public class LockPatternUtils {
      */
     public static final int MIN_PATTERN_REGISTER_FAIL = 3;
 
-    private static final String TAG = "LockPatternUtils";
-
     private static final String LOCK_PATTERN_FILE = "gesture.key";
 
     private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 8fa5713..f84865b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -44,8 +44,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class AkeliusInvest extends Bank {
 
-    private static final String TAG = "AkeliusInvest";
-
     private static final String NAME = "Akelius Invest";
 
     private static final String NAME_SHORT = "akeliusinvest";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 5fcdc51..038f0fe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -45,8 +45,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class AkeliusSpar extends Bank {
 
-    private static final String TAG = "AkeliusSpar";
-
     private static final String NAME = "Akelius Spar";
 
     private static final String NAME_SHORT = "akeliusspar";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 654114f..4940fed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -40,8 +40,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class AppeakPoker extends Bank {
 
-    private static final String TAG = "AppeakPoker";
-
     private static final String NAME = "Appeak Poker";
 
     private static final String NAME_SHORT = "appeakpoker";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
index 8bc5e72..678fcfa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class Audi extends AbsIkanoPartner {
 
-    private static final String TAG = "Audi";
-
     private static final String NAME = "AudiKortet";
 
     private static final String NAME_SHORT = "audi";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 6438d97..eb46cac 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -42,8 +42,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class BetterGlobe extends Bank {
 
-    private static final String TAG = "BetterGlobe";
-
     private static final String NAME = "Better Globe";
 
     private static final String NAME_SHORT = "betterglobe";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index aba3b3b..e31540f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Bioklubben extends Bank {
 
-    private static final String TAG = "Bioklubben";
-
     private static final String NAME = "Bioklubben";
 
     private static final String NAME_SHORT = "bioklubben";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 1c55fc0..62d977f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -40,8 +40,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class BlekingeTrafiken extends Bank {
 
-    private static final String TAG = "Blekingetrafiken";
-
     private static final String NAME = "Blekingetrafiken";
 
     private static final String NAME_SHORT = "blekingetrafiken";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index 7ed675c..7c35408 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -44,8 +44,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class BrummerKF extends Bank {
 
-    private static final String TAG = "BrummerKF";
-
     private static final String NAME = "Brummer KF & Pension";
 
     private static final String NAME_SHORT = "brummer_kf";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index 1ff399c..3640850 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -47,8 +47,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class CSN extends Bank {
 
-    private static final String TAG = "CSN";
-
     private static final String NAME = "CSN";
 
     private static final String NAME_SHORT = "csn";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index b44885f..5276b57 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -26,8 +26,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Chalmrest extends Bank {
 
-    private static final String TAG = "Chalmrest";
-
     private static final String NAME = "Chalmrest";
 
     private static final String NAME_SHORT = "chalmrest";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
index baaeb4f..de3abd3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Chevrolet extends SEBKortBase {
 
-    private static final String TAG = "Chevrolet";
-
     private static final String NAME = "Chevrolet Big Plus Card";
 
     private static final String NAME_SHORT = "chevrolet";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index f347ade..af8c51f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -47,8 +47,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class DanskeBank extends Bank {
 
-    private static final String TAG = "DanskeBank";
-
     private static final String NAME = "DanskeBank";
 
     private static final String NAME_SHORT = "danskebank";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 6ee26d1..1baec10 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -45,8 +45,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class DinersClub extends Bank {
 
-    private static final String TAG = "DinersClub";
-
     private static final String NAME = "Diners Club";
 
     private static final String NAME_SHORT = "dinersclub";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
index 3afa8f3..6440247 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Djurgarden extends SEBKortBase {
 
-    private static final String TAG = "Djurgarden";
-
     private static final String NAME = "Djurgårdskortet MasterCard";
 
     private static final String NAME_SHORT = "djurgarden";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index ececaa1..d3ff765 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -28,8 +28,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class EasyCard extends Bank {
 
-    private static final String TAG = "EasyCard";
-
     private static final String NAME = "EasyCard";
 
     private static final String NAME_SHORT = "easycard";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 85e6441..5722bed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -30,8 +30,6 @@ import java.io.IOException;
 
 public class EurobonusMastercard extends SEBKortBase {
 
-    private static final String TAG = "EurobonusMastercard";
-
     private static final String NAME = "SAS EuroBonus MasterCard (Sweden)";
 
     private static final String NAME_SHORT = "ebmaster";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index 06b3f51..397d768 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -30,8 +30,6 @@ import java.io.IOException;
 
 public class EurobonusMastercardDk extends SEBKortBase {
 
-    private static final String TAG = "EurobonusMastercardDk";
-
     private static final String NAME = "SAS EuroBonus MasterCard (Denmark)";
 
     private static final String NAME_SHORT = "ebmaster_dk";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index 50e1b59..9463db1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -30,8 +30,6 @@ import java.io.IOException;
 
 public class EurobonusMastercardNo extends SEBKortBase {
 
-    private static final String TAG = "EurobonusMastercardNo";
-
     private static final String NAME = "SAS EuroBonus MasterCard (Norway)";
 
     private static final String NAME_SHORT = "ebmaster_no";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
index f8d4d64..4699a9f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Eurocard extends SEBKortBase {
 
-    private static final String TAG = "Eurocard";
-
     private static final String NAME = "Eurocard";
 
     private static final String NAME_SHORT = "eurocard";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 3836d09..729c222 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Everydaycard extends Bank {
 
-    private static final String TAG = "Everydaycard";
-
     private static final String NAME = "Everydaycard";
 
     private static final String NAME_SHORT = "everydaycard";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index efbc2d1..90a513c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -44,8 +44,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class FirstCard extends Bank {
 
-    private static final String TAG = "FirstCard";
-
     private static final String NAME = "First Card";
 
     private static final String NAME_SHORT = "firstcard";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index ea2352c..03f2f30 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -30,9 +30,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class ForexBank extends Bank {
 
-    // Logon url: https://nettbank.edb.com/mobilepayment/index.jsp?n_bank=0087&nativeapp=android
-    private static final String TAG = "ForexBank";
-
     private static final String NAME = "Forex Bank";
 
     private static final String NAME_SHORT = "forex";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 2d897fe..c825370 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -47,8 +47,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Handelsbanken extends Bank {
 
-    private static final String TAG = "Handelsbanken";
-
     private static final String NAME = "Handelsbanken";
 
     private static final String NAME_SHORT = "handelsbanken";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index 75c6f50..8d97593 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -48,8 +48,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Hemkop extends Bank {
 
-    private static final String TAG = "Hemkop";
-
     private static final String NAME = "Hemköp Kundkort";
 
     private static final String NAME_SHORT = "hemkop";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
index 959214f..0930038 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Hors extends Bank {
 
-    private static final String TAG = "Hors";
-
     private static final String NAME = "Hörs";
 
     private static final String NAME_SHORT = "hors";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
index 3ae89f2..3677f55 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class IKEA extends AbsIkanoPartner {
 
-    private static final String TAG = "IKEA";
-
     private static final String NAME = "IKEA HANDLA kort";
 
     private static final String NAME_SHORT = "ikea";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 79380f3..9ea837a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -45,8 +45,6 @@ import timber.log.Timber;
 
 public class IkanoBank extends Bank {
 
-    private static final String TAG = "IkanoBank";
-
     private static final String NAME = "Ikano Bank";
 
     private static final String NAME_SHORT = "ikanobank";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 832a23b..b3c620f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -45,8 +45,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Jojo extends Bank {
 
-    private static final String TAG = "Jojo";
-
     private static final String NAME = "Jojo Reskassa";
 
     private static final String NAME_SHORT = "jojo";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index ba1fab0..6c564d8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -29,8 +29,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Marginalen extends Bank {
 
-    private static final String TAG = "Marginalen";
-
     private static final String NAME = "Marginalen Bank";
 
     private static final String NAME_SHORT = "marginalen";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index b9f2367..1aeefd3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class McDonalds extends Bank {
 
-    private static final String TAG = "McDonalds";
-
     private static final String NAME = "McDonald's Presentkort";
 
     private static final String NAME_SHORT = "mcdonalds";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index f965069..9b20da6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -30,8 +30,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Meniga extends Bank {
 
-    private static final String TAG = "Meniga";
-
     private static final String NAME = "Meniga";
 
     private static final String NAME_SHORT = "meniga";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index 3fb9e17..0afc6f4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -29,8 +29,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class NordeaDK extends Bank {
 
-    private static final String TAG = "NordeaDK";
-
     private static final String NAME = "Nordea DK";
 
     private static final String NAME_SHORT = "nordea_dk";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 8e9b1ed..7552aa9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -46,8 +46,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnet extends Bank {
 
-    private static final String TAG = "Nordnet";
-
     private static final String NAME = "Nordnet";
 
     private static final String NAME_SHORT = "nordnet";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 1c40026..2f78946 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnetdirekt extends Bank {
 
-    private static final String TAG = "Nordnetdirekt";
-
     private static final String NAME = "Nordnetdirekt";
 
     private static final String NAME_SHORT = "nordnetdirekt";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index 97822f6..b740b6e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -45,8 +45,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class OKQ8 extends Bank {
 
-    private static final String TAG = "OKQ8";
-
     private static final String NAME = "OKQ8 VISA";
 
     private static final String NAME_SHORT = "okq8";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
index 424f6dd..45a5bb1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Opel extends SEBKortBase {
 
-    private static final String TAG = "Opel";
-
     private static final String NAME = "OpelKortet";
 
     private static final String NAME_SHORT = "opel";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 9e1502c..37f3770 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -41,8 +41,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Ostgotatrafiken extends Bank {
 
-    private static final String TAG = "Östgötatrafiken";
-
     private static final String NAME = "Östgötatrafiken";
 
     private static final String NAME_SHORT = "ogt";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index c5e18e9..c597d44 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Osuuspankki extends Bank {
 
-    private static final String TAG = "Osuuspankki";
-
     private static final String NAME = "Osuuspankki";
 
     private static final String NAME_SHORT = "osuuspankki";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index a9203c9..e2261ff 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -48,7 +48,6 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PayPal extends Bank {
-    private static final String TAG = "PayPal";
     private static final String NAME = "PayPal";
     private static final String NAME_SHORT = "paypal";
     private static final String ORIGIN_URL =  "https://www.paypal.com";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index abc9868..4f2d1ae 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -44,8 +44,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Payson extends Bank {
 
-    private static final String TAG = "Payson";
-
     private static final String NAME = "Payson";
 
     private static final String NAME_SHORT = "payson";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index dfed1c4..a4da2e4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class PlusGirot extends Bank {
 
-    private static final String TAG = "PlusGirot";
-
     private static final String NAME = "PlusGirot";
 
     private static final String NAME_SHORT = "plusgirot";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
index d076c5e..b780868 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Preem extends AbsIkanoPartner {
 
-    private static final String TAG = "Preem";
-
     private static final String NAME = "Preem Privatkort";
 
     private static final String NAME_SHORT = "preem";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
index 599b7f4..15a3e99 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Quintessentially extends SEBKortBase {
 
-    private static final String TAG = "Quintessentially";
-
     private static final String NAME = "Quintessentially Credit Card";
 
     private static final String NAME_SHORT = "quintessentially";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
index 0cca688..dea7bd5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class SJPrio extends SEBKortBase {
 
-    private static final String TAG = "SJPrio";
-
     private static final String NAME = "SJ Prio MasterCard";
 
     private static final String NAME_SHORT = "sj_prio";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
index 1233458..f65816f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Saab extends SEBKortBase {
 
-    private static final String TAG = "SAAB";
-
     private static final String NAME = "SaabKortet";
 
     private static final String NAME_SHORT = "saab";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
index 873c199..17e1006 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class Seat extends AbsIkanoPartner {
 
-    private static final String TAG = "Seat";
-
     private static final String NAME = "Seatkortet";
 
     private static final String NAME_SHORT = "seat";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 088cd13..490046a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class SevenDay extends Bank {
 
-    private static final String TAG = "SevenDay";
-
     private static final String NAME = "SevenDay";
 
     private static final String NAME_SHORT = "sevenday";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
index ce3daac..768275f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class Shell extends AbsIkanoPartner {
 
-    private static final String TAG = "Shell";
-
     private static final String NAME = "Shell MasterCard";
 
     private static final String NAME_SHORT = "shell";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
index 143ae79..51429a7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class Skoda extends AbsIkanoPartner {
 
-    private static final String TAG = "Skoda";
-
     private static final String NAME = "Skodakortet";
 
     private static final String NAME_SHORT = "skoda";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index f1516db..b722e42 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class SparbankenOresund extends MobilbankenBase {
 
-    private static final String TAG = "SparbankenOresund";
-
     private static final String NAME = "Sparbanken Öresund";
 
     private static final String NAME_SHORT = "sparbanken_oresund";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index 6d4283a..f4f6777 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class SparbankenSyd extends MobilbankenBase {
 
-    private static final String TAG = "SparbankenSyd";
-
     private static final String NAME = "Sparbanken Syd";
 
     private static final String NAME_SHORT = "sparbanken_syd";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
index ee47e26..f883912 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Statoil extends SEBKortBase {
 
-    private static final String TAG = "Statoil";
-
     private static final String NAME = "Statoil Mastercard";
 
     private static final String NAME_SHORT = "statoil";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 8029962..d53ffcc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -49,8 +49,6 @@ import timber.log.Timber;
 
 public class Steam extends Bank {
 
-    private static final String TAG = "Steam";
-
     private static final String NAME = "Steam Wallet";
 
     private static final String NAME_SHORT = "steam";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index fdf1711..620c740 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -30,8 +30,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class SveaDirekt extends Bank {
 
-    private static final String TAG = "SveaDirekt";
-
     private static final String NAME = "Svea Direkt";
 
     private static final String NAME_SHORT = "sveadirekt";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 89c091b..85d795c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class SvenskaSpel extends Bank {
 
-    private static final String TAG = "SvenskaSpel";
-
     private static final String NAME = "Svenska Spel";
 
     private static final String NAME_SHORT = "svenskaspel";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index 10daa01..2ceec08 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -41,8 +41,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class TestBank extends Bank {
 
-    private static final String TAG = "TestBank";
-
     private static final String NAME = "Testbank";
 
     private static final String NAME_SHORT = "testbank";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 01c1f8e..ed68966 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -42,8 +42,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class TicketRikskortet extends Bank {
 
-    private static final String TAG = "Rikskortet";
-
     private static final String NAME = "Ticket Rikskortet";
 
     private static final String NAME_SHORT = "rikskortet";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 5d1b13e..c19925a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -43,8 +43,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class TrustBuddy extends Bank {
 
-    private static final String TAG = "TrustBuddy";
-
     private static final String NAME = "TrustBuddy";
 
     private static final String NAME_SHORT = "trustbuddy";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 71d144e..3c51255 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -42,8 +42,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Vasttrafik extends Bank {
 
-    private static final String TAG = "Västtrafik";
-
     private static final String NAME = "Västtrafik";
 
     private static final String NAME_SHORT = "vasttrafik";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 5ace839..2518cd4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -42,8 +42,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Villabanken extends Bank {
 
-    private static final String TAG = "Villabanken";
-
     private static final String NAME = "Villabanken";
 
     private static final String NAME_SHORT = "villabanken";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
index 36d2e3d..3bb6edb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -28,8 +28,6 @@ import java.io.IOException;
 
 public class Volkswagen extends AbsIkanoPartner {
 
-    private static final String TAG = "Volkswagen";
-
     private static final String NAME = "Volkswagenkortet";
 
     private static final String NAME_SHORT = "volkswagen";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 97d35f1..ba28ae1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -54,8 +54,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Volvofinans extends Bank {
 
-    private static final String TAG = "Volvofinans";
-
     private static final String NAME = "Volvofinans";
 
     private static final String NAME_SHORT = "volvofinans";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
index 8c959eb..49831f0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
@@ -29,8 +29,6 @@ import java.io.IOException;
 
 public class Wallet extends SEBKortBase {
 
-    private static final String TAG = "wallet";
-
     private static final String NAME = "wallet MasterCard";
 
     private static final String NAME_SHORT = "wallet";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 9972d17..a7b13e1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -42,8 +42,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Zidisha extends Bank {
 
-    private static final String TAG = "Zidisha";
-
     private static final String NAME = "Zidisha";
 
     private static final String NAME_SHORT = "zidisha";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index f8f9482..0f789ff 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -38,8 +38,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Bitcoin extends Bank {
 
-    private static final String TAG = "Bitcoin";
-
     private static final String NAME = "Bitcoin";
 
     private static final String NAME_SHORT = "bitcoin";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 5d64059..84bcb8d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -55,8 +55,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Coop extends Bank {
 
-    private static final String TAG = "Coop";
-
     private static final String NAME = "Coop";
 
     private static final String NAME_SHORT = "coop";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index d1c92a7..80a09a2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -45,8 +45,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
 
-    private static final String TAG = "ICABanken";
-
     private static final String NAME = "ICA Banken";
 
     private static final String NAME_SHORT = "icabanken";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 552a85d..2f19c0c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -60,8 +60,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Lansforsakringar extends Bank {
 
-    private static final String TAG = "Lansforsakringar";
-
     private static final String NAME = "Länsförsäkringar";
 
     private static final String NAME_SHORT = "lansforsakringar";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 15f828d..24dbb7e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -44,8 +44,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordea extends Bank {
 
-    private static final String TAG = "Nordea";
-
     private static final String NAME = "Nordea";
 
     private static final String NAME_SHORT = "nordea";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 0d0eab0..c8b5272 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -38,8 +38,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Rikslunchen extends Bank {
 
-    private static final String TAG = "Rikslunchen";
-
     private static final String NAME = "Rikslunchen";
 
     private static final String NAME_SHORT = "rikslunchen";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index 21c7737..b389213 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -56,8 +56,6 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class SEB extends Bank {
 
-    private static final String TAG = "SEB";
-
     private static final String NAME = "SEB";
 
     private static final String NAME_SHORT = "seb";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
index a5e6d69..e7924e9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -14,8 +14,6 @@ public class Sparbankerna extends AbstractSwedbank {
 
     protected static final String NAME_SHORT = "sparbankerna";
 
-    private static final String TAG = "Sparbankerna";
-
     private static final String NAME = "Sparbankerna";
 
     private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
index 738913f..06466d3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
@@ -12,8 +12,6 @@ import java.io.IOException;
 
 public class SparbankernaCorporate extends AbstractSwedbank {
 
-    private static final String TAG = "Sparbankerna Företag";
-
     private static final String NAME = "Sparbankerna Företag";
 
     private static final String NAME_SHORT = "sparbankerna-corporate";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
index ce8977b..10eaaca 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
@@ -12,8 +12,6 @@ import java.io.IOException;
 
 public class SparbankernaYouth extends AbstractSwedbank {
 
-    private static final String TAG = "Sparbankerna Ung";
-
     private static final String NAME = "Sparbankerna Ung";
 
     private static final String NAME_SHORT = "sparbankerna-youth";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
index eb8d862..c73dc9d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -14,8 +14,6 @@ public class Swedbank extends AbstractSwedbank {
 
     protected static final String NAME_SHORT = "swedbank";
 
-    private static final String TAG = "Swedbank";
-
     private static final String NAME = "Swedbank";
 
     private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
index 20c42b0..ea492a3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
@@ -12,8 +12,6 @@ import java.io.IOException;
 
 public class SwedbankCorporate extends AbstractSwedbank {
 
-    private static final String TAG = "Swedbank Företag";
-
     private static final String NAME = "Swedbank Företag";
 
     private static final String NAME_SHORT = "swedbank-corporate";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
index f253d64..c0ed666 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
@@ -12,8 +12,6 @@ import java.io.IOException;
 
 public class SwedbankYouth extends AbstractSwedbank {
 
-    private static final String TAG = "Swedbank Ung";
-
     private static final String NAME = "Swedbank Ung";
 
     private static final String NAME_SHORT = "swedbank-youth";

commit 19a60f2079aec3be0d287f0aea9fdd047d658402
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 10 21:49:49 2016 +0200

    Use Timber for logging

diff --git app/build.gradle app/build.gradle
index a6f8d3e..eeaeac4 100644
--- app/build.gradle
+++ app/build.gradle
@@ -71,6 +71,7 @@ dependencies {
     compile project(':bankdroid-legacy')
     compile project(':bankdroid-core')
     compile 'com.jakewharton:butterknife:6.1.0'
+    compile 'com.jakewharton.timber:timber:4.3.1'
     compile "com.android.support:appcompat-v7:24.1.1"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index 898736e..e4154e6 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -1,17 +1,15 @@
 package com.liato.bankdroid;
 
 import com.crashlytics.android.Crashlytics;
-import com.crashlytics.android.answers.Answers;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
+import com.crashlytics.android.core.CrashlyticsCore;
 
 import android.app.Application;
+import android.support.annotation.Nullable;
+import android.util.Log;
 import android.widget.Toast;
 
-import java.util.List;
-import java.util.Locale;
-
 import io.fabric.sdk.android.Fabric;
+import timber.log.Timber;
 
 public class BankdroidApplication extends Application {
 
@@ -24,22 +22,16 @@ public class BankdroidApplication extends Application {
     @Override
     public void onCreate() {
         super.onCreate();
-        Fabric.with(this, new Crashlytics(), new Answers());
-        Crashlytics.setString(LOG_KEY_LOCALE, Locale.getDefault().toString());
-        logBanks();
-    }
 
-    private void logBanks() {
-        List<Bank> banks = BankFactory.banksFromDb(this, false);
-        StringBuilder bankStringBuilder = new StringBuilder();
-        if (banks != null && !banks.isEmpty()) {
-            for (Bank bank : banks) {
-                bankStringBuilder.append(bank.getName())
-                        .append(",");
-            }
-            Crashlytics.setString(LOG_KEY_BANKS,
-                    bankStringBuilder.substring(0, bankStringBuilder.length() - 1));
+        CrashlyticsCore core = new CrashlyticsCore.Builder()
+                .disabled(BuildConfig.DEBUG)
+                .build();
+        Fabric.with(this, new Crashlytics.Builder().core(core).build());
+
+        if (BuildConfig.DEBUG) {
+            Timber.plant(new Timber.DebugTree());
         }
+        Timber.plant(new CrashlyticsTree());
     }
 
     public void setApplicationMessage(String messageText) {
@@ -53,4 +45,27 @@ public class BankdroidApplication extends Application {
             toast.show();
         }
     }
+
+    public class CrashlyticsTree extends Timber.Tree {
+        private static final String CRASHLYTICS_KEY_PRIORITY = "priority";
+        private static final String CRASHLYTICS_KEY_TAG = "tag";
+        private static final String CRASHLYTICS_KEY_MESSAGE = "message";
+
+        @Override
+        protected void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable t) {
+            if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO) {
+                return;
+            }
+
+            Crashlytics.setInt(CRASHLYTICS_KEY_PRIORITY, priority);
+            Crashlytics.setString(CRASHLYTICS_KEY_TAG, tag);
+            Crashlytics.setString(CRASHLYTICS_KEY_MESSAGE, message);
+
+            if (t == null) {
+                Crashlytics.logException(new Exception(message));
+            } else {
+                Crashlytics.logException(t);
+            }
+        }
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index 0f3d49a..ab70eb9 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -16,7 +16,6 @@
 
 package com.liato.bankdroid;
 
-import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -37,12 +36,13 @@ import android.os.AsyncTask;
 import android.preference.PreferenceManager;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.util.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import timber.log.Timber;
+
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
     private final static String TAG = "DataRetrieverTask";
@@ -137,7 +137,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
 
-                Crashlytics.logException(e);
+                Timber.e(e, "Could not update bank.");
             } catch (final LoginException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
@@ -145,12 +145,11 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
             } catch (BankChoiceException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
-                Log.e(TAG, "BankChoiceError: " + e.getMessage());
             } catch (IOException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
                 if (NetworkUtils.isInternetAvailable()) {
-                    Crashlytics.logException(e);
+                    Timber.e(e);
                 }
             }
 
diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index 91afae0..645a4a4 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -25,12 +25,13 @@ import android.content.SharedPreferences.Editor;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import timber.log.Timber;
+
 /**
  * @author Magnus Andersson
  * @since 8 jun 2011
@@ -84,7 +85,7 @@ public class PairApplicationsActivity extends LockableActivity {
             TextView appNameView = (TextView) findViewById(R.id.app_name);
             appNameView.setText(appName);
         } else {
-            Log.w(TAG, "Unknown application");
+            Timber.w("Unknown application");
         }
 
 
diff --git app/src/main/java/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
index bd8398a..2e54b30 100644
--- app/src/main/java/com/liato/bankdroid/SettingsActivity.java
+++ app/src/main/java/com/liato/bankdroid/SettingsActivity.java
@@ -33,11 +33,12 @@ import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
 import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceScreen;
-import android.util.Log;
 import android.widget.Toast;
 
 import java.math.BigDecimal;
 
+import timber.log.Timber;
+
 public class SettingsActivity extends LockablePreferenceActivity
         implements OnPreferenceClickListener, OnPreferenceChangeListener {
 
@@ -124,7 +125,7 @@ public class SettingsActivity extends LockablePreferenceActivity
                             "http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay")));
             return true;
         } else if ("test_notification".equals(prefKey)) {
-            Log.d(TAG, "Sending test notification.");
+            Timber.d("Sending test notification.");
             Account account1 = new Account("Personkonto", new BigDecimal(8351.00), "22");
             Bank bank1 = new Swedbank(this);
             bank1.setDbid(21);
@@ -152,7 +153,7 @@ public class SettingsActivity extends LockablePreferenceActivity
                 mLockPatternUtils.saveLockPattern(null);
                 ((CheckBoxPreference) findPreference("patternlock_enabled")).setChecked(false);
             } else {
-                Log.d(TAG, "User was unable to disable pattern lock.");
+                Timber.d("User was unable to disable pattern lock.");
             }
         } else if (requestCode == ENABLE_LOCKPATTERN) {
             // User attempted to enable the pattern lock, toggle the checkbox.
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 25a008e..81a0208 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -16,7 +16,6 @@
 
 package com.liato.bankdroid.appwidget;
 
-import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.MainActivity;
 import com.liato.bankdroid.R;
@@ -47,7 +46,6 @@ import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.support.annotation.NonNull;
 import android.support.v4.app.NotificationCompat;
-import android.util.Log;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -55,6 +53,8 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 
+import timber.log.Timber;
+
 public class AutoRefreshService extends Service {
 
     public final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
@@ -182,8 +182,7 @@ public class AutoRefreshService extends Service {
         try {
             pendingIntent.send();
         } catch (final CanceledException e) {
-            // TODO Auto-generated catch block
-            Log.e("", e.getMessage(), e);
+            Timber.w(e, "Problem occurred while updating widget");
         }
     }
 
@@ -208,7 +207,7 @@ public class AutoRefreshService extends Service {
             if (InsideUpdatePeriod()) {
                 new DataRetrieverTask(this).execute();
             } else {
-                Log.v(TAG, "Skipping update due to not in update period.");
+                Timber.v("Skipping update due to not in update period.");
                 stopSelf();
             }
         }
@@ -308,9 +307,9 @@ public class AutoRefreshService extends Service {
             for (final Bank bank : banks) {
                 if (prefs.getBoolean("debug_mode", false)
                         && prefs.getBoolean("debug_only_testbank", false)) {
-                    Log.d(TAG,
-                            "Debug::Only_Testbank is ON. Skipping update for "
-                                    + bank.getName());
+                    Timber.d(
+                            "Only_Testbank is ON. Skipping update for %s",
+                            bank.getName());
                     continue;
                 }
                 if (bank.isDisabled()) {
@@ -391,19 +390,14 @@ public class AutoRefreshService extends Service {
                     }
                 } catch (final BankException e) {
                     // Refresh widgets if an update fails
-                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
-                            + "'; BankException: " + e.getMessage());
-
-                    Crashlytics.logException(e);
+                    Timber.e(e, "Could not update bank %s", bank.getShortName());
                 } catch (final LoginException e) {
-                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
-                            + "'; LoginException: " + e.getMessage());
+                    Timber.d(e, "Invalid credentials for bank %s", bank.getShortName());
                     refreshWidgets = true;
                     db.disableBank(bank.getDbId());
                 } catch (BankChoiceException e) {
                 } catch (Exception e) {
-                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
-                            + "'; Exception: " + e.getMessage());
+                    Timber.e(e, "An unexpected error occurred while updating bank %s", bank.getShortName());
                 }
             }
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 6b679e9..141fed9 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -16,7 +16,6 @@
 
 package com.liato.bankdroid.appwidget;
 
-import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.MainActivity;
 import com.liato.bankdroid.R;
@@ -43,12 +42,13 @@ import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
 import java.io.IOException;
 
+import timber.log.Timber;
+
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
     private final static String TAG = "BankdroidWidgetProvider";
@@ -112,13 +112,13 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
         long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
         if (accountId == null) {
-            Log.w("BankdroidWidgetProvider", "Widget not found. ID: " + appWidgetId);
+            Timber.w("Widget not found. ID: %s", appWidgetId);
             return disableAppWidget(context, appWidgetManager,
                     appWidgetId);
         }
         Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false);
         if (account == null) {
-            Log.w("BankdroidWidgetProvider", "Account not found in db: " + accountId);
+            Timber.w("Account not found in database");
             return disableAppWidget(context, appWidgetManager,
                     appWidgetId);
 
@@ -126,10 +126,9 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
         Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false);
         if (bank == null) {
-            Log.w("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
+            Timber.w("Bank not found in database");
             return disableAppWidget(context, appWidgetManager,
                     appWidgetId);
-
         }
 
         account.setBank(bank);
@@ -376,7 +375,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
             protected Void doInBackground(Void... params) {
                 String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
                 if (accountId == null) {
-                    Log.w("WidgetService", "Widget not found in db: " + appWidgetId);
+                    Timber.w("Widget not found %d", appWidgetId);
                     return null;
                 }
                 long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
@@ -396,20 +395,14 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
                     }
 
                 } catch (BankException e) {
-                    Log.e(TAG, "Error while updating bank '" + bank.getDbId() + "'; " + e
-                            .getMessage());
-                    Crashlytics.logException(e);
+                    Timber.e(e, "Could not update bank %s", bank.getShortName());
                 } catch (LoginException e) {
-                    Log.e("", "Disabling bank: " + bank.getDbId());
+                    Timber.w(e, "Invalid credentials for bank %s", bank.getShortName());
                     DBAdapter.disable(bank, context);
                 } catch (BankChoiceException e) {
-                    Log.e(TAG, "Error while updating bank '" + bank.getDbId() + "'; " + e
-                            .getMessage());
                 } catch (IOException e) {
-                    Log.e(TAG, "Error while updating bank '" + bank.getDbId() + "'; " + e
-                            .getMessage());
                     if (NetworkUtils.isInternetAvailable()) {
-                        Crashlytics.logException(e);
+                        Timber.e(e, "Could not update bank %s", bank.getShortName());
                     }
                 }
                 BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 1fdd0b0..aada78c 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -27,7 +27,6 @@ import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
-import android.util.Log;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -35,6 +34,8 @@ import java.util.Calendar;
 import java.util.List;
 import java.util.Map;
 
+import timber.log.Timber;
+
 
 public class DBAdapter {
 
@@ -174,7 +175,7 @@ public class DBAdapter {
                         try {
                             value = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
                         } catch (Exception e) {
-                            Log.w(TAG, "SimpleCrypto error: " + e.getMessage());
+                            Timber.e(e, "Could not encrypt password.");
                         }
                     }
                     ContentValues propertyValues = new ContentValues();
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index 0b91faf..ea72715 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -23,7 +23,8 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
+
+import timber.log.Timber;
 
 import static com.liato.bankdroid.db.Database.PROPERTY_CONNECTION_ID;
 import static com.liato.bankdroid.db.Database.PROPERTY_KEY;
@@ -60,8 +61,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
     @Override
     public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
             final int newVersion) {
-        Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
-                + " to " + newVersion + ", which will destroy all old data");
+        Timber.d("Upgrading database from version %d to %d", newVersion, oldVersion);
         // Version <= 1.7.2
         if (oldVersion <= 9) {
             // Add an "extras" field to the bank and and "alias for" field to the account.
diff --git app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
index f5f9760..79b808c 100644
--- app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
+++ app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
@@ -52,7 +52,8 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Log;
+
+import timber.log.Timber;
 
 /**
  * Implementation of the Live View plug-in service.
@@ -97,8 +98,7 @@ public class LiveViewService extends Service {
 
         @Override
         public void onServiceConnected(final ComponentName className, IBinder service) {
-            Log.d(PluginConstants.LOG_TAG,
-                    "Enter LiveViewService.ServiceConnection.onServiceConnected.");
+            Timber.d("Enter LiveViewService.ServiceConnection.onServiceConnected.");
 
             mLiveView = IPluginServiceV1.Stub.asInterface(service);
 
@@ -111,20 +111,19 @@ public class LiveViewService extends Service {
                     // Register
                     mPluginId = mLiveView
                             .register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
-                    Log.d(PluginConstants.LOG_TAG, "Plugin registered with id: " + mPluginId);
+                    Timber.d("Plugin registered with id: %d", mPluginId);
                 }
             } catch (RemoteException re) {
-                Log.e(PluginConstants.LOG_TAG, "Failed to install plugin. Stop self.");
+                Timber.e("Failed to install plugin. Stop self.");
                 stopSelf();
             }
 
-            Log.d(PluginConstants.LOG_TAG, "Plugin registered. mPluginId: " + mPluginId);
+            Timber.d("Plugin registered. mPluginId: %d", mPluginId);
         }
 
         @Override
         public void onServiceDisconnected(ComponentName className) {
-            Log.d(PluginConstants.LOG_TAG,
-                    "Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
+            Timber.d("Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
             stopSelf();
         }
 
@@ -142,7 +141,7 @@ public class LiveViewService extends Service {
 
     public void onCreate() {
         super.onCreate();
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
+        Timber.d("Enter LiveViewService.onCreate.");
 
         // Load menu icon
         int iconId = R.drawable.ic_launcher;
@@ -150,7 +149,7 @@ public class LiveViewService extends Service {
     }
 
     public void onDestroy() {
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onDestroy.");
+        Timber.d("Enter LiveViewService.onDestroy.");
 
         // Unbind from LiveView service
         if (mServiceConnection != null) {
@@ -165,7 +164,7 @@ public class LiveViewService extends Service {
 
     public void onStart(Intent intent, int startId) {
         super.onStart(intent, startId);
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
+        Timber.d("Enter LiveViewService.onStart.");
         if (intent == null) {
             return;
         }
@@ -178,19 +177,19 @@ public class LiveViewService extends Service {
                                 extras.getString(INTENT_EXTRA_TITLE),
                                 extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(),
                                 "");
-                        Log.d(PluginConstants.LOG_TAG, "Announce sent to LiveView Application");
+                        Timber.d("Announce sent to LiveView Application");
                     } else {
-                        Log.d(PluginConstants.LOG_TAG, "LiveView Application not reachable");
+                        Timber.d("LiveView Application not reachable");
                     }
                 } catch (Exception e) {
-                    Log.e(PluginConstants.LOG_TAG, "Failed to send announce", e);
+                    Timber.e(e, "Failed to send announce");
                 }
             }
 
         } else {
             // We end up here when LiveView Application probes the plugin
             if (isAlreadyRunning()) {
-                Log.d(PluginConstants.LOG_TAG, "Already started.");
+                Timber.d("Already started.");
             } else {
                 // Init
                 mPluginName = getResources().getString(R.string.app_name);
@@ -206,7 +205,7 @@ public class LiveViewService extends Service {
 
     @Override
     public IBinder onBind(final Intent intent) {
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onBind.");
+        Timber.d("Enter LiveViewService.onBind.");
         return null;
     }
 
@@ -217,9 +216,9 @@ public class LiveViewService extends Service {
         boolean result = bindService(new Intent(PluginConstants.LIVEVIEW_SERVICE_BIND_INTENT),
                 mServiceConnection, 0);
         if (result) {
-            Log.d(PluginConstants.LOG_TAG, "Bound to LiveView.");
+            Timber.d("Bound to LiveView.");
         } else {
-            Log.d(PluginConstants.LOG_TAG, "No bind.");
+            Timber.d("No bind.");
             stopSelf();
         }
     }
@@ -231,7 +230,7 @@ public class LiveViewService extends Service {
      * Opens the MainActivity on the phone.
      */
     protected void openInPhone(String openInPhoneAction) {
-        Log.d(PluginConstants.LOG_TAG, "openInPhone");
+        Timber.d("openInPhone");
         Intent i = new Intent(this, MainActivity.class)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         startActivity(i);
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
index 0d05b28..766ce28 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -45,7 +45,8 @@ import com.liato.bankdroid.SettingsActivity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.util.Log;
+
+import timber.log.Timber;
 
 /**
  * Receives broadcast intents from LiveView service.
@@ -57,7 +58,7 @@ public class PluginReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         String command = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND);
-        Log.d(PluginConstants.LOG_TAG, "Received command: " + command);
+        Timber.v("Received command: %s", command);
 
         if (command == null) {
             return;
@@ -69,7 +70,7 @@ public class PluginReceiver extends BroadcastReceiver {
             String myPluginName = context.getResources().getString(R.string.app_name);
 
             if (pluginName != null && pluginName.contentEquals(myPluginName)) {
-                Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
+                Timber.v("Starting preferences!");
 
                 Intent prefsIntent = new Intent(context, SettingsActivity.class);
                 prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -77,9 +78,9 @@ public class PluginReceiver extends BroadcastReceiver {
             }
         } else if (command.contentEquals(PluginConstants.BROADCAST_COMMAND_START)) {
             if (LiveViewService.isAlreadyRunning()) {
-                Log.d(PluginConstants.LOG_TAG, "Service is already running.");
+                Timber.v("Service is already running.");
             } else {
-                Log.d(PluginConstants.LOG_TAG, "Starting service!");
+                Timber.v("Starting service!");
 
                 context.startService(new Intent(context, LiveViewService.class));
             }
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
index 9eada3a..72a2e1b 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
@@ -43,12 +43,13 @@ import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.util.Log;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 
+import timber.log.Timber;
+
 /**
  * Utils for LiveView plugin.
  *
@@ -69,7 +70,7 @@ public final class PluginUtils {
      */
     public static String storeIconToFile(Context ctx, Resources resources, int resource,
             String fileName) {
-        Log.d(PluginConstants.LOG_TAG, "Store icon to file.");
+        Timber.d("Store icon to file.");
 
         if (resources == null) {
             return "";
@@ -83,11 +84,11 @@ public final class PluginUtils {
             fos.flush();
             fos.close();
         } catch (IOException e) {
-            Log.e(PluginConstants.LOG_TAG, "Failed to store to device", e);
+            Timber.e(e, "Failed to store to device");
         }
 
         File iconFile = ctx.getFileStreamPath(fileName);
-        Log.d(PluginConstants.LOG_TAG, "Icon stored. " + iconFile.getAbsolutePath());
+        Timber.d("Icon stored. %s", iconFile.getAbsolutePath());
 
         return iconFile.getAbsolutePath();
     }
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index 47c2986..15e14b3 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -28,7 +28,6 @@ import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.util.Log;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -38,6 +37,8 @@ import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.List;
 
+import timber.log.Timber;
+
 /**
  * Utilities for the lock patten and its settings.
  */
@@ -231,9 +232,9 @@ public class LockPatternUtils {
      */
     public void saveLockPattern(List<LockPatternView.Cell> pattern) {
         if (pattern == null) {
-            Log.d(TAG, "Removing lock pattern");
+            Timber.d("Removing lock pattern");
         } else {
-            Log.d(TAG, "Saving lock pattern: " + LockPatternUtils.patternToString(pattern));
+            Timber.v("Saving lock pattern: %s", LockPatternUtils.patternToString(pattern));
         }
         // Compute the hash
         final byte[] hash = LockPatternUtils.patternToHash(pattern);
@@ -250,10 +251,10 @@ public class LockPatternUtils {
             setBoolean(PATTERN_EVER_CHOSEN, true);
         } catch (FileNotFoundException fnfe) {
             // Cant do much, unless we want to fail over to using the settings provider
-            Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
+            Timber.e(fnfe, "Unable to save lock pattern to %s", sLockPatternFilename);
         } catch (IOException ioe) {
             // Cant do much
-            Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
+            Timber.e(ioe, "Unable to save lock pattern to %s", sLockPatternFilename);
         }
     }
 
diff --git app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 45984f1..4c0e444 100644
--- app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -28,11 +28,12 @@ import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.preference.PreferenceManager;
-import android.util.Log;
 
 import java.util.HashMap;
 import java.util.Map;
 
+import timber.log.Timber;
+
 /**
  * <p>
  * This is the implementation of the BankTransactionsProvider. It provides
@@ -143,7 +144,7 @@ public class BankTransactionsProvider extends ContentProvider implements
      */
     @Override
     public String getType(final Uri uri) {
-        Log.d(TAG, "Got URI " + uri.toString());
+        Timber.d("Got URI: %s", uri.toString());
 
         switch (uriMatcher.match(uri)) {
             case BANK_ACCOUNTS:
@@ -187,7 +188,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 
         final String apiKey = uri.getPathSegments().get(1);
 
-        Log.d(TAG, "Trying to access database with " + apiKey);
+        Timber.v("Trying to access database with %s", apiKey);
 
         if (!apiKey.startsWith(API_KEY, 0)) {
             return null;
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
index 66cc01a..7166e8a 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -22,11 +22,12 @@ import android.graphics.Bitmap.Config;
 import android.graphics.Color;
 import android.preference.Preference;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import timber.log.Timber;
+
 /**
  * A preference type that allows a user to choose a time
  *
@@ -138,7 +139,7 @@ public class ColorPickerPreference
                 try {
                     mDefaultValue = convertToColorInt(defaultValue);
                 } catch (NumberFormatException e) {
-                    Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
+                    Timber.w("Wrong color: %s", defaultValue);
                     mDefaultValue = convertToColorInt("#FF000000");
                 }
             } else {
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index 012efe0..03007ed 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -28,6 +28,7 @@ dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-interface')
     compile 'com.android.support:appcompat-v7:24.1.1'
+    compile 'com.jakewharton.timber:timber:4.3.1'
     compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'}
     compile 'org.jsoup:jsoup:1.7.3'
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
index 2435e76..f746ff3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
@@ -27,7 +27,6 @@ import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.os.Build;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
@@ -38,6 +37,8 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
+import timber.log.Timber;
+
 public class Helpers {
 
     private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS",
@@ -107,7 +108,7 @@ public class Helpers {
         try {
             ret = new BigDecimal(balance);
         } catch (NumberFormatException e) {
-            Log.e("parseBalance", "Unable to parse: " + balance);
+            Timber.e(e, "Unable to parse balance %s ", balance);
             ret = new BigDecimal(0);
         }
         return ret;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 115f2bb..30c0536 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -36,7 +36,6 @@ import android.content.res.Resources.NotFoundException;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
 import android.text.InputType;
-import android.util.Log;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -47,6 +46,7 @@ import java.util.List;
 import java.util.Map;
 
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
@@ -457,11 +457,11 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             CookieStore cookies = urlopen.getHttpclient().getCookieStore();
             return new SessionPackage(html, cookies);
         } catch (ClientProtocolException e) {
-            Log.e(TAG, e.getMessage());
+            Timber.e(e);
         } catch (IOException e) {
-            Log.e(TAG, e.getMessage());
+            Timber.e(e);
         } catch (BankException e) {
-            Log.e(TAG, e.getMessage());
+            Timber.e(e);
         }
         String html = String.format(preloader,
                 String.format("function go(){window.location=\"%s\" }", this.URL),
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index b8925bd..8fa5713 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -82,7 +82,6 @@ public class AkeliusInvest extends Bank {
 
     public AkeliusInvest(Context context) {
         super(context, R.drawable.logo_akeliusinvest);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index c60189e..5fcdc51 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -83,7 +83,6 @@ public class AkeliusSpar extends Bank {
 
     public AkeliusSpar(Context context) {
         super(context, R.drawable.logo_akeliusspar);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 52f373a..654114f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -58,7 +58,6 @@ public class AppeakPoker extends Bank {
 
     public AppeakPoker(Context context) {
         super(context, R.drawable.logo_appeakpoker);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
index fbd6e59..8bc5e72 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
@@ -41,7 +41,6 @@ public class Audi extends AbsIkanoPartner {
 
     public Audi(Context context) {
         super(context, R.drawable.logo_audi);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 7f2907c..cc859ac 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -26,7 +26,6 @@ public class AvanzaMini extends Avanza {
 
     public AvanzaMini(Context context) {
         super(context, R.drawable.logo_avanzamini);
-        TAG = "AvanzaMini";
         NAME = "Avanza Mini";
         NAME_SHORT = "avanzamini";
         URL = "https://www.avanza.se/mini/hem/";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 7753a93..6438d97 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -72,7 +72,6 @@ public class BetterGlobe extends Bank {
 
     public BetterGlobe(Context context) {
         super(context, R.drawable.logo_betterglobe);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index 5788b0e..aba3b3b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -59,7 +59,6 @@ public class Bioklubben extends Bank {
 
     public Bioklubben(Context context) {
         super(context, R.drawable.logo_bioklubben);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 2e5337c..1c55fc0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -54,7 +54,6 @@ public class BlekingeTrafiken extends Bank {
 
     public BlekingeTrafiken(Context context) {
         super(context, R.drawable.logo_blekingetrafiken);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index a0cf8ba..60145b8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -31,7 +31,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.InputType;
-import android.util.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -41,6 +40,7 @@ import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public class Bredband2VoIP extends Bank {
 
@@ -63,7 +63,6 @@ public class Bredband2VoIP extends Bank {
 
     public Bredband2VoIP(Context context) {
         super(context, R.drawable.logo_bredband2voip);
-        TAG = "Bredband2VoIP";
         NAME = "Bredband2 VoIP";
         NAME_SHORT = "bredband2voip";
         BANKTYPE_ID = IBankTypes.BREDBAND2VOIP;
@@ -148,7 +147,7 @@ public class Bredband2VoIP extends Bank {
                             Helpers.parseBalance(mTransaction.group(5)).negate()));
                 }
             } catch (Exception e) {
-                Log.w(TAG, "Unable to parse: " + mInvoiceUrl.group(1));
+                Timber.w(e, "Unable to parse: %s", mInvoiceUrl.group(1));
             }
         }
         account.setTransactions(transactions);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index b42ec01..7ed675c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -80,7 +80,6 @@ public class BrummerKF extends Bank {
 
     public BrummerKF(Context context) {
         super(context, R.drawable.logo_brummer_kf);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index ff8b541..1ff399c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -84,7 +84,6 @@ public class CSN extends Bank {
 
     public CSN(Context context) {
         super(context, R.drawable.logo_csn);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 922bc9f..b44885f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -49,8 +49,6 @@ public class Chalmrest extends Bank {
 
     public Chalmrest(Context context) {
         super(context, R.drawable.logo_chalmrest);
-
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
index 5f256d0..baaeb4f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -39,7 +39,6 @@ public class Chevrolet extends SEBKortBase {
 
     public Chevrolet(Context context) {
         super(context, "chse", "0086", R.drawable.logo_chevrolet);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index 0b1cb2c..f347ade 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -84,7 +84,6 @@ public class DanskeBank extends Bank {
 
     public DanskeBank(Context context) {
         super(context, R.drawable.logo_danskebank);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 624ac9a..6ee26d1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -78,7 +78,6 @@ public class DinersClub extends Bank {
 
     public DinersClub(Context context) {
         super(context, R.drawable.logo_dinersclub);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
index 26e1a39..3afa8f3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -39,7 +39,6 @@ public class Djurgarden extends SEBKortBase {
 
     public Djurgarden(Context context) {
         super(context, "djse", "0116", R.drawable.logo_djurgarden);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index cf5abb6..ececaa1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -60,8 +60,6 @@ public class EasyCard extends Bank {
 
     public EasyCard(Context context) {
         super(context, R.drawable.logo_easycard);
-
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index db1ebc5..e1c4468 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -50,7 +50,6 @@ public class EspressoHouse extends Bank {
 
     public EspressoHouse(Context context) {
         super(context, R.drawable.logo_espressohouse);
-        TAG = "EspressoHouse";
         NAME = "Espresso House";
         NAME_SHORT = "espressohouse";
         BANKTYPE_ID = IBankTypes.ESPRESSOHOUSE;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 890eb56..85e6441 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -40,7 +40,6 @@ public class EurobonusMastercard extends SEBKortBase {
 
     public EurobonusMastercard(Context context) {
         super(context, "sase", "0102", R.drawable.logo_ebmaster);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index 9678ec3..06b3f51 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -40,7 +40,6 @@ public class EurobonusMastercardDk extends SEBKortBase {
 
     public EurobonusMastercardDk(Context context) {
         super(context, "sadk", "0101", R.drawable.logo_ebmaster_dk);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index 3adfd46..50e1b59 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -40,7 +40,6 @@ public class EurobonusMastercardNo extends SEBKortBase {
 
     public EurobonusMastercardNo(Context context) {
         super(context, "sano", "0117", R.drawable.logo_ebmaster_no);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
index 616f1d7..f8d4d64 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -39,7 +39,6 @@ public class Eurocard extends SEBKortBase {
 
     public Eurocard(Context context) {
         super(context, "ecse", "0005", "secure.eurocard.se", new int[]{R.raw.cert_eurocard}, R.drawable.logo_eurocard);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 8a4e4ed..3836d09 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -69,7 +69,6 @@ public class Everydaycard extends Bank {
 
     public Everydaycard(Context context) {
         super(context, R.drawable.logo_everydaycard);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 1ebd1f1..efbc2d1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -70,7 +70,6 @@ public class FirstCard extends Bank {
 
     public FirstCard(Context context) {
         super(context, R.drawable.logo_firstcard);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index b844ad2..ea2352c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -78,7 +78,6 @@ public class ForexBank extends Bank {
 
     public ForexBank(Context context) {
         super(context, R.drawable.logo_forex);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 1291226..2d897fe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -83,7 +83,6 @@ public class Handelsbanken extends Bank {
 
     public Handelsbanken(Context context) {
         super(context, R.drawable.logo_handelsbanken);
-        super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index cdcd34b..75c6f50 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -66,7 +66,7 @@ public class Hemkop extends Bank {
 
     public Hemkop(Context context) {
         super(context, R.drawable.logo_hemkop);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
index fcbc69d..959214f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
@@ -59,7 +59,7 @@ public class Hors extends Bank {
 
     public Hors(Context context) {
         super(context, R.drawable.logo_hors);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
index 3d974c6..3ae89f2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
@@ -41,7 +41,7 @@ public class IKEA extends AbsIkanoPartner {
 
     public IKEA(Context context) {
         super(context, R.drawable.logo_ikea);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index e76377d..79380f3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -32,7 +32,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -42,6 +41,7 @@ import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public class IkanoBank extends Bank {
 
@@ -82,7 +82,7 @@ public class IkanoBank extends Bank {
 
     public IkanoBank(Context context) {
         super(context, R.drawable.logo_ikanobank);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
@@ -193,13 +193,13 @@ public class IkanoBank extends Bank {
         Matcher matcher;
         matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            Log.e(TAG, "Unable to find ViewState. L156.");
+            Timber.e("Unable to find ViewState. L156.");
             return;
         }
         String strViewState = matcher.group(1);
         matcher = reEventValidation.matcher(response);
         if (!matcher.find()) {
-            Log.e(TAG, "Unable to find EventValidation. L161.");
+            Timber.e("Unable to find EventValidation. L161.");
             return;
         }
         String strEventValidation = matcher.group(1);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 04d01d8..832a23b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -64,7 +64,7 @@ public class Jojo extends Bank {
 
     public Jojo(Context context) {
         super(context, R.drawable.logo_jojo);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index e1a5c34..ba1fab0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -65,7 +65,7 @@ public class Marginalen extends Bank {
 
     public Marginalen(Context context) {
         super(context, R.drawable.logo_marginalen);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index d150b77..b9f2367 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -68,7 +68,7 @@ public class McDonalds extends Bank {
 
     public McDonalds(Context context) {
         super(context, R.drawable.logo_mcdonalds);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index 379029d..f965069 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -54,7 +54,7 @@ public class Meniga extends Bank {
 
     public Meniga(Context context) {
         super(context, R.drawable.logo_meniga);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index 2696a71..3fb9e17 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -81,7 +81,7 @@ public class NordeaDK extends Bank {
     public NordeaDK(Context context) {
         super(context, R.drawable.logo_nordea_dk);
 
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 273a420..8e9b1ed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -67,7 +67,7 @@ public class Nordnet extends Bank {
 
     public Nordnet(Context context) {
         super(context, R.drawable.logo_nordnet);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 48ed6fb..1c40026 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -68,7 +68,7 @@ public class Nordnetdirekt extends Bank {
 
     public Nordnetdirekt(Context context) {
         super(context, R.drawable.logo_nordnetdirekt);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index 25d197b..97822f6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -77,7 +77,7 @@ public class OKQ8 extends Bank {
 
     public OKQ8(Context context) {
         super(context, R.drawable.logo_okq8);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
index 656c8be..424f6dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
@@ -39,7 +39,7 @@ public class Opel extends SEBKortBase {
 
     public Opel(Context context) {
         super(context, "opse", "0107", R.drawable.logo_opel);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 2dcb5f0..9e1502c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -73,7 +73,7 @@ public class Ostgotatrafiken extends Bank {
 
     public Ostgotatrafiken(Context context) {
         super(context, R.drawable.logo_ogt);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 2593ca4..c5e18e9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -64,7 +64,7 @@ public class Osuuspankki extends Bank {
 
     public Osuuspankki(Context context) {
         super(context, R.drawable.logo_osuuspankki);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 76a1c8c..a9203c9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -65,7 +65,7 @@ public class PayPal extends Bank {
 
     public PayPal(Context context) {
         super(context, R.drawable.logo_paypal);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index defe12d..abc9868 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -67,7 +67,7 @@ public class Payson extends Bank {
 
     public Payson(Context context) {
         super(context, R.drawable.logo_payson);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index 6072046..dfed1c4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -65,7 +65,7 @@ public class PlusGirot extends Bank {
 
     public PlusGirot(Context context) {
         super(context, R.drawable.logo_plusgirot);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
index 20c2a38..d076c5e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
@@ -42,7 +42,7 @@ public class Preem extends AbsIkanoPartner {
 
     public Preem(Context context) {
         super(context, R.drawable.logo_preem);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
index 248dfd1..599b7f4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -39,7 +39,7 @@ public class Quintessentially extends SEBKortBase {
 
     public Quintessentially(Context context) {
         super(context, "quse", "0119", R.drawable.logo_quintessentially);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
index 6efece8..0cca688 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -39,7 +39,7 @@ public class SJPrio extends SEBKortBase {
 
     public SJPrio(Context context) {
         super(context, "sjse", "0104", R.drawable.logo_sj_prio);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
index 1583c88..1233458 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
@@ -39,7 +39,7 @@ public class Saab extends SEBKortBase {
 
     public Saab(Context context) {
         super(context, "sbse", "0106", R.drawable.logo_saab);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
index 494512a..873c199 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
@@ -41,7 +41,7 @@ public class Seat extends AbsIkanoPartner {
 
     public Seat(Context context) {
         super(context, R.drawable.logo_seat);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index f69147d..088cd13 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -68,7 +68,7 @@ public class SevenDay extends Bank {
 
     public SevenDay(Context context) {
         super(context, R.drawable.logo_sevenday);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
index 8f96fc8..ce3daac 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
@@ -40,7 +40,7 @@ public class Shell extends AbsIkanoPartner {
 
     public Shell(Context context) {
         super(context, R.drawable.logo_shell);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
index b7107e6..143ae79 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
@@ -41,7 +41,7 @@ public class Skoda extends AbsIkanoPartner {
 
     public Skoda(Context context) {
         super(context, R.drawable.logo_skoda);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index d99b667..f1516db 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -40,7 +40,7 @@ public class SparbankenOresund extends MobilbankenBase {
 
     public SparbankenOresund(Context context) {
         super(context, R.drawable.logo_sparbanken_oresund);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index 57ca163..6d4283a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -40,7 +40,7 @@ public class SparbankenSyd extends MobilbankenBase {
 
     public SparbankenSyd(Context context) {
         super(context, R.drawable.logo_sparbanken_syd);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
index 53e4c7c..ee47e26 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
@@ -39,7 +39,7 @@ public class Statoil extends SEBKortBase {
 
     public Statoil(Context context) {
         super(context, "stse", "0122", R.drawable.logo_statoil);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 90c2fb3..8029962 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -31,7 +31,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.util.Log;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -46,6 +45,7 @@ import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public class Steam extends Bank {
 
@@ -72,7 +72,7 @@ public class Steam extends Bank {
 
     public Steam(Context context) {
         super(context, R.drawable.logo_steam);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
@@ -165,7 +165,7 @@ public class Steam extends Bank {
                             Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(),
                                     "USD")));
                 } catch (ParseException e) {
-                    Log.e(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                    Timber.e(e, "Unable to parse date: %s", matcher.group(1).trim());
                 }
             }
             Collections.sort(transactions, Collections.reverseOrder());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 3ae58a2..fdf1711 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -62,7 +62,7 @@ public class SveaDirekt extends Bank {
 
     public SveaDirekt(Context context) {
         super(context, R.drawable.logo_sveadirekt);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.URL = URL;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index db37df5..89c091b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -63,7 +63,7 @@ public class SvenskaSpel extends Bank {
 
     public SvenskaSpel(Context context) {
         super(context, R.drawable.logo_svenskaspel);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index 566e183..10daa01 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -71,7 +71,7 @@ public class TestBank extends Bank {
 
     public TestBank(Context context) {
         super(context, R.drawable.logo_bankdroid);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 734e1d8..01c1f8e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -72,7 +72,7 @@ public class TicketRikskortet extends Bank {
 
     public TicketRikskortet(Context context) {
         super(context, R.drawable.logo_rikskortet);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index ddb1140..5d1b13e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -70,7 +70,7 @@ public class TrustBuddy extends Bank {
 
     public TrustBuddy(Context context) {
         super(context, R.drawable.logo_trustbuddy);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 34c099c..71d144e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -66,7 +66,7 @@ public class Vasttrafik extends Bank {
 
     public Vasttrafik(Context context) {
         super(context, R.drawable.logo_vasttrafik);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index bdd4b96..5ace839 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -78,13 +78,11 @@ public class Villabanken extends Bank {
     private String accountUrl
             = "https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx";
 
-    ;
-
     private String accountResponse = null;
 
     public Villabanken(Context context) {
         super(context, R.drawable.logo_villabanken);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
index dc5b5e2..36d2e3d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -41,7 +41,7 @@ public class Volkswagen extends AbsIkanoPartner {
 
     public Volkswagen(Context context) {
         super(context, R.drawable.logo_volkswagen);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 8f8e359..97d35f1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -79,7 +79,7 @@ public class Volvofinans extends Bank {
 
     public Volvofinans(Context context) {
         super(context, R.drawable.logo_volvofinans);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
index 8c28a1f..8c959eb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
@@ -39,7 +39,7 @@ public class Wallet extends SEBKortBase {
 
     public Wallet(Context context) {
         super(context, "wase", "0121", R.drawable.logo_wallet);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 1c1c9db..9972d17 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -71,7 +71,7 @@ public class Zidisha extends Bank {
 
     public Zidisha(Context context) {
         super(context, R.drawable.logo_zidisha);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 4d0be3f..f8f9482 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -60,7 +60,7 @@ public class Bitcoin extends Bank {
 
     public Bitcoin(Context context) {
         super(context, R.drawable.logo_bitcoin);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 26acca0..5d64059 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -86,7 +86,7 @@ public class Coop extends Bank {
 
     public Coop(Context context) {
         super(context, R.drawable.logo_coop);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 1703d6f..d1c92a7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -71,7 +71,7 @@ public class ICABanken extends Bank {
 
     public ICABanken(Context context) {
         super(context, R.drawable.logo_icabanken);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index fe3e5dc..552a85d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -82,7 +82,7 @@ public class Lansforsakringar extends Bank {
 
     public Lansforsakringar(Context context) {
         super(context, R.drawable.logo_lansforsakringar);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 3e7912f..15f828d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -211,7 +211,7 @@ public class Nordea extends Bank {
 
     public Nordea(Context context) {
         super(context, R.drawable.logo_nordea);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index a9e0269..0d0eab0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -54,7 +54,7 @@ public class Rikslunchen extends Bank {
 
     public Rikslunchen(Context context) {
         super(context, R.drawable.logo_rikslunchen);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index 4047e5f..21c7737 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -43,7 +43,6 @@ import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
 import android.text.InputType;
-import android.util.Log;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -85,7 +84,7 @@ public class SEB extends Bank {
 
     public SEB(Context context) {
         super(context, R.drawable.logo_seb);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
@@ -217,7 +216,6 @@ public class SEB extends Bank {
 //        }
 //        }
 
-        Log.d("SEB", "Logged in");
 //        Matcher matcher;
 //        try {
 //            response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=digipassAppl1");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index d856ad0..38f511d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -36,7 +36,6 @@ import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.Base64;
-import android.util.Log;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -51,6 +50,7 @@ import java.util.UUID;
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.HttpMethod;
 import eu.nullbyte.android.urllib.Urllib;
+import timber.log.Timber;
 
 public abstract class AbstractSwedbank extends Bank {
 
@@ -213,8 +213,11 @@ public abstract class AbstractSwedbank extends Bank {
             IOException {
         HttpResponse httpResponse = urlopen.openAsHttpResponse(
                 getResourceUri("engagement/cardaccount/" + mIdMap.get(account.getId())), false);
-        if (httpResponse.getStatusLine().getStatusCode() != 200) {
-            Log.i(TAG, "Couldn't find transactions for creditcard");
+        int responseCode = httpResponse.getStatusLine().getStatusCode();
+        if (responseCode != 200) {
+            Timber.i(
+                    "Couldn't find transactions for creditcard. Got response code %d",
+                    responseCode);
             account.setTransactions(Collections.<Transaction>emptyList());
             return;
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
index 8a324fc..a5e6d69 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -24,7 +24,7 @@ public class Sparbankerna extends AbstractSwedbank {
 
     public Sparbankerna(Context context) {
         super(context, R.drawable.logo_sparbankerna);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
index dff1ba8..738913f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
@@ -24,7 +24,7 @@ public class SparbankernaCorporate extends AbstractSwedbank {
 
     public SparbankernaCorporate(Context context) {
         super(context, R.drawable.logo_sparbankerna);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
index 943921a..ce8977b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
@@ -24,7 +24,7 @@ public class SparbankernaYouth extends AbstractSwedbank {
 
     public SparbankernaYouth(Context context) {
         super(context, R.drawable.logo_sparbankerna);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
index ac549ee..eb8d862 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -24,7 +24,7 @@ public class Swedbank extends AbstractSwedbank {
 
     public Swedbank(Context context) {
         super(context, R.drawable.logo_swedbank);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
index 99d8ccb..20c42b0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
@@ -24,7 +24,7 @@ public class SwedbankCorporate extends AbstractSwedbank {
 
     public SwedbankCorporate(Context context) {
         super(context, R.drawable.logo_swedbank);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
index 07b0172..f253d64 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
@@ -24,7 +24,7 @@ public class SwedbankYouth extends AbstractSwedbank {
 
     public SwedbankYouth(Context context) {
         super(context, R.drawable.logo_swedbank);
-        super.TAG = TAG;
+
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;

commit b00624ab54dcf81830b2b17fdbfcaa8f48349f73
Merge: cb74c66 3775b52
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Oct 11 21:25:01 2016 +0200

    Merge pull request #635 from walles/walles/re-enable-lintchecks
    
    Re-enable lots of lint checks

commit 3775b52df82814861750c84cfd8b699889ff931c (walles/walles/re-enable-lintchecks, walles/re-enable-lintchecks)
Author: Johan Walles <johan.walles@gmail.com>
Date:   Tue Oct 11 21:02:24 2016 +0200

    Re-enable lots of lint checks
    
    And provide a script to find out what could actually be enable.

diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 1cd8fbe..2348b8f 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -2,161 +2,56 @@
 <lint>
     <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
 
-    <issue id="AdapterViewChildren" severity="ignore" />
     <issue id="AllowBackup" severity="ignore" />
     <issue id="AlwaysShowAction" severity="ignore" />
     <issue id="AppCompatResource" severity="ignore" />
     <issue id="BatteryLife" severity="ignore" />
     <issue id="ButtonCase" severity="ignore" />
-    <issue id="ButtonOrder" severity="ignore" />
-    <issue id="ButtonStyle" severity="ignore" />
     <issue id="ClickableViewAccessibility" severity="ignore" />
     <issue id="CommitPrefEdits" severity="ignore" />
-    <issue id="CommitTransaction" severity="ignore" />
     <issue id="ContentDescription" severity="ignore" />
-    <issue id="CutPasteId" severity="ignore" />
-    <issue id="DalvikOverride" severity="ignore" />
     <issue id="DefaultLocale" severity="ignore" />
     <issue id="Deprecated" severity="ignore" />
-    <issue id="DeviceAdmin" severity="ignore" />
-    <issue id="DisableBaselineAlignment" severity="ignore" />
-    <issue id="DrawAllocation" severity="ignore" />
-    <issue id="DuplicateActivity" severity="ignore" />
-    <issue id="DuplicateDefinition" severity="ignore" />
-    <issue id="DuplicateIds" severity="ignore" />
-    <issue id="DuplicateIncludedIds" severity="ignore" />
-    <issue id="DuplicateUsesFeature" severity="ignore" />
-    <issue id="EnforceUTF8" severity="ignore" />
-    <issue id="ExportedContentProvider" severity="ignore" />
     <issue id="ExportedReceiver" severity="ignore" />
-    <issue id="ExportedService" severity="ignore" />
-    <issue id="ExtraText" severity="ignore" />
-    <issue id="ExtraTranslation" severity="ignore" />
-    <issue id="FloatMath" severity="ignore" />
     <issue id="GetInstance" severity="ignore" />
-    <issue id="GifUsage" severity="ignore" />
     <issue id="GoogleAppIndexingWarning" severity="ignore" />
     <issue id="GradleDependency" severity="ignore" />
     <issue id="GradleDynamicVersion" severity="ignore" />
-    <issue id="GradleOverrides" severity="ignore" />
-    <issue id="GrantAllUris" severity="ignore" />
-    <issue id="GridLayout" severity="ignore" />
-    <issue id="HandlerLeak" severity="ignore" />
-    <issue id="HardcodedDebugMode" severity="ignore" />
     <issue id="HardcodedText" severity="ignore" />
     <issue id="HardwareIds" severity="ignore" />
-    <issue id="IconColors" severity="ignore" />
     <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
-    <issue id="IconDuplicatesConfig" severity="ignore" />
-    <issue id="IconExtension" severity="ignore" />
-    <issue id="IconLauncherShape" severity="ignore" />
     <issue id="IconLocation" severity="ignore" />
     <issue id="IconMissingDensityFolder" severity="ignore" />
-    <issue id="IconMixedNinePatch" severity="ignore" />
-    <issue id="IconNoDpi" severity="ignore" />
-    <issue id="IconXmlAndPng" severity="ignore" />
-    <issue id="InOrMmUsage" severity="ignore" />
-    <issue id="InflateParams" severity="ignore" />
-    <issue id="InconsistentArrays" severity="ignore" />
-    <issue id="InconsistentLayout" severity="ignore" />
     <issue id="InefficientWeight" severity="ignore" />
+    <issue id="InflateParams" severity="ignore" />
     <issue id="InlinedApi" severity="ignore" />
-    <issue id="InnerclassSeparator" severity="ignore" />
-    <issue id="Instantiatable" severity="ignore" />
-    <issue id="InvalidId" severity="ignore" />
     <issue id="InvalidPackage" severity="ignore" />
-    <issue id="JavascriptInterface" severity="ignore" />
-    <issue id="LabelFor" severity="ignore" />
-    <issue id="LibraryCustomView" severity="ignore" />
-    <issue id="MangledCRLF" severity="ignore" />
     <issue id="ManifestOrder" severity="ignore" />
-    <issue id="ManifestTypo" severity="ignore" />
-    <issue id="MenuTitle" severity="ignore" />
     <issue id="MergeRootFrame" severity="ignore" />
-    <issue id="MissingApplicationIcon" severity="ignore" />
-    <issue id="MissingId" severity="ignore" />
-    <issue id="MissingPrefix" severity="ignore" />
-    <issue id="MissingQuantity" severity="ignore" />
-    <issue id="MissingRegistered" severity="ignore" />
-    <issue id="MissingSuperCall" severity="ignore" />
     <issue id="MissingTranslation" severity="ignore" />
-    <issue id="MissingVersion" severity="ignore" />
-    <issue id="MockLocation" severity="ignore" />
-    <issue id="MultipleUsesSdk" severity="ignore" />
-    <issue id="NamespaceTypo" severity="ignore" />
-    <issue id="NestedScrolling" severity="ignore" />
-    <issue id="NestedWeights" severity="ignore" />
     <issue id="NewApi" severity="ignore" />
     <issue id="NotSibling" severity="ignore" />
     <issue id="ObsoleteLayoutParam" severity="ignore" />
-    <issue id="OldTargetApi" severity="ignore" />
-    <issue id="OnClick" severity="ignore" />
     <issue id="Orientation" severity="ignore" />
     <issue id="Overdraw" severity="ignore" />
-    <issue id="Override" severity="ignore" />
-    <issue id="PackagedPrivateKey" severity="ignore" />
     <issue id="ParcelClassLoader" severity="ignore" />
-    <issue id="ParcelCreator" severity="ignore" />
     <issue id="PluralsCandidate" severity="ignore" />
-    <issue id="Proguard" severity="ignore" />
-    <issue id="ProguardSplit" severity="ignore" />
-    <issue id="ProtectedPermissions" severity="ignore" />
-    <issue id="PxUsage" severity="ignore" />
-    <issue id="Recycle" severity="ignore" />
     <issue id="Registered" severity="ignore" />
-    <issue id="RequiredSize" severity="ignore" />
     <issue id="RtlHardcoded" severity="ignore" />
     <issue id="RtlSymmetry" severity="ignore" />
-    <issue id="ScrollViewCount" severity="ignore" />
     <issue id="ScrollViewSize" severity="ignore" />
-    <issue id="SdCardPath" severity="ignore" />
-    <issue id="SecureRandom" severity="ignore" />
-    <issue id="ServiceCast" severity="ignore" />
     <issue id="SetJavaScriptEnabled" severity="ignore" />
-    <issue id="ShowToast" severity="ignore" />
     <issue id="SimpleDateFormat" severity="ignore" />
-    <issue id="SmallSp" severity="ignore" />
     <issue id="SpUsage" severity="ignore" />
     <issue id="StaticFieldLeak" severity="ignore" />
-    <issue id="StateListReachable" severity="ignore" />
-    <issue id="StringFormatCount" severity="ignore" />
-    <issue id="StringFormatInvalid" severity="ignore" />
-    <issue id="StringFormatMatches" severity="ignore" />
-    <issue id="StyleCycle" severity="ignore" />
-    <issue id="Suspicious0dp" severity="ignore" />
-    <issue id="SuspiciousImport" severity="ignore" />
-    <issue id="TextFields" severity="ignore" />
-    <issue id="TextViewEdits" severity="ignore" />
-    <issue id="TooDeepLayout" severity="ignore" />
-    <issue id="TooManyViews" severity="ignore" />
     <issue id="TrulyRandom" severity="ignore" />
-    <issue id="TypographyDashes" severity="ignore" />
     <issue id="TypographyEllipsis" severity="ignore" />
-    <issue id="TypographyFractions" severity="ignore" />
-    <issue id="TypographyOther" severity="ignore" />
     <issue id="Typos" severity="ignore" />
-    <issue id="UniquePermission" severity="ignore" />
-    <issue id="UnknownId" severity="ignore" />
     <issue id="UnknownIdInLayout" severity="ignore" />
-    <issue id="UnlocalizedSms" severity="ignore" />
     <issue id="UnusedAttribute" severity="ignore" />
-    <issue id="UseCheckPermission" severity="ignore" />
     <issue id="UseCompoundDrawables" severity="ignore" />
-    <issue id="UseSparseArrays" severity="ignore" />
     <issue id="UseValueOf" severity="ignore" />
-    <issue id="UselessLeaf" severity="ignore" />
     <issue id="UselessParent" severity="ignore" />
-    <issue id="UsesMinSdkAttributes" severity="ignore" />
-    <issue id="ValidFragment" severity="ignore" />
-    <issue id="ViewConstructor" severity="ignore" />
-    <issue id="ViewTag" severity="ignore" />
-    <issue id="Wakelock" severity="ignore" />
     <issue id="WorldReadableFiles" severity="ignore" />
-    <issue id="WorldWriteableFiles" severity="ignore" />
-    <issue id="WrongCall" severity="ignore" />
-    <issue id="WrongCase" severity="ignore" />
-    <issue id="WrongFolder" severity="ignore" />
-    <issue id="WrongManifestParent" severity="ignore" />
-    <issue id="WrongViewCast" severity="ignore" />
 </lint>
diff --git create-lint-suppressions.sh create-lint-suppressions.sh
new file mode 100755
index 0000000..65d3802
--- /dev/null
+++ create-lint-suppressions.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Create an Android Lint suppressions file with a list of all
+# failing Lint checks. Store in config/quality/lint/lint.xml.
+
+LINT_XML='config/quality/lint/lint.xml'
+
+# From: https://sipb.mit.edu/doc/safe-shell/
+set -euf -o pipefail
+
+# List failing lint checks (with no suppressions)
+echo '<lint></lint>' > ${LINT_XML}
+./gradlew clean check --continue || true
+RESULTSFILES=$(find . -name 'lint-results*.xml')
+
+cat << EOF
+
+Here's an Android Lint config file with suppressions for
+everything we're violating.
+
+For great success, store in ${LINT_XML}.
+
+Or just fix all issues and skip the suppressions file entirely.
+
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
+
+EOF
+
+for RULE in $(egrep -h ' *id=".*"$' ${RESULTSFILES} | cut '-d"' -f2 | sort | uniq) ; do
+    echo "    <issue id=\"${RULE}\" severity=\"ignore\" />"
+done
+
+cat << EOF
+</lint>
+EOF

commit cb74c6632555c9295575522879884b82aa029f34
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Oct 10 21:46:56 2016 +0200

    Android Lint: Enforce no unused resources

diff --git app/src/main/res/drawable-hdpi-v4/background.png app/src/main/res/drawable-hdpi-v4/background.png
deleted file mode 100644
index 30d4a2d..0000000
Binary files app/src/main/res/drawable-hdpi-v4/background.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/date_background.png app/src/main/res/drawable-hdpi-v4/date_background.png
deleted file mode 100644
index a1d9225..0000000
Binary files app/src/main/res/drawable-hdpi-v4/date_background.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/date_bg_2.9.png app/src/main/res/drawable-hdpi-v4/date_bg_2.9.png
deleted file mode 100644
index 1cb8b57..0000000
Binary files app/src/main/res/drawable-hdpi-v4/date_bg_2.9.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/ic_menu_donate.png app/src/main/res/drawable-hdpi-v4/ic_menu_donate.png
deleted file mode 100644
index 248589f..0000000
Binary files app/src/main/res/drawable-hdpi-v4/ic_menu_donate.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/ic_menu_info_details.png app/src/main/res/drawable-hdpi-v4/ic_menu_info_details.png
deleted file mode 100644
index 7696ceb..0000000
Binary files app/src/main/res/drawable-hdpi-v4/ic_menu_info_details.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/ic_menu_view.png app/src/main/res/drawable-hdpi-v4/ic_menu_view.png
deleted file mode 100644
index 75155d4..0000000
Binary files app/src/main/res/drawable-hdpi-v4/ic_menu_view.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png
deleted file mode 100644
index a844745..0000000
Binary files app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/popup_bg_down_o.png app/src/main/res/drawable-hdpi-v4/popup_bg_down_o.png
deleted file mode 100644
index 99efa53..0000000
Binary files app/src/main/res/drawable-hdpi-v4/popup_bg_down_o.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/popup_bg_up_o.png app/src/main/res/drawable-hdpi-v4/popup_bg_up_o.png
deleted file mode 100644
index 414cc6f..0000000
Binary files app/src/main/res/drawable-hdpi-v4/popup_bg_up_o.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_icon_add.png app/src/main/res/drawable-hdpi-v4/title_icon_add.png
deleted file mode 100644
index 415ee04..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_icon_add.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_icon_back.png app/src/main/res/drawable-hdpi-v4/title_icon_back.png
deleted file mode 100644
index 2e45562..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_icon_back.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_icon_donate.png app/src/main/res/drawable-hdpi-v4/title_icon_donate.png
deleted file mode 100644
index 0aea001..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_icon_donate.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_icon_forward.png app/src/main/res/drawable-hdpi-v4/title_icon_forward.png
deleted file mode 100644
index f6fa1d8..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_icon_forward.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_icon_refresh.png app/src/main/res/drawable-hdpi-v4/title_icon_refresh.png
deleted file mode 100644
index 27df0b0..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_icon_refresh.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_icon_web.png app/src/main/res/drawable-hdpi-v4/title_icon_web.png
deleted file mode 100644
index 8247847..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_icon_web.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_logo_focused.png app/src/main/res/drawable-hdpi-v4/title_logo_focused.png
deleted file mode 100644
index 4c7e999..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_logo_focused.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi-v4/title_logo_normal.png app/src/main/res/drawable-hdpi-v4/title_logo_normal.png
deleted file mode 100644
index 9248894..0000000
Binary files app/src/main/res/drawable-hdpi-v4/title_logo_normal.png and /dev/null differ
diff --git app/src/main/res/drawable/background_repeats.xml app/src/main/res/drawable/background_repeats.xml
deleted file mode 100644
index 5beea90..0000000
--- app/src/main/res/drawable/background_repeats.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/background" 
-    android:tileMode="repeat" />
\ No newline at end of file
diff --git app/src/main/res/drawable/ic_bullet_key_permission.png app/src/main/res/drawable/ic_bullet_key_permission.png
deleted file mode 100644
index c8a4939..0000000
Binary files app/src/main/res/drawable/ic_bullet_key_permission.png and /dev/null differ
diff --git app/src/main/res/drawable/ic_menu_forward.png app/src/main/res/drawable/ic_menu_forward.png
deleted file mode 100644
index 0936fac..0000000
Binary files app/src/main/res/drawable/ic_menu_forward.png and /dev/null differ
diff --git app/src/main/res/drawable/ic_menu_info_details.png app/src/main/res/drawable/ic_menu_info_details.png
deleted file mode 100644
index 1786d1e..0000000
Binary files app/src/main/res/drawable/ic_menu_info_details.png and /dev/null differ
diff --git app/src/main/res/drawable/ic_menu_view.png app/src/main/res/drawable/ic_menu_view.png
deleted file mode 100644
index 69828a9..0000000
Binary files app/src/main/res/drawable/ic_menu_view.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_unknown_app.png app/src/main/res/drawable/logo_unknown_app.png
similarity index 100%
rename from bankdroid-legacy/src/main/res/drawable/logo_unknown_app.png
rename to app/src/main/res/drawable/logo_unknown_app.png
diff --git app/src/main/res/drawable/progress_horizontal.xml app/src/main/res/drawable/progress_horizontal.xml
deleted file mode 100644
index 99250a8..0000000
--- app/src/main/res/drawable/progress_horizontal.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<layer-list
-	xmlns:android="http://schemas.android.com/apk/res/android">
-
-	<item
-		android:id="@android:id/background"
-		android:drawable="@android:color/transparent" />
-
-	<item
-		android:id="@android:id/secondaryProgress">
-		<clip>
-			<shape>
-				<gradient
-					android:startColor="#589bd4"
-					android:endColor="#2b5b83"
-					android:angle="-90" />
-			</shape>
-		</clip>
-	</item>
-
-	<item
-		android:id="@android:id/progress">
-		<clip>
-			<shape>
-				<gradient
-					android:startColor="#589bd4"
-					android:endColor="#2b5b83"
-					android:angle="-90" />
-			</shape>
-		</clip>
-	</item>
-
-</layer-list>
-
diff --git app/src/main/res/drawable/title_background.xml app/src/main/res/drawable/title_background.xml
deleted file mode 100644
index 0e30069..0000000
--- app/src/main/res/drawable/title_background.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <gradient
-        android:startColor="#3a3838"
-        android:endColor="#020202"
-        android:angle="-90" />
-</shape>
\ No newline at end of file
diff --git app/src/main/res/drawable/title_bar_medium.9.png app/src/main/res/drawable/title_bar_medium.9.png
deleted file mode 100644
index 311a54a..0000000
Binary files app/src/main/res/drawable/title_bar_medium.9.png and /dev/null differ
diff --git app/src/main/res/drawable/title_item_background.xml app/src/main/res/drawable/title_item_background.xml
deleted file mode 100644
index 37e7fbe..0000000
--- app/src/main/res/drawable/title_item_background.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<item
-		android:state_pressed="true"
-		android:drawable="@drawable/title_item_background_focused">
-	</item>
-
-	<item
-		android:state_focused="true"
-		android:drawable="@drawable/title_item_background_focused">
-	</item>
-
-	<item
-		android:drawable="@android:color/transparent"
-		android:state_focused="false"
-		android:state_pressed="false">
-	</item>
-</selector>
diff --git app/src/main/res/drawable/title_item_background_focused.xml app/src/main/res/drawable/title_item_background_focused.xml
deleted file mode 100644
index 213d1a7..0000000
--- app/src/main/res/drawable/title_item_background_focused.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <gradient
-        android:startColor="#589bd4"
-        android:endColor="#2b5b83"
-        android:angle="-90" />
-</shape>
\ No newline at end of file
diff --git app/src/main/res/drawable/title_logo.xml app/src/main/res/drawable/title_logo.xml
deleted file mode 100644
index 442b4ad..0000000
--- app/src/main/res/drawable/title_logo.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<item
-		android:state_pressed="true"
-		android:drawable="@drawable/title_logo_focused">
-	</item>
-
-	<item
-		android:state_focused="true"
-		android:drawable="@drawable/title_logo_focused">
-	</item>
-
-	<item
-		android:drawable="@drawable/title_logo_normal">
-	</item>
-</selector>
\ No newline at end of file
diff --git app/src/main/res/drawable/title_separator.xml app/src/main/res/drawable/title_separator.xml
deleted file mode 100644
index 26450b1..0000000
--- app/src/main/res/drawable/title_separator.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <gradient
-        android:startColor="#4d4c4c"
-        android:endColor="#4d4c4c"
-        android:angle="-90" />
-</shape>
\ No newline at end of file
diff --git app/src/main/res/layout/about.xml app/src/main/res/layout/about.xml
index 6cd3b73..82dda73 100644
--- app/src/main/res/layout/about.xml
+++ app/src/main/res/layout/about.xml
@@ -12,8 +12,7 @@
 		android:layout_height="fill_parent"
 		android:layout_weight="1">
 		<LinearLayout
-			android:id="@+id/LinearLayout03"
-			android:orientation="vertical"
+				android:orientation="vertical"
 			android:layout_height="fill_parent"
 			android:paddingLeft="20dp"
 			android:paddingRight="20dp" android:layout_width="fill_parent">
@@ -30,15 +29,13 @@
 			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtVersion" android:text="@string/version" android:textSize="15dp" android:layout_below="@+id/imgTextLogo" android:gravity="right" android:textColor="#78ffffff" android:layout_toLeftOf="@+id/imgNullbyteLogo" android:layout_marginRight="4dp"></TextView>
 </RelativeLayout>
 			<TextView
-				android:id="@+id/TextView04"
-				android:layout_height="wrap_content"
+					android:layout_height="wrap_content"
 				android:text="@string/thanks_to"
 				android:textStyle="bold"
 				android:layout_marginTop="10dp"
 				android:layout_width="fill_parent" android:textSize="20dp"></TextView>
 			<TextView
-				android:id="@+id/TextView03"
-				android:layout_height="wrap_content"
+					android:layout_height="wrap_content"
 				android:text="@string/thanks"
 				android:layout_width="fill_parent"
 				android:paddingLeft="10dp"
diff --git app/src/main/res/layout/bank.xml app/src/main/res/layout/bank.xml
index 1a30276..d5186bc 100644
--- app/src/main/res/layout/bank.xml
+++ app/src/main/res/layout/bank.xml
@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/RelativeLayout01"
-    android:layout_width="fill_parent"
+                android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:background="@drawable/background_repeat">
 
@@ -66,8 +65,7 @@
         android:stretchColumns="0,2">
 
         <TableRow
-            android:id="@+id/TableRow01"
-            android:layout_width="fill_parent"
+                android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical|center_horizontal"
             android:gravity="center_vertical|center_horizontal">
diff --git app/src/main/res/layout/listitem_banks.xml app/src/main/res/layout/listitem_banks.xml
deleted file mode 100644
index 0034a9e..0000000
--- app/src/main/res/layout/listitem_banks.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="?android:attr/listPreferredItemHeight"
-	android:paddingBottom="5dp"
-	android:paddingTop="5dp">
-
-	<ImageView
-		android:id="@+id/imgListitemBanks"
-
-		android:layout_width="wrap_content"
-		android:layout_height="fill_parent"
-
-		android:layout_alignParentTop="true"
-		android:layout_alignParentBottom="true"
-		android:layout_marginRight="2dp"
-
-		android:src="@drawable/ic_launcher"
-		android:maxHeight="32dp"
-		android:maxWidth="32dp" />
-
-	<TextView
-		android:id="@+id/txtListitemBankname"
-
-		android:layout_width="fill_parent"
-		android:layout_height="26dip"
-
-		android:layout_toRightOf="@id/imgListitemBanks"
-		android:layout_alignParentBottom="true"
-		android:layout_alignParentRight="true"
-
-		android:singleLine="true"
-		android:ellipsize="marquee"
-		android:gravity="center_vertical"
-		android:text="Banknamn" />
-
-	<TextView
-		android:layout_height="wrap_content"
-
-		android:layout_toRightOf="@id/imgListitemBanks"
-		android:layout_alignParentTop="true"
-		android:layout_above="@id/txtListitemBankname"
-		android:layout_alignWithParentIfMissing="true"
-
-		android:gravity="center_vertical"
-		android:id="@+id/txtListitemAccountname"
-		android:textSize="23sp"
-		android:text="Personnummer"
-		android:layout_width="wrap_content"
-		android:layout_alignParentRight="false" />
-	<ImageView
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:background="@drawable/indicator_input_error"
-		android:layout_alignParentRight="true"
-		android:layout_marginRight="15dp"
-		android:layout_marginTop="6dp"
-		android:visibility="invisible"
-		android:id="@+id/imgWarning"></ImageView>
-
-
-</RelativeLayout>
\ No newline at end of file
diff --git app/src/main/res/layout/main.xml app/src/main/res/layout/main.xml
index baad1e1..8c059d1 100644
--- app/src/main/res/layout/main.xml
+++ app/src/main/res/layout/main.xml
@@ -49,15 +49,13 @@
             android:visibility="gone">
 
             <TableRow
-                android:id="@+id/TableRow01"
-                android:layout_width="fill_parent"
+                    android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_vertical|center_horizontal"
                 android:gravity="center_vertical|center_horizontal">
 
                 <Button
-                    android:id="@+id/btnAddBank"
-                    style="@style/Menu_Button"
+                        style="@style/Menu_Button"
                     android:drawableLeft="@drawable/button_add"
                     android:text="@string/add_new_account"></Button>
 
@@ -72,11 +70,10 @@
                     android:src="@drawable/menu_separator"></ImageView>
 
                 <Button
-                    android:id="@+id/btnAccountsRefresh"
-                    style="@style/Menu_Button"
+                        style="@style/Menu_Button"
                     android:drawableLeft="@drawable/button_refresh"
                     android:text="@string/refresh_balance"></Button>
             </TableRow>
         </TableLayout>
     </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git app/src/main/res/layout/main_htc.xml app/src/main/res/layout/main_htc.xml
deleted file mode 100644
index 80d877e..0000000
--- app/src/main/res/layout/main_htc.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_width="wrap_content"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat">
-	<CheckBox
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:id="@+id/chkTransperantBackground"
-		android:visibility="gone"
-		android:layout_margin="10dp"
-		android:text="@string/transparent_background" />
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:id="@+id/txtAccountsDesc"
-		android:visibility="visible"
-		android:layout_margin="10dp"
-		android:text="@string/main_instructions" />
-	<com.htc.widget.HtcListView
-		android:layout_width="fill_parent"
-		android:id="@+id/lstAccountsList"
-		android:layout_height="wrap_content"
-		android:cacheColorHint="#00000000"
-		android:layout_above="@+id/layMainMenu"
-		android:layout_below="@+id/chkTransperantBackground"
-		android:layout_alignWithParentIfMissing="true"
-		android:dividerHeight="0dp" />
-	<TableLayout
-		android:stretchColumns="0,2"
-		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content"
-		android:id="@+id/layMainMenu">
-		<TableRow
-			android:id="@+id/TableRow01"
-			android:layout_height="wrap_content"
-			android:gravity="center_vertical|center_horizontal"
-			android:layout_gravity="center_vertical|center_horizontal"
-			android:layout_width="fill_parent">
-			<Button
-				android:text="@string/add_new_account"
-				android:drawableLeft="@drawable/button_add"
-				android:id="@+id/btnAddBank"
-				style="@style/Menu_Button" />
-			<ImageView
-				android:layout_height="wrap_content"
-				android:focusable="false"
-				android:src="@drawable/menu_separator"
-				android:adjustViewBounds="true"
-				android:scaleType="fitXY"
-				android:minWidth="3dp"
-				android:maxWidth="3dp"
-				android:layout_width="wrap_content" />
-			<Button
-				android:id="@+id/btnAccountsRefresh"
-				android:drawableLeft="@drawable/button_refresh"
-				android:text="@string/refresh_balance"
-				style="@style/Menu_Button" />
-		</TableRow>
-	</TableLayout>
-</RelativeLayout>
diff --git app/src/main/res/layout/pair_applications_layout.xml app/src/main/res/layout/pair_applications_layout.xml
index 739e02c..a571a4c 100644
--- app/src/main/res/layout/pair_applications_layout.xml
+++ app/src/main/res/layout/pair_applications_layout.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
 	android:layout_width="wrap_content"
 	android:layout_height="fill_parent"
 	android:background="@drawable/background_repeat">
@@ -19,12 +18,12 @@
 				android:typeface="sans"
 				android:textSize="16sp"
 				android:text="@string/pair_message" />
-				
-		<ImageView 
-			android:layout_width="wrap_content" 
-			android:src="@drawable/logo_unknown_app" 
-			android:layout_height="wrap_content" 
-			android:id="@+id/imageView1" 
+
+		<ImageView
+			android:layout_width="wrap_content"
+			android:src="@drawable/logo_unknown_app"
+			android:layout_height="wrap_content"
+			android:id="@+id/imageView1"
 			android:layout_gravity="center_horizontal"
 			android:paddingTop="40dp"
 			/>
@@ -49,8 +48,7 @@
 		android:layout_below="@+id/LinearLayout01"
 		android:gravity="bottom">
 		<TableRow
-			android:id="@+id/TableRow01"
-			android:layout_height="wrap_content"
+				android:layout_height="wrap_content"
 			android:gravity="center_vertical|center_horizontal"
 			android:layout_gravity="center_vertical|center_horizontal"
 			android:layout_width="fill_parent">
@@ -75,6 +73,6 @@
 				android:drawableLeft="@drawable/button_accept"
 				android:text="@string/approve"
 				style="@style/Menu_Button"></Button>
-		</TableRow>		
+		</TableRow>
 	</TableLayout>
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git app/src/main/res/layout/status_bar_latest_event_content.xml app/src/main/res/layout/status_bar_latest_event_content.xml
deleted file mode 100644
index 96d0b0d..0000000
--- app/src/main/res/layout/status_bar_latest_event_content.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent"
-	android:orientation="vertical"
-	android:paddingTop="7dp"
-	android:paddingLeft="5dp"
-	android:background="#ffffffff">
-
-	<LinearLayout
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:orientation="horizontal"
-		android:paddingTop="3dp">
-		<!--com.android.server.status.AnimatedImageView android:id="@+id/icon" -->
-		<ImageView
-			android:id="@+id/icon"
-			android:layout_width="25dp"
-			android:layout_height="25dp"
-			android:src="@drawable/ic_launcher" android:scaleType="fitXY"/>
-		<TextView
-			android:id="@+id/title"
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-			android:singleLine="true"
-			android:ellipsize="marquee"
-			android:fadingEdge="horizontal"
-			android:paddingLeft="4dp"
-			android:textSize="16sp"
-			android:textStyle="bold"
-			android:textColor="#ff000000"
-			android:text="Familjekonto" />
-	</LinearLayout>
-	<LinearLayout
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:orientation="horizontal">
-		<TextView
-			android:id="@+id/text"
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_weight="1"
-			android:singleLine="true"
-			android:ellipsize="marquee"
-			android:fadingEdge="horizontal"
-			android:paddingLeft="4dp"
-			android:textColor="#ff6b6b6b" android:text="Personkonto: -143,50 SEK (8 351,00 SEK)"/>
-		<TextView
-			android:id="@+id/time"
-			android:layout_marginLeft="4dp"
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:singleLine="true"
-			android:paddingRight="5dp"
-			android:text="1:37 PM"
-			android:textColor="#ff6b6b6b" />
-	</LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git app/src/main/res/layout/title.xml app/src/main/res/layout/title.xml
deleted file mode 100644
index 1c9944f..0000000
--- app/src/main/res/layout/title.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent"
-	android:background="@drawable/title_background"
-	android:id="@+id/layTitle">
-	<ProgressBar
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:id="@+id/progressBar"
-		android:focusable="false"
-		android:indeterminateOnly="false"
-		android:progressDrawable="@drawable/progress_horizontal" android:minHeight="7dp"
-	android:progress="0" android:visibility="gone"></ProgressBar>
-	<LinearLayout
-		android:layout_width="wrap_content"
-		android:id="@+id/layLogoContainer"
-		android:layout_height="fill_parent"
-		android:layout_toLeftOf="@+id/layTitleButtons"
-		android:layout_alignParentLeft="true"
-		android:clickable="true"
-		android:focusable="true">
-		<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:src="@drawable/ic_launcher"
-			android:scaleType="fitXY"
-			android:adjustViewBounds="true"
-			android:id="@+id/imgLogoIcon"
-			android:layout_gravity="center_vertical"
-			android:paddingLeft="2dp"
-			android:maxHeight="20dp"
-			android:visibility="gone"></ImageView>
-		<ImageView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:src="@drawable/title_logo"
-			android:scaleType="fitXY"
-			android:adjustViewBounds="true"
-			android:id="@+id/imgTitle"
-			android:layout_gravity="center_vertical"
-			android:maxHeight="17dp"
-			android:paddingLeft="6dp"
-			android:duplicateParentState="true"></ImageView>
-	</LinearLayout>
-	<LinearLayout
-		android:layout_width="wrap_content"
-		android:id="@+id/layTitleButtons"
-		android:layout_height="fill_parent"
-		android:layout_alignParentRight="true"></LinearLayout>
-</RelativeLayout>
\ No newline at end of file
diff --git app/src/main/res/layout/title_item.xml app/src/main/res/layout/title_item.xml
deleted file mode 100644
index 6596cc9..0000000
--- app/src/main/res/layout/title_item.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="wrap_content"
-	android:id="@+id/layTitleItem"
-	android:layout_height="fill_parent"
-	android:layout_gravity="right">
-	<ImageView
-		android:layout_width="wrap_content"
-		android:background="@drawable/title_separator"
-		android:layout_height="fill_parent"
-		android:maxWidth="1dp"
-		android:minWidth="1dp"></ImageView>
-	<ImageButton
-		android:layout_width="wrap_content"
-		android:adjustViewBounds="true"
-		android:id="@+id/imgItemIcon"
-		android:paddingLeft="5dp"
-		android:src="@drawable/title_icon_add"
-		android:paddingRight="5dp"
-		android:layout_height="fill_parent"
-		android:layout_gravity="center_vertical|center"
-		android:background="@drawable/title_item_background"
-		android:paddingBottom="0dp"></ImageButton>
-
-</LinearLayout>
\ No newline at end of file
diff --git app/src/main/res/layout/transactions.xml app/src/main/res/layout/transactions.xml
index 306ac68..15d0e4b 100644
--- app/src/main/res/layout/transactions.xml
+++ app/src/main/res/layout/transactions.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/RelativeLayout01"
-    android:layout_width="wrap_content"
+                android:layout_width="wrap_content"
     android:layout_height="fill_parent"
     android:background="@drawable/background_repeat">
 
diff --git app/src/main/res/layout/widget.xml app/src/main/res/layout/widget.xml
index afa34e3..9216f02 100644
--- app/src/main/res/layout/widget.xml
+++ app/src/main/res/layout/widget.xml
@@ -81,8 +81,7 @@
 			android:text="Loading..." />
 	</LinearLayout>
 	<LinearLayout
-		android:id="@+id/layWidgetRow03"
-		android:layout_below="@+id/layWidgetRow02"
+			android:layout_below="@+id/layWidgetRow02"
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
 		android:gravity="bottom"
@@ -101,7 +100,6 @@
 				android:indeterminate="true"
 				android:layout_height="wrap_content"
 				style="@style/Widget_Progress"
-				android:id="@+id/prgProgress"
 				android:maxHeight="2dp"
 				android:minHeight="2dp"
 				android:minWidth="17dp"
@@ -124,4 +122,4 @@
 				android:layout_width="wrap_content"></ImageView>
 		</FrameLayout>
 	</LinearLayout>
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git app/src/main/res/layout/widget_large.xml app/src/main/res/layout/widget_large.xml
index 2fa6ca4..ff2a059 100644
--- app/src/main/res/layout/widget_large.xml
+++ app/src/main/res/layout/widget_large.xml
@@ -26,8 +26,7 @@
 			android:layout_width="52dp"
 			android:src="@drawable/icon_large"></ImageView>
 		<RelativeLayout
-			android:id="@+id/RelativeLayout01"
-			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+				android:layout_above="@+id/txtListitemAccountsItemAccountname"
 			android:layout_toRightOf="@+id/imgWidgetIcon"
 			android:layout_height="wrap_content"
 			android:layout_width="fill_parent">
@@ -81,12 +80,11 @@
 				android:gravity="right"
 				android:layout_alignTop="@+id/txtWidgetAccountbalance"
 				android:paddingTop="37dp"></TextView>
-		
+
 </RelativeLayout>
 	</RelativeLayout>
 	<RelativeLayout
-		android:id="@+id/RelativeLayout03"
-		android:layout_width="wrap_content"
+			android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		android:layout_alignParentRight="true"
 		android:paddingTop="15dp"
@@ -129,7 +127,6 @@
 				android:indeterminate="true"
 				android:layout_height="wrap_content"
 				style="@style/Widget_Progress"
-				android:id="@+id/prgProgress"
 				android:minWidth="17dp"
 				android:visibility="visible"
 				android:minHeight="6dp"
@@ -137,4 +134,4 @@
 				android:layout_gravity="top|center_horizontal"></ProgressBar>
 		</FrameLayout>
 	</RelativeLayout>
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git app/src/main/res/layout/widget_large_transparent.xml app/src/main/res/layout/widget_large_transparent.xml
index 4d3253c..c23f5e5 100644
--- app/src/main/res/layout/widget_large_transparent.xml
+++ app/src/main/res/layout/widget_large_transparent.xml
@@ -25,8 +25,7 @@
 			android:layout_width="52dp"
 			android:src="@drawable/icon_large"></ImageView>
 		<RelativeLayout
-			android:id="@+id/RelativeLayout01"
-			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+				android:layout_above="@+id/txtListitemAccountsItemAccountname"
 			android:layout_toRightOf="@+id/imgWidgetIcon"
 			android:layout_height="wrap_content"
 			android:layout_width="fill_parent">
@@ -52,7 +51,7 @@
 				android:id="@+id/txtWidgetAccountnameBlur"
 				android:layout_alignRight="@+id/imgBalanceblur"
 				android:layout_alignTop="@+id/imgBalanceblur"
-				android:visibility="gone"></TextView>			
+				android:visibility="gone"></TextView>
 			<TextView
 				android:textColor="#fff"
 				android:inputType="none"
@@ -83,8 +82,7 @@
 		</RelativeLayout>
 	</RelativeLayout>
 	<RelativeLayout
-		android:id="@+id/RelativeLayout03"
-		android:layout_width="wrap_content"
+			android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
 		android:layout_alignParentRight="true"
 		android:paddingTop="15dp"
@@ -127,7 +125,6 @@
 				android:indeterminate="true"
 				android:layout_height="wrap_content"
 				style="@style/Widget_Progress"
-				android:id="@+id/prgProgress"
 				android:minWidth="17dp"
 				android:visibility="visible"
 				android:minHeight="6dp"
@@ -135,4 +132,4 @@
 				android:layout_gravity="top|center_horizontal"></ProgressBar>
 		</FrameLayout>
 	</RelativeLayout>
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git app/src/main/res/layout/widget_transparent.xml app/src/main/res/layout/widget_transparent.xml
index 345c3d6..bc7b30b 100644
--- app/src/main/res/layout/widget_transparent.xml
+++ app/src/main/res/layout/widget_transparent.xml
@@ -54,7 +54,7 @@
 		android:layout_marginRight="2dp"
 		android:text="Bankdroid"
 		android:lines="1"
-		android:visibility="gone"></TextView>		
+		android:visibility="gone"></TextView>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -85,8 +85,7 @@
 			android:text="Loading..." />
 	</LinearLayout>
 	<LinearLayout
-		android:id="@+id/layWidgetRow03"
-		android:layout_below="@+id/layWidgetRow02"
+			android:layout_below="@+id/layWidgetRow02"
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
 		android:gravity="bottom"
@@ -105,7 +104,6 @@
 				android:indeterminate="true"
 				android:layout_height="wrap_content"
 				style="@style/Widget_Progress"
-				android:id="@+id/prgProgress"
 				android:maxHeight="2dp"
 				android:minHeight="2dp"
 				android:minWidth="17dp"
@@ -131,4 +129,4 @@
 
 
 
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index da83f0b..ff8a6f5 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    
+
     <string name="about">Om</string>
     <string name="version">Version $version av</string>
     <string name="widget_name_small">Bankdroid (Liten)</string>
@@ -11,9 +11,7 @@
     <string name="errors_when_updating">Fel vid uppdatering</string>
     <string name="logging_in">Loggar in...</string>
     <string name="could_not_create_account">Kunde ej skapa konto</string>
-    <string name="menu_edit">Redigera</string>
-    <string name="menu_remove">Radera</string>
-    <string name="transparent_background">Transparent bakgrund</string>
+	<string name="transparent_background">Transparent bakgrund</string>
     <string name="settings">Inställningar</string>
     <string name="refresh">Uppdatera</string>
     <string name="add_account">Lägg till konto</string>
@@ -24,15 +22,14 @@
 
     <string name="cancel">AVBRYT</string>
     <string name="save">SPARA</string>
-   
+
 	<string name="add_new_account">LÄGG TILL BANK</string>
-	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
-	
+
 	<string name="main_instructions">Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto.</string>
 	<string name="refresh_balance">UPPDATERA</string>
 
 	<string name="choose_an_account">Välj ett konto</string>
-	
+
 	<!--  Settings  -->
 	<string name="security_and_privacy">Säkerhet</string>
 	<string name="enable_patternlock_title">Aktivera grafiskt lösenord</string>
@@ -105,33 +102,14 @@
 	<string name="api_key_title">API-nyckel</string>
 	<string name="api_key_summary">Använd denna nyckel för för att komma åt kontoutdrag från andra applikationer</string>
 
-	<string name="update_frequency">Uppdateringsfrekvens</string>
-	<string name="access_code">Lösenord</string>
-	<string name="access_code_repeat">Upprepa lösenord</string>
-	<string name="passwords_mismatch">Du har angivit två olika lösenord. Skriv samma lösenord i båda fälten.</string>
-	<string name="passwords_mismatch_title">Felaktigt lösenord</string>
-	<string name="pin_desc">Ange ett lösenord om du vill lösenordsskydda applikationen och tillhörande widgets.</string>
-	<string name="notify_on_change">Notifiera vid kontohändelser</string>
-	<string name="with_sound">Med ljud</string>
-	<string name="vibrate">Vibrera</string>
-	<string name="notify_account_types">Endast för följande konototyper:</string>
 	<string name="funds">Fonder</string>
 	<string name="ccards">Kreditkort</string>
 	<string name="loans">Lån</string>
 	<string name="deposit_account">Transaktionskonto</string>
 	<string name="other">Andra</string>
 	<!--  /Settings  -->
-		
-    <string name="login">Logga in</string>
-    <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
-    
-    <string name="disabled">Inaktiverat</string>
- 	<string name="minutes">minuter</string>
-    <string name="hour">timme</string>
-    <string name="hours">timmar</string>
-    <string name="daily">Dagligen</string>
-
-    <string name="popup_refresh">Uppdatera</string>
+
+	<string name="popup_refresh">Uppdatera</string>
     <string name="popup_edit">Redigera</string>
     <string name="popup_www">WWW</string>
     <string name="popup_remove">Radera</string>
@@ -147,10 +125,10 @@
     <string name="remove_bank_title">Radera bank?</string>
     <string name="yes">Ja</string>
     <string name="no">Nej</string>
- 
+
     <string name="menu_show_hidden">Visa dolda konton</string>
     <string name="menu_hide_hidden">Göm dolda konton</string>
-    
+
     <string name="tran_desc">Inget kontoutdrag tillgängligt för detta konto.</string>
 
     <string name="thanks_to">Tack till</string>
@@ -159,10 +137,8 @@
     <!-- Unlock header -->
     <string name="patternlock_header">Rita ditt grafiska lösenord för att låsa upp Bankdroid</string>
     <!-- Security & location settings screen, header -->
-    <string name="lock_settings_title">Lås för SIM-kort</string>
-    <!-- Security & location settings screen, setting option name -->
-    <string name="lockpattern_change_lock_pattern_label">Byt grafiskt lösenord</string>
-    <!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern".  We first ask the user toe nter the current pattern, and this is the message seen -->
+	<!-- Security & location settings screen, setting option name -->
+	<!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern".  We first ask the user toe nter the current pattern, and this is the message seen -->
     <string name="lockpattern_need_to_unlock">Bekräfta sparat grafiskt lösenord</string>
     <!-- Do not translate. -->
     <string name="lockpattern_need_to_unlock_footer"></string>
@@ -192,20 +168,15 @@
     <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen. Once they draw a new pattern and confirm it by drawing it again, they press this button to exit -->
     <string name="lockpattern_continue_button_text">Fortsätt</string>
     <!-- Security & location settings screen, unlock screen activity title -->
-    <string name="lockpattern_settings_title">Grafiskt lösenord</string>
-    <!-- Security & location settings screen, setting check box title if the unlock pattern MUST be drawn everytime they turn on the screen -->
-    <string name="lockpattern_settings_enable_title">Begär grafiskt lösenord</string>
-    <!-- Security & location settings screen, setting summary for the checkbox "Require pattern" -->
-    <string name="lockpattern_settings_enable_summary">Måste rita grafiskt lösenord för att låsa upp skärmen</string>
-    <!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern.  If checked, this line is drawn.  If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
+	<!-- Security & location settings screen, setting check box title if the unlock pattern MUST be drawn everytime they turn on the screen -->
+	<!-- Security & location settings screen, setting summary for the checkbox "Require pattern" -->
+	<!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern.  If checked, this line is drawn.  If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
     <string name="lockpattern_settings_enable_visible_pattern_title">Anv. synligt graf. lös.</string>
     <!-- Security & location settings screen, setting check box title. This setting controls whether tactile feedback will be produced when the user draws the pattern.-->
     <string name="lockpattern_settings_enable_tactile_feedback_title">Använd känslig feedback</string>
     <!-- Security & location settings screen, setting option name when user has never set an unlock pattern -->
-    <string name="lockpattern_settings_choose_lock_pattern">Ange grafiskt lösenord</string>
-    <!-- Security & location settings screen, setting option name when user has previously set an unlock pattern and wants to change to a new pattern -->
-    <string name="lockpattern_settings_change_lock_pattern">Byt grafiskt lösenord</string>
-    <!-- Security & location settings screen, the help instructions (an animation) caption -->
+	<!-- Security & location settings screen, setting option name when user has previously set an unlock pattern and wants to change to a new pattern -->
+	<!-- Security & location settings screen, the help instructions (an animation) caption -->
     <string name="lockpattern_settings_help_how_to_record">Så här ritar du ett grafiskt lösenord</string>
     <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen after too many incorrect attempts -->
     <string name="lockpattern_too_many_failed_confirmation_attempts_header">För många felaktiga försök!</string>
@@ -226,7 +197,7 @@
 		\n<font height="17">\n</font><b>3</b>\u00A0 Rita ditt grafiska lösenord igen för att bekräfta.
 		\n<font height="17">\n</font><b>Är du redo att börja? Välj \u201CNästa\u201D</b>.
 		\n<font height="3">\n</font>"Välj \u201CAvbryt\u201D om du vill lämna telefonen oskyddad.</font>
-		
+
 	</string>
     <!-- ChooseLockPatternExample --> <skip />
     <!-- ChooseLockPatternExample, screen title that shows an example pattern -->
diff --git app/src/main/res/values/colors.xml app/src/main/res/values/colors.xml
index b70edf6..0908ea0 100644
--- app/src/main/res/values/colors.xml
+++ app/src/main/res/values/colors.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,8 +16,7 @@
 
 <resources>
     <color name="black">#000</color>
-    <color name="red">#F00</color>
     <color name="colorPrimary">#212121</color>
     <color name="colorPrimaryDark">#212121</color>
 </resources>
-         
+
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index c6e9a5f..4770b58 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -10,9 +10,7 @@
     <string name="errors_when_updating">Errors while refreshing</string>
     <string name="logging_in">Signing in...</string>
     <string name="could_not_create_account">Could not create account</string>
-    <string name="menu_edit">Edit</string>
-    <string name="menu_remove">Remove</string>
-    <string name="transparent_background">Transparent background</string>
+	<string name="transparent_background">Transparent background</string>
     <string name="settings">Settings</string>
     <string name="refresh">Refresh</string>
     <string name="add_account">Add account</string>
@@ -25,16 +23,15 @@
 
     <string name="cancel">CANCEL</string>
     <string name="save">SAVE</string>
-    
+
 	<string name="add_new_account">ADD BANK</string>
-	<string name="banks_instructions">You have not added any bank accounts yet. Press the button to add a new account.</string>
-	
+
 	<string name="main_instructions">You have not added any bank accounts yet, press the "Accounts" button in the menu to add a new account.</string>
 	<string name="refresh_balance">REFRESH</string>
 
 	<string name="choose_an_account">Choose an account</string>
-	
-	
+
+
 	<!--  Settings  -->
 	<string name="security_and_privacy">Security and Privacy</string>
 	<string name="enable_patternlock_title">Enable Pattern Lock</string>
@@ -106,35 +103,16 @@
 	<string name="share_data_enable_summary">Grant other installed apps access to your transaction history</string>
 	<string name="api_key_title">API Key</string>
 	<string name="api_key_summary">Use this key to allow access for trusted applications</string>
-	
-	<string name="update_frequency">Update frequency</string>
-	<string name="access_code">Access code</string>
-	<string name="access_code_repeat">Repeat access code</string>
-	<string name="passwords_mismatch">You\'ve entered two different access codes. Enter the same password in both password fields.</string>
-	<string name="passwords_mismatch_title">Access code mismatch</string>
-	<string name="pin_desc">Enter an access code if you want to password protect the application and widgets.</string>
-	<string name="notify_on_change">Notify on changes</string>
-	<string name="with_sound">With sound</string>
-	<string name="vibrate">Vibrate</string>
-	<string name="notify_account_types">Only for the following account types:</string>
+
 	<string name="funds">Funds</string>
 	<string name="ccards">Credit cards</string>
 	<string name="loans">Loans</string>
 	<string name="deposit_account">Deposit accounts</string>
 	<string name="other">Other</string>
 	<!--  /Settings  -->
-	
-    <string name="login">Login</string>
-    <string name="invalid_access_code">Invalid access code. Try again.</string>
-    
 
-    <string name="disabled">Disabled</string>
-    <string name="minutes">minutes</string>
-    <string name="hour">hour</string>
-    <string name="hours">hours</string>
-    <string name="daily">Daily</string>
-    
-    <string name="popup_refresh">Refresh</string>
+
+	<string name="popup_refresh">Refresh</string>
     <string name="popup_edit">Edit</string>
     <string name="popup_www">WWW</string>
     <string name="popup_remove">Remove</string>
@@ -145,19 +123,19 @@
     <string name="popup_unhide_a">Unhide\naccounts</string>
     <string name="popup_enable_notifications">Enable notifications</string>
     <string name="popup_disable_notifications">Disable notifications</string>
-        
+
     <string name="remove_bank_msg">Are you sure you want to remove this bank?</string>
     <string name="remove_bank_title">Remove bank?</string>
     <string name="yes">Yes</string>
     <string name="no">No</string>
-    
+
     <string name="menu_show_hidden">Show hidden accounts</string>
     <string name="menu_hide_hidden">Hide hidden accounts</string>
 
     <string name="tran_desc">No transaction history available for this account.</string>
-    
+
     <string name="thanks_to">Thanks to</string>
-    <string name="thanks"> 
+    <string name="thanks">
     Wendell Fernandes (Icon)
     \nKingcool (ICA Banken &amp; SEB)
     \ngrief (Länsförsäkringar)
@@ -205,16 +183,14 @@
 	\nEmil Andersson (Chalmrest)
 	\Richard Ginzburg (Forex Bank)
      </string>
-     
-     
+
+
     <!-- Lock Pattern settings -->
     <!-- Unlock header -->
     <string name="patternlock_header">Draw pattern to unlock Bankdroid</string>
     <!-- Security & location settings screen, header -->
-    <string name="lock_settings_title">Screen unlock pattern</string>
-    <!-- Security & location settings screen, setting option name -->
-    <string name="lockpattern_change_lock_pattern_label">Change unlock pattern</string>
-    <!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern".  We first ask the user toe nter the current pattern, and this is the message seen -->
+	<!-- Security & location settings screen, setting option name -->
+	<!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern".  We first ask the user toe nter the current pattern, and this is the message seen -->
     <string name="lockpattern_need_to_unlock">Confirm saved pattern</string>
     <!-- Do not translate. -->
     <string name="lockpattern_need_to_unlock_footer"></string>
@@ -244,20 +220,15 @@
     <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen. Once they draw a new pattern and confirm it by drawing it again, they press this button to exit -->
     <string name="lockpattern_continue_button_text">Continue</string>
     <!-- Security & location settings screen, unlock screen activity title -->
-    <string name="lockpattern_settings_title">Unlock pattern</string>
-    <!-- Security & location settings screen, setting check box title if the unlock pattern MUST be drawn everytime they turn on the screen -->
-    <string name="lockpattern_settings_enable_title">Require pattern</string>
-    <!-- Security & location settings screen, setting summary for the checkbox "Require pattern" -->
-    <string name="lockpattern_settings_enable_summary">Must draw pattern to unlock screen</string>
-    <!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern.  If checked, this line is drawn.  If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
+	<!-- Security & location settings screen, setting check box title if the unlock pattern MUST be drawn everytime they turn on the screen -->
+	<!-- Security & location settings screen, setting summary for the checkbox "Require pattern" -->
+	<!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern.  If checked, this line is drawn.  If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
     <string name="lockpattern_settings_enable_visible_pattern_title">Use visible pattern</string>
     <!-- Security & location settings screen, setting check box title. This setting controls whether tactile feedback will be produced when the user draws the pattern.-->
     <string name="lockpattern_settings_enable_tactile_feedback_title">Use tactile feedback</string>
     <!-- Security & location settings screen, setting option name when user has never set an unlock pattern -->
-    <string name="lockpattern_settings_choose_lock_pattern">Set unlock pattern</string>
-    <!-- Security & location settings screen, setting option name when user has previously set an unlock pattern and wants to change to a new pattern -->
-    <string name="lockpattern_settings_change_lock_pattern">Change unlock pattern</string>
-    <!-- Security & location settings screen, the help instructions (an animation) caption -->
+	<!-- Security & location settings screen, setting option name when user has previously set an unlock pattern and wants to change to a new pattern -->
+	<!-- Security & location settings screen, the help instructions (an animation) caption -->
     <string name="lockpattern_settings_help_how_to_record">How to draw an unlock pattern</string>
     <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen after too many incorrect attempts -->
     <string name="lockpattern_too_many_failed_confirmation_attempts_header">Too many incorrect attempts!</string>
@@ -278,8 +249,8 @@
         \n<font height="17">\n</font><b>3</b>\u00A0 Redraw your pattern to confirm.
         \n<font height="17">\n</font><b>Ready to start? Select \u201CNext\u201D</b>.
         \n<font height="3">\n</font>To leave your phone unprotected, select \u201CCancel\u201D.</font>
-    </string>    
-        
+    </string>
+
     <!-- ChooseLockPatternExample --> <skip />
     <!-- ChooseLockPatternExample, screen title that shows an example pattern -->
     <string name="lock_example_title">Example pattern</string>
@@ -297,11 +268,11 @@
 	<string name="invalid_integer">%1$s is not a valid positive integer, please try again.</string>
 	<string name="pair_message">The Application below wants to access account types and transaction data from BankDroid.</string>
 	<string name="approve">APPROVE</string>
-	<string name="pair_app_name">Unknown application</string>	
-	
+	<string name="pair_app_name">Unknown application</string>
+
     <!-- Color Picker -->
     <string name="dialog_color_picker">Color Picker</string>
-    <string name="press_color_to_apply">Press on Color to apply</string>    
+    <string name="press_color_to_apply">Press on Color to apply</string>
 
     <!-- Error messages -->
     <string name="error_bank_not_found">The chosen bank could not be found.</string>
diff --git app/src/main/res/values/styles.xml app/src/main/res/values/styles.xml
index 2617f06..2a94ef4 100644
--- app/src/main/res/values/styles.xml
+++ app/src/main/res/values/styles.xml
@@ -22,10 +22,10 @@
 	<item name="android:background">@drawable/menu_button</item>
 	<item name="android:gravity">center_vertical|center_horizontal</item>
 	<item name="android:drawablePadding">0dp</item>
-	<item name="android:layout_width">fill_parent</item>    
+	<item name="android:layout_width">fill_parent</item>
   </style>
   <style name="Popup_Button" parent="@android:style/Widget.Button">
-	<item name="android:layout_width">wrap_content</item>    
+	<item name="android:layout_width">wrap_content</item>
 	<item name="android:layout_height">fill_parent</item>
 	<item name="android:paddingTop">4dp</item>
 	<item name="android:paddingBottom">4dp</item>
@@ -40,34 +40,32 @@
   <style name="Popup_Separator">
 		<item name="android:layout_width">wrap_content</item>
 		<item name="android:background">@drawable/popup_separator</item>
-		<item name="android:layout_height">fill_parent</item>  	
-  </style>  
-  
+		<item name="android:layout_height">fill_parent</item>
+  </style>
+
 	<style name="Animations" />
 
 	<style name="Animations.GrowFromBottom">
 		<item name="@android:windowEnterAnimation">@anim/grow_from_bottom</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_top</item>
 	</style>
-	
+
 	<style name="Animations.GrowFromTop">
 		<item name="@android:windowEnterAnimation">@anim/grow_from_top</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_bottom</item>
 	</style>
-	
+
 	<style name="Animations.PopDownMenu">
 		<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
 	</style>
-    <style name="WindowTitleBackground" parent="@*android:WindowTitleBackground">    
-        <item name="android:background">@android:color/transparent</item>        
-    </style>
-    <style name="listViewStyle" parent="@android:style/Widget.ListView">
-    	<item name="android:cacheColorHint">@android:color/transparent</item>  
+
+	<style name="listViewStyle" parent="@android:style/Widget.ListView">
+    	<item name="android:cacheColorHint">@android:color/transparent</item>
     </style>
     <style name="checkBoxStyle" parent="@android:style/Widget.CompoundButton.CheckBox">
     	<item name="android:button">@drawable/btn_check</item>
     	<item name="android:background">@drawable/btn_check_label_background</item>
     </style>
- 	
+
 </resources>
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 5575575..7f2907c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -17,6 +17,7 @@
 package com.liato.bankdroid.banking.banks;
 
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -24,11 +25,11 @@ import android.content.Context;
 public class AvanzaMini extends Avanza {
 
     public AvanzaMini(Context context) {
-        super(context);
+        super(context, R.drawable.logo_avanzamini);
         TAG = "AvanzaMini";
         NAME = "Avanza Mini";
         NAME_SHORT = "avanzamini";
         URL = "https://www.avanza.se/mini/hem/";
         BANKTYPE_ID = IBankTypes.AVANZAMINI;
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 717e0d6..e0ee2d8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -39,6 +39,7 @@ import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.content.Context;
+import android.support.annotation.DrawableRes;
 import android.util.Base64;
 
 import java.io.IOException;
@@ -54,8 +55,8 @@ public class Avanza extends Bank {
 
     private static final String API_URL = "https://iphone.avanza.se/iphone-ws/";
 
-    public Avanza(Context context) {
-        super(context, R.drawable.logo_avanza);
+    protected Avanza(Context context, @DrawableRes int logoResource) {
+        super(context, logoResource);
         TAG = "Avanza";
         NAME = "Avanza";
         NAME_SHORT = "avanza";
@@ -63,10 +64,8 @@ public class Avanza extends Bank {
         BANKTYPE_ID = IBankTypes.AVANZA;
     }
 
-    public Avanza(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
+    public Avanza(Context context) {
+        this(context, R.drawable.logo_avanza);
     }
 
     @Override
diff --git bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_supremecard.png bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_supremecard.png
deleted file mode 100644
index da5c480..0000000
Binary files bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_supremecard.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/drawable/logo_moneybookers.png bankdroid-legacy/src/main/res/drawable/logo_moneybookers.png
deleted file mode 100644
index 4f4e123..0000000
Binary files bankdroid-legacy/src/main/res/drawable/logo_moneybookers.png and /dev/null differ
diff --git bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm
deleted file mode 100644
index c5e9440..0000000
--- bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm
+++ /dev/null
@@ -1,123 +0,0 @@
-
- 
- 
- 
- 
- 
- 
- 
- 
- 
-<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> 
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="sv"> 
-  <head> 
-    <title>Swedbank mobil</title> 
-    <meta http-equiv="Content-Type" content="application/vnd.wap.xhtml+xml; charset=iso-8859-1" /> 
-    <meta http-equiv="Content-Style-Type" content="text/css" /> 
-    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/> 
-    <meta name="format-detection" content="telephone=no" /> 
-    <link href="/banking/swedbank/css/style.css" rel="stylesheet" type="text/css" media="all" /> 
-        <link href="/banking/swedbank/css/screen.css" rel="stylesheet" type="text/css" media="Screen" /> 
-            <link href="/banking/swedbank/css/iphone.css" rel="stylesheet" type="text/css" media="Screen" /> 
-    <link rel="apple-touch-icon" href="/banking/swedbank/images/icon.png"/> 
-      </head> 
-    <body> 
-      <div id="header"> 
-            <img class="logo" alt="Swedbank" src="/banking/swedbank/images/18114_mynt_hk_2.png"/> 
-          </div> 
-    <div id="content"> 
-<h1> Privatkont </h1> 
-<ul class="grouped">    
-  <li class="first">Clearingnummer<br/><span class="secondary">1234-5</span></li> 
-  <li>Kontonummer<br/><span class="secondary">123 456 789-0</span></li> 
-  <li>Tillg. belopp<br/><span class="secondary">1 234</span></li>          
-</ul> 
-<br /> 
-                              <h2>De senaste transaktionerna</h2> 
-<ul class="grouped"> 
-  
-              <li  class="first" > 
-        <div class="trans-date"> 11-01-28 </div> 
-        <div class="trans-subject"> SF BIO AB </div> 
-        <div class="trans-amount"> -375 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-28 </div> 
-        <div class="trans-subject"> Ins&auml;ttning </div> 
-        <div class="trans-amount"> 1 100 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-25 </div> 
-        <div class="trans-subject"> MCDONALDS </div> 
-        <div class="trans-amount"> -75 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-25 </div> 
-        <div class="trans-subject"> ICA SUPERMARKET </div> 
-        <div class="trans-amount"> -45 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-25 </div> 
-        <div class="trans-subject"> LöN </div> 
-        <div class="trans-amount"> 9876.54 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-24 </div> 
-        <div class="trans-subject"> COOP KONSUM</div> 
-        <div class="trans-amount"> -24 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-21 </div> 
-        <div class="trans-subject"> KONTANTEN DIREKT </div> 
-        <div class="trans-amount"> -500 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-19 </div> 
-        <div class="trans-subject"> ICA KVANTUM </div> 
-        <div class="trans-amount"> -17 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-18 </div> 
-        <div class="trans-subject"> COOP KONSUM </div> 
-        <div class="trans-amount"> -84 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-17 </div> 
-        <div class="trans-subject"> ICA KVANTUM </div> 
-        <div class="trans-amount"> -91 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-17 </div> 
-        <div class="trans-subject"> CLAS OHLSON AB </div> 
-        <div class="trans-amount"> -69 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-17 </div> 
-        <div class="trans-subject"> BURGER KING </div> 
-        <div class="trans-amount"> -72 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-14 </div> 
-        <div class="trans-subject"> CDON AB </div> 
-        <div class="trans-amount"> -384 </div> 
-      </li> 
-                <li > 
-        <div class="trans-date"> 11-01-14 </div> 
-        <div class="trans-subject"> Överföring </div> 
-        <div class="trans-amount"> 3000 </div> 
-      </li> 
-      </ul> 
- 
-  <p class="trans-nav"> 
-      &nbsp;
-        <a href="?id=0&amp;action=next" class="trans-next">N&auml;sta</a> 
-    </p> 
- 
-</div> 
-<div id="nav"> 
-        <a href="/banking/swedbank/accounts.html" class="back">Tillbaka</a>&nbsp; &nbsp;
-    <a href="/banking/swedbank/logout.html" class="logout">Logga ut</a> 
-</div> 
-    <div id="footer"><p>Swedbank</p></div> 
-  </body> 
-</html> 
\ No newline at end of file
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
index 4e52c3a..a80426d 100644
--- bankdroid-legacy/src/main/res/values/strings.xml
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -5,7 +5,6 @@
     <string name="password">Password</string>
     <string name="extras_field">Extras</string>
     <string name="card_number">Card number</string>
-    <string name="cvc">CVC</string>
     <string name="account_number">Account number</string>
     <string name="control_code">Control code</string>
     <string name="email">E-mail</string>
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index d165d32..1cd8fbe 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -56,7 +56,6 @@
     <issue id="IconMixedNinePatch" severity="ignore" />
     <issue id="IconNoDpi" severity="ignore" />
     <issue id="IconXmlAndPng" severity="ignore" />
-    <issue id="IllegalResourceRef" severity="ignore" />
     <issue id="InOrMmUsage" severity="ignore" />
     <issue id="InflateParams" severity="ignore" />
     <issue id="InconsistentArrays" severity="ignore" />
@@ -70,7 +69,6 @@
     <issue id="JavascriptInterface" severity="ignore" />
     <issue id="LabelFor" severity="ignore" />
     <issue id="LibraryCustomView" severity="ignore" />
-    <issue id="LocalSuppress" severity="ignore" />
     <issue id="MangledCRLF" severity="ignore" />
     <issue id="ManifestOrder" severity="ignore" />
     <issue id="ManifestTypo" severity="ignore" />
@@ -101,7 +99,6 @@
     <issue id="ParcelClassLoader" severity="ignore" />
     <issue id="ParcelCreator" severity="ignore" />
     <issue id="PluralsCandidate" severity="ignore" />
-    <issue id="PrivateResource" severity="ignore" />
     <issue id="Proguard" severity="ignore" />
     <issue id="ProguardSplit" severity="ignore" />
     <issue id="ProtectedPermissions" severity="ignore" />
@@ -109,8 +106,6 @@
     <issue id="Recycle" severity="ignore" />
     <issue id="Registered" severity="ignore" />
     <issue id="RequiredSize" severity="ignore" />
-    <issue id="ResAuto" severity="ignore" />
-    <issue id="ResourceAsColor" severity="ignore" />
     <issue id="RtlHardcoded" severity="ignore" />
     <issue id="RtlSymmetry" severity="ignore" />
     <issue id="ScrollViewCount" severity="ignore" />
@@ -146,7 +141,6 @@
     <issue id="UnknownIdInLayout" severity="ignore" />
     <issue id="UnlocalizedSms" severity="ignore" />
     <issue id="UnusedAttribute" severity="ignore" />
-    <issue id="UnusedResources" severity="ignore" />
     <issue id="UseCheckPermission" severity="ignore" />
     <issue id="UseCompoundDrawables" severity="ignore" />
     <issue id="UseSparseArrays" severity="ignore" />

commit 8e4f32f450cf5588b76cfd38a9ffc2062e6fd601
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 10 17:31:52 2016 +0200

    Removes unnecessary cert for amex.
    
    Improved error handling for amex

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
deleted file mode 100644
index 2f6c7e1..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.util.Log;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class AmericanExpress extends Bank {
-
-    private static final String TAG = "AmericanExpress";
-
-    private static final String NAME = "American Express";
-
-    private static final String NAME_SHORT = "americanexpress";
-
-    private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
-
-    private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
-
-    private Pattern reAccounts = Pattern.compile(
-            "leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private Pattern reTransactions = Pattern.compile(
-            "id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>.*?([0-9.,\\s]*kr|&nbsp;)</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr|&nbsp;)",
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private String response = null;
-
-    public AmericanExpress(Context context) {
-        super(context, R.drawable.logo_americanexpress);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-    }
-
-    public AmericanExpress(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
-                R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
-        urlopen.setAllowCircularRedirects(true);
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-
-        postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
-        postData.add(new BasicNameValuePair("DestPage",
-                "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
-        postData.add(new BasicNameValuePair("Face", "sv_SE"));
-        postData.add(new BasicNameValuePair("brandname", ""));
-        postData.add(new BasicNameValuePair("TARGET",
-                "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
-        postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
-        postData.add(new BasicNameValuePair("Logon", "Continue..."));
-        postData.add(new BasicNameValuePair("devicePrint",
-                "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
-        postData.add(new BasicNameValuePair("REMEMBERME", "on"));
-        postData.add(new BasicNameValuePair("manage", "option1"));
-        postData.add(new BasicNameValuePair("UserID", getUsername()));
-        postData.add(new BasicNameValuePair("USERID", getUsername()));
-        postData.add(new BasicNameValuePair("Password", getPassword()));
-        postData.add(new BasicNameValuePair("PWD", getPassword()));
-
-        return new LoginPackage(urlopen, postData, response,
-                "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-        if (!response.contains("Your Personal Cards")) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty() || getPassword().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        Matcher matcher = reAccounts.matcher(response);
-
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Account number        XXX-11111
-             * 2: ID                    0
-             * 3: Name                  SAS EuroBonus American Express&reg; Card
-             * 4: Amount                1.111,11 kr
-             *
-             */
-            accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString()
-                    .replace("American Express", "Amex")
-                    .replace("EuroBonus", "EB")
-                    .trim(),
-                    Helpers.parseBalance(matcher.group(4)).negate(),
-                    matcher.group(2).trim()));
-            balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
-        }
-
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException {
-        super.updateTransactions(account, urlopen);
-
-        response = urlopen.open(
-                "https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index="
-                        + account.getId());
-        Matcher matcher = reTransactions.matcher(response);
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-        SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv","SE"));
-        SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
-        Date transactionDate;
-
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Date                  17 jan 2011
-             * 2: Specification         xx
-             * 3: Amount (if positive)  1.582,00 kr (else &nbsp)
-             * 4: Amount (if negative)  1.582,00 kr (else &nbsp)
-             *
-             */
-            try {
-                transactionDate = sdfFrom.parse(matcher.group(1).trim());
-                String strDate = sdfTo.format(transactionDate);
-                BigDecimal amount;
-                if (matcher.group(3).trim().equals("&nbsp;")) {
-                    amount = Helpers.parseBalance(matcher.group(4).trim()).negate();
-                } else {
-                    amount = Helpers.parseBalance(matcher.group(3).trim());
-                }
-
-                transactions.add(new Transaction(strDate,
-                        Html.fromHtml(matcher.group(2)).toString().trim(),
-                        amount));
-            } catch (ParseException e) {
-                Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
-                Log.w(TAG, e);
-            }
-        }
-        account.setTransactions(transactions);
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
index 8e8da5c..396af06 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
@@ -40,6 +40,7 @@ import org.apache.http.protocol.HTTP;
 import org.joda.time.format.DateTimeFormat;
 
 import android.content.Context;
+import android.support.annotation.Nullable;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -57,12 +58,11 @@ public class AmericanExpress extends Bank {
 
     private static final String NAME_SHORT = "americanexpress";
 
-    private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
-
     private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
 
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
+    @Nullable
     private LoginResponse loginResponse;
 
     public AmericanExpress(Context context) {
@@ -71,7 +71,6 @@ public class AmericanExpress extends Bank {
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
         super.WEB_VIEW_ENABLED = false;
     }
 
@@ -84,9 +83,9 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context,
-                R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
+                R.raw.cert_americanexpress_global));
         urlopen.setAllowCircularRedirects(true);
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        urlopen.setContentCharset(HTTP.UTF_8);
         urlopen.addHeader("Face", "sv_SE");
         return new LoginPackage(urlopen, null, null,
                 "https://global.americanexpress.com/myca/intl/moblclient/emea/svc/v1/loginSummary.do");
@@ -95,17 +94,15 @@ public class AmericanExpress extends Bank {
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
+        loginResponse = parseLoginResponse(urlopen.openAsHttpResponse(
+                lp.getLoginTarget(),
+                new StringEntity(
+                        objectAsJson(new LoginRequest(
+                                getUsername(),
+                                getPassword())),
+                        HTTP.UTF_8),
+                true));
 
-        HttpResponse response = urlopen.openAsHttpResponse(lp.getLoginTarget(),
-                new StringEntity(objectAsJson(new LoginRequest(getUsername(), getPassword())),
-                        HTTP.UTF_8), true);
-
-        loginResponse = MAPPER.reader()
-                .withType(LoginResponse.class)
-                .readValue(response.getEntity().getContent());
-        if(loginResponse.getLogonData().getStatus() != 0) {
-            throw new BankException(loginResponse.getLogonData().getMessage());
-        }
         urlopen.addHeader("cupcake", loginResponse.getLogonData().getCupcake());
         return urlopen;
     }
@@ -121,10 +118,10 @@ public class AmericanExpress extends Bank {
 
         for(Card card : loginResponse.getCards()) {
             Account account = asAccount(card);
-            accounts.add(account);
             if(card.isTransactionsEnabled()) {
                 account.setTransactions(fetchTransactionsFor(card));
             }
+            accounts.add(account);
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -141,12 +138,18 @@ public class AmericanExpress extends Bank {
                         "}",
                         HTTP.UTF_8), true);
         if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+            response.getEntity().consumeContent();
             throw new BankException(
-                    "There were a problem updating the transaction details. Please try again later.");
+                    res.getText(R.string.update_transactions_error).toString());
         }
+
         TransactionsResponse details = MAPPER.reader()
                 .withType(TransactionsResponse.class)
                 .readValue(response.getEntity().getContent());
+
+        if(details.getTransactionDetails() == null) {
+            throw new BankException(res.getText(R.string.server_error_try_again).toString());
+        }
         if(details.getTransactionDetails().getStatus() != 0) {
             throw new BankException(details.getTransactionDetails().getMessage());
         }
@@ -154,10 +157,12 @@ public class AmericanExpress extends Bank {
         return transactionsOf(details.getTransactionDetails());
     }
 
-    private List<Transaction> transactionsOf(TransactionDetails details) {
+    private List<Transaction> transactionsOf(@Nullable TransactionDetails details) {
         List<Transaction> transactions = new ArrayList<>();
-        for(com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) {
-            transactions.add(asTransaction(transaction));
+        if(details != null) {
+            for(com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) {
+                transactions.add(asTransaction(transaction));
+            }
         }
         return transactions;
     }
@@ -189,4 +194,22 @@ public class AmericanExpress extends Bank {
             throw new BankException(e.getMessage(), e);
         }
     }
+
+    private LoginResponse parseLoginResponse(HttpResponse response) throws IOException, BankException {
+        if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+            response.getEntity().consumeContent();
+            throw new BankException(res.getText(R.string.server_error_try_again).toString());
+        }
+        LoginResponse loginResponse = MAPPER.reader()
+                .withType(LoginResponse.class)
+                .readValue(response.getEntity().getContent());
+        if(loginResponse == null || loginResponse.getLogonData() == null) {
+            throw new BankException(res.getText(R.string.server_error_try_again).toString());
+        }
+        if(loginResponse.getLogonData().getStatus() != 0) {
+            throw new BankException(loginResponse.getLogonData().getMessage());
+        }
+
+        return loginResponse;
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
index c51dad3..b63fdd0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
@@ -1,6 +1,8 @@
 package com.liato.bankdroid.banking.banks.americanexpress.model;
 
 
+import android.support.annotation.Nullable;
+
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
 import java.util.Collections;
@@ -10,6 +12,8 @@ import java.util.List;
 public class LoginResponse {
 
     private int status;
+
+    @Nullable
     private LogonData logonData;
 
     public SummaryData getSummaryData() {
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
deleted file mode 100644
index 50b4af7..0000000
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ /dev/null
@@ -1,49 +0,0 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
-www.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/values-sv/strings.xml bankdroid-legacy/src/main/res/values-sv/strings.xml
index f63fab6..36f71c5 100644
--- bankdroid-legacy/src/main/res/values-sv/strings.xml
+++ bankdroid-legacy/src/main/res/values-sv/strings.xml
@@ -26,5 +26,5 @@
     <string name="invalid_card_number">Ogiltigt kortnummer.</string>
     <string name="bank_closed">Banken är för närvarande stängd.</string>
     <string name="server_error_try_again">Serverfel. Var god försök igen om en stund.</string>
-
+    <string name="update_transactions_error">Kunde ej uppdatera transaktionsdata. Var vänlig försök igen senare.</string>
 </resources>
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
index b73c531..4e52c3a 100644
--- bankdroid-legacy/src/main/res/values/strings.xml
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -30,5 +30,6 @@
     <string name="invalid_card_number">Invalid card number.</string>
     <string name="bank_closed">The bank is currently closed.</string>
     <string name="server_error_try_again">Server error. Please try again later.</string>
+    <string name="update_transactions_error">"There was a problem updating the transaction details. Please try again later."</string>
 
 </resources>

commit 744babc5e640fa1150e2daaa2434ce38289c639a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Oct 9 22:44:16 2016 +0200

    Adapt to AmericanExpress mobile REST API

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 88c2454..2e610f1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -2,7 +2,7 @@ package com.liato.bankdroid.banking;
 
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
-import com.liato.bankdroid.banking.banks.AmericanExpress;
+import com.liato.bankdroid.banking.banks.americanexpress.AmericanExpress;
 import com.liato.bankdroid.banking.banks.AppeakPoker;
 import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
new file mode 100644
index 0000000..8e8da5c
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/AmericanExpress.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.americanexpress;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.americanexpress.model.Card;
+import com.liato.bankdroid.banking.banks.americanexpress.model.LoginRequest;
+import com.liato.bankdroid.banking.banks.americanexpress.model.LoginResponse;
+import com.liato.bankdroid.banking.banks.americanexpress.model.TransactionDetails;
+import com.liato.bankdroid.banking.banks.americanexpress.model.TransactionsResponse;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IAccountTypes;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HTTP;
+import org.joda.time.format.DateTimeFormat;
+
+import android.content.Context;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AmericanExpress extends Bank {
+
+    private static final String TAG = "AmericanExpress";
+
+    private static final String NAME = "American Express";
+
+    private static final String NAME_SHORT = "americanexpress";
+
+    private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
+
+    private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    private LoginResponse loginResponse;
+
+    public AmericanExpress(Context context) {
+        super(context, R.drawable.logo_americanexpress);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.WEB_VIEW_ENABLED = false;
+    }
+
+    public AmericanExpress(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
+                R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
+        urlopen.setAllowCircularRedirects(true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        urlopen.addHeader("Face", "sv_SE");
+        return new LoginPackage(urlopen, null, null,
+                "https://global.americanexpress.com/myca/intl/moblclient/emea/svc/v1/loginSummary.do");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+
+        HttpResponse response = urlopen.openAsHttpResponse(lp.getLoginTarget(),
+                new StringEntity(objectAsJson(new LoginRequest(getUsername(), getPassword())),
+                        HTTP.UTF_8), true);
+
+        loginResponse = MAPPER.reader()
+                .withType(LoginResponse.class)
+                .readValue(response.getEntity().getContent());
+        if(loginResponse.getLogonData().getStatus() != 0) {
+            throw new BankException(loginResponse.getLogonData().getMessage());
+        }
+        urlopen.addHeader("cupcake", loginResponse.getLogonData().getCupcake());
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+
+        for(Card card : loginResponse.getCards()) {
+            Account account = asAccount(card);
+            accounts.add(account);
+            if(card.isTransactionsEnabled()) {
+                account.setTransactions(fetchTransactionsFor(card));
+            }
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    private List<Transaction> fetchTransactionsFor(Card card) throws IOException, BankException {
+        HttpResponse response = urlopen.openAsHttpResponse(
+                "https://global.americanexpress.com/myca/intl/moblclient/emea/svc/v1/transaction.do",
+                new StringEntity("{" +
+                        "\"billingIndexList\": [\"0\"]," +
+                        "\"sortedIndex\":" + card.getSortedIndex() +
+                        "}",
+                        HTTP.UTF_8), true);
+        if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+            throw new BankException(
+                    "There were a problem updating the transaction details. Please try again later.");
+        }
+        TransactionsResponse details = MAPPER.reader()
+                .withType(TransactionsResponse.class)
+                .readValue(response.getEntity().getContent());
+        if(details.getTransactionDetails().getStatus() != 0) {
+            throw new BankException(details.getTransactionDetails().getMessage());
+        }
+
+        return transactionsOf(details.getTransactionDetails());
+    }
+
+    private List<Transaction> transactionsOf(TransactionDetails details) {
+        List<Transaction> transactions = new ArrayList<>();
+        for(com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction : details.getTransactions()) {
+            transactions.add(asTransaction(transaction));
+        }
+        return transactions;
+    }
+
+    private Transaction asTransaction(com.liato.bankdroid.banking.banks.americanexpress.model.Transaction transaction) {
+        return new Transaction(
+                DateTimeFormat.forPattern("yyyyMMdd")
+                        .parseDateTime(
+                                Long.toString(transaction.getChargeDate().getRawValue())
+                        ).toString("yyyy-MM-dd"),
+                transaction.getDescription().get(0),
+                new BigDecimal(transaction.getAmount().getRawValue()).negate()
+        );
+    }
+
+    private Account asAccount(Card card) {
+        Account account = new Account(
+                card.getCardProductName(),
+                card.getBalance(),
+                card.getCardKey());
+        account.setType(IAccountTypes.CCARD);
+        return account;
+    }
+
+    private String objectAsJson(Object value) throws BankException {
+        try {
+            return MAPPER.writeValueAsString(value);
+        } catch (JsonProcessingException e) {
+            throw new BankException(e.getMessage(), e);
+        }
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java
new file mode 100644
index 0000000..ab4e0c9
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/AccountActivity.java
@@ -0,0 +1,18 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AccountActivity {
+    List<Transaction> transactionList;
+
+    public List<Transaction> getTransactionList() {
+        return transactionList;
+    }
+
+    public void setTransactionList(List<Transaction> transactionList) {
+        this.transactionList = transactionList;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Amount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Amount.java
new file mode 100644
index 0000000..bdf3fdb
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Amount.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Amount {
+    public double getRawValue() {
+        return rawValue;
+    }
+
+    public void setRawValue(double rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    private double rawValue;
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Capabilities.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Capabilities.java
new file mode 100644
index 0000000..ec7812b
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Capabilities.java
@@ -0,0 +1,17 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Capabilities {
+
+    private TransactionCapabilities transactions;
+
+    public TransactionCapabilities getTransactions() {
+        return transactions;
+    }
+
+    public void setTransactions(TransactionCapabilities transactions) {
+        this.transactions = transactions;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java
new file mode 100644
index 0000000..c9abbe6
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Card.java
@@ -0,0 +1,78 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.liato.bankdroid.Helpers;
+
+import java.math.BigDecimal;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Card {
+    private String cardProductName;
+    private String cardKey;
+    private String cardNumberDisplay;
+    private int sortedIndex;
+
+    private Summary summary;
+    private Capabilities capabilities;
+
+    public String getCardProductName() {
+        return cardProductName;
+    }
+
+    public void setCardProductName(String cardProductName) {
+        this.cardProductName = cardProductName;
+    }
+
+    public String getCardKey() {
+        return cardKey;
+    }
+
+    public void setCardKey(String cardKey) {
+        this.cardKey = cardKey;
+    }
+
+    public String getCardNumberDisplay() {
+        return cardNumberDisplay;
+    }
+
+    public void setCardNumberDisplay(String cardNumberDisplay) {
+        this.cardNumberDisplay = cardNumberDisplay;
+    }
+
+    public Summary getSummary() {
+        return summary;
+    }
+
+    public void setSummary(Summary summary) {
+        this.summary = summary;
+    }
+
+    public Capabilities getCapabilities() {
+        return capabilities;
+    }
+
+    public void setCapabilities(Capabilities capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    public int getSortedIndex() {
+        return sortedIndex;
+    }
+
+    public void setSortedIndex(int sortedIndex) {
+        this.sortedIndex = sortedIndex;
+    }
+
+    public boolean isTransactionsEnabled() {
+        return capabilities != null &&
+                capabilities.getTransactions() != null &&
+                capabilities.getTransactions().isEnabled();
+    }
+
+    public BigDecimal getBalance() {
+        if(summary != null && summary.getTotalBalance() != null) {
+            return Helpers.parseBalance(summary.getTotalBalance().getValue()).negate();
+        }
+        return BigDecimal.ZERO;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Date.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Date.java
new file mode 100644
index 0000000..7b8457e
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Date.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Date {
+    private long rawValue;
+
+    public long getRawValue() {
+        return rawValue;
+    }
+
+    public void setRawValue(long rawValue) {
+        this.rawValue = rawValue;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginRequest.java
new file mode 100644
index 0000000..b90d8e0
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginRequest.java
@@ -0,0 +1,28 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import org.joda.time.DateTime;
+
+public class LoginRequest {
+
+    private String user;
+    private String password;
+    private long userTimeStampInMilli;
+
+    public LoginRequest(String username, String password) {
+        this.user = username;
+        this.password = password;
+        userTimeStampInMilli = DateTime.now().getMillis();
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public long getUserTimeStampInMilli() {
+        return userTimeStampInMilli;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
new file mode 100644
index 0000000..c51dad3
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LoginResponse.java
@@ -0,0 +1,47 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.Collections;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LoginResponse {
+
+    private int status;
+    private LogonData logonData;
+
+    public SummaryData getSummaryData() {
+        return summaryData;
+    }
+
+    public void setSummaryData(SummaryData summaryData) {
+        this.summaryData = summaryData;
+    }
+
+    private SummaryData summaryData;
+
+    public int getStatus() {
+        return status;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public LogonData getLogonData() {
+        return logonData;
+    }
+
+    public void setLogonData(LogonData logonData) {
+        this.logonData = logonData;
+    }
+
+    public List<Card> getCards() {
+        if(summaryData != null && summaryData.getCardList() != null) {
+            return summaryData.getCardList();
+        }
+        return Collections.emptyList();
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LogonData.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LogonData.java
new file mode 100644
index 0000000..086a0fe
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/LogonData.java
@@ -0,0 +1,35 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LogonData {
+
+    private int status;
+    private String message;
+    private String cupcake;
+
+    public int getStatus() {
+        return status;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getCupcake() {
+        return cupcake;
+    }
+
+    public void setCupcake(String cupcake) {
+        this.cupcake = cupcake;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Summary.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Summary.java
new file mode 100644
index 0000000..3c992b5
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Summary.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Summary {
+    private TotalBalance totalBalance;
+
+    public TotalBalance getTotalBalance() {
+        return totalBalance;
+    }
+
+    public void setTotalBalance(TotalBalance totalBalance) {
+        this.totalBalance = totalBalance;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/SummaryData.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/SummaryData.java
new file mode 100644
index 0000000..7156603
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/SummaryData.java
@@ -0,0 +1,28 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SummaryData {
+
+    private int status;
+    private List<Card> cardList;
+
+    public int getStatus() {
+        return status;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public List<Card> getCardList() {
+        return cardList;
+    }
+
+    public void setCardList(List<Card> cardList) {
+        this.cardList = cardList;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TotalBalance.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TotalBalance.java
new file mode 100644
index 0000000..404dc11
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TotalBalance.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TotalBalance {
+    private String value;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Transaction.java
new file mode 100644
index 0000000..c8e0b6f
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/Transaction.java
@@ -0,0 +1,36 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Transaction {
+    private Amount amount;
+    private Date chargeDate;
+    private List<String> description;
+
+    public Amount getAmount() {
+        return amount;
+    }
+
+    public void setAmount(Amount amount) {
+        this.amount = amount;
+    }
+
+    public Date getChargeDate() {
+        return chargeDate;
+    }
+
+    public void setChargeDate(Date chargeDate) {
+        this.chargeDate = chargeDate;
+    }
+
+    public List<String> getDescription() {
+        return description;
+    }
+
+    public void setDescription(List<String> description) {
+        this.description = description;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionCapabilities.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionCapabilities.java
new file mode 100644
index 0000000..eccdaac
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionCapabilities.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TransactionCapabilities {
+        private boolean enabled;
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java
new file mode 100644
index 0000000..2efa7ea
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionDetails.java
@@ -0,0 +1,50 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TransactionDetails {
+    private long status;
+    private String message;
+
+    private List<AccountActivity> activityList;
+
+    public long getStatus() {
+        return status;
+    }
+
+    public void setStatus(long status) {
+        this.status = status;
+    }
+
+    public List<AccountActivity> getActivityList() {
+        return activityList;
+    }
+
+    public void setActivityList(List<AccountActivity> activityList) {
+        this.activityList = activityList;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public List<Transaction> getTransactions() {
+        if (activityList != null) {
+            List<Transaction> transactions = new ArrayList<>();
+            for(AccountActivity activity : activityList) {
+                transactions.addAll(activity.getTransactionList());
+            }
+            return transactions;
+        }
+        return Collections.emptyList();
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionsResponse.java
new file mode 100644
index 0000000..5b0b374
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/americanexpress/model/TransactionsResponse.java
@@ -0,0 +1,17 @@
+package com.liato.bankdroid.banking.banks.americanexpress.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TransactionsResponse {
+
+    private TransactionDetails transactionDetails;
+
+    public TransactionDetails getTransactionDetails() {
+        return transactionDetails;
+    }
+
+    public void setTransactionDetails(TransactionDetails transactionDetails) {
+        this.transactionDetails = transactionDetails;
+    }
+}

commit e92ce1cf6fce50a584ca20eeb2e3250afadf3bc7
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 10 18:38:04 2016 +0200

    minor code improvement

diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index a1a721f..898736e 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -24,8 +24,7 @@ public class BankdroidApplication extends Application {
     @Override
     public void onCreate() {
         super.onCreate();
-        Fabric.with(this, new Crashlytics());
-        Fabric.with(this, new Answers());
+        Fabric.with(this, new Crashlytics(), new Answers());
         Crashlytics.setString(LOG_KEY_LOCALE, Locale.getDefault().toString());
         logBanks();
     }

commit 9a5f09b3fe41b85744e8a91c02001d92cc6ebdbe
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 10 17:50:31 2016 +0200

    Update crashlytics version

diff --git app/build.gradle app/build.gradle
index 828dbab..a6f8d3e 100644
--- app/build.gradle
+++ app/build.gradle
@@ -73,7 +73,7 @@ dependencies {
     compile 'com.jakewharton:butterknife:6.1.0'
     compile "com.android.support:appcompat-v7:24.1.1"
     compile 'com.google.collections:google-collections:1.0'
-    compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
+    compile('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
         transitive = true;
     }
 
diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index 5dbf2f0..a1a721f 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -1,6 +1,7 @@
 package com.liato.bankdroid;
 
 import com.crashlytics.android.Crashlytics;
+import com.crashlytics.android.answers.Answers;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
 
@@ -24,6 +25,7 @@ public class BankdroidApplication extends Application {
     public void onCreate() {
         super.onCreate();
         Fabric.with(this, new Crashlytics());
+        Fabric.with(this, new Answers());
         Crashlytics.setString(LOG_KEY_LOCALE, Locale.getDefault().toString());
         logBanks();
     }

commit 20edd29bc4a15de88d6ddb8513c687e6375a782a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 6 21:02:44 2016 +0200

    Adapt to new web service for Rikslunchen

diff --git CHANGELOG CHANGELOG
index 339ce95..7a93dc1 100644
--- CHANGELOG
+++ CHANGELOG
@@ -10,6 +10,7 @@ v1.9.10.9
 * Ticket Rikskortet: Adapt to changed web page
 * Removes IcaBanken since they now require BankID
 * SveaDirekt: Adapt to changed web page
+* Rikslunchen: Adapt to new web service
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 38dfa3f..a9e0269 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -16,26 +16,21 @@
  */
 package com.liato.bankdroid.banking.banks.rikslunchen;
 
-import com.liato.bankdroid.Helpers;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.rikslunchen.model.Envelope;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 
-import org.apache.http.entity.StringEntity;
-import org.simpleframework.xml.Serializer;
-import org.simpleframework.xml.core.Persister;
-
+import org.apache.http.HttpResponse;
 import android.content.Context;
 import android.text.InputType;
-import android.text.TextUtils;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 
 import eu.nullbyte.android.urllib.CertificateReader;
@@ -53,7 +48,9 @@ public class Rikslunchen extends Bank {
 
     private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
 
-    private String myResponse = "";
+    private static final String BASE_URL = "http://www.rikslunchen.se/isr/isr/services/bankdroid/getbalance";
+
+    private static final ObjectReader READER = new ObjectMapper().reader();
 
     public Rikslunchen(Context context) {
         super(context, R.drawable.logo_rikslunchen);
@@ -84,42 +81,23 @@ public class Rikslunchen extends Bank {
         if (getUsername().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
-        try {
-            urlopen = new Urllib(context,
-                    CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
-            urlopen.addHeader("Authorization", "basic Q0g6ODlAUHFqJGw4NyMjTVM=");
-            urlopen.addHeader("SOAPAction", "");
-            urlopen.addHeader("Content-Type", "text/xml;charset=UTF-8");
-            StringEntity body = new StringEntity(String.format(
-                    "<v:Envelope xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:v=\"http://schemas.xmlsoap.org/soap/envelope/\"><v:Header /><v:Body><n0:getBalance id=\"o0\" c:root=\"1\" xmlns:n0=\"urn:PhoneService\"><cardNo i:type=\"d:string\">%s</cardNo></n0:getBalance></v:Body></v:Envelope>",
-                    getUsername()), "UTF-8");
-            InputStream is = urlopen.openStream("https://www.rikslunchen.se/rkchws/PhoneService",
-                    body, true);
-
-            Serializer serializer = new Persister();
-            Envelope resp = null;
-            try {
-                resp = serializer.read(Envelope.class, is, false);
-            } catch (Exception e) {
-                throw new BankException(e.getMessage(), e);
-            }
-
-            if (resp != null && resp.body != null && resp.body.fault != null && !TextUtils.isEmpty(
-                    resp.body.fault.faultstring)) {
-                throw new LoginException(context.getString(R.string.invalid_card_number));
-                //faultString isn't always very descriptive
-                //throw new BankException(resp.body.fault.faultstring);
-            } else if (resp == null || resp.body == null || resp.body.getBalanceResponse == null
-                    || resp.body.getBalanceResponse.responseReturn == null
-                    || resp.body.getBalanceResponse.responseReturn.amount == null) {
-                throw new LoginException(context.getString(R.string.invalid_card_number));
-            }
-            BigDecimal balance = Helpers.parseBalance(
-                    resp.body.getBalanceResponse.responseReturn.amount);
-            accounts.add(new Account("Rikslunchen", balance, "1"));
-        } catch (UnsupportedEncodingException e) {
-            throw new BankException(e.getMessage(), e);
+
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
+
+        HttpResponse response = urlopen.openAsHttpResponse(
+                BASE_URL + "?cardid=" + getUsername(),
+                false);
+        if(response.getStatusLine().getStatusCode() != 200) {
+            response.getEntity().consumeContent();
+            throw new LoginException(context.getString(R.string.invalid_card_number));
         }
+
+        JsonNode node = READER.readTree(response.getEntity().getContent());
+
+        BigDecimal balance = new BigDecimal(node.get("balance").asDouble());
+            accounts.add(new Account("Rikslunchen", balance, "1"));
+
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found)
                     .toString());

commit cadd70cc510a867a57b902b6f3b45c0e55013670
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sun Oct 9 21:08:14 2016 +0200

    Use static Android resource loading everywhere
    
    This change replaces dynamic resource loading with static in all
    places I could find.
    
    There are two points with this:
    1. It makes it obvious at compile time if a resource is missing, like
    the Östgötatrafiken logo.
    2. It makes it obvious to Android Lint which resources are actually
    unused and can be removed.

diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index 69f9268..91afae0 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -22,7 +22,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
-import android.content.res.Resources.NotFoundException;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
@@ -73,19 +72,14 @@ public class PairApplicationsActivity extends LockableActivity {
             String appName = bundle.getString(PAIR_APP_NAME);
 
             ImageView img = (ImageView) findViewById(R.id.imageView1);
-            String logoUri = "drawable/applogo_" + appName.toLowerCase();
-
-            // Dynamically load logo
-            int imageResource = getResources().getIdentifier(logoUri, null, getPackageName());
-
-            try {
-                Drawable d = getResources().getDrawable(imageResource);
-                img.setImageDrawable(d);
-                img.requestLayout();
-            } catch (NotFoundException e) {
-                Log.e(TAG, "Could not find the requested image using uri " + logoUri);
-                e.printStackTrace();
-            }
+
+            // Note that we used to load this dynamically, but Ekonomipuls was the
+            // only user ever. Doing it statically like this helps Android Lint
+            // know that the logo in question is still in use.
+            Drawable d = getResources().getDrawable(R.drawable.applogo_ekonomipuls);
+            img.setImageDrawable(d);
+            img.requestLayout();
+
             // Change application name
             TextView appNameView = (TextView) findViewById(R.id.app_name);
             appNameView.setText(appName);
diff --git app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
index 638e5ac..f5f9760 100644
--- app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
+++ app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
@@ -40,6 +40,7 @@
 package com.liato.bankdroid.liveview;
 
 import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
 import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
 import com.sonyericsson.extras.liveview.IPluginServiceV1;
 
@@ -144,7 +145,7 @@ public class LiveViewService extends Service {
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
 
         // Load menu icon
-        int iconId = PluginUtils.getDynamicResourceId(this, "ic_launcher", "drawable");
+        int iconId = R.drawable.ic_launcher;
         mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
     }
 
@@ -192,8 +193,7 @@ public class LiveViewService extends Service {
                 Log.d(PluginConstants.LOG_TAG, "Already started.");
             } else {
                 // Init
-                mPluginName = PluginUtils.getDynamicResourceString(this,
-                        PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+                mPluginName = getResources().getString(R.string.app_name);
 
                 // Bind to LiveView
                 connectToLiveView();
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
index af3be15..355c1d0 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
@@ -25,7 +25,7 @@
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in
- * 
+ *
  * all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
@@ -55,9 +55,6 @@ public final class PluginConstants {
 
     public static final String BROADCAST_COMMAND_PLUGIN_NAME = "pluginName";
 
-    // Resource string constants
-    public static final String RESOURCE_STRING_PLUGIN_NAME = "app_name";
-
     // LiveView Plugin interface intents
     public static final String LIVEVIEW_SERVICE_BIND_INTENT
             = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
index d31170f..0d05b28 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -25,7 +25,7 @@
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in
- * 
+ *
  * all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
@@ -39,6 +39,7 @@
 
 package com.liato.bankdroid.liveview;
 
+import com.liato.bankdroid.R;
 import com.liato.bankdroid.SettingsActivity;
 
 import android.content.BroadcastReceiver;
@@ -65,8 +66,7 @@ public class PluginReceiver extends BroadcastReceiver {
         if (command.contentEquals(PluginConstants.BROADCAST_COMMAND_PREFERENCES)) {
             String pluginName = intent.getExtras()
                     .getString(PluginConstants.BROADCAST_COMMAND_PLUGIN_NAME);
-            String myPluginName = PluginUtils
-                    .getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+            String myPluginName = context.getResources().getString(R.string.app_name);
 
             if (pluginName != null && pluginName.contentEquals(myPluginName)) {
                 Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
index 2a1927c..9eada3a 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
@@ -25,7 +25,7 @@
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be included in
- * 
+ *
  * all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
@@ -91,21 +91,4 @@ public final class PluginUtils {
 
         return iconFile.getAbsolutePath();
     }
-
-    /**
-     * Gets resource id dynamically
-     */
-    public static int getDynamicResourceId(Context context, String resourceName,
-            String resourceType) {
-        return context.getResources()
-                .getIdentifier(resourceName, resourceType, context.getPackageName());
-    }
-
-    /**
-     * Gets resource string dynamically
-     */
-    public static String getDynamicResourceString(Context context, String resourceName) {
-        int resourceId = getDynamicResourceId(context, resourceName, "string");
-        return context.getString(resourceId);
-    }
 }
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
index 48128ce..672a786 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
@@ -175,15 +175,6 @@ public class LockPatternView extends View {
         mBitmapArrowGreenUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_green_up);
         mBitmapArrowRedUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_red_up);
 
-        //mBitmapBtnDefault = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_default", null, null));
-        //mBitmapBtnTouched = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_touched", null, null));
-        //mBitmapCircleDefault = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_default", null, null));
-        //mBitmapCircleGreen = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_green", null, null));
-        //mBitmapCircleRed = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_red", null, null));
-
-        //mBitmapArrowGreenUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_green_up", null, null));
-        //mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));
-
         // we assume all bitmaps have the same size
         mBitmapWidth = mBitmapBtnDefault.getWidth();
         mBitmapHeight = mBitmapBtnDefault.getHeight();
diff --git app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
index 58c4489..b821497 100644
--- app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
+++ app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
@@ -23,7 +23,7 @@ public class DataRetrieverTaskTest {
         private boolean hasUpdated = false;
 
         public TestableBank(int balanceBeforeUpdate, int balanceAfterUpdate) {
-            super(Mockito.mock(Context.class));
+            super(Mockito.mock(Context.class), 0);
 
             this.balanceBeforeUpdate = balanceBeforeUpdate;
             this.balanceAfterUpdate = balanceAfterUpdate;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index eaed6e6..115f2bb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -33,6 +33,7 @@ import org.apache.http.client.CookieStore;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
+import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
 import android.text.InputType;
 import android.util.Log;
@@ -51,6 +52,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     private final ProviderConfiguration defaultConfiguration = new LegacyProviderConfiguration(this);
 
+    @DrawableRes
+    private final int logoResource;
+
     protected String TAG = "Bank";
 
     protected String NAME = "Bank";
@@ -130,9 +134,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     private Map<String, String> properties;
 
-    public Bank(Context context) {
+    public Bank(Context context, @DrawableRes int logoResource) {
         this.context = context;
         this.res = this.context.getResources();
+        this.logoResource = logoResource;
     }
 
     public boolean toggleHideAccounts() {
@@ -384,8 +389,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return BROKEN;
     }
 
-    public int getImageResource() {
-        return res.getIdentifier("logo_" + NAME_SHORT, "drawable", context.getPackageName());
+    @DrawableRes
+    public final int getImageResource() {
+        return logoResource;
     }
 
     public int compareTo(Bank another) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index f46bc24..1abfc23 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -33,6 +33,7 @@ import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
 import android.content.Context;
+import android.support.annotation.DrawableRes;
 import android.text.InputType;
 import android.text.TextUtils;
 
@@ -55,18 +56,18 @@ public abstract class AbsIkanoPartner extends Bank {
 
     private String response = null;
 
-    public AbsIkanoPartner(Context context) {
-        super(context);
+    public AbsIkanoPartner(Context context, @DrawableRes int logoResource) {
+        super(context, logoResource);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = true;
     }
 
-    public AbsIkanoPartner(String username, String password, Context context)
+    public AbsIkanoPartner(String username, String password, Context context, @DrawableRes int logoResource)
             throws BankException, LoginException,
             BankChoiceException, IOException {
-        this(context);
+        this(context, logoResource);
         this.update(username, password);
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 96b45d2..b8925bd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -81,7 +81,7 @@ public class AkeliusInvest extends Bank {
     private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 
     public AkeliusInvest(Context context) {
-        super(context);
+        super(context, R.drawable.logo_akeliusinvest);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index ee79842..c60189e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -82,7 +82,7 @@ public class AkeliusSpar extends Bank {
     private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 
     public AkeliusSpar(Context context) {
-        super(context);
+        super(context, R.drawable.logo_akeliusspar);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index ed5609f..2f6c7e1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -71,7 +71,7 @@ public class AmericanExpress extends Bank {
     private String response = null;
 
     public AmericanExpress(Context context) {
-        super(context);
+        super(context, R.drawable.logo_americanexpress);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index cf00a9e..52f373a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -57,7 +57,7 @@ public class AppeakPoker extends Bank {
     private String mChips = null;
 
     public AppeakPoker(Context context) {
-        super(context);
+        super(context, R.drawable.logo_appeakpoker);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
index 16ed51c..fbd6e59 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -39,7 +40,7 @@ public class Audi extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.AUDI;
 
     public Audi(Context context) {
-        super(context);
+        super(context, R.drawable.logo_audi);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index d879d5a..7753a93 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -71,7 +71,7 @@ public class BetterGlobe extends Bank {
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     public BetterGlobe(Context context) {
-        super(context);
+        super(context, R.drawable.logo_betterglobe);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index 5ba1723..5788b0e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -58,7 +58,7 @@ public class Bioklubben extends Bank {
     private String response = null;
 
     public Bioklubben(Context context) {
-        super(context);
+        super(context, R.drawable.logo_bioklubben);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index b9165e2..2e5337c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -53,7 +53,7 @@ public class BlekingeTrafiken extends Bank {
     private String response = null;
 
     public BlekingeTrafiken(Context context) {
-        super(context);
+        super(context, R.drawable.logo_blekingetrafiken);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 6915d7d..a0cf8ba 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -16,10 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -33,6 +29,10 @@ import com.liato.bankdroid.provider.IBankTypes;
 import org.apache.http.NameValuePair;
 import org.apache.http.message.BasicNameValuePair;
 
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -62,7 +62,7 @@ public class Bredband2VoIP extends Bank {
     private String response = null;
 
     public Bredband2VoIP(Context context) {
-        super(context);
+        super(context, R.drawable.logo_bredband2voip);
         TAG = "Bredband2VoIP";
         NAME = "Bredband2 VoIP";
         NAME_SHORT = "bredband2voip";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index 577a2d6..b42ec01 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -79,7 +79,7 @@ public class BrummerKF extends Bank {
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     public BrummerKF(Context context) {
-        super(context);
+        super(context, R.drawable.logo_brummer_kf);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index e83fc7a..ff8b541 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -83,7 +83,7 @@ public class CSN extends Bank {
     private String response = null;
 
     public CSN(Context context) {
-        super(context);
+        super(context, R.drawable.logo_csn);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index a5a0314..922bc9f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -48,7 +48,7 @@ public class Chalmrest extends Bank {
     private String response = null;
 
     public Chalmrest(Context context) {
-        super(context);
+        super(context, R.drawable.logo_chalmrest);
 
         super.TAG = TAG;
         super.NAME = NAME;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
index cd6bc86..5f256d0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class Chevrolet extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.CHEVROLET;
 
     public Chevrolet(Context context) {
-        super(context, "chse", "0086");
+        super(context, "chse", "0086", R.drawable.logo_chevrolet);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Chevrolet extends SEBKortBase {
 
     public Chevrolet(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "chse", "0086");
+        super(username, password, context, "chse", "0086", R.drawable.logo_chevrolet);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index 1ece04d..0b1cb2c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -83,7 +83,7 @@ public class DanskeBank extends Bank {
     private String mPersonnr = null;
 
     public DanskeBank(Context context) {
-        super(context);
+        super(context, R.drawable.logo_danskebank);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 7e4241d..624ac9a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
  * Contributors: mhagander
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
@@ -77,7 +77,7 @@ public class DinersClub extends Bank {
     private String invoiceUrl;
 
     public DinersClub(Context context) {
-        super(context);
+        super(context, R.drawable.logo_dinersclub);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -160,7 +160,7 @@ public class DinersClub extends Bank {
              * 1: Name              Privatkort
              * 2: Card number       1234 789456 741
              * 3: Balance           3.331,79 kr
-             * 
+             *
              */
             accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
                     Helpers.parseBalance(matcher.group(3)), "1"));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
index 7cf7fd6..26e1a39 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class Djurgarden extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.DJURGARDEN;
 
     public Djurgarden(Context context) {
-        super(context, "djse", "0116");
+        super(context, "djse", "0116", R.drawable.logo_djurgarden);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Djurgarden extends SEBKortBase {
 
     public Djurgarden(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "djse", "0116");
+        super(username, password, context, "djse", "0116", R.drawable.logo_djurgarden);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index 66a166c..cf5abb6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -59,7 +59,7 @@ public class EasyCard extends Bank {
     private String response = null;
 
     public EasyCard(Context context) {
-        super(context);
+        super(context, R.drawable.logo_easycard);
 
         super.TAG = TAG;
         super.NAME = NAME;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index c247a79..db1ebc5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -49,7 +49,7 @@ public class EspressoHouse extends Bank {
     private Document dResponse = null;
 
     public EspressoHouse(Context context) {
-        super(context);
+        super(context, R.drawable.logo_espressohouse);
         TAG = "EspressoHouse";
         NAME = "Espresso House";
         NAME_SHORT = "espressohouse";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index e2f3c84..890eb56 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -21,6 +21,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -38,7 +39,7 @@ public class EurobonusMastercard extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
 
     public EurobonusMastercard(Context context) {
-        super(context, "sase", "0102");
+        super(context, "sase", "0102", R.drawable.logo_ebmaster);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -47,7 +48,7 @@ public class EurobonusMastercard extends SEBKortBase {
 
     public EurobonusMastercard(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sase", "0102");
+        super(username, password, context, "sase", "0102", R.drawable.logo_ebmaster);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index 62e891c..9678ec3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -21,6 +21,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -38,7 +39,7 @@ public class EurobonusMastercardDk extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_DK;
 
     public EurobonusMastercardDk(Context context) {
-        super(context, "sadk", "0101");
+        super(context, "sadk", "0101", R.drawable.logo_ebmaster_dk);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -48,7 +49,7 @@ public class EurobonusMastercardDk extends SEBKortBase {
 
     public EurobonusMastercardDk(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sadk", "0101");
+        super(username, password, context, "sadk", "0101", R.drawable.logo_ebmaster_dk);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index ee66bc5..3adfd46 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -21,6 +21,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -38,7 +39,7 @@ public class EurobonusMastercardNo extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_NO;
 
     public EurobonusMastercardNo(Context context) {
-        super(context, "sano", "0117");
+        super(context, "sano", "0117", R.drawable.logo_ebmaster_no);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -48,7 +49,7 @@ public class EurobonusMastercardNo extends SEBKortBase {
 
     public EurobonusMastercardNo(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sano", "0117");
+        super(username, password, context, "sano", "0117", R.drawable.logo_ebmaster_no);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
index 1a295dc..616f1d7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -38,7 +38,7 @@ public class Eurocard extends SEBKortBase {
     private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
 
     public Eurocard(Context context) {
-        super(context, "ecse", "0005", "secure.eurocard.se", new int[]{R.raw.cert_eurocard});
+        super(context, "ecse", "0005", "secure.eurocard.se", new int[]{R.raw.cert_eurocard}, R.drawable.logo_eurocard);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -48,7 +48,7 @@ public class Eurocard extends SEBKortBase {
     public Eurocard(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
         super(username, password, context, "ecse", "0005", "secure.eurocard.se",
-                new int[]{R.raw.cert_eurocard});
+                new int[]{R.raw.cert_eurocard}, R.drawable.logo_eurocard);
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 380b8cb..8a4e4ed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -68,7 +68,7 @@ public class Everydaycard extends Bank {
     private String response = null;
 
     public Everydaycard(Context context) {
-        super(context);
+        super(context, R.drawable.logo_everydaycard);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 44d5ad7..1ebd1f1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -69,7 +69,7 @@ public class FirstCard extends Bank {
     private String response = null;
 
     public FirstCard(Context context) {
-        super(context);
+        super(context, R.drawable.logo_firstcard);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index 9ba9212..b844ad2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -77,7 +77,7 @@ public class ForexBank extends Bank {
             Pattern.MULTILINE | Pattern.DOTALL);
 
     public ForexBank(Context context) {
-        super(context);
+        super(context, R.drawable.logo_forex);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index fa831b1..1291226 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -82,7 +82,7 @@ public class Handelsbanken extends Bank {
     private String response = null;
 
     public Handelsbanken(Context context) {
-        super(context);
+        super(context, R.drawable.logo_handelsbanken);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -181,4 +181,4 @@ public class Handelsbanken extends Bank {
         });
         account.setTransactions(transactions);
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index c51674d..cdcd34b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -65,7 +65,7 @@ public class Hemkop extends Bank {
     private String response = null;
 
     public Hemkop(Context context) {
-        super(context);
+        super(context, R.drawable.logo_hemkop);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
index 1709cfb..fcbc69d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
@@ -15,9 +15,6 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -35,6 +32,9 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -58,7 +58,7 @@ public class Hors extends Bank {
     private String response = null;
 
     public Hors(Context context) {
-        super(context);
+        super(context, R.drawable.logo_hors);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
index 0ca9fff..3d974c6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -39,7 +40,7 @@ public class IKEA extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.IKEA;
 
     public IKEA(Context context) {
-        super(context);
+        super(context, R.drawable.logo_ikea);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 8fb36b4..e76377d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -81,7 +81,7 @@ public class IkanoBank extends Bank {
     private String response = null;
 
     public IkanoBank(Context context) {
-        super(context);
+        super(context, R.drawable.logo_ikanobank);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -171,7 +171,7 @@ public class IkanoBank extends Bank {
              * 2: Name                  Kontonamn1
              * 3: Account number        123456
              * 4: Balance               316 000,39
-             * 
+             *
              */
             accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
                     Helpers.parseBalance(matcher.group(4).trim()), matcher.group(1).trim()));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 466bece..04d01d8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -63,7 +63,7 @@ public class Jojo extends Bank {
     private String response = null;
 
     public Jojo(Context context) {
-        super(context);
+        super(context, R.drawable.logo_jojo);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index 90033c5..e1a5c34 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -64,7 +64,7 @@ public class Marginalen extends Bank {
     private String accountUrl = "";
 
     public Marginalen(Context context) {
-        super(context);
+        super(context, R.drawable.logo_marginalen);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 7fa2357..d150b77 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -67,7 +67,7 @@ public class McDonalds extends Bank {
     private String response = "";
 
     public McDonalds(Context context) {
-        super(context);
+        super(context, R.drawable.logo_mcdonalds);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -119,7 +119,7 @@ public class McDonalds extends Bank {
              * Capture groups:
              * GROUP                    EXAMPLE DATA
              * 1: balance               845
-             * 
+             *
              */
             Account account = new Account("Presentkort", Helpers.parseBalance(matcher.group(1)),
                     "1");
@@ -133,7 +133,7 @@ public class McDonalds extends Bank {
                  * 1: Date                  11-03-17
                  * 2: Location              Sthlm, Sk&ouml;ndal
                  * 3: Amount                -144
-                 * 
+                 *
                  */
                 transactions.add(new Transaction("20" + matcher.group(1).trim(),
                         Html.fromHtml(matcher.group(2)).toString().trim(),
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index 5147981..379029d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -53,7 +53,7 @@ public class Meniga extends Bank {
             "\"Id\":([^,]*),.*?\"Text\":\"([^\"]*)\".*?\"OriginalDate\":\".?.?Date\\(([^\\)]*)\\).*?\"Amount\":([^,]*),");
 
     public Meniga(Context context) {
-        super(context);
+        super(context, R.drawable.logo_meniga);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index 9fafb1a..b6f3cbb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -47,7 +47,7 @@ import eu.nullbyte.android.urllib.Urllib;
 public class MinPension extends Bank {
 
     public MinPension(Context context) {
-        super(context);
+        super(context, R.drawable.logo_minpension);
         TAG = "MinPension";
         NAME = "Min Pension.se";
         NAME_SHORT = "minpension";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 5b30f79..0d6ab45 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -30,6 +30,7 @@ import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
+import android.support.annotation.DrawableRes;
 import android.text.Html;
 import android.text.InputType;
 
@@ -65,16 +66,16 @@ public abstract class MobilbankenBase extends Bank {
     private String response = null;
 
 
-    public MobilbankenBase(Context context) {
-        super(context);
+    public MobilbankenBase(Context context, @DrawableRes int logoResource) {
+        super(context , logoResource);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public MobilbankenBase(String username, String password, Context context) throws BankException,
+    public MobilbankenBase(String username, String password, Context context, @DrawableRes int logoResource) throws BankException,
             LoginException, BankChoiceException, IOException {
-        this(context);
+        this(context, logoResource);
         this.update(username, password);
     }
 
@@ -134,7 +135,7 @@ public abstract class MobilbankenBase extends Bank {
              * 3: Account number    9570 012.345.678-9 SEK
              * 4: ?                 xxxxxxxxxxx
              * 5: Amount            ?
-             *   
+             *
              */
             accounts.add(new Account(
                     Html.fromHtml(matcher.group(2)).toString().trim(),
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index 6f306dd..2696a71 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -79,7 +79,7 @@ public class NordeaDK extends Bank {
     private String response;
 
     public NordeaDK(Context context) {
-        super(context);
+        super(context, R.drawable.logo_nordea_dk);
 
         super.TAG = TAG;
         super.NAME = NAME;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 9d0c10f..273a420 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -66,7 +66,7 @@ public class Nordnet extends Bank {
     private String response = null;
 
     public Nordnet(Context context) {
-        super(context);
+        super(context, R.drawable.logo_nordnet);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 8a5d97f..48ed6fb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -67,7 +67,7 @@ public class Nordnetdirekt extends Bank {
     private String response = null;
 
     public Nordnetdirekt(Context context) {
-        super(context);
+        super(context, R.drawable.logo_nordnetdirekt);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index f49cc23..25d197b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -76,7 +76,7 @@ public class OKQ8 extends Bank {
     private String response = null;
 
     public OKQ8(Context context) {
-        super(context);
+        super(context, R.drawable.logo_okq8);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
index 043699f..656c8be 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class Opel extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.OPEL;
 
     public Opel(Context context) {
-        super(context, "opse", "0107");
+        super(context, "opse", "0107", R.drawable.logo_opel);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Opel extends SEBKortBase {
 
     public Opel(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "opse", "0107");
+        super(username, password, context, "opse", "0107", R.drawable.logo_opel);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 18357a9..2dcb5f0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -72,7 +72,7 @@ public class Ostgotatrafiken extends Bank {
     private String response = null;
 
     public Ostgotatrafiken(Context context) {
-        super(context);
+        super(context, R.drawable.logo_ogt);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 1d07c1e..2593ca4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -63,7 +63,7 @@ public class Osuuspankki extends Bank {
     private String response = null;
 
     public Osuuspankki(Context context) {
-        super(context);
+        super(context, R.drawable.logo_osuuspankki);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 183816a..76a1c8c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -64,7 +64,7 @@ public class PayPal extends Bank {
     private String response = null;
 
     public PayPal(Context context) {
-        super(context);
+        super(context, R.drawable.logo_paypal);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index 249773d..defe12d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -66,7 +66,7 @@ public class Payson extends Bank {
     private JSONObject userInfo = null;
 
     public Payson(Context context) {
-        super(context);
+        super(context, R.drawable.logo_payson);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index 96df24c..6072046 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -64,7 +64,7 @@ public class PlusGirot extends Bank {
     private String response = null;
 
     public PlusGirot(Context context) {
-        super(context);
+        super(context, R.drawable.logo_plusgirot);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
index 2ee4315..20c2a38 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -40,7 +41,7 @@ public class Preem extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.PREEM;
 
     public Preem(Context context) {
-        super(context);
+        super(context, R.drawable.logo_preem);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -56,4 +57,4 @@ public class Preem extends AbsIkanoPartner {
     }
 
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
index 0a22cd4..248dfd1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class Quintessentially extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.QUINTESSENTIALLY;
 
     public Quintessentially(Context context) {
-        super(context, "quse", "0119");
+        super(context, "quse", "0119", R.drawable.logo_quintessentially);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Quintessentially extends SEBKortBase {
 
     public Quintessentially(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "quse", "0119");
+        super(username, password, context, "quse", "0119", R.drawable.logo_quintessentially);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index a233fb9..116a1f8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -55,7 +55,7 @@ public class ResursBank extends Bank {
     private String response = null;
 
     public ResursBank(Context context) {
-        super(context);
+        super(context, R.drawable.logo_resursbank);
         super.TAG = "ResursBank";
         super.NAME = "Resurs Bank";
         super.NAME_SHORT = "resursbank";
@@ -111,7 +111,7 @@ public class ResursBank extends Bank {
              * 3: Utnyttjad kredit      0,00 kr
              * 4: Reserverat  belopp    0,00 kr
              * 5: Kvar att utnyttja     0,00 kr
-             * 
+             *
              */
             String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll(
                     "[^0-9]*", "");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
index df9615f..6efece8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class SJPrio extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.SJPRIO;
 
     public SJPrio(Context context) {
-        super(context, "sjse", "0104");
+        super(context, "sjse", "0104", R.drawable.logo_sj_prio);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,6 +47,6 @@ public class SJPrio extends SEBKortBase {
 
     public SJPrio(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sjse", "0104");
+        super(username, password, context, "sjse", "0104", R.drawable.logo_sj_prio);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
index 6ba7fcc..1583c88 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class Saab extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.SAAB;
 
     public Saab(Context context) {
-        super(context, "sbse", "0106");
+        super(context, "sbse", "0106", R.drawable.logo_saab);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Saab extends SEBKortBase {
 
     public Saab(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "sbse", "0106");
+        super(username, password, context, "sbse", "0106", R.drawable.logo_saab);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
index 42435c0..494512a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -39,7 +40,7 @@ public class Seat extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.SEAT;
 
     public Seat(Context context) {
-        super(context);
+        super(context, R.drawable.logo_seat);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 311bf85..f69147d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -67,7 +67,7 @@ public class SevenDay extends Bank {
     private String response = null;
 
     public SevenDay(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sevenday);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
index 86d859f..8f96fc8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -38,7 +39,7 @@ public class Shell extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.SHELL;
 
     public Shell(Context context) {
-        super(context);
+        super(context, R.drawable.logo_shell);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 531c748..bad3a38 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -75,7 +75,7 @@ public class Skandiabanken extends Bank {
     private int customerId = 0;
 
     public Skandiabanken(Context context) {
-        super(context);
+        super(context, R.drawable.logo_skandiabanken);
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
index 97cdab9..b7107e6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -39,7 +40,7 @@ public class Skoda extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.SKODA;
 
     public Skoda(Context context) {
-        super(context);
+        super(context, R.drawable.logo_skoda);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index 17bee6d..d99b667 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -38,7 +39,7 @@ public class SparbankenOresund extends MobilbankenBase {
     private static final int BANKTYPE_ID = Bank.SPARBANKEN_ORESUND;
 
     public SparbankenOresund(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sparbanken_oresund);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index 532662d..57ca163 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -38,7 +39,7 @@ public class SparbankenSyd extends MobilbankenBase {
     private static final int BANKTYPE_ID = Bank.SPARBANKEN_SYD;
 
     public SparbankenSyd(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sparbanken_syd);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
index e7dbcbd..53e4c7c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -37,7 +38,7 @@ public class Statoil extends SEBKortBase {
     private static final int BANKTYPE_ID = IBankTypes.STATOIL;
 
     public Statoil(Context context) {
-        super(context, "stse", "0122");
+        super(context, "stse", "0122", R.drawable.logo_statoil);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Statoil extends SEBKortBase {
 
     public Statoil(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "stse", "0122");
+        super(username, password, context, "stse", "0122", R.drawable.logo_statoil);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 0bc81e0..90c2fb3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -71,7 +71,7 @@ public class Steam extends Bank {
     private String response = null;
 
     public Steam(Context context) {
-        super(context);
+        super(context, R.drawable.logo_steam);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -124,7 +124,7 @@ public class Steam extends Bank {
              * Capture groups:
              * GROUP                EXAMPLE DATA
              * 1: Amount            0,--&#8364;
-             * 
+             *
              */
             String amount = Html.fromHtml(matcher.group(1)).toString().trim().replace("--", "00");
             Account account = new Account("Wallet", Helpers.parseBalance(amount), "1");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 2c6e7e1..3ae58a2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -61,7 +61,7 @@ public class SveaDirekt extends Bank {
     private String response;
 
     public SveaDirekt(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sveadirekt);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index e067df0..db37df5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -62,7 +62,7 @@ public class SvenskaSpel extends Bank {
     private String response = "";
 
     public SvenskaSpel(Context context) {
-        super(context);
+        super(context, R.drawable.logo_svenskaspel);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index 7959116..566e183 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -70,7 +70,7 @@ public class TestBank extends Bank {
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     public TestBank(Context context) {
-        super(context);
+        super(context, R.drawable.logo_bankdroid);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -179,9 +179,4 @@ public class TestBank extends Bank {
         }
         account.setTransactions(transactions);
     }
-
-    @Override
-    public int getImageResource() {
-        return res.getIdentifier("icon_large", "drawable", context.getPackageName());
-    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index a517b95..734e1d8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -71,7 +71,7 @@ public class TicketRikskortet extends Bank {
     private String response = null;
 
     public TicketRikskortet(Context context) {
-        super(context);
+        super(context, R.drawable.logo_rikskortet);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -149,7 +149,7 @@ public class TicketRikskortet extends Bank {
              * Capture groups:
              * GROUP                EXAMPLE DATA
              * 1: Balance           590,22 kr
-             * 
+             *
              */
             BigDecimal b = Helpers.parseBalance(matcher.group(1));
             accounts.add(new Account("Saldo", b, "1"));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index b65a41f..ddb1140 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -69,7 +69,7 @@ public class TrustBuddy extends Bank {
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     public TrustBuddy(Context context) {
-        super(context);
+        super(context, R.drawable.logo_trustbuddy);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 7012a16..34c099c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -65,7 +65,7 @@ public class Vasttrafik extends Bank {
     private String response = null;
 
     public Vasttrafik(Context context) {
-        super(context);
+        super(context, R.drawable.logo_vasttrafik);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index de78bc0..bdd4b96 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -83,7 +83,7 @@ public class Villabanken extends Bank {
     private String accountResponse = null;
 
     public Villabanken(Context context) {
-        super(context);
+        super(context, R.drawable.logo_villabanken);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
index ca8277d..dc5b5e2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -19,6 +19,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -39,7 +40,7 @@ public class Volkswagen extends AbsIkanoPartner {
     private static final int BANKTYPE_ID = Bank.VOLKSWAGEN;
 
     public Volkswagen(Context context) {
-        super(context);
+        super(context, R.drawable.logo_volkswagen);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 146d421..8f8e359 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -78,7 +78,7 @@ public class Volvofinans extends Bank {
     private HashMap<String, String> mAccountUrlMappings = new HashMap<String, String>();
 
     public Volvofinans(Context context) {
-        super(context);
+        super(context, R.drawable.logo_volvofinans);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
index 7243461..8c28a1f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import android.content.Context;
 
@@ -37,7 +38,7 @@ public class Wallet extends SEBKortBase {
     private static final int BANKTYPE_ID = Bank.WALLET;
 
     public Wallet(Context context) {
-        super(context, "wase", "0121");
+        super(context, "wase", "0121", R.drawable.logo_wallet);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -46,7 +47,7 @@ public class Wallet extends SEBKortBase {
 
     public Wallet(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-        super(username, password, context, "wase", "0121");
+        super(username, password, context, "wase", "0121", R.drawable.logo_wallet);
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index d495898..1c1c9db 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -70,7 +70,7 @@ public class Zidisha extends Bank {
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     public Zidisha(Context context) {
-        super(context);
+        super(context, R.drawable.logo_zidisha);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index b85e747..717e0d6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -55,7 +55,7 @@ public class Avanza extends Bank {
     private static final String API_URL = "https://iphone.avanza.se/iphone-ws/";
 
     public Avanza(Context context) {
-        super(context);
+        super(context, R.drawable.logo_avanza);
         TAG = "Avanza";
         NAME = "Avanza";
         NAME_SHORT = "avanza";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index c689501..4d0be3f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -59,7 +59,7 @@ public class Bitcoin extends Bank {
     private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0.00000000 ");
 
     public Bitcoin(Context context) {
-        super(context);
+        super(context, R.drawable.logo_bitcoin);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 7d18694..26acca0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid.banking.banks.coop;
 
-import android.content.Context;
-import android.text.TextUtils;
-
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
@@ -40,6 +37,9 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.TextUtils;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
@@ -85,7 +85,7 @@ public class Coop extends Bank {
     private String response;
 
     public Coop(Context context) {
-        super(context);
+        super(context, R.drawable.logo_coop);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index 963cd92..ffc18a5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -65,7 +65,7 @@ public class ICA extends Bank {
     private Map<String, String> mHeaders = new HashMap<String, String>();
 
     public ICA(Context context) {
-        super(context);
+        super(context, R.drawable.logo_ica);
         TAG = "ICA";
         NAME = "ICA";
         NAME_SHORT = "ica";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 36427e0..1703d6f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -70,7 +70,7 @@ public class ICABanken extends Bank {
     private static final String API_VERSION = "1.0";
 
     public ICABanken(Context context) {
-        super(context);
+        super(context, R.drawable.logo_icabanken);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 211759c..fe3e5dc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -81,7 +81,7 @@ public class Lansforsakringar extends Bank {
     private HashMap<String, String> mAccountLedger = new HashMap<>();
 
     public Lansforsakringar(Context context) {
-        super(context);
+        super(context, R.drawable.logo_lansforsakringar);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index d2b12d2..3e7912f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -210,7 +210,7 @@ public class Nordea extends Bank {
     private int currentPageType;
 
     public Nordea(Context context) {
-        super(context);
+        super(context, R.drawable.logo_nordea);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 3d3ecbf..38dfa3f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -56,7 +56,7 @@ public class Rikslunchen extends Bank {
     private String myResponse = "";
 
     public Rikslunchen(Context context) {
-        super(context);
+        super(context, R.drawable.logo_rikslunchen);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index d263d83..4047e5f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -84,7 +84,7 @@ public class SEB extends Bank {
     private ObjectMapper mObjectMapper;
 
     public SEB(Context context) {
-        super(context);
+        super(context, R.drawable.logo_seb);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 7bcf933..7e5486d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -38,6 +38,7 @@ import org.apache.http.NameValuePair;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.support.annotation.DrawableRes;
 import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
@@ -80,13 +81,13 @@ public abstract class SEBKortBase extends Bank {
     private Map<Account, String> mBillingUnitIds = new HashMap<Account, String>();
 
 
-    public SEBKortBase(Context context, String providerPart, String prodgroup) {
-        this(context, providerPart, prodgroup, "secure.sebkort.com", new int[]{R.raw.cert_sebkort});
+    public SEBKortBase(Context context, String providerPart, String prodgroup, @DrawableRes int logoResource) {
+        this(context, providerPart, prodgroup, "secure.sebkort.com", new int[]{R.raw.cert_sebkort}, logoResource);
     }
 
     public SEBKortBase(Context context, String providerPart, String prodgroup, String apiBase,
-            int[] certificates) {
-        super(context);
+            int[] certificates, @DrawableRes int logoResource) {
+        super(context, logoResource);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
@@ -103,16 +104,16 @@ public abstract class SEBKortBase extends Bank {
     }
 
     public SEBKortBase(String username, String password, Context context, String url,
-            String prodgroup)
+            String prodgroup, @DrawableRes int logoResource)
             throws BankException, LoginException, BankChoiceException, IOException {
-        this(context, url, prodgroup);
+        this(context, url, prodgroup, logoResource);
         this.update(username, password);
     }
 
     public SEBKortBase(String username, String password, Context context, String url,
-            String prodgroup, String apiBase, int[] certificates)
+            String prodgroup, String apiBase, int[] certificates, @DrawableRes int logoResource)
             throws BankException, LoginException, BankChoiceException, IOException {
-        this(context, url, prodgroup, apiBase, certificates);
+        this(context, url, prodgroup, apiBase, certificates, logoResource);
         this.update(username, password);
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 4dfa04e..d856ad0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -31,6 +31,7 @@ import org.apache.http.entity.StringEntity;
 import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
+import android.support.annotation.DrawableRes;
 import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
@@ -66,8 +67,8 @@ public abstract class AbstractSwedbank extends Bank {
 
     private Map<String, String> mIdMap = new HashMap<String, String>();
 
-    public AbstractSwedbank(Context context) {
-        super(context);
+    public AbstractSwedbank(Context context, @DrawableRes int logoResource) {
+        super(context, logoResource);
         SimpleModule module = new SimpleModule();
         module.addDeserializer(BigDecimal.class, new BalanceDeserializer());
         mObjectMapper.registerModule(module);
@@ -77,9 +78,9 @@ public abstract class AbstractSwedbank extends Bank {
         super.WEB_VIEW_ENABLED = WEB_VIEW_ENABLED;
     }
 
-    public AbstractSwedbank(String username, String password, Context context) throws BankException,
+    public AbstractSwedbank(String username, String password, Context context, @DrawableRes int logoResource) throws BankException,
             LoginException, BankChoiceException, IOException {
-        this(context);
+        this(context, logoResource);
         this.update(username, password);
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
index 155c399..8a324fc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -22,7 +23,7 @@ public class Sparbankerna extends AbstractSwedbank {
     private static final String APP_ID = "qdorTi1mqZ09Zcyc";
 
     public Sparbankerna(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sparbankerna);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
index 17818fc..dff1ba8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -22,7 +23,7 @@ public class SparbankernaCorporate extends AbstractSwedbank {
     private static final String APP_ID = "qdorTi1mqZ09Zcyc";
 
     public SparbankernaCorporate(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sparbankerna);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -40,10 +41,4 @@ public class SparbankernaCorporate extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
-
-    @Override
-    public int getImageResource() {
-        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable",
-                context.getPackageName());
-    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
index 55f89ee..943921a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -22,7 +23,7 @@ public class SparbankernaYouth extends AbstractSwedbank {
     private static final String APP_ID = "QtDHyRnJvEuET2vU";
 
     public SparbankernaYouth(Context context) {
-        super(context);
+        super(context, R.drawable.logo_sparbankerna);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -40,10 +41,4 @@ public class SparbankernaYouth extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
-
-    @Override
-    public int getImageResource() {
-        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable",
-                context.getPackageName());
-    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
index dcaf3bc..ac549ee 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -22,7 +23,7 @@ public class Swedbank extends AbstractSwedbank {
     private static final String APP_ID = "vgmYRMelBJ0Yzujs";
 
     public Swedbank(Context context) {
-        super(context);
+        super(context, R.drawable.logo_swedbank);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
index 1a8fe17..99d8ccb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -22,7 +23,7 @@ public class SwedbankCorporate extends AbstractSwedbank {
     private static final String APP_ID = "Our91qzclXdNmpdE";
 
     public SwedbankCorporate(Context context) {
-        super(context);
+        super(context, R.drawable.logo_swedbank);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -40,10 +41,4 @@ public class SwedbankCorporate extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
-
-    @Override
-    public int getImageResource() {
-        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable",
-                context.getPackageName());
-    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
index 158f77e..07b0172 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
@@ -22,7 +23,7 @@ public class SwedbankYouth extends AbstractSwedbank {
     private static final String APP_ID = "19AaEzp0jQJDt3vO";
 
     public SwedbankYouth(Context context) {
-        super(context);
+        super(context, R.drawable.logo_swedbank);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -40,10 +41,4 @@ public class SwedbankYouth extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
-
-    @Override
-    public int getImageResource() {
-        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable",
-                context.getPackageName());
-    }
 }
diff --git app/src/main/res/drawable-xxhdpi/logo_bitcoin.png bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_bitcoin.png
similarity index 100%
rename from app/src/main/res/drawable-xxhdpi/logo_bitcoin.png
rename to bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_bitcoin.png
diff --git app/src/main/res/drawable-xxhdpi/logo_supremecard.png bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_supremecard.png
similarity index 100%
rename from app/src/main/res/drawable-xxhdpi/logo_supremecard.png
rename to bankdroid-legacy/src/main/res/drawable-xxhdpi/logo_supremecard.png
diff --git app/src/main/res/drawable/logo_akeliusinvest.png bankdroid-legacy/src/main/res/drawable/logo_akeliusinvest.png
similarity index 100%
rename from app/src/main/res/drawable/logo_akeliusinvest.png
rename to bankdroid-legacy/src/main/res/drawable/logo_akeliusinvest.png
diff --git app/src/main/res/drawable/logo_akeliusspar.png bankdroid-legacy/src/main/res/drawable/logo_akeliusspar.png
similarity index 100%
rename from app/src/main/res/drawable/logo_akeliusspar.png
rename to bankdroid-legacy/src/main/res/drawable/logo_akeliusspar.png
diff --git app/src/main/res/drawable/logo_americanexpress.png bankdroid-legacy/src/main/res/drawable/logo_americanexpress.png
similarity index 100%
rename from app/src/main/res/drawable/logo_americanexpress.png
rename to bankdroid-legacy/src/main/res/drawable/logo_americanexpress.png
diff --git app/src/main/res/drawable/logo_appeakpoker.png bankdroid-legacy/src/main/res/drawable/logo_appeakpoker.png
similarity index 100%
rename from app/src/main/res/drawable/logo_appeakpoker.png
rename to bankdroid-legacy/src/main/res/drawable/logo_appeakpoker.png
diff --git app/src/main/res/drawable/logo_audi.png bankdroid-legacy/src/main/res/drawable/logo_audi.png
similarity index 100%
rename from app/src/main/res/drawable/logo_audi.png
rename to bankdroid-legacy/src/main/res/drawable/logo_audi.png
diff --git app/src/main/res/drawable/logo_avanza.png bankdroid-legacy/src/main/res/drawable/logo_avanza.png
similarity index 100%
rename from app/src/main/res/drawable/logo_avanza.png
rename to bankdroid-legacy/src/main/res/drawable/logo_avanza.png
diff --git app/src/main/res/drawable/logo_avanzamini.png bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png
similarity index 100%
rename from app/src/main/res/drawable/logo_avanzamini.png
rename to bankdroid-legacy/src/main/res/drawable/logo_avanzamini.png
diff --git bankdroid-legacy/src/main/res/drawable/logo_bankdroid.png bankdroid-legacy/src/main/res/drawable/logo_bankdroid.png
new file mode 100644
index 0000000..a6bafd4
Binary files /dev/null and bankdroid-legacy/src/main/res/drawable/logo_bankdroid.png differ
diff --git app/src/main/res/drawable/logo_betterglobe.png bankdroid-legacy/src/main/res/drawable/logo_betterglobe.png
similarity index 100%
rename from app/src/main/res/drawable/logo_betterglobe.png
rename to bankdroid-legacy/src/main/res/drawable/logo_betterglobe.png
diff --git app/src/main/res/drawable/logo_bioklubben.png bankdroid-legacy/src/main/res/drawable/logo_bioklubben.png
similarity index 100%
rename from app/src/main/res/drawable/logo_bioklubben.png
rename to bankdroid-legacy/src/main/res/drawable/logo_bioklubben.png
diff --git app/src/main/res/drawable/logo_blekingetrafiken.png bankdroid-legacy/src/main/res/drawable/logo_blekingetrafiken.png
similarity index 100%
rename from app/src/main/res/drawable/logo_blekingetrafiken.png
rename to bankdroid-legacy/src/main/res/drawable/logo_blekingetrafiken.png
diff --git app/src/main/res/drawable/logo_bredband2voip.png bankdroid-legacy/src/main/res/drawable/logo_bredband2voip.png
similarity index 100%
rename from app/src/main/res/drawable/logo_bredband2voip.png
rename to bankdroid-legacy/src/main/res/drawable/logo_bredband2voip.png
diff --git app/src/main/res/drawable/logo_brummer_kf.png bankdroid-legacy/src/main/res/drawable/logo_brummer_kf.png
similarity index 100%
rename from app/src/main/res/drawable/logo_brummer_kf.png
rename to bankdroid-legacy/src/main/res/drawable/logo_brummer_kf.png
diff --git app/src/main/res/drawable/logo_chalmrest.png bankdroid-legacy/src/main/res/drawable/logo_chalmrest.png
similarity index 100%
rename from app/src/main/res/drawable/logo_chalmrest.png
rename to bankdroid-legacy/src/main/res/drawable/logo_chalmrest.png
diff --git app/src/main/res/drawable/logo_chevrolet.png bankdroid-legacy/src/main/res/drawable/logo_chevrolet.png
similarity index 100%
rename from app/src/main/res/drawable/logo_chevrolet.png
rename to bankdroid-legacy/src/main/res/drawable/logo_chevrolet.png
diff --git app/src/main/res/drawable/logo_coop.png bankdroid-legacy/src/main/res/drawable/logo_coop.png
similarity index 100%
rename from app/src/main/res/drawable/logo_coop.png
rename to bankdroid-legacy/src/main/res/drawable/logo_coop.png
diff --git app/src/main/res/drawable/logo_csn.png bankdroid-legacy/src/main/res/drawable/logo_csn.png
similarity index 100%
rename from app/src/main/res/drawable/logo_csn.png
rename to bankdroid-legacy/src/main/res/drawable/logo_csn.png
diff --git app/src/main/res/drawable/logo_danskebank.png bankdroid-legacy/src/main/res/drawable/logo_danskebank.png
similarity index 100%
rename from app/src/main/res/drawable/logo_danskebank.png
rename to bankdroid-legacy/src/main/res/drawable/logo_danskebank.png
diff --git app/src/main/res/drawable/logo_dinersclub.png bankdroid-legacy/src/main/res/drawable/logo_dinersclub.png
similarity index 100%
rename from app/src/main/res/drawable/logo_dinersclub.png
rename to bankdroid-legacy/src/main/res/drawable/logo_dinersclub.png
diff --git app/src/main/res/drawable/logo_djurgarden.png bankdroid-legacy/src/main/res/drawable/logo_djurgarden.png
similarity index 100%
rename from app/src/main/res/drawable/logo_djurgarden.png
rename to bankdroid-legacy/src/main/res/drawable/logo_djurgarden.png
diff --git app/src/main/res/drawable/logo_easycard.png bankdroid-legacy/src/main/res/drawable/logo_easycard.png
similarity index 100%
rename from app/src/main/res/drawable/logo_easycard.png
rename to bankdroid-legacy/src/main/res/drawable/logo_easycard.png
diff --git app/src/main/res/drawable/logo_ebmaster.png bankdroid-legacy/src/main/res/drawable/logo_ebmaster.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ebmaster.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ebmaster.png
diff --git app/src/main/res/drawable/logo_ebmaster_dk.png bankdroid-legacy/src/main/res/drawable/logo_ebmaster_dk.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ebmaster_dk.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ebmaster_dk.png
diff --git app/src/main/res/drawable/logo_ebmaster_no.png bankdroid-legacy/src/main/res/drawable/logo_ebmaster_no.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ebmaster_no.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ebmaster_no.png
diff --git app/src/main/res/drawable/logo_espressohouse.png bankdroid-legacy/src/main/res/drawable/logo_espressohouse.png
similarity index 100%
rename from app/src/main/res/drawable/logo_espressohouse.png
rename to bankdroid-legacy/src/main/res/drawable/logo_espressohouse.png
diff --git app/src/main/res/drawable/logo_eurocard.png bankdroid-legacy/src/main/res/drawable/logo_eurocard.png
similarity index 100%
rename from app/src/main/res/drawable/logo_eurocard.png
rename to bankdroid-legacy/src/main/res/drawable/logo_eurocard.png
diff --git app/src/main/res/drawable/logo_everydaycard.png bankdroid-legacy/src/main/res/drawable/logo_everydaycard.png
similarity index 100%
rename from app/src/main/res/drawable/logo_everydaycard.png
rename to bankdroid-legacy/src/main/res/drawable/logo_everydaycard.png
diff --git app/src/main/res/drawable/logo_firstcard.png bankdroid-legacy/src/main/res/drawable/logo_firstcard.png
similarity index 100%
rename from app/src/main/res/drawable/logo_firstcard.png
rename to bankdroid-legacy/src/main/res/drawable/logo_firstcard.png
diff --git app/src/main/res/drawable/logo_forex.png bankdroid-legacy/src/main/res/drawable/logo_forex.png
similarity index 100%
rename from app/src/main/res/drawable/logo_forex.png
rename to bankdroid-legacy/src/main/res/drawable/logo_forex.png
diff --git app/src/main/res/drawable/logo_handelsbanken.png bankdroid-legacy/src/main/res/drawable/logo_handelsbanken.png
similarity index 100%
rename from app/src/main/res/drawable/logo_handelsbanken.png
rename to bankdroid-legacy/src/main/res/drawable/logo_handelsbanken.png
diff --git app/src/main/res/drawable/logo_hemkop.png bankdroid-legacy/src/main/res/drawable/logo_hemkop.png
similarity index 100%
rename from app/src/main/res/drawable/logo_hemkop.png
rename to bankdroid-legacy/src/main/res/drawable/logo_hemkop.png
diff --git app/src/main/res/drawable/logo_hors.png bankdroid-legacy/src/main/res/drawable/logo_hors.png
similarity index 100%
rename from app/src/main/res/drawable/logo_hors.png
rename to bankdroid-legacy/src/main/res/drawable/logo_hors.png
diff --git app/src/main/res/drawable/logo_ica.png bankdroid-legacy/src/main/res/drawable/logo_ica.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ica.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ica.png
diff --git app/src/main/res/drawable/logo_icabanken.png bankdroid-legacy/src/main/res/drawable/logo_icabanken.png
similarity index 100%
rename from app/src/main/res/drawable/logo_icabanken.png
rename to bankdroid-legacy/src/main/res/drawable/logo_icabanken.png
diff --git app/src/main/res/drawable/logo_ikanobank.png bankdroid-legacy/src/main/res/drawable/logo_ikanobank.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ikanobank.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ikanobank.png
diff --git app/src/main/res/drawable/logo_ikea.png bankdroid-legacy/src/main/res/drawable/logo_ikea.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ikea.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ikea.png
diff --git app/src/main/res/drawable/logo_jojo.png bankdroid-legacy/src/main/res/drawable/logo_jojo.png
similarity index 100%
rename from app/src/main/res/drawable/logo_jojo.png
rename to bankdroid-legacy/src/main/res/drawable/logo_jojo.png
diff --git app/src/main/res/drawable/logo_lansforsakringar.png bankdroid-legacy/src/main/res/drawable/logo_lansforsakringar.png
similarity index 100%
rename from app/src/main/res/drawable/logo_lansforsakringar.png
rename to bankdroid-legacy/src/main/res/drawable/logo_lansforsakringar.png
diff --git app/src/main/res/drawable/logo_marginalen.png bankdroid-legacy/src/main/res/drawable/logo_marginalen.png
similarity index 100%
rename from app/src/main/res/drawable/logo_marginalen.png
rename to bankdroid-legacy/src/main/res/drawable/logo_marginalen.png
diff --git app/src/main/res/drawable/logo_mcdonalds.png bankdroid-legacy/src/main/res/drawable/logo_mcdonalds.png
similarity index 100%
rename from app/src/main/res/drawable/logo_mcdonalds.png
rename to bankdroid-legacy/src/main/res/drawable/logo_mcdonalds.png
diff --git app/src/main/res/drawable/logo_meniga.png bankdroid-legacy/src/main/res/drawable/logo_meniga.png
similarity index 100%
rename from app/src/main/res/drawable/logo_meniga.png
rename to bankdroid-legacy/src/main/res/drawable/logo_meniga.png
diff --git app/src/main/res/drawable/logo_minpension.png bankdroid-legacy/src/main/res/drawable/logo_minpension.png
similarity index 100%
rename from app/src/main/res/drawable/logo_minpension.png
rename to bankdroid-legacy/src/main/res/drawable/logo_minpension.png
diff --git app/src/main/res/drawable/logo_moneybookers.png bankdroid-legacy/src/main/res/drawable/logo_moneybookers.png
similarity index 100%
rename from app/src/main/res/drawable/logo_moneybookers.png
rename to bankdroid-legacy/src/main/res/drawable/logo_moneybookers.png
diff --git app/src/main/res/drawable/logo_nordea.png bankdroid-legacy/src/main/res/drawable/logo_nordea.png
similarity index 100%
rename from app/src/main/res/drawable/logo_nordea.png
rename to bankdroid-legacy/src/main/res/drawable/logo_nordea.png
diff --git app/src/main/res/drawable/logo_nordea_dk.png bankdroid-legacy/src/main/res/drawable/logo_nordea_dk.png
similarity index 100%
rename from app/src/main/res/drawable/logo_nordea_dk.png
rename to bankdroid-legacy/src/main/res/drawable/logo_nordea_dk.png
diff --git app/src/main/res/drawable/logo_nordnet.png bankdroid-legacy/src/main/res/drawable/logo_nordnet.png
similarity index 100%
rename from app/src/main/res/drawable/logo_nordnet.png
rename to bankdroid-legacy/src/main/res/drawable/logo_nordnet.png
diff --git app/src/main/res/drawable/logo_nordnetdirekt.png bankdroid-legacy/src/main/res/drawable/logo_nordnetdirekt.png
similarity index 100%
rename from app/src/main/res/drawable/logo_nordnetdirekt.png
rename to bankdroid-legacy/src/main/res/drawable/logo_nordnetdirekt.png
diff --git app/src/main/res/drawable/logo_ogt.png bankdroid-legacy/src/main/res/drawable/logo_ogt.png
similarity index 100%
rename from app/src/main/res/drawable/logo_ogt.png
rename to bankdroid-legacy/src/main/res/drawable/logo_ogt.png
diff --git app/src/main/res/drawable/logo_okq8.png bankdroid-legacy/src/main/res/drawable/logo_okq8.png
similarity index 100%
rename from app/src/main/res/drawable/logo_okq8.png
rename to bankdroid-legacy/src/main/res/drawable/logo_okq8.png
diff --git app/src/main/res/drawable/logo_opel.png bankdroid-legacy/src/main/res/drawable/logo_opel.png
similarity index 100%
rename from app/src/main/res/drawable/logo_opel.png
rename to bankdroid-legacy/src/main/res/drawable/logo_opel.png
diff --git app/src/main/res/drawable/logo_osuuspankki.png bankdroid-legacy/src/main/res/drawable/logo_osuuspankki.png
similarity index 100%
rename from app/src/main/res/drawable/logo_osuuspankki.png
rename to bankdroid-legacy/src/main/res/drawable/logo_osuuspankki.png
diff --git app/src/main/res/drawable/logo_paypal.png bankdroid-legacy/src/main/res/drawable/logo_paypal.png
similarity index 100%
rename from app/src/main/res/drawable/logo_paypal.png
rename to bankdroid-legacy/src/main/res/drawable/logo_paypal.png
diff --git app/src/main/res/drawable/logo_payson.png bankdroid-legacy/src/main/res/drawable/logo_payson.png
similarity index 100%
rename from app/src/main/res/drawable/logo_payson.png
rename to bankdroid-legacy/src/main/res/drawable/logo_payson.png
diff --git app/src/main/res/drawable/logo_plusgirot.png bankdroid-legacy/src/main/res/drawable/logo_plusgirot.png
similarity index 100%
rename from app/src/main/res/drawable/logo_plusgirot.png
rename to bankdroid-legacy/src/main/res/drawable/logo_plusgirot.png
diff --git app/src/main/res/drawable/logo_preem.png bankdroid-legacy/src/main/res/drawable/logo_preem.png
similarity index 100%
rename from app/src/main/res/drawable/logo_preem.png
rename to bankdroid-legacy/src/main/res/drawable/logo_preem.png
diff --git app/src/main/res/drawable/logo_quintessentially.png bankdroid-legacy/src/main/res/drawable/logo_quintessentially.png
similarity index 100%
rename from app/src/main/res/drawable/logo_quintessentially.png
rename to bankdroid-legacy/src/main/res/drawable/logo_quintessentially.png
diff --git app/src/main/res/drawable/logo_resursbank.png bankdroid-legacy/src/main/res/drawable/logo_resursbank.png
similarity index 100%
rename from app/src/main/res/drawable/logo_resursbank.png
rename to bankdroid-legacy/src/main/res/drawable/logo_resursbank.png
diff --git app/src/main/res/drawable/logo_rikskortet.png bankdroid-legacy/src/main/res/drawable/logo_rikskortet.png
similarity index 100%
rename from app/src/main/res/drawable/logo_rikskortet.png
rename to bankdroid-legacy/src/main/res/drawable/logo_rikskortet.png
diff --git app/src/main/res/drawable/logo_rikslunchen.png bankdroid-legacy/src/main/res/drawable/logo_rikslunchen.png
similarity index 100%
rename from app/src/main/res/drawable/logo_rikslunchen.png
rename to bankdroid-legacy/src/main/res/drawable/logo_rikslunchen.png
diff --git app/src/main/res/drawable/logo_saab.png bankdroid-legacy/src/main/res/drawable/logo_saab.png
similarity index 100%
rename from app/src/main/res/drawable/logo_saab.png
rename to bankdroid-legacy/src/main/res/drawable/logo_saab.png
diff --git app/src/main/res/drawable/logo_seat.png bankdroid-legacy/src/main/res/drawable/logo_seat.png
similarity index 100%
rename from app/src/main/res/drawable/logo_seat.png
rename to bankdroid-legacy/src/main/res/drawable/logo_seat.png
diff --git app/src/main/res/drawable/logo_seb.png bankdroid-legacy/src/main/res/drawable/logo_seb.png
similarity index 100%
rename from app/src/main/res/drawable/logo_seb.png
rename to bankdroid-legacy/src/main/res/drawable/logo_seb.png
diff --git app/src/main/res/drawable/logo_sevenday.png bankdroid-legacy/src/main/res/drawable/logo_sevenday.png
similarity index 100%
rename from app/src/main/res/drawable/logo_sevenday.png
rename to bankdroid-legacy/src/main/res/drawable/logo_sevenday.png
diff --git app/src/main/res/drawable/logo_shell.png bankdroid-legacy/src/main/res/drawable/logo_shell.png
similarity index 100%
rename from app/src/main/res/drawable/logo_shell.png
rename to bankdroid-legacy/src/main/res/drawable/logo_shell.png
diff --git app/src/main/res/drawable/logo_sj_prio.png bankdroid-legacy/src/main/res/drawable/logo_sj_prio.png
similarity index 100%
rename from app/src/main/res/drawable/logo_sj_prio.png
rename to bankdroid-legacy/src/main/res/drawable/logo_sj_prio.png
diff --git app/src/main/res/drawable/logo_skandiabanken.png bankdroid-legacy/src/main/res/drawable/logo_skandiabanken.png
similarity index 100%
rename from app/src/main/res/drawable/logo_skandiabanken.png
rename to bankdroid-legacy/src/main/res/drawable/logo_skandiabanken.png
diff --git app/src/main/res/drawable/logo_skoda.png bankdroid-legacy/src/main/res/drawable/logo_skoda.png
similarity index 100%
rename from app/src/main/res/drawable/logo_skoda.png
rename to bankdroid-legacy/src/main/res/drawable/logo_skoda.png
diff --git app/src/main/res/drawable/logo_sparbanken_oresund.png bankdroid-legacy/src/main/res/drawable/logo_sparbanken_oresund.png
similarity index 100%
rename from app/src/main/res/drawable/logo_sparbanken_oresund.png
rename to bankdroid-legacy/src/main/res/drawable/logo_sparbanken_oresund.png
diff --git app/src/main/res/drawable/logo_sparbanken_syd.png bankdroid-legacy/src/main/res/drawable/logo_sparbanken_syd.png
similarity index 100%
rename from app/src/main/res/drawable/logo_sparbanken_syd.png
rename to bankdroid-legacy/src/main/res/drawable/logo_sparbanken_syd.png
diff --git app/src/main/res/drawable/logo_sparbankerna.png bankdroid-legacy/src/main/res/drawable/logo_sparbankerna.png
similarity index 100%
rename from app/src/main/res/drawable/logo_sparbankerna.png
rename to bankdroid-legacy/src/main/res/drawable/logo_sparbankerna.png
diff --git app/src/main/res/drawable/logo_statoil.png bankdroid-legacy/src/main/res/drawable/logo_statoil.png
similarity index 100%
rename from app/src/main/res/drawable/logo_statoil.png
rename to bankdroid-legacy/src/main/res/drawable/logo_statoil.png
diff --git app/src/main/res/drawable/logo_steam.png bankdroid-legacy/src/main/res/drawable/logo_steam.png
similarity index 100%
rename from app/src/main/res/drawable/logo_steam.png
rename to bankdroid-legacy/src/main/res/drawable/logo_steam.png
diff --git app/src/main/res/drawable/logo_sveadirekt.png bankdroid-legacy/src/main/res/drawable/logo_sveadirekt.png
similarity index 100%
rename from app/src/main/res/drawable/logo_sveadirekt.png
rename to bankdroid-legacy/src/main/res/drawable/logo_sveadirekt.png
diff --git app/src/main/res/drawable/logo_svenskaspel.png bankdroid-legacy/src/main/res/drawable/logo_svenskaspel.png
similarity index 100%
rename from app/src/main/res/drawable/logo_svenskaspel.png
rename to bankdroid-legacy/src/main/res/drawable/logo_svenskaspel.png
diff --git app/src/main/res/drawable/logo_swedbank.png bankdroid-legacy/src/main/res/drawable/logo_swedbank.png
similarity index 100%
rename from app/src/main/res/drawable/logo_swedbank.png
rename to bankdroid-legacy/src/main/res/drawable/logo_swedbank.png
diff --git app/src/main/res/drawable/logo_trustbuddy.png bankdroid-legacy/src/main/res/drawable/logo_trustbuddy.png
similarity index 100%
rename from app/src/main/res/drawable/logo_trustbuddy.png
rename to bankdroid-legacy/src/main/res/drawable/logo_trustbuddy.png
diff --git app/src/main/res/drawable/logo_unknown_app.png bankdroid-legacy/src/main/res/drawable/logo_unknown_app.png
similarity index 100%
rename from app/src/main/res/drawable/logo_unknown_app.png
rename to bankdroid-legacy/src/main/res/drawable/logo_unknown_app.png
diff --git app/src/main/res/drawable/logo_vasttrafik.png bankdroid-legacy/src/main/res/drawable/logo_vasttrafik.png
similarity index 100%
rename from app/src/main/res/drawable/logo_vasttrafik.png
rename to bankdroid-legacy/src/main/res/drawable/logo_vasttrafik.png
diff --git app/src/main/res/drawable/logo_villabanken.png bankdroid-legacy/src/main/res/drawable/logo_villabanken.png
similarity index 100%
rename from app/src/main/res/drawable/logo_villabanken.png
rename to bankdroid-legacy/src/main/res/drawable/logo_villabanken.png
diff --git app/src/main/res/drawable/logo_volkswagen.png bankdroid-legacy/src/main/res/drawable/logo_volkswagen.png
similarity index 100%
rename from app/src/main/res/drawable/logo_volkswagen.png
rename to bankdroid-legacy/src/main/res/drawable/logo_volkswagen.png
diff --git app/src/main/res/drawable/logo_volvofinans.png bankdroid-legacy/src/main/res/drawable/logo_volvofinans.png
similarity index 100%
rename from app/src/main/res/drawable/logo_volvofinans.png
rename to bankdroid-legacy/src/main/res/drawable/logo_volvofinans.png
diff --git app/src/main/res/drawable/logo_wallet.png bankdroid-legacy/src/main/res/drawable/logo_wallet.png
similarity index 100%
rename from app/src/main/res/drawable/logo_wallet.png
rename to bankdroid-legacy/src/main/res/drawable/logo_wallet.png
diff --git app/src/main/res/drawable/logo_zidisha.png bankdroid-legacy/src/main/res/drawable/logo_zidisha.png
similarity index 100%
rename from app/src/main/res/drawable/logo_zidisha.png
rename to bankdroid-legacy/src/main/res/drawable/logo_zidisha.png

commit 5db78d869f99ed46855365fb731887037534dad1
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sat Oct 8 22:14:20 2016 +0200

    Fail build on Android Lint problems
    
    Fix one issue, disable lots of warnings to enable merging *something*
    at least.

diff --git app/build.gradle app/build.gradle
index 9043e6e..828dbab 100644
--- app/build.gradle
+++ app/build.gradle
@@ -54,10 +54,6 @@ android {
         exclude 'META-INF/NOTICE.txt'
     }
 
-    lintOptions {
-        disable 'InvalidPackage'
-    }
-
     buildTypes {
         release {
             minifyEnabled false
diff --git app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 6ec8059..45984f1 100644
--- app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -50,7 +50,8 @@ public class BankTransactionsProvider extends ContentProvider implements
 
     private static final String CONTENT_PROVIDER_API_KEY = "content_provider_api_key";
 
-    private final static String TAG = "BankTransactionsProvider";
+    // Tags can be at most 23 characters, note the slight abbreviation
+    private final static String TAG = "BankTransactionsProvdr";
 
     private final static int TRANSACTIONS = 0;
 
diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
index 293d793..d165d32 100644
--- config/quality/lint/lint.xml
+++ config/quality/lint/lint.xml
@@ -1,11 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <lint>
+    <!-- FIXME: This file should be empty and all violations fixed. Then we'll all hug. -->
+
     <issue id="AdapterViewChildren" severity="ignore" />
     <issue id="AllowBackup" severity="ignore" />
     <issue id="AlwaysShowAction" severity="ignore" />
+    <issue id="AppCompatResource" severity="ignore" />
+    <issue id="BatteryLife" severity="ignore" />
     <issue id="ButtonCase" severity="ignore" />
     <issue id="ButtonOrder" severity="ignore" />
     <issue id="ButtonStyle" severity="ignore" />
+    <issue id="ClickableViewAccessibility" severity="ignore" />
     <issue id="CommitPrefEdits" severity="ignore" />
     <issue id="CommitTransaction" severity="ignore" />
     <issue id="ContentDescription" severity="ignore" />
@@ -28,16 +33,20 @@
     <issue id="ExtraText" severity="ignore" />
     <issue id="ExtraTranslation" severity="ignore" />
     <issue id="FloatMath" severity="ignore" />
+    <issue id="GetInstance" severity="ignore" />
     <issue id="GifUsage" severity="ignore" />
+    <issue id="GoogleAppIndexingWarning" severity="ignore" />
+    <issue id="GradleDependency" severity="ignore" />
+    <issue id="GradleDynamicVersion" severity="ignore" />
     <issue id="GradleOverrides" severity="ignore" />
     <issue id="GrantAllUris" severity="ignore" />
     <issue id="GridLayout" severity="ignore" />
     <issue id="HandlerLeak" severity="ignore" />
     <issue id="HardcodedDebugMode" severity="ignore" />
     <issue id="HardcodedText" severity="ignore" />
+    <issue id="HardwareIds" severity="ignore" />
     <issue id="IconColors" severity="ignore" />
-    <issue id="IconDensities" severity="error" />
-    <issue id="IconDipSize" severity="error" />
+    <issue id="IconDensities" severity="ignore" />
     <issue id="IconDuplicates" severity="ignore" />
     <issue id="IconDuplicatesConfig" severity="ignore" />
     <issue id="IconExtension" severity="ignore" />
@@ -49,6 +58,7 @@
     <issue id="IconXmlAndPng" severity="ignore" />
     <issue id="IllegalResourceRef" severity="ignore" />
     <issue id="InOrMmUsage" severity="ignore" />
+    <issue id="InflateParams" severity="ignore" />
     <issue id="InconsistentArrays" severity="ignore" />
     <issue id="InconsistentLayout" severity="ignore" />
     <issue id="InefficientWeight" severity="ignore" />
@@ -88,7 +98,9 @@
     <issue id="Overdraw" severity="ignore" />
     <issue id="Override" severity="ignore" />
     <issue id="PackagedPrivateKey" severity="ignore" />
+    <issue id="ParcelClassLoader" severity="ignore" />
     <issue id="ParcelCreator" severity="ignore" />
+    <issue id="PluralsCandidate" severity="ignore" />
     <issue id="PrivateResource" severity="ignore" />
     <issue id="Proguard" severity="ignore" />
     <issue id="ProguardSplit" severity="ignore" />
@@ -99,6 +111,8 @@
     <issue id="RequiredSize" severity="ignore" />
     <issue id="ResAuto" severity="ignore" />
     <issue id="ResourceAsColor" severity="ignore" />
+    <issue id="RtlHardcoded" severity="ignore" />
+    <issue id="RtlSymmetry" severity="ignore" />
     <issue id="ScrollViewCount" severity="ignore" />
     <issue id="ScrollViewSize" severity="ignore" />
     <issue id="SdCardPath" severity="ignore" />
@@ -109,6 +123,7 @@
     <issue id="SimpleDateFormat" severity="ignore" />
     <issue id="SmallSp" severity="ignore" />
     <issue id="SpUsage" severity="ignore" />
+    <issue id="StaticFieldLeak" severity="ignore" />
     <issue id="StateListReachable" severity="ignore" />
     <issue id="StringFormatCount" severity="ignore" />
     <issue id="StringFormatInvalid" severity="ignore" />
@@ -130,8 +145,7 @@
     <issue id="UnknownId" severity="ignore" />
     <issue id="UnknownIdInLayout" severity="ignore" />
     <issue id="UnlocalizedSms" severity="ignore" />
-    <issue id="UnusedNamespace" severity="ignore" />
-    <issue id="UnusedQuantity" severity="ignore" />
+    <issue id="UnusedAttribute" severity="ignore" />
     <issue id="UnusedResources" severity="ignore" />
     <issue id="UseCheckPermission" severity="ignore" />
     <issue id="UseCompoundDrawables" severity="ignore" />
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 8290a15..bd0e0b1 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -21,9 +21,15 @@ checkstyle {
 
 android {
     lintOptions {
-        abortOnError false // TODO Set to true when project has been cleaned.
+        abortOnError true
+        warningsAsErrors true
+
+        // FIXME: This file contains *far* too many disabled checks. Somebody think of the children!
         lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
 
+        textOutput "stdout"
+        textReport true
+
         htmlReport true
         // optional path to report (default will be lint-results.html in the builddir)
         htmlOutput file("$project.buildDir/reports/lint/lint.html")

commit 703161c1fa6e8e41a502ecd24f5866ff55f2c3e7
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Oct 6 22:48:37 2016 +0200

    Enforce PMD rules on "./gradlew check"
    
    Since fixing everything at once isn't really possible I just removed
    all the rules, put in a much shorter list and fixed that.
    
    If more rules are deemed important, there are instructions in
    pmd-ruleset.xml on how to do that.

diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index f50a11d..25a008e 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -187,13 +187,9 @@ public class AutoRefreshService extends Service {
         }
     }
 
-    @Override
-    public void onCreate() {
-
-    }
-
     @Override
     public void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
         handleStart(intent, startId);
     }
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 2e6ec71..6b679e9 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -286,6 +286,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
         @Override
         public void onStart(Intent intent, int startId) {
+            super.onStart(intent, startId);
             handleStart(intent, startId);
         }
 
diff --git app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
index 0669e13..638e5ac 100644
--- app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
+++ app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
@@ -149,7 +149,6 @@ public class LiveViewService extends Service {
     }
 
     public void onDestroy() {
-        super.onDestroy();
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onDestroy.");
 
         // Unbind from LiveView service
@@ -159,6 +158,8 @@ public class LiveViewService extends Service {
 
         // No longer a running service
         alreadyRunning = false;
+
+        super.onDestroy();
     }
 
     public void onStart(Intent intent, int startId) {
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
index 59e3fbb..115304d 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
@@ -292,13 +292,13 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener
 
     @Override
     protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-
         outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
         if (mChosenPattern != null) {
             outState.putString(KEY_PATTERN_CHOICE,
                     LockPatternUtils.patternToString(mChosenPattern));
         }
+
+        super.onSaveInstanceState(outState);
     }
 
     /**
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
index 2341f03..6b17998 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
@@ -65,8 +65,8 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi
 
     @Override
     protected void onPause() {
-        super.onPause();
         stopAnimation(mAnimation);
+        super.onPause();
     }
 
     public void onClick(View v) {
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
index 75bf336..4e86626 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
@@ -172,15 +172,16 @@ public class ConfirmLockPattern extends Activity {
     protected void onSaveInstanceState(Bundle outState) {
         // deliberately not calling super since we are managing this in full
         outState.putInt(KEY_NUM_WRONG_ATTEMPTS, mNumWrongConfirmAttempts);
+        super.onSaveInstanceState(outState);
     }
 
     @Override
     protected void onPause() {
-        super.onPause();
-
         if (mCountdownTimer != null) {
             mCountdownTimer.cancel();
         }
+
+        super.onPause();
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
@@ -282,8 +283,8 @@ public class ConfirmLockPattern extends Activity {
 
     @Override
     public void finish() {
-        super.finish();
         Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
+        super.finish();
     }
 
     private enum Stage {
diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index 892ab08..caf5f2b 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -9,20 +9,24 @@
     <exclude-pattern>.*/R.java</exclude-pattern>
     <exclude-pattern>.*/gen/.*</exclude-pattern>
 
-    <rule ref="rulesets/java/android.xml"/>
-
-    <rule ref="rulesets/java/clone.xml" />
-    <rule ref="rulesets/java/finalizers.xml" />
-    <rule ref="rulesets/java/imports.xml" />
-    <rule ref="rulesets/java/logging-java.xml" />
-    <rule ref="rulesets/java/braces.xml" />
-    <rule ref="rulesets/java/strings.xml" />
-    <rule ref="rulesets/java/basic.xml" />
-    <rule ref="rulesets/java/naming.xml">
-        <exclude name="AbstractNaming" />
-        <exclude name="LongVariable" />
-        <exclude name="ShortMethodName" />
-        <exclude name="ShortVariable" />
-        <exclude name="VariableNamingConventions" />
+    <!--
+    FIXME: This file needs a lot more rules.
+
+    To add more, first decide on one from here:
+    https://github.com/pmd/pmd/tree/master/pmd-java/src/main/resources/rulesets/java
+
+    Then add it just like android.xml has been added (below).
+
+    Do "./gradlew check" to test your newly added rule. If there are violations, check
+    the console output or the HTML report and remedy them until the build passes.
+
+    If you can't / won't fix a specific violation, you can exclude rules like in the
+    logging-java.xml example below.
+    -->
+    <rule ref="rulesets/java/android.xml" />
+
+    <rule ref="rulesets/java/logging-java.xml">
+        <!-- FIXME: Re-enable this rule and fix all instances -->
+        <exclude name="AvoidPrintStackTrace" />
     </rule>
 </ruleset>
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 808a435..8290a15 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -56,7 +56,8 @@ task findbugs(type: FindBugs, dependsOn: 'compileDebugSources') {
 
 task pmd(type: Pmd) {
     ruleSetFiles = files("${project.rootDir}/config/quality/pmd/pmd-ruleset.xml")
-    ignoreFailures = true // TODO Set to false when project has been cleaned.
+    ignoreFailures = false
+    consoleOutput = true
     ruleSets = []
 
     source 'src'

commit 1a6e80d746eb3356d14070e6eae86ec782ebe99b
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Oct 6 23:53:00 2016 +0200

    Fail build on Checkstyle violations
    
    Some checks have been disabled, some have been commented out, some
    issues have been fixed.
    
    After this has been merged anybody can add the now-inactive rules back,
    but then of course at the cost of having to fix up violations.

diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index 3dadcd4..0b91faf 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -25,7 +25,10 @@ import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.util.Log;
 
-import static com.liato.bankdroid.db.Database.*;
+import static com.liato.bankdroid.db.Database.PROPERTY_CONNECTION_ID;
+import static com.liato.bankdroid.db.Database.PROPERTY_KEY;
+import static com.liato.bankdroid.db.Database.PROPERTY_TABLE_NAME;
+import static com.liato.bankdroid.db.Database.PROPERTY_VALUE;
 
 /**
  * @since 8 jan 2011
@@ -59,7 +62,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
             final int newVersion) {
         Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
                 + " to " + newVersion + ", which will destroy all old data");
-        // Version <= 1.7.2 
+        // Version <= 1.7.2
         if (oldVersion <= 9) {
             // Add an "extras" field to the bank and and "alias for" field to the account.
             db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " ADD " +
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
index 453a8d6..48128ce 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
@@ -608,8 +608,10 @@ public class LockPatternView extends View {
                                     bottom = startY;
                                 }
                             } else {
-                                left = right = startX;
-                                top = bottom = startY;
+                                left = startX;
+                                right = startX;
+                                top = startY;
+                                bottom = startY;
                             }
 
                             final float widthOffset = mSquareWidth / 2f;
@@ -900,7 +902,7 @@ public class LockPatternView extends View {
     /**
      * The call back interface for detecting patterns entered by the user.
      */
-    public static interface OnPatternListener {
+    public interface OnPatternListener {
 
         /**
          * A new pattern has begun.
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
index 75613e7..3bc7c6a 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -126,7 +126,7 @@ public class ColorPickerDialog
 
     public interface OnColorChangedListener {
 
-        public void onColorChanged(int color);
+        void onColorChanged(int color);
     }
 
 }
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
index 6e315e5..8ff79d3 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -898,7 +898,6 @@ public class ColorPickerView extends View {
             mSatShader = null;
             mHueShader = null;
             mAlphaShader = null;
-            ;
 
             requestLayout();
         }
@@ -950,6 +949,6 @@ public class ColorPickerView extends View {
 
     public interface OnColorChangedListener {
 
-        public void onColorChanged(int color);
+        void onColorChanged(int color);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index b8b3865..eaed6e6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -136,7 +136,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public boolean toggleHideAccounts() {
-        return hideAccounts = !hideAccounts;
+        hideAccounts = !hideAccounts;
+        return hideAccounts;
     }
 
     public boolean getHideAccounts() {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
index 2db1be0..3a73f3d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
@@ -5,10 +5,8 @@ import com.liato.bankdroid.api.configuration.FieldBuilder;
 import com.liato.bankdroid.api.configuration.FieldType;
 import com.liato.bankdroid.api.configuration.ProviderConfiguration;
 
-import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.ResourceBundle;
 
 public class BasicProviderConfiguration implements ProviderConfiguration {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index a60f4fd..88c2454 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -1,9 +1,5 @@
 package com.liato.bankdroid.banking;
 
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
@@ -57,13 +53,16 @@ import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
 import com.liato.bankdroid.banking.banks.coop.Coop;
 import com.liato.bankdroid.banking.banks.ica.ICA;
-import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
 import java.util.ArrayList;
 import java.util.List;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index e10434f..ed5609f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -145,7 +145,7 @@ public class AmericanExpress extends Bank {
              * 2: ID                    0
              * 3: Name                  SAS EuroBonus American Express&reg; Card
              * 4: Amount                1.111,11 kr
-             * 
+             *
              */
             accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString()
                     .replace("American Express", "Amex")
@@ -191,10 +191,11 @@ public class AmericanExpress extends Bank {
                 transactionDate = sdfFrom.parse(matcher.group(1).trim());
                 String strDate = sdfTo.format(transactionDate);
                 BigDecimal amount;
-                if (matcher.group(3).trim().equals("&nbsp;"))
+                if (matcher.group(3).trim().equals("&nbsp;")) {
                     amount = Helpers.parseBalance(matcher.group(4).trim()).negate();
-                else
+                } else {
                     amount = Helpers.parseBalance(matcher.group(3).trim());
+                }
 
                 transactions.add(new Transaction(strDate,
                         Html.fromHtml(matcher.group(2)).toString().trim(),
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index b930846..d879d5a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -148,7 +148,6 @@ public class BetterGlobe extends Bank {
             accounts.add(brutto);
             accounts.add(netto);
             balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-            ;
         }
 
         response = urlopen.open("http://betterglobe.com/mytrees.aspx");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index 3c7b5d6..9fafb1a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -36,6 +33,9 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -54,7 +54,6 @@ public class MinPension extends Bank {
         BANKTYPE_ID = IBankTypes.MINPENSION;
         INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
         INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD;
-        ;
         INPUT_HINT_USERNAME = res.getText(R.string.pno).toString();
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 84073e3..183816a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -166,8 +166,9 @@ public class PayPal extends Bank {
                     JSONObject a = accArr.getJSONObject(i);
                     String accountName = a.getString("currency");
                     String displayName = accountName;
-                    if (accountName.equals(this.getCurrency()))
+                    if (accountName.equals(this.getCurrency())) {
                         displayName = accountName + " (Primary)";
+                    }
                     Double amount = a.getJSONObject("available")
                             .getDouble("unformattedAmount");
                     Account account = new Account(displayName,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 9032561..531c748 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -251,8 +251,8 @@ public class Skandiabanken extends Bank {
         String test = Secure.getString(context.getContentResolver(),
                 Secure.ANDROID_ID);
 
-        if (test == null) // null for emulator
-        {
+        if (test == null) {
+            // null for emulator
             test = "0";
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 75fbe83..c689501 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -29,7 +29,6 @@ import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
-import android.text.TextUtils;
 
 import java.io.IOException;
 import java.math.BigDecimal;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
index a3e9212..1d9f236 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
@@ -24,7 +24,8 @@ public class CaptchaBreaker {
                     if (!numberpart) {
                         segment.start = x;
                     }
-                    numberpart = numberpartcol = true;
+                    numberpartcol = true;
+                    numberpart = true;
                     break;
                 }
             }
@@ -50,7 +51,7 @@ public class CaptchaBreaker {
 
     }
 
-    private final static String extractNumber(Bitmap bitmap) {
+    private static String extractNumber(Bitmap bitmap) {
         int width = bitmap.getWidth();
         for (int i = 0; i < NUMBERS.length; i++) {
             int matches = 0;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
index 1dfdaac..ec33c90 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
@@ -22,9 +22,9 @@ package com.liato.bankdroid.provider;
  */
 public interface IAccountTypes {
 
-    public final static int REGULAR = 1;
-    public final static int FUNDS = 2;
-    public final static int LOANS = 3;
-    public final static int CCARD = 4;
-    public final static int OTHER = 5;
-}
\ No newline at end of file
+    int REGULAR = 1;
+    int FUNDS = 2;
+    int LOANS = 3;
+    int CCARD = 4;
+    int OTHER = 5;
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index 0d3dd84..1a83021 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -15,8 +15,6 @@
  */
 package com.liato.bankdroid.provider;
 
-import java.math.BigDecimal;
-
 /**
  * <p>
  * This interface provides constants that can conveniently be used with the
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 1a7a018..cc75877 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -22,91 +22,91 @@ package com.liato.bankdroid.provider;
  */
 public interface IBankTypes {
 
-    public final static int TESTBANK = 0;
-    public final static int SWEDBANK = 1;
-    public final static int NORDEA = 2;
-    public final static int ICABANKEN = 3;
-    public final static int LANSFORSAKRINGAR = 4;
-    public final static int HANDELSBANKEN = 5;
-    public final static int COOP = 6;
-    public final static int ICA = 7;
-    public final static int STATOIL = 8;
-    public final static int AVANZA = 9;
-    public final static int VILLABANKEN = 10;
-    public final static int AVANZAMINI = 11;
-    public final static int OKQ8 = 12;
-    public final static int EUROCARD = 13;
-    public final static int FIRSTCARD = 14;
-    public final static int PAYPAL = 15;
-    public final static int PAYSON = 16;
-    public final static int JOJO = 17;
-    public final static int IKANOBANK = 18;
-    public final static int STEAM = 19;
-    public final static int DINERSCLUB = 20;
-    public final static int SASEUROBONUSMASTERCARD = 21;
-    public final static int RIKSLUNCHEN = 22;
-    public final static int HEMKOP = 23;
-    public final static int SEB = 24;
-    public final static int NORDNET = 25;
-    public final static int SEVENDAY = 26;
-    public final static int OSUUSPANKKI = 27;
-    public final static int VOLVOFINANS = 28;
-    public final static int CSN = 29;
-    public final static int RESURSBANK = 30;
-    public final static int AMERICANEXPRESS = 31;
-    public final static int MCDONALDS = 32;
-    public final static int SAAB = 33;
-    public final static int WALLET = 34;
-    public final static int CHEVROLET = 35;
-    public final static int SJPRIO = 36;
-    public final static int OPEL = 37;
-    public final static int DJURGARDEN = 38;
-    public final static int QUINTESSENTIALLY = 39;
-    public final static int PLUSGIROT = 40;
-    public final static int SHELL = 41;
-    public final static int VOLKSWAGEN = 42;
-    public final static int AUDI = 43;
-    public final static int PREEM = 44;
-    public final static int SEAT = 45;
-    public final static int SKODA = 46;
-    public final static int IKEA = 47;
-    public final static int SPARBANKEN_SYD = 48;
-    public final static int SPARBANKEN_ORESUND = 49;
-    public final static int NORDNETDIREKT = 50;
-    public final static int SKANDIABANKEN = 51;
-    public final static int DANSKEBANK = 52;
-    public final static int NORDEA_DK = 53;
-    public final static int VASTTRAFIK = 54;
-    public final static int EVERYDAYCARD = 55;
-    public static final int AKELIUSINVEST = 56;
-    public static final int MENIGA = 57;
-    public static final int RIKSKORTET = 58;
-    public static final int BIOKLUBBEN = 59;
-    public static final int CHALMREST = 60;
-    public static final int MARGINALEN = 61;
-    public static final int AKELIUSSPAR = 62;
-    public static final int SVENSKASPEL = 63;
-    public static final int EASYCARD = 64;
-    public static final int APPEAKPOKER = 65;
-    public static final int TRUSTBUDDY = 66;
-    public static final int BRUMMER_KF = 67;
-    public static final int ZIDISHA = 68;
-    public static final int BETTERGLOBE = 69;
-    public static final int FOREX = 70;
-    public final static int SASEUROBONUSMASTERCARD_NO = 71;
-    public final static int BITCOIN = 72;
-    public final static int SASEUROBONUSMASTERCARD_DK = 73;
-    public final static int SVEADIREKT = 74;
-    public final static int SUPREMECARD = 75;
-    public final static int SPARBANKERNA = 76;
-    public final static int BLEKINGETRAFIKEN = 77;
-    public final static int OSTGOTATRAFIKEN = 78;
-    public final static int BREDBAND2VOIP = 79;
-    public final static int ESPRESSOHOUSE = 80;
-    public final static int MINPENSION = 81;
-    public final static int SWEDBANK_YOUTH = 82;
-    public final static int SWEDBANK_CORPORATE = 83;
-    public final static int SPARBANKERNA_YOUTH = 84;
-    public final static int SPARBANKERNA_CORPORATE = 85;
-    public final static int HORS = 86;
+    int TESTBANK = 0;
+    int SWEDBANK = 1;
+    int NORDEA = 2;
+    int ICABANKEN = 3;
+    int LANSFORSAKRINGAR = 4;
+    int HANDELSBANKEN = 5;
+    int COOP = 6;
+    int ICA = 7;
+    int STATOIL = 8;
+    int AVANZA = 9;
+    int VILLABANKEN = 10;
+    int AVANZAMINI = 11;
+    int OKQ8 = 12;
+    int EUROCARD = 13;
+    int FIRSTCARD = 14;
+    int PAYPAL = 15;
+    int PAYSON = 16;
+    int JOJO = 17;
+    int IKANOBANK = 18;
+    int STEAM = 19;
+    int DINERSCLUB = 20;
+    int SASEUROBONUSMASTERCARD = 21;
+    int RIKSLUNCHEN = 22;
+    int HEMKOP = 23;
+    int SEB = 24;
+    int NORDNET = 25;
+    int SEVENDAY = 26;
+    int OSUUSPANKKI = 27;
+    int VOLVOFINANS = 28;
+    int CSN = 29;
+    int RESURSBANK = 30;
+    int AMERICANEXPRESS = 31;
+    int MCDONALDS = 32;
+    int SAAB = 33;
+    int WALLET = 34;
+    int CHEVROLET = 35;
+    int SJPRIO = 36;
+    int OPEL = 37;
+    int DJURGARDEN = 38;
+    int QUINTESSENTIALLY = 39;
+    int PLUSGIROT = 40;
+    int SHELL = 41;
+    int VOLKSWAGEN = 42;
+    int AUDI = 43;
+    int PREEM = 44;
+    int SEAT = 45;
+    int SKODA = 46;
+    int IKEA = 47;
+    int SPARBANKEN_SYD = 48;
+    int SPARBANKEN_ORESUND = 49;
+    int NORDNETDIREKT = 50;
+    int SKANDIABANKEN = 51;
+    int DANSKEBANK = 52;
+    int NORDEA_DK = 53;
+    int VASTTRAFIK = 54;
+    int EVERYDAYCARD = 55;
+    int AKELIUSINVEST = 56;
+    int MENIGA = 57;
+    int RIKSKORTET = 58;
+    int BIOKLUBBEN = 59;
+    int CHALMREST = 60;
+    int MARGINALEN = 61;
+    int AKELIUSSPAR = 62;
+    int SVENSKASPEL = 63;
+    int EASYCARD = 64;
+    int APPEAKPOKER = 65;
+    int TRUSTBUDDY = 66;
+    int BRUMMER_KF = 67;
+    int ZIDISHA = 68;
+    int BETTERGLOBE = 69;
+    int FOREX = 70;
+    int SASEUROBONUSMASTERCARD_NO = 71;
+    int BITCOIN = 72;
+    int SASEUROBONUSMASTERCARD_DK = 73;
+    int SVEADIREKT = 74;
+    int SUPREMECARD = 75;
+    int SPARBANKERNA = 76;
+    int BLEKINGETRAFIKEN = 77;
+    int OSTGOTATRAFIKEN = 78;
+    int BREDBAND2VOIP = 79;
+    int ESPRESSOHOUSE = 80;
+    int MINPENSION = 81;
+    int SWEDBANK_YOUTH = 82;
+    int SWEDBANK_CORPORATE = 83;
+    int SPARBANKERNA_YOUTH = 84;
+    int SPARBANKERNA_CORPORATE = 85;
+    int HORS = 86;
 }
diff --git config/quality/checkstyle/checkstyle.xml config/quality/checkstyle/checkstyle.xml
index fa1b9cd..204efc7 100644
--- config/quality/checkstyle/checkstyle.xml
+++ config/quality/checkstyle/checkstyle.xml
@@ -2,7 +2,7 @@
    "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
 <module name="Checker">
     <property name="charset" value="UTF-8"/>
-    
+
     <property name="severity" value="error" />
 
     <module name="SuppressionFilter">
@@ -11,8 +11,9 @@
     <module name="FileTabCharacter">
         <property name="eachLine" value="true"/>
     </module>
-    <module name="NewlineAtEndOfFile" />
     <module name="Translation" />
+
+    <!--
     <module name="RegexpSingleline">
         <property name="format" value="\s+$" />
         <property name="minimum" value="0" />
@@ -20,45 +21,32 @@
         <property name="message" value="Line has trailing spaces." />
         <property name="severity" value="info" />
     </module>
+    -->
 
     <module name="TreeWalker">
         <property name="tabWidth" value="4" />
-        <module name="ConstantName" />
-        <module name="LocalFinalVariableName" />
-        <module name="LocalVariableName" />
-        <module name="MethodName" />
-        <module name="PackageName" />
-        <module name="ParameterName" />
-        <module name="TypeName" />
-        <module name="MemberName">
-            <property name="format" value="^m[A-Z][a-zA-Z0-9]*$" />
-        </module>
-        <module name="StaticVariableName">
-            <property name="format" value="^s[A-Z][a-zA-Z0-9]*$" />
-        </module>
         <module name="AvoidStarImport" />
         <module name="IllegalImport" />
         <module name="RedundantImport" />
         <module name="UnusedImports" />
-       <!-- <module name="MethodLength" /> -->
-        <module name="ParameterNumber" />
+        <!-- <module name="ParameterNumber" /> -->
         <module name="EmptyForIteratorPad" />
         <module name="MethodParamPad" />
+
+        <!--
         <module name="NoWhitespaceAfter">
             <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS" />
         </module>
         <module name="NoWhitespaceBefore" />
-        <module name="OperatorWrap" />
-        <module name="ParenPad" />
-        <module name="TypecastParenPad" />
         <module name="WhitespaceAfter" />
         <module name="WhitespaceAround">
            <property name="allowEmptyMethods" value="true" />
         </module>
-        <module name="ModifierOrder" />
+        -->
+        <module name="ParenPad" />
+        <module name="TypecastParenPad" />
         <module name="RedundantModifier" />
         <module name="AvoidNestedBlocks" />
-        <!--<module name="EmptyBlock" />-->
         <module name="LeftCurly" />
         <module name="NeedBraces" />
         <module name="RightCurly" />
@@ -66,23 +54,19 @@
         <module name="EqualsHashCode" />
         <module name="IllegalInstantiation" />
         <module name="InnerAssignment" />
-        <!-- <module name="MagicNumber" /> -->
-        <!--<module name="MissingSwitchDefault" />-->
         <module name="SimplifyBooleanExpression" />
         <module name="SimplifyBooleanReturn" />
-        <module name="FinalClass" />
-        <module name="HideUtilityClassConstructor" />
-        <module name="InterfaceIsType" />
+        <!-- <module name="HideUtilityClassConstructor" /> -->
+        <!-- <module name="InterfaceIsType" /> -->
         <module name="ArrayTypeStyle" />
 
         <module name="UpperEll" />
-      <!--  <module name="MethodLength">
-            <property name="max" value="40" />
-        </module> -->
+
+        <!--
         <module name="LineLength">
             <property name="max" value="100" />
-             <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://|content://"/>
+            <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://|content://"/>
         </module>
-        <module name="InnerTypeLast" />
+        -->
     </module>
 </module>
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 6f52db2..808a435 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -16,7 +16,7 @@ task checkstyle(type: Checkstyle) {
 
 checkstyle {
     toolVersion '6.1.1' // TODO https://github.com/jshiell/checkstyle-idea/blob/dbe595028c3488400790e6caed2f122fba0bded1/README#L13-19
-    ignoreFailures true // TODO Remove when project has been cleaned.
+    ignoreFailures false
 }
 
 android {

commit bef1e2314636001b79d8192ec505f2e78932a837
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 6 17:15:28 2016 +0200

    Sveadirekt: adapt to new web page

diff --git CHANGELOG CHANGELOG
index be2042c..339ce95 100644
--- CHANGELOG
+++ CHANGELOG
@@ -9,6 +9,7 @@ v1.9.10.9
 * Skip Server Name Indication (SNI) when refreshing bank certificates to avoid certificate mismatches (bankdroid doesn't use SNI)
 * Ticket Rikskortet: Adapt to changed web page
 * Removes IcaBanken since they now require BankID
+* SveaDirekt: Adapt to changed web page
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 398ea29..2c6e7e1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -53,10 +53,10 @@ public class SveaDirekt extends Bank {
             = "https://services.sveadirekt.se/mypages/sv/j_security_check";
 
     private static final String ACCOUNTS_URL
-            = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/home.jsp";
+            = "https://services.sveadirekt.se/customerweb/mypages/save/index.page";
 
     private static final String TRANSACTIONS_URL
-            = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/balance.jsp";
+            = "https://services.sveadirekt.se/customerweb/mypages/save/account-details.page";
 
     private String response;
 
@@ -96,7 +96,7 @@ public class SveaDirekt extends Bank {
         }
         String strLoginUrl = LOGIN_URL;
 
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<>();
         postData.add(new BasicNameValuePair("j_username", getUsername()));
         postData.add(new BasicNameValuePair("j_password", getPassword()));
         return new LoginPackage(urlopen, postData, response, strLoginUrl);
@@ -123,26 +123,11 @@ public class SveaDirekt extends Bank {
 
         urlopen = login();
 
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("homeForm:balance", "Saldo"));
-        postData.add(new BasicNameValuePair("homeForm", "homeForm"));
-        response = urlopen.open(ACCOUNTS_URL, postData);
+        response = urlopen.open(ACCOUNTS_URL);
         Document doc = Jsoup.parse(response);
         ArrayList<Account> accounts = parseAccounts(doc);
-
-        if (!accounts.isEmpty()) {
-            Account firstAccount = accounts.get(0);
-            // Get account details for first account
-            addAccountDetails(firstAccount, doc);
-            firstAccount.setTransactions(parseTransactions(response));
-
-        }
-
-        // Fetch additional accounts transaction pages to get their balance.
-        for (int i = 1; i < accounts.size(); i++) {
-            Account account = accounts.get(i);
-            response = urlopen.open(TRANSACTIONS_URL, createTransactionParams(account));
-            addAccountDetails(account, Jsoup.parse(response));
+        for(Account account : accounts) {
+            response = urlopen.open(TRANSACTIONS_URL + "?account=" + account.getId());
             account.setTransactions(parseTransactions(response));
         }
         this.setAccounts(accounts);
@@ -150,57 +135,40 @@ public class SveaDirekt extends Bank {
     }
 
     private ArrayList<Account> parseAccounts(Document pDocument) {
-        ArrayList<Account> accountList = new ArrayList<Account>();
-        Element element = pDocument.getElementById("balanceForm:accountsList");
-        Elements accounts = element.select("td a[href=#]");
-        for (int i = 0; i < accounts.size(); i++) {
-            Account account = new Account("", BigDecimal.ZERO, Integer.toString(i));
+        ArrayList<Account> accountList = new ArrayList<>();
+        Elements accounts = pDocument.select("table > tbody > tr");
+        for (Element accountElement : accounts) {
+            Account account = new Account(
+                    accountElement.child(1).text(),
+                    amountOf(accountElement.child(3).text()),
+                    accountElement.child(0).text());
             accountList.add(account);
         }
         return accountList;
     }
 
-    private Account addAccountDetails(Account pAccount, Document pDocument) {
-        Elements vAccountDetails = pDocument
-                .select("strong:contains(Saldo och transaktioner) ~ table")
-                .first().select("tr td:last-child");
-        String vAccountType = vAccountDetails.first().text();
-        String vBalance = vAccountDetails.last().text();
-        pAccount.setName(vAccountType);
-        pAccount.setCurrency("SEK");
-        BigDecimal balance = new BigDecimal(vBalance.replaceAll("[^\\d]", ""));
-        pAccount.setBalance(balance);
-        return pAccount;
-    }
-
     private List<Transaction> parseTransactions(String pResponse) {
-        List<Transaction> vTransactions = new ArrayList<Transaction>();
+        List<Transaction> vTransactions = new ArrayList<>();
         Document doc = Jsoup.parse(pResponse);
-        Elements vTransactionElements =
-                doc.getElementById("balanceForm:transactionPostList").select("tbody tr");
-
-        for (Element element : vTransactionElements) {
-
-            Elements vTransactionElement = element.select("td");
+        Elements transactionElements =
+                doc.select("table > tbody").get(1).children();
 
-            BigDecimal amount = new BigDecimal(vTransactionElement.get(1).text()
-                    .replaceAll("[^\\d-]", ""));
-            String description = vTransactionElement.get(2).text();
+        for (Element element : transactionElements) {
+            BigDecimal amount = amountOf(element.child(2).text());
+            String description = element.child(1).text();
             if (description == null || description.isEmpty()) {
                 description = amount.compareTo(BigDecimal.ZERO) > 0 ? "Insättning"
                         : "Uttag";
             }
-            String date = vTransactionElement.first().text();
+            String date = element.child(0).text();
             vTransactions.add(new Transaction(date, description, amount));
         }
         return vTransactions;
     }
 
-    List<NameValuePair> createTransactionParams(Account pAccount) {
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("balanceForm", "balanceForm"));
-        postData.add(new BasicNameValuePair("balanceForm:_idcl",
-                "balanceForm:accountsList:" + pAccount.getId() + ":_id15"));
-        return postData;
+    private BigDecimal amountOf(String amount) {
+        return new BigDecimal(amount
+                .replaceAll("\\u2011", "-")
+                .replaceAll("[^\\d-]", ""));
     }
 }

commit 2e796f1ee2ffa0b1a3975f2cf547b9ce98545b0e
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Oct 6 00:56:50 2016 +0200

    Fix "./gradlew check" task dependencies
    
    Before this change, just doing `./gradlew check` would fail because
    FindBugs required `assembleDebug` to run first.
    
    This change tells Gradle about this dependency and enables one to do
    `./gradlew check` without doing `assembleDebug` first.

diff --git config/quality/quality.gradle config/quality/quality.gradle
index 2098f80..6f52db2 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -30,7 +30,7 @@ android {
     }
 }
 
-task findbugs(type: FindBugs) {
+task findbugs(type: FindBugs, dependsOn: 'compileDebugSources') {
     effort = "max"
     reportLevel = "high"
     excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")

commit 6e1940dab8488d3842cff3d2967dace159e5f64b
Merge: fcac51d ae0f28c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 5 19:37:00 2016 +0200

    Merge pull request #621 from liato/feature/fixes-failing-tests-within-android-studio
    
    Removes irrelevant tests

commit fcac51d7d3b78a491fde09aa58425fa6b1165042
Merge: 9000a3b 66bfe06
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 5 19:32:27 2016 +0200

    Merge pull request #620 from liato/feature/619-remove-icabanken
    
    Removes support for IcaBanken

commit ae0f28cd436fdc2903364311ee32656c22603370
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 5 19:29:32 2016 +0200

    Adds workaround for handling java test resources correctly

diff --git build.gradle build.gradle
index 75ad630..bb0898c 100644
--- build.gradle
+++ build.gradle
@@ -18,6 +18,17 @@ allprojects {
     }
 }
 
+subprojects {
+    // Workaround. See https://code.google.com/p/android/issues/detail?id=64887#c54
+    plugins.withType(JavaPlugin).whenPluginAdded {
+        task copyTestResources(type: Copy) {
+            from "${projectDir}/src/test/resources"
+            into "${buildDir}/classes/test"
+        }
+        processTestResources.dependsOn copyTestResources
+    }
+}
+
 task wrapper(type: Wrapper) {
     gradleVersion = '3.1'
 }

commit c5e4d663dfb4fc4e0e3592cb3241f498bbd65cd9
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 5 19:28:59 2016 +0200

    Removes irrelevant tests

diff --git bankdroid-interface/src/test/java/com/liato/bankdroid/api/configuration/FieldBuilderTest.java bankdroid-interface/src/test/java/com/liato/bankdroid/api/configuration/FieldBuilderTest.java
deleted file mode 100644
index 9028b51..0000000
--- bankdroid-interface/src/test/java/com/liato/bankdroid/api/configuration/FieldBuilderTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.liato.bankdroid.api.configuration;
-
-import org.junit.Test;
-
-import java.util.Locale;
-import java.util.PropertyResourceBundle;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-public class FieldBuilderTest {
-
-    private static final String PACKAGE = FieldBuilderTest.class.getPackage().getName();
-    private static final String REFERENCE = "reference";
-
-    private static final String DEFAULT_BUNDLE = "com.liato.bankdroid.api.configuration.defaultFieldBuilderTest";
-
-    private static final String MISSING_KEY_BUNDLE = "com.liato.bankdroid.api.configuration.missingKeyFieldBuilderTest";
-
-    @Test
-    public void testDefaultLocaleFieldBuilder() {
-        FieldBuilder builder = new FieldBuilder(REFERENCE, PropertyResourceBundle.getBundle(DEFAULT_BUNDLE));
-        Field field = builder.build();
-
-        assertEquals("defaultPlaceholder",field.getPlaceholder());
-        assertEquals("defaultLabel", field.getLabel());
-    }
-
-    @Test
-    public void testMissingKeyLocaleFieldBuilder() {
-        FieldBuilder builder = new FieldBuilder(REFERENCE, PropertyResourceBundle.getBundle(MISSING_KEY_BUNDLE));
-        Field field = builder.build();
-
-        assertEquals("defaultPlaceholder", field.getPlaceholder());
-        assertEquals("field.reference.label", field.getLabel());
-    }
-
-    @Test
-    public void testLocaleFieldBuilder() {
-        FieldBuilder builder = new FieldBuilder(REFERENCE, PropertyResourceBundle.getBundle(DEFAULT_BUNDLE, new Locale("sv_SE")));
-        Field field = builder.build();
-
-        assertEquals("defaultPlaceholder", field.getPlaceholder());
-        assertEquals("localeLabel", field.getLabel());
-    }
-
-    @Test
-    public void testFieldBuilder() {
-        FieldBuilder builder = new FieldBuilder(REFERENCE);
-        Field field = builder.build();
-
-        assertNull(field.getLabel());
-        assertNull(field.getPlaceholder());
-    }
-}
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
deleted file mode 100644
index dceece7..0000000
--- bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-field.reference.placeholder=defaultPlaceholder
-field.reference.label=defaultLabel
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
deleted file mode 100644
index 2fe26f1..0000000
--- bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
+++ /dev/null
@@ -1 +0,0 @@
-field.reference.label=localeLabel
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
deleted file mode 100644
index 9ff7001..0000000
--- bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
+++ /dev/null
@@ -1 +0,0 @@
-field.reference.placeholder=defaultPlaceholder

commit 66bfe065dca82c986eee4be07d38b2c8d49b0a68
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Oct 5 19:02:13 2016 +0200

    Removes support for IcaBanken

diff --git CHANGELOG CHANGELOG
index 43ab0e0..be2042c 100644
--- CHANGELOG
+++ CHANGELOG
@@ -8,6 +8,7 @@ v1.9.10.9
 * Östgötatrafiken: Adapt to changed web page
 * Skip Server Name Indication (SNI) when refreshing bank certificates to avoid certificate mismatches (bankdroid doesn't use SNI)
 * Ticket Rikskortet: Adapt to changed web page
+* Removes IcaBanken since they now require BankID
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 4efc9dd..a60f4fd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -83,8 +83,8 @@ public class LegacyBankFactory {
                 return new Nordea(context);
             case IBankTypes.LANSFORSAKRINGAR:
                 return new Lansforsakringar(context);
-            case IBankTypes.ICABANKEN:
-                return new ICABanken(context);
+            // case IBankTypes.ICABANKEN:
+            //    return new ICABanken(context);
             // case IBankTypes.HANDELSBANKEN:
             //     return new Handelsbanken(context);
             case IBankTypes.COOP:
@@ -258,7 +258,7 @@ public class LegacyBankFactory {
         banks.add(new BrummerKF(context));
         // banks.add(new Swedbank(context));
         banks.add(new Nordea(context));
-        banks.add(new ICABanken(context));
+        // banks.add(new ICABanken(context));
         banks.add(new Lansforsakringar(context));
         // banks.add(new Handelsbanken(context));
         banks.add(new Coop(context));

commit 9000a3bc8170fb26795542317db04a4ce4cbda64
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Wed Oct 5 07:43:23 2016 +0200

    Ticket Rikskortet: Adapt to changed web page

diff --git CHANGELOG CHANGELOG
index af45755..43ab0e0 100644
--- CHANGELOG
+++ CHANGELOG
@@ -7,6 +7,7 @@ v1.9.10.9
 * Östgötatrafiken: Update certificate
 * Östgötatrafiken: Adapt to changed web page
 * Skip Server Name Indication (SNI) when refreshing bank certificates to avoid certificate mismatches (bankdroid doesn't use SNI)
+* Ticket Rikskortet: Adapt to changed web page
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index ca41559..a517b95 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -65,7 +65,7 @@ public class TicketRikskortet extends Bank {
             Pattern.CASE_INSENSITIVE);
 
     private Pattern reTransactions = Pattern.compile(
-            "(\\d{4}-\\d{2}-\\d{2})\\s\\d{2}:\\d{2}:\\d{2}</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>",
+            "(\\d{4}-\\d{2}-\\d{2})</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>",
             Pattern.CASE_INSENSITIVE);
 
     private String response = null;

commit 55e6eb690be22f7e732f8564f75e7bd9647c9cac
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Tue Oct 4 23:49:33 2016 +0200

    Östgötatrafiken: Adapt to changed web page

diff --git CHANGELOG CHANGELOG
index a0b8ce5..af45755 100644
--- CHANGELOG
+++ CHANGELOG
@@ -5,6 +5,7 @@ v1.9.10.9
 * Improve Javadocs in the Bank class
 * Make successfully refreshing a disabled bank re-enable it
 * Östgötatrafiken: Update certificate
+* Östgötatrafiken: Adapt to changed web page
 * Skip Server Name Indication (SNI) when refreshing bank certificates to avoid certificate mismatches (bankdroid doesn't use SNI)
 
 v1.9.10.8 (2016-09-29)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index e3f2a1f..18357a9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -66,7 +66,7 @@ public class Ostgotatrafiken extends Bank {
     private Pattern reCardName = Pattern.compile("<li class=\"selected\">.*?>(\\w+?)</span>",
             Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
 
-    private Pattern reCardBalance = Pattern.compile(">Saldo<.*?>\\s*(\\d+)\\s*kr\\s*</span>",
+    private Pattern reCardBalance = Pattern.compile(">Saldo.*?>\\s*(\\d+)\\s*kr\\s*</span>",
             Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
 
     private String response = null;

commit 1ccbaee603aaf7de7d499d99384a269413debc2f
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Wed Oct 5 00:13:40 2016 +0200

    Don't use Server Name Indication when refreshing certificates
    
    It looks like some servers return different certificates depending on
    whether SNI is set or not. Bankdroid doesn't seem to set SNI when
    connecting to the banks, so the script refresh_bank_certificates
    shouldn't use SNI either or there will be certificate verification
    failures.
    
    This fixes certificate verification for Östgötatrafiken.
    
    I've refreshed all bank certificates with this change and only a few
    certificates changed. I've verified that Östgötatrafiken works. The
    other affected banks look disabled (except for Meniga bank, but do we
    know if that bank is working?)

diff --git CHANGELOG CHANGELOG
index 67da4fa..a0b8ce5 100644
--- CHANGELOG
+++ CHANGELOG
@@ -4,6 +4,8 @@ v1.9.10.9
 * Länsförsäkringar: Remove broken web links
 * Improve Javadocs in the Bank class
 * Make successfully refreshing a disabled bank re-enable it
+* Östgötatrafiken: Update certificate
+* Skip Server Name Indication (SNI) when refreshing bank certificates to avoid certificate mismatches (bankdroid doesn't use SNI)
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git bankdroid-legacy/src/main/res/raw/cert_eurocard.pem bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
index b143c62..73f9ab7 100644
--- bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
@@ -1,40 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIG6jCCBdKgAwIBAgIQKjjCmo6AAOaKfGTNfQnuxzANBgkqhkiG9w0BAQsFADB3
+MIIGfTCCBWWgAwIBAgIQI3a+KH/DbEY9fTb2fzlYhTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj

+retcxhIyl4nBN1O84LH6XwuqSfCe/mmYIIZPV9xmU40Z
 -----END CERTIFICATE-----
 secure.eurocard.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_meniga.pem bankdroid-legacy/src/main/res/raw/cert_meniga.pem
index 9b52725..828d693 100644
--- bankdroid-legacy/src/main/res/raw/cert_meniga.pem
+++ bankdroid-legacy/src/main/res/raw/cert_meniga.pem
@@ -1,40 +1,31 @@
 -----BEGIN CERTIFICATE-----

-rUgT/u18sTiJ/VynHSJNdQ==

+83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0=
 -----END CERTIFICATE-----
 www.meniga.is:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
index 591a187..748e230 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -1,33 +1,33 @@
 -----BEGIN CERTIFICATE-----

-FKRv1EBIx1ZFS0Q+XfGY4rhcAApBVFvuAG9CgnAoa7RHNr4ya95b

+E1dVzW3GXPiOEh4LMGnnJERSVztgihJziES2RVE=
 -----END CERTIFICATE-----
 www.ostgotatrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_sebkort.pem bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
index 0008442..b167f07 100644
--- bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
+++ bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
@@ -1,41 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIG9jCCBd6gAwIBAgIQAzn0x8pnZjksbYjz9X74LzANBgkqhkiG9w0BAQsFADB3
+MIIGfTCCBWWgAwIBAgIQI3a+KH/DbEY9fTb2fzlYhTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj

-2mAtTkzsi6a7yg==

+retcxhIyl4nBN1O84LH6XwuqSfCe/mmYIIZPV9xmU40Z
 -----END CERTIFICATE-----
 secure.sebkort.com:443
diff --git tools/refresh_bank_certificates tools/refresh_bank_certificates
index acc54a5..1aa497e 100755
--- tools/refresh_bank_certificates
+++ tools/refresh_bank_certificates
@@ -50,9 +50,6 @@ def get_pem_certificate(host):
             s.connect(host)
             ssl_connection = ssl.Connection(ssl.Context(ssl_method), s)
             ssl_connection.set_connect_state()
-            # Some servers require "Server Name Indication" to be set
-            # in the client's TLS hello
-            ssl_connection.set_tlsext_host_name(host[0])
 
             handshake_start_time = time.time()
             while time.time() - handshake_start_time < CONNECTION_TIMEOUT:

commit 9595c9b87d50fa6be4547df9cc91f9ec51c51b18
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sun Oct 2 19:45:25 2016 +0200

    Enable refreshing disabled banks
    
    If the user refreshes an individual bank, we'll do it even if it's
    disabled. The idea is that maybe it works this time around, and if
    so we'll just be re-enable it.

diff --git CHANGELOG CHANGELOG
index 09ca569..67da4fa 100644
--- CHANGELOG
+++ CHANGELOG
@@ -3,6 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 v1.9.10.9
 * Länsförsäkringar: Remove broken web links
 * Improve Javadocs in the Bank class
+* Make successfully refreshing a disabled bank re-enable it
 
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index 0810167..0f3d49a 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -29,15 +29,19 @@ import com.liato.bankdroid.utils.NetworkUtils;
 
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.os.AsyncTask;
 import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
 
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
@@ -51,8 +55,6 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
     private ArrayList<String> errors;
 
-    private int bankcount;
-
     private long bankId = -1;
 
     public DataRetrieverTask(final MainActivity parent) {
@@ -68,37 +70,68 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
     @Override
     protected void onPreExecute() {
-        this.dialog.setMessage(res.getText(R.string.updating_account_balance)
+        getDialog().setMessage(res.getText(R.string.updating_account_balance)
                 + "\n ");
-        this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-        this.dialog.setCancelable(false);
-        this.dialog.show();
+        getDialog().setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+        getDialog().setCancelable(false);
+        getDialog().show();
+    }
+
+    @NonNull
+    protected ProgressDialog getDialog() {
+        return this.dialog;
+    }
+
+    protected Bank getBankFromDb(long bankId, Context parent) {
+        return BankFactory.bankFromDb(bankId, parent, true);
+    }
+
+    protected List<Bank> getBanksFromDb(Context parent) {
+        return BankFactory.banksFromDb(parent, true);
+    }
+
+    protected void saveBank(Bank bank, Context context) {
+        DBAdapter.save(bank, parent);
+    }
+
+    protected void publishProgress(int zeroBasedBankNumber, @Nullable Bank bank) {
+        String text = "";
+        if (bank != null) {
+            text = bank.getName() + " (" + bank.getUsername() + ")";
+        }
+        publishProgress(Integer.toString(zeroBasedBankNumber), text);
+    }
+
+    protected boolean isContentProviderEnabled() {
+        final SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(parent);
+        return prefs.getBoolean("content_provider_enabled", false);
     }
 
     @Override
     protected Void doInBackground(final String... args) {
-        errors = new ArrayList<String>();
-        ArrayList<Bank> banks;
+        errors = new ArrayList<>();
+        List<Bank> banks;
         if (bankId != -1) {
-            banks = new ArrayList<Bank>();
-            banks.add(BankFactory.bankFromDb(bankId, parent, true));
+            banks = new ArrayList<>();
+            banks.add(getBankFromDb(bankId, parent));
         } else {
-            banks = BankFactory.banksFromDb(parent, true);
+            banks = getBanksFromDb(parent);
         }
-        bankcount = banks.size();
-        this.dialog.setMax(bankcount);
+        getDialog().setMax(banks.size());
         int i = 0;
         for (final Bank bank : banks) {
-            publishProgress(new String[]{new Integer(i).toString(),
-                    bank.getName() + " (" + bank.getUsername() + ")"});
-            if (bank.isDisabled()) {
+            publishProgress(i, bank);
+
+            if (isListingAllBanks() && bank.isDisabled()) {
                 continue;
             }
+
             try {
                 bank.update();
                 bank.updateAllTransactions();
                 bank.closeConnection();
-                DBAdapter.save(bank, parent);
+                saveBank(bank, parent);
                 i++;
             } catch (final BankException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
@@ -121,9 +154,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
                 }
             }
 
-            final SharedPreferences prefs = PreferenceManager
-                    .getDefaultSharedPreferences(parent);
-            if (prefs.getBoolean("content_provider_enabled", false)) {
+            if (isContentProviderEnabled()) {
                 final ArrayList<Account> accounts = bank.getAccounts();
                 for (final Account account : accounts) {
                     AutoRefreshService.broadcastTransactionUpdate(parent,
@@ -131,14 +162,18 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
                 }
             }
         }
-        publishProgress(new String[]{new Integer(i).toString(), ""});
+        publishProgress(i, null);
         return null;
     }
 
+    private boolean isListingAllBanks() {
+        return bankId == -1;
+    }
+
     @Override
     protected void onProgressUpdate(final String... args) {
-        this.dialog.setProgress(Integer.parseInt(args[0]));
-        this.dialog.setMessage(res.getText(R.string.updating_account_balance)
+        getDialog().setProgress(Integer.parseInt(args[0]));
+        getDialog().setMessage(res.getText(R.string.updating_account_balance)
                 + "\n" + args[1]);
     }
 
@@ -146,12 +181,12 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
     protected void onPostExecute(final Void unused) {
         parent.refreshView();
         AutoRefreshService.sendWidgetRefresh(parent);
-        ActivityHelper.dismissDialog(this.dialog);
+        ActivityHelper.dismissDialog(getDialog());
 
         if ((this.errors != null) && !this.errors.isEmpty()) {
             final StringBuilder errormsg = new StringBuilder();
-            errormsg.append(res.getText(R.string.accounts_were_not_updated)
-                    + ":\n");
+            errormsg.append(res.getText(R.string.accounts_were_not_updated))
+                    .append(":\n");
             for (final String err : errors) {
                 errormsg.append(err);
                 errormsg.append("\n");
diff --git app/src/test/java/com/liato/bankdroid/DataRetrieverTaskTest.java app/src/test/java/com/liato/bankdroid/DataRetrieverTaskTest.java
new file mode 100644
index 0000000..c1c8dbc
--- /dev/null
+++ app/src/test/java/com/liato/bankdroid/DataRetrieverTaskTest.java
@@ -0,0 +1,128 @@
+package com.liato.bankdroid;
+
+import com.liato.bankdroid.banking.Bank;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.support.annotation.NonNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class DataRetrieverTaskTest {
+    // Any positive number would do here
+    private static final int BANK_ID = 5;
+
+    private static class TestableDataRetrieverTask extends DataRetrieverTask {
+        private final Bank[] banks;
+        private final ProgressDialog dialog;
+
+        @Override
+        protected void publishProgress(int zeroBasedBankNumber, Bank bank) {
+            // This method intentionally left blank
+        }
+
+        @Override
+        protected Bank getBankFromDb(long bankId, Context parent) {
+            Assert.assertEquals(BANK_ID, bankId);
+            return banks[0];
+        }
+
+        @Override
+        protected List<Bank> getBanksFromDb(Context parent) {
+            return Arrays.asList(banks);
+        }
+
+        @Override
+        protected void saveBank(Bank bank, Context context) {
+            // This method intentionally left blank
+        }
+
+        @Override
+        protected boolean isContentProviderEnabled() {
+            return false;
+        }
+
+        @NonNull
+        @Override
+        protected ProgressDialog getDialog() {
+            return dialog;
+        }
+
+        /**
+         * Constructor for testing a specific bank
+         */
+        public TestableDataRetrieverTask(Bank bank) {
+            super(Mockito.mock(MainActivity.class), BANK_ID);
+
+            this.banks = new Bank[] { bank };
+            this.dialog = Mockito.mock(ProgressDialog.class);
+        }
+
+        /**
+         * Constructor for testing all banks
+         */
+        public TestableDataRetrieverTask(Bank[] allBanks) {
+            super(Mockito.mock(MainActivity.class));
+
+            this.banks = allBanks;
+            this.dialog = Mockito.mock(ProgressDialog.class);
+        }
+    }
+
+    @Test
+    public void testUpdateSingleDisabledBank() throws Exception {
+        Bank bank = Mockito.mock(Bank.class);
+        Mockito.when(bank.isDisabled()).thenReturn(true);
+
+        TestableDataRetrieverTask testMe = new TestableDataRetrieverTask(bank);
+        testMe.doInBackground();
+
+        // Single disabled bank should be updated
+        Mockito.verify(bank, Mockito.atLeastOnce()).update();
+
+        // At least at the time of writing this (2016oct2) updating the bank
+        // implicitly enables it. Of course having a test for that would be
+        // better than not having one, but we don't right now.
+    }
+
+    @Test
+    public void testUpdateSingleEnabledBank() throws Exception {
+        Bank bank = Mockito.mock(Bank.class);
+        Mockito.when(bank.isDisabled()).thenReturn(false);
+
+        TestableDataRetrieverTask testMe = new TestableDataRetrieverTask(bank);
+        testMe.doInBackground();
+
+        // Single enabled bank should be updated
+        Mockito.verify(bank, Mockito.atLeastOnce()).update();
+    }
+
+    @Test
+    public void testUpdateMultiDisabledBank() throws Exception {
+        Bank bank = Mockito.mock(Bank.class);
+        Mockito.when(bank.isDisabled()).thenReturn(true);
+
+        TestableDataRetrieverTask testMe = new TestableDataRetrieverTask(new Bank[]{bank});
+        testMe.doInBackground();
+
+        // When doing all banks, disabled ones shouldn't update
+        Mockito.verify(bank, Mockito.never()).update();
+    }
+
+    @Test
+    public void testUpdateMultiEnabledBank() throws Exception {
+        Bank bank = Mockito.mock(Bank.class);
+        Mockito.when(bank.isDisabled()).thenReturn(false);
+
+        TestableDataRetrieverTask testMe = new TestableDataRetrieverTask(new Bank[]{bank});
+        testMe.doInBackground();
+
+        // When doing all banks, enabled ones should update
+        Mockito.verify(bank, Mockito.atLeastOnce()).update();
+    }
+}

commit 07d06d846d2b78d0d12a410c133f036531edac40
Author: Johan Walles <johan.walles@gmail.com>
Date:   Sun Oct 2 20:54:18 2016 +0200

    Fail build on FindBugs violations
    
    And remedy those left; they weren't that many to begin with.
    
    I like FindBugs; it finds bugs. And I prefer it finding them to me
    finding them.

diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index b891631..0810167 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -137,7 +137,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
     @Override
     protected void onProgressUpdate(final String... args) {
-        this.dialog.setProgress(new Integer(args[0]));
+        this.dialog.setProgress(Integer.parseInt(args[0]));
         this.dialog.setMessage(res.getText(R.string.updating_account_balance)
                 + "\n" + args[1]);
     }
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index 5176b21..47c2986 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -18,6 +18,8 @@ package com.liato.bankdroid.lockpattern;
 
 import com.google.common.collect.Lists;
 
+import com.liato.bankdroid.utils.StringUtils;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -88,23 +90,17 @@ public class LockPatternUtils {
 
     private static String sLockPatternFilename;
 
-    private static Context mContext;
-
     private static SharedPreferences mPrefs;
 
     private final ContentResolver mContentResolver;
 
-    /**
-     * @param contentResolver Used to look up and save settings.
-     */
     public LockPatternUtils(Context context) {
-        mContext = context;
         mContentResolver = context.getContentResolver();
         mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
         // Initialize the location of gesture lock file
         if (sLockPatternFilename == null) {
             sLockPatternFilename = context.getFilesDir() + LOCK_PATTERN_FILE;
-            //sLockPatternFilename = android.os.Environment.getDataDirectory() 
+            //sLockPatternFilename = android.os.Environment.getDataDirectory()
             //        .getAbsolutePath() + LOCK_PATTERN_FILE;
         }
     }
@@ -118,7 +114,7 @@ public class LockPatternUtils {
     public static List<LockPatternView.Cell> stringToPattern(String string) {
         List<LockPatternView.Cell> result = Lists.newArrayList();
 
-        final byte[] bytes = string.getBytes();
+        final byte[] bytes = StringUtils.getBytes(string);
         for (int i = 0; i < bytes.length; i++) {
             byte b = bytes[i];
             result.add(LockPatternView.Cell.of(b / 3, b % 3));
@@ -143,7 +139,7 @@ public class LockPatternUtils {
             LockPatternView.Cell cell = pattern.get(i);
             res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
         }
-        return new String(res);
+        return StringUtils.toString(res);
     }
 
     /*
@@ -389,6 +385,4 @@ public class LockPatternUtils {
         editor.putLong(systemSettingKey, value);
         editor.commit();
     }
-
-
 }
diff --git app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
index 88e3650..ce6d124 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
@@ -83,8 +83,8 @@ public class AlphaPatternDrawable extends Drawable {
         int height = bounds.height();
         int width = bounds.width();
 
-        numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
-        numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
+        numRectanglesHorizontal = width / mRectangleSize;
+        numRectanglesVertical = height / mRectangleSize;
 
         generatePatternBitmap();
 
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
index 66a7c4d..6e315e5 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -168,7 +168,7 @@ public class ColorPickerView extends View {
     }
 
     private void init() {
-        if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 11) {
+        if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 11) {
             setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         }
         mDensity = getContext().getResources().getDisplayMetrics().density;
diff --git app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
index 2c2d817..d4a1995 100644
--- app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
+++ app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -5,6 +5,8 @@
 
 package net.sf.andhsli.hotspotlogin;
 
+import com.liato.bankdroid.utils.StringUtils;
+
 import java.security.SecureRandom;
 
 import javax.crypto.Cipher;
@@ -27,16 +29,16 @@ public class SimpleCrypto {
     private final static String HEX = "0123456789ABCDEF";
 
     public static String encrypt(String seed, String cleartext) throws Exception {
-        byte[] rawKey = getRawKey(seed.getBytes());
-        byte[] result = encrypt(rawKey, cleartext.getBytes());
+        byte[] rawKey = getRawKey(StringUtils.getBytes(seed));
+        byte[] result = encrypt(rawKey, StringUtils.getBytes(cleartext));
         return toHex(result);
     }
 
     public static String decrypt(String seed, String encrypted) throws Exception {
-        byte[] rawKey = getRawKey(seed.getBytes());
+        byte[] rawKey = getRawKey(StringUtils.getBytes(seed));
         byte[] enc = toByte(encrypted);
         byte[] result = decrypt(rawKey, enc);
-        return new String(result);
+        return StringUtils.toString(result);
     }
 
     private static byte[] getRawKey(byte[] seed) throws Exception {
@@ -70,14 +72,6 @@ public class SimpleCrypto {
         return decrypted;
     }
 
-    public static String toHex(String txt) {
-        return toHex(txt.getBytes());
-    }
-
-    public static String fromHex(String hex) {
-        return new String(toByte(hex));
-    }
-
     public static byte[] toByte(String hexString) {
         int len = hexString.length() / 2;
         byte[] result = new byte[len];
@@ -101,5 +95,4 @@ public class SimpleCrypto {
     private static void appendHex(StringBuffer sb, byte b) {
         sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
     }
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index bfb87ee..f49cc23 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -36,7 +36,6 @@ import android.text.InputType;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -98,7 +97,6 @@ public class OKQ8 extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_okq8));
-        Date d = new Date();
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         response = urlopen
                 .open("https://nettbank.edb.com/authenticate/login/basicauth?configKey=okq8");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index d58e3d6..1d07c1e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -123,7 +123,7 @@ public class Osuuspankki extends Bank {
              * 3: Account name          FI91 5553 5140 0165 27
              * 4: Amount                +882,35
              * 5: Currency              &nbsp;&euro;
-             * 
+             *
              */
             String currency = Helpers.parseCurrency(
                     Html.fromHtml(matcher.group(5)).toString().trim(), "EUR");
@@ -167,7 +167,7 @@ public class Osuuspankki extends Bank {
              * 5: Amount in EUR         -3,99
              *
              */
-            String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split(".");
+            String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split("\\.");
             Transaction transaction = new Transaction(Helpers.getTransactionDate(date[1], date[0]),
                     Html.fromHtml(matcher.group(3)).toString().trim(),
                     Helpers.parseBalance(matcher.group(5)));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 15dec15..84073e3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -38,6 +35,9 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -69,7 +69,6 @@ public class PayPal extends Bank {
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 0119131..d495898 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -114,7 +114,7 @@ public class Zidisha extends Bank {
 
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
-        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
         return urlopen;
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 3521ae7..b85e747 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -30,6 +30,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
+import com.liato.bankdroid.utils.StringUtils;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
@@ -38,7 +39,6 @@ import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.content.Context;
-import android.text.TextUtils;
 import android.util.Base64;
 
 import java.io.IOException;
@@ -97,7 +97,7 @@ public class Avanza extends Bank {
                 CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
-                new String(getUsername() + ":" + getPassword()).getBytes(), Base64.NO_WRAP));
+                StringUtils.getBytes(getUsername() + ":" + getPassword()), Base64.NO_WRAP));
         balance = new BigDecimal(0);
 
         try {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index fde8c3a..963cd92 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -28,6 +28,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
+import com.liato.bankdroid.utils.StringUtils;
 
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
@@ -89,7 +90,7 @@ public class ICA extends Bank {
         urlopen.addHeader("Accept", "application/json;charset=UTF-8");
         urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
-                new String(getUsername() + ":" + getPassword()).getBytes(), Base64.NO_WRAP));
+                StringUtils.getBytes(getUsername() + ":" + getPassword()), Base64.NO_WRAP));
 
         try {
             HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login",
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index dc7a0c4..36427e0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -146,7 +146,7 @@ public class ICABanken extends Bank {
             alias.setAliasfor(icaAccount.getAccountId());
             accounts.add(account);
             accounts.add(alias);
-            balance.add(account.getBalance());
+            balance = balance.add(account.getBalance());
         }
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index ce65a80..211759c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
+import com.liato.bankdroid.utils.StringUtils;
 
 import android.content.Context;
 import android.text.InputType;
@@ -154,7 +155,7 @@ public class Lansforsakringar extends Bank {
             String h = Integer.toHexString(
                     originalChallenge + (1000 * 20 / 4) + 100 * (18 / 3) + 10 * (2 / 2) + 6);
             MessageDigest md = MessageDigest.getInstance("SHA-1");
-            byte[] messageDigest = md.digest(h.getBytes());
+            byte[] messageDigest = md.digest(StringUtils.getBytes(h));
             BigInteger number = new BigInteger(1, messageDigest);
             String md5 = number.toString(16);
             while (md5.length() < 40) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
index 8a03e66..ad181f3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
@@ -2,7 +2,9 @@ package com.liato.bankdroid.banking.banks.seb.model;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-public class UserCredentials {
+import java.io.Serializable;
+
+public class UserCredentials implements Serializable {
 
     @JsonProperty("ApplicationName")
     private String applicationName;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index f1cdc48..4dfa04e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -23,6 +23,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.utils.Installation;
+import com.liato.bankdroid.utils.StringUtils;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -38,7 +39,6 @@ import android.util.Log;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -316,16 +316,10 @@ public abstract class AbstractSwedbank extends Bank {
     }
 
     private String getAuthenticationHeader() {
-        try {
-            byte[] data = new StringBuilder(getAppId())
-                    .append(':')
-                    .append(Installation.id(context))
-                    .toString().getBytes("UTF-8");
-            return Base64.encodeToString(data, Base64.NO_WRAP);
-        } catch (UnsupportedEncodingException e) {
-            // Ignore
-        }
-        return null;
+        byte[] data = StringUtils.getBytes(getAppId() +
+                ':' +
+                Installation.id(context));
+        return Base64.encodeToString(data, Base64.NO_WRAP);
     }
 
     private String getResourceUri(String resource) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
index 761b52e..6a7de4c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
@@ -50,13 +50,13 @@ public class Installation {
         byte[] bytes = new byte[(int) f.length()];
         f.readFully(bytes);
         f.close();
-        return new String(bytes);
+        return StringUtils.toString(bytes);
     }
 
     private static void writeInstallationFile(File installation) throws IOException {
         FileOutputStream out = new FileOutputStream(installation);
         String id = UUID.randomUUID().toString();
-        out.write(id.getBytes());
+        out.write(StringUtils.getBytes(id));
         out.close();
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java
new file mode 100644
index 0000000..f85b8f2
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/StringUtils.java
@@ -0,0 +1,27 @@
+package com.liato.bankdroid.utils;
+
+import java.io.UnsupportedEncodingException;
+
+public class StringUtils {
+    private static final String CHARSET = "UTF-8";
+
+    private StringUtils() {
+        // This constructor is here to prevent people from instantiating this utility class
+    }
+
+    public static byte[] getBytes(String string) {
+        try {
+            return string.getBytes(CHARSET);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Internal error");
+        }
+    }
+
+    public static String toString(byte[] bytes) {
+        try {
+            return new String(bytes, CHARSET);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Internal error");
+        }
+    }
+}
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index e336da1..099fb17 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -48,7 +48,6 @@ import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.client.DefaultRedirectHandler;
 import org.apache.http.impl.client.DefaultRequestDirector;
@@ -204,7 +203,6 @@ public class Urllib {
         HttpResponse response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
-        ResponseHandler<String> responseHandler = new BasicResponseHandler();
         HttpUriRequest request;
         switch (method) {
             case GET:
@@ -470,4 +468,4 @@ public class Urllib {
         }
     }
 
-}
\ No newline at end of file
+}
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 9d26732..2098f80 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -8,7 +8,7 @@ check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'lint'
 task checkstyle(type: Checkstyle) {
     configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
     configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
-    
+
     source 'src'
     include '**/*.java'
     classpath = files()
@@ -31,7 +31,6 @@ android {
 }
 
 task findbugs(type: FindBugs) {
-    ignoreFailures = true // TODO Set to false when project has been cleaned.
     effort = "max"
     reportLevel = "high"
     excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")

commit 8c04fd55c6eb4f5e4688dd831dcbeaf9b5440536
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Oct 3 06:19:47 2016 +0200

    Remove the broken web-bank links from LF
    
    Also comment some previously undocumented parts of the Bank class.
    
    Have tried Länsförsäkringar with this change applied and it still works
    like a charm.

diff --git CHANGELOG CHANGELOG
index 6874b26..09ca569 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.9
+* Länsförsäkringar: Remove broken web links
+* Improve Javadocs in the Bank class
+
 v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
 * Fix widget not updating when the balance change was lower than the notification threshold.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 0ee5f68..b8b3865 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -33,6 +33,7 @@ import org.apache.http.client.CookieStore;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
+import android.support.annotation.Nullable;
 import android.text.InputType;
 import android.util.Log;
 
@@ -58,6 +59,15 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     protected int BANKTYPE_ID = 0;
 
+    /**
+     * URL for human-accessible web bank.
+     * <p/>
+     * Can be set to null to disable. Lots of banks don't have this any more, but have
+     * apps instead.
+     * <p/>
+     * @see #isWebViewEnabled()
+     */
+    @Nullable
     protected String URL;
 
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
@@ -87,6 +97,13 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     protected boolean DISPLAY_DECIMALS = true;
 
+    /**
+     * Whether or not we support opening the web version of a bank.
+     * <p/>
+     * Lots of banks don't have this any more, but have apps instead.
+     * @see #isWebViewEnabled()
+     * @see #URL
+     */
     protected boolean WEB_VIEW_ENABLED = true;
 
     protected Context context;
@@ -335,8 +352,15 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return INPUT_TITLETEXT_EXTRAS;
     }
 
+    /**
+     * Whether or not we support opening the web version of a bank.
+     * <p/>
+     * Lots of banks don't have this any more, but have apps instead.
+     * @see #WEB_VIEW_ENABLED
+     * @see #URL
+     */
     public boolean isWebViewEnabled() {
-        return WEB_VIEW_ENABLED;
+        return URL != null && WEB_VIEW_ENABLED;
     }
 
     public Map<String, String> getProperties() {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 463e25d..ce65a80 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -40,9 +40,6 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import org.apache.http.NameValuePair;
-import org.apache.http.message.BasicNameValuePair;
-
 import android.content.Context;
 import android.text.InputType;
 
@@ -55,10 +52,7 @@ import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.List;
 import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -71,9 +65,6 @@ public class Lansforsakringar extends Bank {
 
     private static final String NAME_SHORT = "lansforsakringar";
 
-    private static final String URL
-            = "https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces";
-
     private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
 
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
@@ -84,16 +75,9 @@ public class Lansforsakringar extends Bank {
 
     private static final String API_BASEURL = "https://mobil.lansforsakringar.se/appoutlet/";
 
-    private Pattern reViewState = Pattern.compile(
-            "(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reLoginToken = Pattern.compile("login:loginToken\"\\s+.*?value=\"([^\"]+)\"",
-            Pattern.CASE_INSENSITIVE);
-
     private ObjectMapper mObjectMapper = new ObjectMapper();
 
-    private HashMap<String, String> mAccountLedger = new HashMap<String, String>();
+    private HashMap<String, String> mAccountLedger = new HashMap<>();
 
     public Lansforsakringar(Context context) {
         super(context);
@@ -101,7 +85,6 @@ public class Lansforsakringar extends Bank {
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
@@ -110,45 +93,6 @@ public class Lansforsakringar extends Bank {
         mObjectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
     }
 
-    public Lansforsakringar(String username, String password, Context context) throws BankException,
-            LoginException, BankChoiceException, IOException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, IOException {
-        Urllib weblogin = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
-        weblogin.setAllowCircularRedirects(true);
-
-        String response = weblogin.open(
-                "https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
-        }
-        String viewState = matcher.group(1);
-        matcher = reLoginToken.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(
-                    res.getText(R.string.unable_to_find).toString() + " LoginToken.");
-        }
-        String loginToken = matcher.group(1);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("login:userId", getUsername()));
-        postData.add(new BasicNameValuePair("login:pin", getPassword()));
-        postData.add(new BasicNameValuePair("login", "login"));
-        postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
-        postData.add(
-                new BasicNameValuePair("login:time", Long.toString(System.currentTimeMillis())));
-        postData.add(new BasicNameValuePair("login:loginToken", loginToken));
-        postData.add(new BasicNameValuePair("login:loginButton", "login:loginButton"));
-        return new LoginPackage(weblogin, postData, response, weblogin.getCurrentURI());
-    }
-
     public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
@@ -196,7 +140,7 @@ public class Lansforsakringar extends Bank {
         return readJsonValue(urlopen.openStream(url, postData, false), valueType);
     }
 
-    public String objectAsJson(Object value) {
+    private String objectAsJson(Object value) {
         try {
             return mObjectMapper.writeValueAsString(value);
         } catch (JsonProcessingException e) {
@@ -271,7 +215,7 @@ public class Lansforsakringar extends Bank {
             return;
         }
 
-        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        ArrayList<Transaction> transactions = new ArrayList<>();
         //TODO: Get upcoming transactions?
         //TransactionsResponse tr = readJsonValue(API_BASEURL + "account/upcoming", objectAsJson(new UpcomingTransactionsRequest(account.getId())), TransactionsResponse.class);
 

commit 4bb43d0f11535f4289c762d326cc066b9a3ee681
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 29 21:10:39 2016 +0200

    Upgrades gradle wrapper to v 3.1

diff --git gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
index 3baa851..6ffa237 100644
Binary files gradle/wrapper/gradle-wrapper.jar and gradle/wrapper/gradle-wrapper.jar differ
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 9aab6dd..8893515 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Sat Sep 24 21:00:18 CEST 2016
+#Thu Sep 29 21:09:55 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
diff --git gradlew gradlew
index 27309d9..9aa616c 100755
--- gradlew
+++ gradlew
@@ -161,4 +161,9 @@ function splitJvmOpts() {
 eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
 JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
 
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
+  cd "$(dirname "$0")"
+fi
+
 exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git gradlew.bat gradlew.bat
index f6d5974..e95643d 100644
--- gradlew.bat
+++ gradlew.bat
@@ -49,7 +49,6 @@ goto fail
 @rem Get command-line arguments, handling Windows variants
 
 if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
 
 :win9xME_args
 @rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
 if "x%~1" == "x" goto execute
 
 set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
 
 :execute
 @rem Setup the command line

commit d30984efccc160b1e094db4482cc5e585a5c7780 (tag: v1.9.10.8)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 29 21:03:51 2016 +0200

    Creates release 1.9.10.8

diff --git CHANGELOG CHANGELOG
index 30894f2..6874b26 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,6 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-v1.9.10.8
+v1.9.10.8 (2016-09-29)
 * Add a Volatile account to the Test Bank that always changes its balance.
 * Fix widget not updating when the balance change was lower than the notification threshold.
 
diff --git app/build.gradle app/build.gradle
index 192ce23..9043e6e 100644
--- app/build.gradle
+++ app/build.gradle
@@ -31,8 +31,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 24
-        versionCode 223
-        versionName "1.9.10.7"
+        versionCode 224
+        versionName "1.9.10.8"
     }
 
     signingConfigs {

commit 42b661587b868dd654f2c6c57685b6b8249785d1
Author: Johan Walles <johan.walles@gmail.com>
Date:   Mon Sep 26 20:12:46 2016 +0200

    Fix widget not refreshing on auto updates
    
    Before this change:
    * when the banks were auto updated
    * and the bank's balance change was lower than the notification
      threshold
    ... then the widget wasn't updated.
    
    With this change in place the widget is actually updated even in this
    case.
    
    This change also adds unit testing of the auto update data retrieval
    code.

diff --git CHANGELOG CHANGELOG
index 3b8edb8..30894f2 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 v1.9.10.8
 * Add a Volatile account to the Test Bank that always changes its balance.
+* Fix widget not updating when the balance change was lower than the notification threshold.
 
 v1.9.10.7 (2016-08-18)
 * Update certificates for AmericanExpress and Coop
diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index df3dc78..6f65d6f 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -42,11 +42,12 @@ Development
   Mikael Eriksson                   https://github.com/mikaeler
   Mikael Auno                       https://github.com/auno
   robho                             https://github.com/robho
+  Johan Walles                      https://github.com/walles
 
 
   Stats at:
   https://github.com/liato/android-bankdroid/graphs/contributors?type=a
- 
+
 --------------------------------------------------------------------------------
 Beta testing
 --------------------------------------------------------------------------------
diff --git app/build.gradle app/build.gradle
index aeb3bed..192ce23 100644
--- app/build.gradle
+++ app/build.gradle
@@ -80,4 +80,7 @@ dependencies {
     compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
         transitive = true;
     }
+
+    testCompile 'junit:junit:4.12'
+    testCompile 'org.mockito:mockito-core:1.10.19'
 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index ad350ec..f50a11d 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -16,6 +16,19 @@
 
 package com.liato.bankdroid.appwidget;
 
+import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.liveview.LiveViewService;
+
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -32,26 +45,15 @@ import android.os.AsyncTask;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
+import android.support.annotation.NonNull;
 import android.support.v4.app.NotificationCompat;
 import android.util.Log;
 
-import com.crashlytics.android.Crashlytics;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.MainActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.liveview.LiveViewService;
-
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 
 public class AutoRefreshService extends Service {
 
@@ -208,7 +210,7 @@ public class AutoRefreshService extends Service {
                 ni.isConnected() &&
                 shouldUpdateOnRoaming(ni)) {
             if (InsideUpdatePeriod()) {
-                new DataRetrieverTask().execute();
+                new DataRetrieverTask(this).execute();
             } else {
                 Log.v(TAG, "Skipping update due to not in update period.");
                 stopSelf();
@@ -253,32 +255,54 @@ public class AutoRefreshService extends Service {
         return null;
     }
 
-    private class DataRetrieverTask extends AsyncTask<String, String, Void> {
+    static class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
-        SharedPreferences prefs = PreferenceManager
-                .getDefaultSharedPreferences(AutoRefreshService.this);
+        private final SharedPreferences prefs;
 
         private ArrayList<String> errors;
+        protected final AutoRefreshService autoRefreshService;
 
         private Resources res;
 
-        public DataRetrieverTask() {
+        // This constructor is for unit testing only
+        protected DataRetrieverTask(AutoRefreshService autoRefreshService, SharedPreferences prefs) {
+            this.autoRefreshService = autoRefreshService;
+            this.prefs = prefs;
+        }
+
+        public DataRetrieverTask(AutoRefreshService autoRefreshService) {
+            this(autoRefreshService,
+                    PreferenceManager.getDefaultSharedPreferences(autoRefreshService));
         }
 
         @Override
         protected void onPreExecute() {
         }
 
+        protected List<Bank> getBanks() {
+            return BankFactory.banksFromDb(autoRefreshService, true);
+        }
+
+        @NonNull
+        protected DBAdapter getDBAdapter() {
+            return new DBAdapter(autoRefreshService);
+        }
+
+        protected void sendWidgetRefresh() {
+            final Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
+            autoRefreshService.sendBroadcast(updateIntent);
+            AutoRefreshService.sendWidgetRefresh(autoRefreshService);
+        }
+
         @Override
         protected Void doInBackground(final String... args) {
             errors = new ArrayList<String>();
             Boolean refreshWidgets = false;
-            final ArrayList<Bank> banks = BankFactory.banksFromDb(
-                    AutoRefreshService.this, true);
+            final List<Bank> banks = getBanks();
             if (banks.isEmpty()) {
                 return null;
             }
-            final DBAdapter db = new DBAdapter(AutoRefreshService.this);
+            final DBAdapter db = getDBAdapter();
             BigDecimal currentBalance;
             BigDecimal diff;
             BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0"));
@@ -304,6 +328,11 @@ public class AutoRefreshService extends Service {
                     }
                     bank.update();
                     diff = currentBalance.subtract(bank.getBalance());
+
+                    if (diff.compareTo(BigDecimal.ZERO) != 0) {
+                        refreshWidgets = true;
+                    }
+
                     if (diff.compareTo(new BigDecimal(0)) != 0
                             && diff.abs().compareTo(minDelta) != -1) {
                         Account oldAccount;
@@ -343,10 +372,8 @@ public class AutoRefreshService extends Service {
                                         diff = account.getBalance().subtract(
                                                 oldAccount.getBalance());
                                         showNotification(bank, account, diff,
-                                                AutoRefreshService.this);
+                                                autoRefreshService);
                                     }
-
-                                    refreshWidgets = true;
                                 }
                             }
                         }
@@ -362,7 +389,7 @@ public class AutoRefreshService extends Service {
                     // database transaction history
                     if (prefs.getBoolean("content_provider_enabled", false)) {
                         for (final Account account : bank.getAccounts()) {
-                            broadcastTransactionUpdate(getBaseContext(),
+                            broadcastTransactionUpdate(autoRefreshService.getBaseContext(),
                                     bank.getDbId(), account.getId());
                         }
                     }
@@ -385,9 +412,7 @@ public class AutoRefreshService extends Service {
             }
 
             if (refreshWidgets) {
-                final Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
-                sendBroadcast(updateIntent);
-                sendWidgetRefresh(AutoRefreshService.this);
+                sendWidgetRefresh();
             }
             return null;
         }
@@ -410,7 +435,7 @@ public class AutoRefreshService extends Service {
             Editor edit = prefs.edit();
             edit.putLong("autoupdates_last_update", System.currentTimeMillis());
             edit.commit();
-            AutoRefreshService.this.stopSelf();
+            autoRefreshService.stopSelf();
         }
     }
 }
diff --git app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
new file mode 100644
index 0000000..58c4489
--- /dev/null
+++ app/src/test/java/com/liato/bankdroid/appwidget/DataRetrieverTaskTest.java
@@ -0,0 +1,118 @@
+package com.liato.bankdroid.appwidget;
+
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.db.DBAdapter;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.annotation.NonNull;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DataRetrieverTaskTest {
+    private static class TestableBank extends Bank {
+        private final int balanceBeforeUpdate;
+        private final int balanceAfterUpdate;
+        private boolean hasUpdated = false;
+
+        public TestableBank(int balanceBeforeUpdate, int balanceAfterUpdate) {
+            super(Mockito.mock(Context.class));
+
+            this.balanceBeforeUpdate = balanceBeforeUpdate;
+            this.balanceAfterUpdate = balanceAfterUpdate;
+        }
+
+        @Override
+        public void update() {
+            hasUpdated = true;
+        }
+
+        @Override
+        public ArrayList<Account> getAccounts() {
+            int balance;
+            if (hasUpdated) {
+                balance = balanceAfterUpdate;
+            } else {
+                balance = balanceBeforeUpdate;
+            }
+
+            Account account = Mockito.mock(Account.class);
+            Mockito.when(account.getBalance()).thenReturn(BigDecimal.valueOf(balance));
+
+            ArrayList<Account> accounts = new ArrayList<>();
+            accounts.add(account);
+
+            return accounts;
+        }
+
+        @Override
+        public BigDecimal getBalance() {
+            return getAccounts().get(0).getBalance();
+        }
+    }
+
+    private static class TestableDataRetrieverTask extends AutoRefreshService.DataRetrieverTask {
+        private final Bank bank;
+        private boolean hasRefreshedWidget = false;
+
+        private TestableDataRetrieverTask(
+                AutoRefreshService autoRefreshService, SharedPreferences prefs, Bank bank) {
+            super(autoRefreshService, prefs);
+
+            this.bank = bank;
+        }
+
+        @Override
+        protected List<Bank> getBanks() {
+            List<Bank> returnMe = new ArrayList<>();
+            returnMe.add(bank);
+            return returnMe;
+        }
+
+        @NonNull
+        @Override
+        protected DBAdapter getDBAdapter() {
+            return Mockito.mock(DBAdapter.class);
+        }
+
+        @Override
+        protected void sendWidgetRefresh() {
+            hasRefreshedWidget = true;
+        }
+    }
+
+    @Test
+    public void testIncreaseLessThanNotificationThreshold() throws Exception {
+        AutoRefreshService autoRefreshService = Mockito.mock(AutoRefreshService.class);
+
+        SharedPreferences prefs = Mockito.mock(SharedPreferences.class);
+        Mockito.when(prefs.getString("notify_min_delta", "0")).thenReturn("300");
+
+        TestableDataRetrieverTask testMe =
+                new TestableDataRetrieverTask(autoRefreshService, prefs, new TestableBank(100, 200));
+        testMe.doInBackground();
+
+        Assert.assertTrue("Widget should have been refreshed", testMe.hasRefreshedWidget);
+    }
+
+    @Test
+    public void testNoChange() throws Exception {
+        AutoRefreshService autoRefreshService = Mockito.mock(AutoRefreshService.class);
+
+        SharedPreferences prefs = Mockito.mock(SharedPreferences.class);
+        Mockito.when(prefs.getString("notify_min_delta", "0")).thenReturn("0");
+
+        TestableDataRetrieverTask testMe =
+                new TestableDataRetrieverTask(autoRefreshService, prefs, new TestableBank(100, 100));
+        testMe.doInBackground();
+
+        Assert.assertFalse("Widget shouldn't have been refreshed", testMe.hasRefreshedWidget);
+    }
+}

commit 84b30ea6354f2a21ca40471d76a70f02bcac23e4
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Sep 28 22:22:53 2016 +0200

    Adds Slack badge

diff --git README.rst README.rst
index 6f0d790..c7c5351 100644
--- README.rst
+++ README.rst
@@ -1,9 +1,9 @@
 .. image:: https://travis-ci.org/liato/android-bankdroid.svg?branch=master
     :target: https://travis-ci.org/liato/android-bankdroid
 
-.. image:: https://badges.gitter.im/Join%20Chat.svg
-    :alt: Join the chat at https://gitter.im/liato/android-bankdroid
-    :target: https://gitter.im/liato/android-bankdroid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
+.. image:: https://bankdroid.herokuapp.com/badge.svg
+    :alt: Join the chat at https://bankdroid.herokuapp.com/
+    :target: https://bankdroid.herokuapp.com/
 
 Bankdroid
 =========

commit 6123960017c1b7d32c1867a810b101685239f828
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Sep 28 21:43:07 2016 +0200

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_easycard.pem bankdroid-legacy/src/main/res/raw/cert_easycard.pem
index b692c7f..0a1c6cb 100644
--- bankdroid-legacy/src/main/res/raw/cert_easycard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_easycard.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIGcDCCBVigAwIBAgIQIBLV1aMHhwIvpDSH8jsnLDANBgkqhkiG9w0BAQsFADB3
+MIIGcjCCBVqgAwIBAgIQB8lyS7zLlYN0QgIpKT0xMDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwODE4MDAwMDAwWhcNMTYwOTA0
-MjM1OTU5WjCB9TETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwODA1MDAwMDAwWhcNMTcwOTA1
+MjM1OTU5WjCB8DETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzU1NjU1Mi0zNTg1MQswCQYDVQQGEwJT

-XFEii/wZ3VLPyzEJ0WXObbtjE3Y=

+oUqagmah9/w06kPvE1LqLw5zhZvm0A==
 -----END CERTIFICATE-----
 kundportal.cerdo.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_meniga.pem bankdroid-legacy/src/main/res/raw/cert_meniga.pem
index 828d693..9b52725 100644
--- bankdroid-legacy/src/main/res/raw/cert_meniga.pem
+++ bankdroid-legacy/src/main/res/raw/cert_meniga.pem
@@ -1,31 +1,40 @@
 -----BEGIN CERTIFICATE-----

-83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0=

+rUgT/u18sTiJ/VynHSJNdQ==
 -----END CERTIFICATE-----
 www.meniga.is:443
diff --git bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
index 99b6565..218e2f3 100644
--- bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
+++ bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
@@ -1,8 +1,8 @@
 -----BEGIN CERTIFICATE-----
-MIIG9zCCBd+gAwIBAgIQNbf9NhCle6o26BwNVVbfTDANBgkqhkiG9w0BAQsFADB3
+MIIHADCCBeigAwIBAgIQDAxQC/0E8l6cRqJZhsHVPTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwNjI2MDAwMDAwWhcNMTYwOTE3
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNjI3MDAwMDAwWhcNMTcwOTE4
 MjM1OTU5WjCCAQIxEzARBgsrBgEEAYI3PAIBAxMCREsxHTAbBgNVBA8TFFByaXZh
 dGUgT3JnYW5pemF0aW9uMREwDwYDVQQFEwgxMzUyMjE5NzELMAkGA1UEBhMCREsx
 DTALBgNVBBEMBDE0MDExEzARBgNVBAgMCkNvcGVuaGFnZW4xEzARBgNVBAcMCkNv
@@ -14,28 +14,28 @@ bLx1jG6PWnKJHwmOjx+cuYOdESBKpxJKvJeiN7S0EAWdPu/iOFmBB0z+aYi/gxwz
 eRz9s4iAgoZM/krLZcclqF4+rDDutQq+pOml7f8DPMO2SNDRxMc+6M5pfWvfaCRT
 6+BngRac2IigSYjIclc4S7bxX07O3/SbfONPPPEpAoOmNDJ123FFt7MOzFQ4yMw7
 +9dPimG1Zox495xpWpkC9Q6gMg/R4LfpmN/QRYbQjIyEkBVPRi/qmKHBVKTpXjPB
-xE0CEy8XpY8oe4KgosSP0vjCXAt4tTK0fip8nvrpAgMBAAGjggLwMIIC7DAgBgNV
+xE0CEy8XpY8oe4KgosSP0vjCXAt4tTK0fip8nvrpAgMBAAGjggL5MIIC9TAgBgNV
 HREEGTAXghV3d3cubmV0YmFuay5ub3JkZWEuZGswCQYDVR0TBAIwADAOBgNVHQ8B

-eT3tiWPk6FAVE7Q=

+qh6i9DDaCOeqbWj8ZNfvIAa9VCQ=
 -----END CERTIFICATE-----
 www.netbank.nordea.dk:443
diff --git bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
index c9e5693..2c7e128 100644
--- bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
+++ bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIEwjCCA6qgAwIBAgIQEXBl353tWyoPPBA+rSg/KjANBgkqhkiG9w0BAQsFADB+
+MIIFyzCCBLOgAwIBAgIQNuC1ww5v/flYBsp+YToqozANBgkqhkiG9w0BAQsFADB+
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj
-IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE1MDkxMTAwMDAwMFoX
-DTE2MDkxMTIzNTk1OVowXDELMAkGA1UEBhMCRkkxEDAOBgNVBAgMB1V1c2ltYWEx
+IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MDkxMzAwMDAwMFoX
+DTE3MDkxNDIzNTk1OVowXDELMAkGA1UEBhMCRkkxEDAOBgNVBAgMB1V1c2ltYWEx
 ETAPBgNVBAcMCEhlbHNpbmtpMRYwFAYDVQQKDA1PUCBPc3V1c2t1bnRhMRAwDgYD
 VQQDDAdtLm9wLmZpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlU2n
 tR+HsJxXUG19V0nLXNGzDlO6JV/nZfYtebWDSTXIbbU+7+Nkp7sKXZ0Q7h5HgWQC
@@ -11,19 +11,24 @@ wRsy1BQpILs8aJW4cS8k8P8D4sinT7hkB7RknJlLGlYP6ET9ueypeCejQf3/FZAC
 LW75G3/KgMEYp6oYHB0rkqiYdDF7x0xwzYLXpzqrYcK4LEYer6vQ1TKDzbcl0z4W
 hfvd1yTvj2jhh2XBcqYGkq1tkESBMDRY/BGHWtmv9lA19pDl8bPtguwzVlRHyG2Y
 HSsGL5xeYEkKMxZU9hVeapjYyrIn1aQkL5MBWZWs/GFyL4muNQL3r0/VGaDS8EJh
-uzl+W+RJZq2D59/fcQIDAQABo4IBXDCCAVgwEgYDVR0RBAswCYIHbS5vcC5maTAJ
+uzl+W+RJZq2D59/fcQIDAQABo4ICZTCCAmEwEgYDVR0RBAswCYIHbS5vcC5maTAJ
 BgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
 KwYBBQUHAwIwYQYDVR0gBFowWDBWBgZngQwBAgIwTDAjBggrBgEFBQcCARYXaHR0
-cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGRoXaHR0cHM6Ly9kLnN5
+cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGQwXaHR0cHM6Ly9kLnN5
 bWNiLmNvbS9ycGEwHwYDVR0jBBgwFoAUX2DPYZBV34RDFIpgKrL1evRDGO8wKwYD
 VR0fBCQwIjAgoB6gHIYaaHR0cDovL3NzLnN5bWNiLmNvbS9zcy5jcmwwVwYIKwYB
 BQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8vc3Muc3ltY2QuY29tMCYGCCsG
-AQUFBzAChhpodHRwOi8vc3Muc3ltY2IuY29tL3NzLmNydDANBgkqhkiG9w0BAQsF
-AAOCAQEAjoIh7VARmvMxzy+7TMGYIIp00X+Y7sLua8JHFcOqnUKVLRAzQs7RzJ8V
-VzGpb/xjgHB8cPZSQD6nImR2QFgIn/wPWP9kLNEDgOOCtAZJHQGChWnulPWguEl4
-Vmoc6mPObz8IBO3xK8ELOstAQy+P8JXGluwRzaKcIkV13XAqvJlD1oKwqpL7aDyq
-45qEfD438kp5aSJ6ETZjThCoYgIx5S18U/LDm+5+gZI+LwxY9lb27pbrAYGuLaK2
-GJQsYHpKXbweETWXWoCcxLC7KyX8Vcx9mQO4f8kCidd1hYrVQWBGifNzUKj0gc5M
-bCeldzB9nAQ/I/ibHX6t+93A5AEkpw==

 -----END CERTIFICATE-----
 m.op.fi:443
diff --git bankdroid-legacy/src/main/res/raw/cert_villabanken.pem bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
index b692c7f..0a1c6cb 100644
--- bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
+++ bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIGcDCCBVigAwIBAgIQIBLV1aMHhwIvpDSH8jsnLDANBgkqhkiG9w0BAQsFADB3
+MIIGcjCCBVqgAwIBAgIQB8lyS7zLlYN0QgIpKT0xMDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwODE4MDAwMDAwWhcNMTYwOTA0
-MjM1OTU5WjCB9TETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwODA1MDAwMDAwWhcNMTcwOTA1
+MjM1OTU5WjCB8DETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzU1NjU1Mi0zNTg1MQswCQYDVQQGEwJT

-XFEii/wZ3VLPyzEJ0WXObbtjE3Y=

+oUqagmah9/w06kPvE1LqLw5zhZvm0A==
 -----END CERTIFICATE-----
 kundportal.cerdo.se:443

commit 91de0082b1d0c402416e74d6f0c5cd3284a1604b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Sep 28 21:23:22 2016 +0200

    Add caching for travis

diff --git .travis.yml .travis.yml
index b7186c2..ba6f24b 100644
--- .travis.yml
+++ .travis.yml
@@ -1,5 +1,13 @@
 language: android
 jdk: oraclejdk8
+
+before_cache:
+  - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
+cache:
+  directories:
+    - $HOME/.gradle/caches/
+    - $HOME/.gradle/wrapper/
+
 env:
   matrix:
     - ANDROID_TARGET=android-24  ANDROID_ABI=armeabi-v7a
@@ -11,7 +19,7 @@ android:
     - build-tools-24.0.1
     - android-24
     - extra-android-m2repository
-    
+
 script: ./gradlew assembleDebug check
 
 notifications:

commit 9dda76625707ef95d09ed1324bec39ce55047511
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Sep 28 21:14:09 2016 +0200

    Adds missing keystore.properties file

diff --git app/keystore.properties.example app/keystore.properties
similarity index 100%
rename from app/keystore.properties.example
rename to app/keystore.properties

commit 0a0f189addb83ef600ee2d558e76c9e1de4f674e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Sep 24 21:37:17 2016 +0200

    Upgrade gradle to 3.1 and android-gradle-plugin to 2.2

diff --git .gitignore .gitignore
index 884bba3..3e8418e 100644
--- .gitignore
+++ .gitignore
@@ -46,3 +46,4 @@ app/src/main/java/com/liato/bankdroid/db/Crypto.java.dev
 dev/
 app/release.keystore
 app/crashlytics.properties
+app/keystore.properties
diff --git app/build.gradle app/build.gradle
index 1cff76e..aeb3bed 100644
--- app/build.gradle
+++ app/build.gradle
@@ -18,6 +18,9 @@ repositories {
     maven { url 'https://maven.fabric.io/public' }
 }
 
+def keystorePropertiesFile = project.file("keystore.properties")
+def keystoreProperties = new Properties()
+keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
 
 android {
     compileSdkVersion 24
@@ -34,10 +37,10 @@ android {
 
     signingConfigs {
         release {
-            storeFile file("release.keystore")
-            storePassword ""
-            keyAlias "andmrkt"
-            keyPassword ""
+            storeFile file(keystoreProperties['storeFile'])
+            storePassword keystoreProperties['storePassword']
+            keyAlias keystoreProperties['keyAlias']
+            keyPassword keystoreProperties['keyPassword']
         }
     }
 
@@ -55,26 +58,6 @@ android {
         disable 'InvalidPackage'
     }
 
-    // Get signing keys for release
-    gradle.taskGraph.whenReady { taskGraph ->
-        if(taskGraph.hasTask(':app:assembleRelease')) {
-            if(System.console() != null) { 
-                def keystorePassword = System.console().readPassword("\nEnter keystore password: ")
-                keystorePassword = new String(keystorePassword)
-                if(keystorePassword.isEmpty()) {
-                    throw new InvalidUserDataException("You must enter a keystore password to proceed.")
-                }
-                def password = System.console().readPassword("Enter key password: ")
-                password = new String(password)
-                if(password.isEmpty()) {
-                    throw new InvalidUserDataException("You must enter a password to proceed.")
-                }
-                android.signingConfigs.release.storePassword keystorePassword
-                android.signingConfigs.release.keyPassword password
-            }
-        }
-    }
-        
     buildTypes {
         release {
             minifyEnabled false
diff --git app/keystore.properties.example app/keystore.properties.example
new file mode 100644
index 0000000..1501bf8
--- /dev/null
+++ app/keystore.properties.example
@@ -0,0 +1,4 @@
+storePassword=
+keyPassword=
+keyAlias=andmrkt
+storeFile=release.keystore
diff --git build.gradle build.gradle
index 087cd79..75ad630 100644
--- build.gradle
+++ build.gradle
@@ -2,10 +2,10 @@
 
 buildscript {
     repositories {
-        mavenCentral()
+        jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.1.3'
+        classpath 'com.android.tools.build:gradle:2.2.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -19,5 +19,5 @@ allprojects {
 }
 
 task wrapper(type: Wrapper) {
-    gradleVersion = '2.14.1'
+    gradleVersion = '3.1'
 }
diff --git gradle.properties gradle.properties
index 5d08ba7..c00f681 100644
--- gradle.properties
+++ gradle.properties
@@ -10,9 +10,9 @@
 # Specifies the JVM arguments used for the daemon process.
 # The setting is particularly useful for tweaking memory settings.
 # Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
 
 # When configured, Gradle will run in incubating parallel mode.
 # This option should only be used with decoupled projects. More details, visit
 # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
+# org.gradle.parallel=true
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index cf638ec..9aab6dd 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Aug 31 22:48:54 CEST 2016
+#Sat Sep 24 21:00:18 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip

commit 19bd194b14de01cbb893690c21e38015c843385d
Merge: 7f40600 52df977
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Sep 24 20:43:37 2016 +0200

    Merge pull request #606 from walles/walles/volatile-testbank
    
    Add a Volatile account to the Test Bank

commit 52df977cd78e15a5777f1eadb81428dff6e4e912 (walles/walles/volatile-testbank, walles/volatile-testbank)
Author: Johan Walles <johan.walles@gmail.com>
Date:   Thu Sep 22 19:25:32 2016 +0200

    Add a Volatile account to the Test Bank
    
    The account changes its balance randomly every time you refresh it.
    
    The purpose of the volatile account is to help me debug why the widget
    doesn't update even though the app does. For that I want an account that
    always changes its balance.
    
    Also, before this change the Test Bank didn't have any accounts, since
    the URL where it tries to get its data from isn't available any more.
    With this change in place the Test Bank at least gets one account.

diff --git CHANGELOG CHANGELOG
index 2c3853c..3b8edb8 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.8
+* Add a Volatile account to the Test Bank that always changes its balance.
+
 v1.9.10.7 (2016-08-18)
 * Update certificates for AmericanExpress and Coop
 
@@ -86,7 +89,7 @@ v1.9.8.0 (2015-02-27)
 * Fixes support for Nordea accounts with number in the account name
 * Fixes Swedbank and Sparbankerna if you have corporate credit card
 * Fixes www login for Coop
-* Fixes application crash if SonyEricsson's LiveView integration is enabled 
+* Fixes application crash if SonyEricsson's LiveView integration is enabled
 * Fixes application crash if screen is rotated during a bank update
 * Improved error handling
 * Disabled www-button for Swedbank and Sparbankerna
@@ -105,7 +108,7 @@ v1.9.7.4: (2015-02-21)
 * Fix for null currency for credit cards for Swedbank and Sparbankerna. Defaults to SEK.
 * Fix Handshake failed errors for FirstCard and PostGirot
 * Fix for credit card currency error for Nordea (thanks to Ree)
-* Fix for Västtrafik (thanks to jonasgroth) 
+* Fix for Västtrafik (thanks to jonasgroth)
 * Fix balance for Avanza (thanks to fredrike)
 
 v1.9.7.3: (2014-11-21)
@@ -344,7 +347,7 @@ v1.8.7: (2012-01-29)
 
 
 v1.8.6: (2012-01-29)
-* Fix for SEB 
+* Fix for SEB
 * Fix for LED color picker on pre ICS devices
 
 
@@ -479,13 +482,13 @@ v1.6.0: (2010-12-29)
 
 v1.5.3: (2010-12-21)
 + Support for Ikano Bank
-+ MedMera Faktura for Coop 
++ MedMera Faktura for Coop
 * Multiple accounts for Eurocard
 
 
 v1.5.2: (2010-12-18)
 + Support for Diners Club
-+ Transactions for Länsförsäkringar 
++ Transactions for Länsförsäkringar
 
 
 v1.5.1: (2010-12-15)
@@ -542,7 +545,7 @@ v1.4.0: (2010-11-02)
 + Support for First Card with transactions
 * Avanza was split into Avanza and AvanzaMini
 + Nordea credit cards (Visa Gold and others)
-+ Transactions for Coop MedMera Visa 
++ Transactions for Coop MedMera Visa
 * Statoil Mastercard fixed
 * Transactions for Handelsbanken fixed
 * A bit faster updates by skipping an unnecessary login when fetching transactions (thanks to DEGE)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index 5e24c77..7959116 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -31,7 +31,9 @@ import android.text.Html;
 import android.text.InputType;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -55,6 +57,10 @@ public class TestBank extends Bank {
 
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
+    private static final String VOLATILE_ACCOUNT_NAME = "Volatile";
+
+    private final Random random = new Random();
+
     private Pattern reAccounts = Pattern.compile(
             "<div>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</",
             Pattern.CASE_INSENSITIVE);
@@ -87,6 +93,30 @@ public class TestBank extends Bank {
         return urlopen;
     }
 
+    /**
+     * Adds a new account to the accounts list.
+     * <p/>
+     * If the account is already there it will have its balance updated.
+     * <p/>
+     * The purpose of this account is to test updates and how they propagate in the UI.
+     */
+    private void addVolatileAccount() {
+        Account volatileAccount = null;
+        for (Account account: accounts) {
+            if (VOLATILE_ACCOUNT_NAME.equals(account.getName())) {
+                volatileAccount = account;
+            }
+        }
+
+        if (volatileAccount == null) {
+            volatileAccount =
+                new Account(VOLATILE_ACCOUNT_NAME, BigDecimal.ZERO, VOLATILE_ACCOUNT_NAME);
+            accounts.add(volatileAccount);
+        }
+        double balance = Math.round(random.nextDouble() * 1000000) / 100;
+        volatileAccount.setBalance(BigDecimal.valueOf(balance));
+    }
+
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
@@ -105,7 +135,6 @@ public class TestBank extends Bank {
              * 2: Amount            83553,70
              * 3: ID                1
              * 4: Type              trans|fund
-             *
              */
             Account acc = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
                     Helpers.parseBalance(matcher.group(2)),
@@ -118,6 +147,8 @@ public class TestBank extends Bank {
             accounts.add(acc);
         }
 
+        addVolatileAccount();
+
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }

commit 7f40600987935c8f7292c67d95afa3569c0424fe
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Aug 31 22:50:37 2016 +0200

    Upgrade gradle to 2.14.1 and android gradle build tool to 2.1.3

diff --git build.gradle build.gradle
index 5e265de..087cd79 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.1.2'
+        classpath 'com.android.tools.build:gradle:2.1.3'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -19,5 +19,5 @@ allprojects {
 }
 
 task wrapper(type: Wrapper) {
-    gradleVersion = '2.14'
+    gradleVersion = '2.14.1'
 }
diff --git gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
index 2c6137b..3baa851 100644
Binary files gradle/wrapper/gradle-wrapper.jar and gradle/wrapper/gradle-wrapper.jar differ
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index c853fe7..cf638ec 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Jul 10 12:14:33 CEST 2016
+#Wed Aug 31 22:48:54 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
diff --git gradlew gradlew
index 9d82f78..27309d9 100755
--- gradlew
+++ gradlew
@@ -6,12 +6,30 @@
 ##
 ##############################################################################
 
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
 
 APP_NAME="Gradle"
 APP_BASE_NAME=`basename "$0"`
 
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD="maximum"
 
@@ -30,6 +48,7 @@ die ( ) {
 cygwin=false
 msys=false
 darwin=false
+nonstop=false
 case "`uname`" in
   CYGWIN* )
     cygwin=true
@@ -40,26 +59,11 @@ case "`uname`" in
   MINGW* )
     msys=true
     ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
 esac
 
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
 # Determine the Java command to use to start the JVM.
@@ -85,7 +89,7 @@ location of your Java installation."
 fi
 
 # Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
     MAX_FD_LIMIT=`ulimit -H -n`
     if [ $? -eq 0 ] ; then
         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
diff --git gradlew.bat gradlew.bat
index 72d362d..f6d5974 100644
--- gradlew.bat
+++ gradlew.bat
@@ -8,14 +8,14 @@
 @rem Set local scope for the variables with windows NT shell
 if "%OS%"=="Windows_NT" setlocal
 
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
 set DIRNAME=%~dp0
 if "%DIRNAME%" == "" set DIRNAME=.
 set APP_BASE_NAME=%~n0
 set APP_HOME=%DIRNAME%
 
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
 @rem Find java.exe
 if defined JAVA_HOME goto findJavaFromJavaHome
 

commit 9aeada1b3eb0470f66682589537b3f5ac220051b (tag: v1.9.10.7)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 18 08:30:55 2016 +0200

    Create release 1.9.10.7

diff --git CHANGELOG CHANGELOG
index 111387f..2c3853c 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.7 (2016-08-18)
+* Update certificates for AmericanExpress and Coop
+
 v1.9.10.6 (2016-08-01)
 * Update outdated certificates
 * Upgrade to android-build-tools v.24
diff --git app/build.gradle app/build.gradle
index e0ef2eb..1cff76e 100644
--- app/build.gradle
+++ app/build.gradle
@@ -28,8 +28,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 24
-        versionCode 222
-        versionName "1.9.10.6"
+        versionCode 223
+        versionName "1.9.10.7"
     }
 
     signingConfigs {

commit 4be0e845f185ba3e47801340ecd7f74ac3470fed
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 18 08:26:22 2016 +0200

    Update certificates for Coop and AmericanExpress

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index c28450d..50b4af7 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,48 +1,49 @@
 -----BEGIN CERTIFICATE-----
-MIIIRzCCBy+gAwIBAgIQM6YtQegAKinET998p+HuNzANBgkqhkiG9w0BAQsFADBE
+MIIImjCCB4KgAwIBAgIQTDOPvHuUgF2iSeyuNS8FtDANBgkqhkiG9w0BAQsFADBE
 MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU
-R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYwNzExMDAwMDAwWhcNMTcwNzExMjM1
+R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYwODEwMDAwMDAwWhcNMTcwODA3MjM1
 OTU5WjCBjjELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0FyaXpvbmExEDAOBgNVBAcM
 B1Bob2VuaXgxPTA7BgNVBAoMNEFtZXJpY2FuIEV4cHJlc3MgVHJhdmVsIFJlbGF0
 ZWQgU2VydmljZXMgQ29tcGFueSBJbmMxHDAaBgNVBAMME2FtZXJpY2FuZXhwcmVz

-AZQ56voKxlA5uzI=

 -----END CERTIFICATE-----
 www.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_coop.pem bankdroid-legacy/src/main/res/raw/cert_coop.pem
index 808a4d0..2baed7e 100644
--- bankdroid-legacy/src/main/res/raw/cert_coop.pem
+++ bankdroid-legacy/src/main/res/raw/cert_coop.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIGfzCCBWegAwIBAgIQE5zdq5ZwHaepzP86A5rUcjANBgkqhkiG9w0BAQsFADB3
+MIIGiDCCBXCgAwIBAgIQXZGLlRfJZXnZe5PsDszKujANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUxMTE2MDAwMDAwWhcNMTYwODI1
-MjM1OTU5WjCB5TETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwODA0MDAwMDAwWhcNMTcwODI2
+MjM1OTU5WjCB1zETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzU1NjcxMC01NDgwMQswCQYDVQQGEwJT
 RTEPMA0GA1UEEQwGMTcxIDQxMRIwEAYDVQQIDAlTdG9ja2hvbG0xDjAMBgNVBAcM
 BVNvbG5hMRkwFwYDVQQJDBBFTkdMVU5EQVbDhEdFTiA0MRgwFgYDVQQKDA9Db29w

-F4EcgP8rjJT4pM3jnw0hWoGw4ll1u1dpc/QuYWAu5EQllo8=

 -----END CERTIFICATE-----
 www.coop.se:443

commit a1bf66355311ab4babef59f0137961405e2b8c53 (tag: v1.9.10.6)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Aug 1 13:41:33 2016 +0200

    Create release 1.9.10.6

diff --git CHANGELOG CHANGELOG
index b34966c..111387f 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,10 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.6 (2016-08-01)
+* Update outdated certificates
+* Upgrade to android-build-tools v.24
+* Upgrade to gradle 2.14
+
 v1.9.10.5 (2016-04-03)
 * Fix for OKQ8
 * Update certificates for AmericanExpress, DankeBank, FirstCard, Rikslunchen and SveaDirekt.
diff --git app/build.gradle app/build.gradle
index d36b345..e0ef2eb 100644
--- app/build.gradle
+++ app/build.gradle
@@ -28,8 +28,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 24
-        versionCode 221
-        versionName "1.9.10.5"
+        versionCode 222
+        versionName "1.9.10.6"
     }
 
     signingConfigs {

commit cb685d3c083d641693b0a06bcb9ea7f1a99f30d2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Aug 1 13:37:06 2016 +0200

    Upgrade cert for American Express

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index 4443013..c28450d 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,47 +1,48 @@
 -----BEGIN CERTIFICATE-----
-MIIINzCCBx+gAwIBAgIQTr1Khf/PqGUGIzynNcG/vzANBgkqhkiG9w0BAQsFADBE
+MIIIRzCCBy+gAwIBAgIQM6YtQegAKinET998p+HuNzANBgkqhkiG9w0BAQsFADBE
 MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU
-R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYwNTEwMDAwMDAwWhcNMTcwNjA5MjM1
-OTU5WjCBoTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0FyaXpvbmExEDAOBgNVBAcM
+R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTYwNzExMDAwMDAwWhcNMTcwNzExMjM1
+OTU5WjCBjjELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0FyaXpvbmExEDAOBgNVBAcM
 B1Bob2VuaXgxPTA7BgNVBAoMNEFtZXJpY2FuIEV4cHJlc3MgVHJhdmVsIFJlbGF0

+AZQ56voKxlA5uzI=
 -----END CERTIFICATE-----
 www.americanexpress.com:443

commit 1cbdb1eedc0387931c8ac494144157bfb3525b34
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jul 29 00:57:18 2016 +0200

    Upgrade to JDK8 for travis builds

diff --git .travis.yml .travis.yml
index 707cc51..b7186c2 100644
--- .travis.yml
+++ .travis.yml
@@ -1,5 +1,5 @@
 language: android
-jdk: oraclejdk7
+jdk: oraclejdk8
 env:
   matrix:
     - ANDROID_TARGET=android-24  ANDROID_ABI=armeabi-v7a

commit 1bf928f34e2e4ce92f1038e05e6c5763dfb87b70
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jul 29 00:51:29 2016 +0200

    Adds missing upgrade of legacy module

diff --git app/build.gradle app/build.gradle
index 31531df..d36b345 100644
--- app/build.gradle
+++ app/build.gradle
@@ -92,7 +92,7 @@ dependencies {
     compile project(':bankdroid-legacy')
     compile project(':bankdroid-core')
     compile 'com.jakewharton:butterknife:6.1.0'
-    compile "com.android.support:appcompat-v7:23.1.1"
+    compile "com.android.support:appcompat-v7:24.1.1"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
         transitive = true;
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index be66594..012efe0 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -2,13 +2,13 @@ apply plugin: 'com.android.library'
 apply from: '../config/quality/quality.gradle'
 
 android {
-    compileSdkVersion 23
-    buildToolsVersion "23.0.0"
+    compileSdkVersion 24
+    buildToolsVersion "24.0.1"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
         minSdkVersion 9
-        targetSdkVersion 23
+        targetSdkVersion 24
         versionCode 1
         versionName "1.0"
     }
@@ -27,7 +27,7 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-interface')
-    compile 'com.android.support:appcompat-v7:23.1.1'
+    compile 'com.android.support:appcompat-v7:24.1.1'
     compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'}
     compile 'org.jsoup:jsoup:1.7.3'
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'

commit 67836995a0077e1d67d411965a31ac2a36c78b0e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jul 29 00:31:57 2016 +0200

    Upgrade to android-24 and buildtools-24.0.1

diff --git .travis.yml .travis.yml
index 4f2c73b..707cc51 100644
--- .travis.yml
+++ .travis.yml
@@ -2,15 +2,16 @@ language: android
 jdk: oraclejdk7
 env:
   matrix:
-    - ANDROID_TARGET=android-23  ANDROID_ABI=armeabi-v7a
+    - ANDROID_TARGET=android-24  ANDROID_ABI=armeabi-v7a
 
 android:
   components:
     - tools
-    - build-tools-23.0.0
+    - platform-tools
+    - build-tools-24.0.1
+    - android-24
     - extra-android-m2repository
-    - android-23
-
+    
 script: ./gradlew assembleDebug check
 
 notifications:
diff --git app/build.gradle app/build.gradle
index 14a6de0..31531df 100644
--- app/build.gradle
+++ app/build.gradle
@@ -20,14 +20,14 @@ repositories {
 
 
 android {
-    compileSdkVersion 23
-    buildToolsVersion "23.0.0"
+    compileSdkVersion 24
+    buildToolsVersion "24.0.1"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
-        targetSdkVersion 23
+        targetSdkVersion 24
         versionCode 221
         versionName "1.9.10.5"
     }

commit 2b789dc27517b7e188eb7095d6f22fc3f53ba746
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Jul 13 22:01:00 2016 +0200

    Revert buildToolsVersion to 23.0.0

diff --git .travis.yml .travis.yml
index e602a6c..4f2c73b 100644
--- .travis.yml
+++ .travis.yml
@@ -7,7 +7,7 @@ env:
 android:
   components:
     - tools
-    - build-tools-23.0.2
+    - build-tools-23.0.0
     - extra-android-m2repository
     - android-23
 
diff --git app/build.gradle app/build.gradle
index b0195c2..14a6de0 100644
--- app/build.gradle
+++ app/build.gradle
@@ -21,7 +21,7 @@ repositories {
 
 android {
     compileSdkVersion 23
-    buildToolsVersion "23.0.2"
+    buildToolsVersion "23.0.0"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {

commit bedc26fe615a8c4350fcc5aaa9009e8382f36bdf
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Jul 13 21:52:51 2016 +0200

    Fixes failing build

diff --git .travis.yml .travis.yml
index ca57b07..e602a6c 100644
--- .travis.yml
+++ .travis.yml
@@ -6,6 +6,7 @@ env:
 
 android:
   components:
+    - tools
     - build-tools-23.0.2
     - extra-android-m2repository
     - android-23

commit 2248678ee8a7f6534d3326a2ac9d77e25b2ba7a6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Jul 10 12:26:05 2016 +0200

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index e88eeeb..4443013 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,47 +1,47 @@
 -----BEGIN CERTIFICATE-----
-MIIIGTCCBwGgAwIBAgIQf09RTR/43i5VAoutsWselDANBgkqhkiG9w0BAQsFADBE
+MIIINzCCBx+gAwIBAgIQTr1Khf/PqGUGIzynNcG/vzANBgkqhkiG9w0BAQsFADBE
 MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU

-xFeqP4kh39gEFoMNTg==

 -----END CERTIFICATE-----
 www.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_csn.pem bankdroid-legacy/src/main/res/raw/cert_csn.pem
index a545900..dd24c6d 100644
--- bankdroid-legacy/src/main/res/raw/cert_csn.pem
+++ bankdroid-legacy/src/main/res/raw/cert_csn.pem
@@ -1,32 +1,40 @@
 -----BEGIN CERTIFICATE-----
-MIIFXDCCBESgAwIBAgIQERGa0Po6OjjVmZh+gJqk0TANBgkqhkiG9w0BAQsFADB3
+MIIG5zCCBc+gAwIBAgIQTLNgc4bcnhgB4J96YXHi9jANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTQxMDIwMDAwMDAwWhcNMTYwNDIw
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNDEyMDAwMDAwWhcNMTgwNDIx
 MjM1OTU5WjCB9DETMBEGCysGAQQBgjc8AgEDEwJTRTEaMBgGA1UEDxMRR292ZXJu
 bWVudCBFbnRpdHkxFDASBgNVBAUTCzIwMjEwMC0xODE5MQswCQYDVQQGEwJTRTEP
 MA0GA1UEEQwGODUyIDM3MRIwEAYDVQQIDAlTdW5kc3ZhbGwxEjAQBgNVBAcMCVN1
 bmRzdmFsbDEcMBoGA1UECQwTTm9ycmEgVGrDpHJuZ2F0YW4gMjEkMCIGA1UECgwb
 Q2VudHJhbGEgc3R1ZGllc3RvZHNuYW1uZGVuMQwwCgYDVQQLDANDU04xEzARBgNV

 LnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF

-OFeejCXt98KVdMUSG0s7Zm6eB7pFq1dbYBlS/V30aNo=

 -----END CERTIFICATE-----
 www.csn.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_firstcard.pem bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
index 39dca97..179433a 100644
--- bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
@@ -1,37 +1,36 @@
 -----BEGIN CERTIFICATE-----

-yygJuQ8bzLYSQl9JJ7JL8yMxleAfK+3txdgmIA==

+YE4=
 -----END CERTIFICATE-----
 www.firstcard.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_forexbank.pem bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
index 324d7e4..49ff36a 100644
--- bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
@@ -1,36 +1,39 @@
 -----BEGIN CERTIFICATE-----
-MIIGIzCCBQugAwIBAgIQd0xG7Hn0mKfuw2Gx5R1fCzANBgkqhkiG9w0BAQsFADB3
+MIIGpjCCBY6gAwIBAgIQLfVa7JpgOJYVyDHLos+aYTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwNTIxMDAwMDAwWhcNMTYwNzE5
-MjM1OTU5WjCBrTETMBEGCysGAQQBgjc8AgEDEwJOTzEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNTE4MDAwMDAwWhcNMTcwODE3
+MjM1OTU5WjCBrjETMBEGCysGAQQBgjc8AgEDEwJOTzEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzkzMyAwMTIgODY3MQswCQYDVQQGEwJO

-tycBv7BN+iM2iBPW1SE/w8TqBWH7NPlqC9Dc3WYL5SspLkaKcV67

+hldUTZe6PNFogJtLQ49aehfHDSOCNLM4xrE=
 -----END CERTIFICATE-----
 nettbank.edb.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
index fd38ff7..fc5c10d 100644
--- bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
+++ bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIGcjCCBVqgAwIBAgIQCs1VH583LF5+CAZdguTD1DANBgkqhkiG9w0BAQsFADB3
+MIIGezCCBWOgAwIBAgIQae/rFgyzqL292z0BIveJUDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwNDI4MDAwMDAwWhcNMTYwNTA2
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNDI1MDAwMDAwWhcNMTcwNTA3
 MjM1OTU5WjCB+TETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xEzARBgNVBAUTCjUwMjAwNzc4NjIxCzAJBgNVBAYTAlNF
 MQ4wDAYDVQQRDAUxMTU0MDESMBAGA1UECAwJU1RPQ0tIT0xNMRIwEAYDVQQHDAlT
 VE9DS0hPTE0xGjAYBgNVBAkMEVRlZ2VsdWRkc3ZhZ2VuIDEwMSEwHwYDVQQKDBhT
-dmVuc2thIEhhbmRlbHNiYW5rZW4gQUIxDTALBgNVBAsMBEhJTlQxGzAZBgNVBAMM
+dmVuc2thIEhhbmRlbHNiYW5rZW4gQUIxDTALBgNVBAsMBENET1ExGzAZBgNVBAMM
 Em0uaGFuZGVsc2Jhbmtlbi5zZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC

 aGFuZGVsc2Jhbmtlbi5zZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNV

-8py6j8xewRxlpn2m9wkZNhuu8mRb0w==

+blFMqDEj/1eo3DvuDjonVoCOPtMitBUDAKb2ia9pcA==
 -----END CERTIFICATE-----
 m.handelsbanken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
index f4cf3a6..c3a2f70 100644
--- bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
@@ -1,39 +1,52 @@
 -----BEGIN CERTIFICATE-----

+ON+jB1Oe99EbwuPC1bFJybo=
 -----END CERTIFICATE-----
 secure.ikanobank.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_okq8.pem bankdroid-legacy/src/main/res/raw/cert_okq8.pem
index 324d7e4..49ff36a 100644
--- bankdroid-legacy/src/main/res/raw/cert_okq8.pem
+++ bankdroid-legacy/src/main/res/raw/cert_okq8.pem
@@ -1,36 +1,39 @@
 -----BEGIN CERTIFICATE-----
-MIIGIzCCBQugAwIBAgIQd0xG7Hn0mKfuw2Gx5R1fCzANBgkqhkiG9w0BAQsFADB3
+MIIGpjCCBY6gAwIBAgIQLfVa7JpgOJYVyDHLos+aYTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwNTIxMDAwMDAwWhcNMTYwNzE5
-MjM1OTU5WjCBrTETMBEGCysGAQQBgjc8AgEDEwJOTzEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNTE4MDAwMDAwWhcNMTcwODE3
+MjM1OTU5WjCBrjETMBEGCysGAQQBgjc8AgEDEwJOTzEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzkzMyAwMTIgODY3MQswCQYDVQQGEwJO

-tycBv7BN+iM2iBPW1SE/w8TqBWH7NPlqC9Dc3WYL5SspLkaKcV67

+hldUTZe6PNFogJtLQ49aehfHDSOCNLM4xrE=
 -----END CERTIFICATE-----
 nettbank.edb.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
index 5207955..b5416d5 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
@@ -1,32 +1,35 @@
 -----BEGIN CERTIFICATE-----

-YQuw4+jd

 -----END CERTIFICATE-----
 webtick.ostgotatrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_payson.pem bankdroid-legacy/src/main/res/raw/cert_payson.pem
index 87e8266..0000815 100644
--- bankdroid-legacy/src/main/res/raw/cert_payson.pem
+++ bankdroid-legacy/src/main/res/raw/cert_payson.pem
@@ -1,39 +1,39 @@
 -----BEGIN CERTIFICATE-----
-MIIGoDCCBYigAwIBAgIQA7XNnlTBRH+NCWn+tNJs0DANBgkqhkiG9w0BAQsFADB3
+MIIGsTCCBZmgAwIBAgIQGQ6DXwcjHWGwsEDhbB8dKjANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwMTE1MDAwMDAwWhcNMTYwODA5
-MjM1OTU5WjCBtDETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNjA4MDAwMDAwWhcNMTgwOTA3
+MjM1OTU5WjCBsDETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xFDASBgNVBAUTCzU1NjY0Ni0yODU4MQswCQYDVQQGEwJT

-Utz4DO4Z7SsyjWrNA3DVbXN+zZw=

+jYpLhiApQY5dOsFYOIP9pWFdV9azfAvqe1NSFQ1OSdPZoVelKA==
 -----END CERTIFICATE-----
 www.payson.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_resursbank.pem bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
index 2cc361f..73c1371 100644
--- bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
@@ -1,32 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIFQzCCBCugAwIBAgIQCGQ0CJiJ7a5ssPAWwfXMrjANBgkqhkiG9w0BAQsFADBw
+MIIFTTCCBDWgAwIBAgIQCqD2p/peVbc8aG9bqGsXHzANBgkqhkiG9w0BAQsFADBw
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
-dXJhbmNlIFNlcnZlciBDQTAeFw0xNTA2MjQwMDAwMDBaFw0xNjA3MDgxMjAwMDBa
+dXJhbmNlIFNlcnZlciBDQTAeFw0xNjA2MTUwMDAwMDBaFw0xOTA4MDUxMjAwMDBa
 MGIxCzAJBgNVBAYTAlNFMQ4wDAYDVQQIEwVTa2FuZTEUMBIGA1UEBxMLSGVsc2lu
 Z2JvcmcxFzAVBgNVBAoTDlJlc3VycyBCYW5rIEFCMRQwEgYDVQQDDAsqLnJlc3Vy

 LnJlc3Vycy5zZYIJcmVzdXJzLnNlMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
 BggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2Ny

-F9FJrJeibg==

+W/XNhjLrhdvTh2RAciWb01s=
 -----END CERTIFICATE-----
 secure.resurs.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_seb.pem bankdroid-legacy/src/main/res/raw/cert_seb.pem
index 9a25f83..915fe13 100644
--- bankdroid-legacy/src/main/res/raw/cert_seb.pem
+++ bankdroid-legacy/src/main/res/raw/cert_seb.pem
@@ -1,34 +1,41 @@
 -----BEGIN CERTIFICATE-----

-YzLm2CrBWbKi6C2uth4xbS4cldJHWWSCimVXLC8xhKzl

+HMyRgKehX5A=
 -----END CERTIFICATE-----
 mP.seb.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
index 242dcf8..a1c851f 100644
--- bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
+++ bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
@@ -1,8 +1,8 @@
 -----BEGIN CERTIFICATE-----
-MIIGoDCCBYigAwIBAgIQTHbYaos9DgSykqU0qoQj+DANBgkqhkiG9w0BAQsFADB3
+MIIHJDCCBgygAwIBAgIQR26lBh+7DwXPQtJSfT8vwjANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwNDIyMDAwMDAwWhcNMTYwNTAy
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwNDIyMDAwMDAwWhcNMTgwNTAz
 MjM1OTU5WjCB9zETMBEGCysGAQQBgjc8AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xEzARBgNVBAUTCjU1NjQ2MDE4MTIxCzAJBgNVBAYTAlNF
 MQ8wDQYDVQQRDAY2MjEgMzkxEDAOBgNVBAgMB0dvdGxhbmQxDjAMBgNVBAcMBVZp
@@ -14,26 +14,29 @@ dya1x2GujbZyyidPt3CbTtro5LbldCrdD06lVH8W5Lfl58CaI+CjuOfNvHveFDYf
 BWkBvVme0YFsnsBLaS+OI1tcLos/ZIWk5a7jFAJzdsQOlX+wZ39hmXzl+j6kDLny
 ZDpJ2ik2XRxPEvhNCMPxvtd3EMb1XBpEbnEC6KJKMAfKHdgNiwebQSVJDmtOC5Ib
 drePnnFqiDY7y9LonkmNYyME4UyPCsy9On+z+hNu51jdDBBvCsx44hhttFXv4R5q
-Ij025IKu+oy7Vs+80vG0vlKFAgMBAAGjggKlMIICoTBOBgNVHREERzBFghZhcGku
+Ij025IKu+oy7Vs+80vG0vlKFAgMBAAGjggMpMIIDJTBOBgNVHREERzBFghZhcGku
 d3d3LnN2ZW5za2FzcGVsLnNlghdsdW5hLnd3dy5zdmVuc2thc3BlbC5zZYISd3d3
 LnN2ZW5za2FzcGVsLnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud

-IjJdqIKhnCyWbUVHbXNC9uc5NKk=

+W/iRil53ZpA=
 -----END CERTIFICATE-----
 api.www.svenskaspel.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_swedbank.pem bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
index de1da63..e16225a 100644
--- bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
@@ -1,30 +1,36 @@
 -----BEGIN CERTIFICATE-----
-MIIE+TCCA+GgAwIBAgIQZuMv5N7yUoRembpcN2BERTANBgkqhkiG9w0BAQsFADB+
+MIIF/TCCBOWgAwIBAgIQf/+gywq62tbhCvTb16JhwjANBgkqhkiG9w0BAQsFADB+
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj
-IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE1MDQxMDAwMDAwMFoX
-DTE2MDQyMzIzNTk1OVowgYExCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv
+IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MDQwNzAwMDAwMFoX
+DTE3MDQyNDIzNTk1OVowgYExCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hv
 bG0xEzARBgNVBAcMClN1bmRieWJlcmcxFDASBgNVBAoMC1NXRURCQU5LIEFCMRQw
 EgYDVQQLDAtTV0VEQkFOSyBJVDEdMBsGA1UEAwwUYXV0aC5hcGkuc3dlZGJhbmsu

 ZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD

-0UQR4Q6bOkPvbFXCMH5TXVONTkI33QMTEiUZ3hg=

+wg==
 -----END CERTIFICATE-----
 auth.api.swedbank.se:443

commit 021186fe939c70dd9d2e3e968581e02e5688fb8f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Jul 10 12:24:09 2016 +0200

    Upgrades gradle to v2.14 and android build tools to v23.0.2

diff --git .travis.yml .travis.yml
index 6ddd7f4..ca57b07 100644
--- .travis.yml
+++ .travis.yml
@@ -6,7 +6,7 @@ env:
 
 android:
   components:
-    - build-tools-23.0.0
+    - build-tools-23.0.2
     - extra-android-m2repository
     - android-23
 
diff --git app/build.gradle app/build.gradle
index 14a6de0..b0195c2 100644
--- app/build.gradle
+++ app/build.gradle
@@ -21,7 +21,7 @@ repositories {
 
 android {
     compileSdkVersion 23
-    buildToolsVersion "23.0.0"
+    buildToolsVersion "23.0.2"
 
     useLibrary 'org.apache.http.legacy'
     defaultConfig {
diff --git build.gradle build.gradle
index c80e45c..5e265de 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.5.0'
+        classpath 'com.android.tools.build:gradle:2.1.2'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -19,5 +19,5 @@ allprojects {
 }
 
 task wrapper(type: Wrapper) {
-    gradleVersion = '2.4'
+    gradleVersion = '2.14'
 }
diff --git gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
index b5166da..2c6137b 100644
Binary files gradle/wrapper/gradle-wrapper.jar and gradle/wrapper/gradle-wrapper.jar differ
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 527b1f9..c853fe7 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Dec 21 08:16:02 CET 2015
+#Sun Jul 10 12:14:33 CEST 2016
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
diff --git gradlew gradlew
index 91a7e26..9d82f78 100755
--- gradlew
+++ gradlew
@@ -42,11 +42,6 @@ case "`uname`" in
     ;;
 esac
 
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
     fi
 done
 SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
 APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
@@ -114,6 +109,7 @@ fi
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git gradlew.bat gradlew.bat
index aec9973..72d362d 100644
--- gradlew.bat
+++ gradlew.bat
@@ -46,7 +46,7 @@ echo location of your Java installation.
 goto fail
 
 :init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
 
 if not "%OS%" == "Windows_NT" goto win9xME_args
 if "%@eval[2+2]" == "4" goto 4NT_args

commit f49157479b9a1c033cb3d62f887a25228f9d8252 (tag: v1.9.10.5)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Apr 3 13:20:19 2016 +0200

    Create release v1.9.10.5

diff --git CHANGELOG CHANGELOG
index a7ba190..b34966c 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.5 (2016-04-03)
+* Fix for OKQ8
+* Update certificates for AmericanExpress, DankeBank, FirstCard, Rikslunchen and SveaDirekt.
+
 v1.9.10.4 (2016-02-25)
 * Removes support for EspressoHouse
 * Adds support Högskolerestaurangers kund-/studentkort
diff --git app/build.gradle app/build.gradle
index 6ed66cf..14a6de0 100644
--- app/build.gradle
+++ app/build.gradle
@@ -28,8 +28,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 23
-        versionCode 220
-        versionName "1.9.10.4"
+        versionCode 221
+        versionName "1.9.10.5"
     }
 
     signingConfigs {

commit d6db093ef9cf4a76663743b94d71ff2f89a8a9ea
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Apr 3 13:19:50 2016 +0200

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index 4851b39..e88eeeb 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,40 +1,47 @@
 -----BEGIN CERTIFICATE-----

-bApazU27

+xFeqP4kh39gEFoMNTg==
 -----END CERTIFICATE-----
 www.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_danskebank.pem bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
index 1694f1a..328a9ec 100644
--- bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
@@ -1,31 +1,31 @@
 -----BEGIN CERTIFICATE-----

-f7/fEt942nMenqvNpWMF9jNb3rYNS9phdg==

 -----END CERTIFICATE-----
 mobil.danskebank.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_firstcard.pem bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
index 5e5cff0..39dca97 100644
--- bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
@@ -1,10 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIIFQzCCBCugAwIBAgIQX3ptE1gYbo87yC16QpVgITANBgkqhkiG9w0BAQUFADCB
+MIIGSDCCBTCgAwIBAgIQRspMb94R9QyDJGR3Nm34fTANBgkqhkiG9w0BAQUFADCB
 vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMt
 VmVyaVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMB4X
-DTE1MDEwOTAwMDAwMFoXDTE2MDMxOTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIw
+DTE1MTIyMzAwMDAwMFoXDTE2MTIzMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIw
 EAYDVQQIEwlTdG9ja2hvbG0xEjAQBgNVBAcUCVN0b2NraG9sbTEXMBUGA1UEChQO
 Tm9yZGVhIEJhbmsgQUIxGjAYBgNVBAsUEUlUIFJldGFpbCBCYW5raW5nMRkwFwYD
 VQQDFBB3d3cuZmlyc3RjYXJkLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
@@ -13,20 +13,25 @@ OKVWqraVkJq0cPNQEgknC7ocwCZdLFzMWI4jvAc83XMF226FNDf//C+O0I2XqRnm
 WS1SOVfEMh8rgxDV2sV/Tj7wMx+Y0Tj794WStrGAMnPJlz0iT94jv+YgYYiEppFr
 nr6lGtUVxrC5BGC9bUCuobpduH1NA5MJ/BKGfONEy1Pp2oBLabc/fOPAf2r9dIqM
 /NLSGrcnSEkU4wlCYha+Q6lPKSyAZSn7I79sumjne2RmvetEkDgUi85x69Sm8HG3
-MpjOOSgvQq9kriKkT0Y2XtTv9l1P6QIDAQABo4IBdDCCAXAwGwYDVR0RBBQwEoIQ
+MpjOOSgvQq9kriKkT0Y2XtTv9l1P6QIDAQABo4ICeTCCAnUwGwYDVR0RBBQwEoIQ
 d3d3LmZpcnN0Y2FyZC5zZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAoBgNV

-NA3K8eVpSw==

+yygJuQ8bzLYSQl9JJ7JL8yMxleAfK+3txdgmIA==
 -----END CERTIFICATE-----
 www.firstcard.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
index 74b9e17..7afa260 100644
--- bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
+++ bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
@@ -1,29 +1,26 @@
 -----BEGIN CERTIFICATE-----
-MIIEszCCA5ugAwIBAgIDB7nCMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAlVT
+MIIEOTCCAyGgAwIBAgIDCkK4MA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAlVT
 MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMSAwHgYDVQQDExdSYXBpZFNTTCBTSEEy

-mrN/2dgPDQ==

+rObGzID7GRO2w+H/KWkfkGe1hf1PiEZ0DGKHU3g=
 -----END CERTIFICATE-----
 www.rikslunchen.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
index cedc057..4fa7992 100644
--- bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
+++ bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
@@ -1,9 +1,9 @@
 -----BEGIN CERTIFICATE-----
-MIIFFDCCA/ygAwIBAgIQbE14YL7qz+87NhP0z0veDTANBgkqhkiG9w0BAQsFADB+
+MIIGFjCCBP6gAwIBAgIQZQtOWNvqlxeWRXvCoRU4iDANBgkqhkiG9w0BAQsFADB+
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVj
-IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE1MDMzMDAwMDAwMFoX
-DTE2MDMzMDIzNTk1OVowgYgxCzAJBgNVBAYTAlNFMRgwFgYDVQQIDA9TdG9ja2hv
+IENsYXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MB4XDTE2MDMyOTAwMDAwMFoX
+DTE3MDMzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlNFMRgwFgYDVQQIDA9TdG9ja2hv
 bG1zIEzDpG4xDjAMBgNVBAcMBVNvbG5hMRgwFgYDVQQKDA9TdmVhIEVrb25vbWkg
 QUIxFDASBgNVBAsMC1N2ZWEgRGlyZWt0MR8wHQYDVQQDDBZzZXJ2aWNlcy5zdmVh
 ZGlyZWt0LnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuHvXAKj5
@@ -12,20 +12,25 @@ k5aGpc/WyXakfDVw60+9UQwiit2bctXtI1trd9U5oRTmV9JZbSNXmDWMxpRNsFZp
 OZQlBi49DufCuDmjTmpwtV6ozcJ8rd6HdhxyHyOfvFF3Vavgsx2rvbKroBEgV8qj
 7YR3zMjWgyEelWgr4sTxr6uYWDObXiWlzKwAO0d7C5M0LtmlMjeRaBfkKvPnMWtz
 +Bi1A0P80t1jQrIfMhGNMcaSxQbCk4qpsqgzXW2831Zd8bO4yPL0OghRWOnk0ULX
-oGDHBA4GN7h7gQIDAQABo4IBgTCCAX0wMwYDVR0RBCwwKoIWc2VydmljZXMuc3Zl
+oGDHBA4GN7h7gQIDAQABo4ICgzCCAn8wMwYDVR0RBCwwKoIWc2VydmljZXMuc3Zl
 YWRpcmVrdC5zZYIQd3Muc3ZlYWRpcmVrdC5zZTAJBgNVHRMEAjAAMA4GA1UdDwEB

-/B5LM6Txr5Y=

+P2Q+Ku4TW1U8XTyODlsk3DUhaMIuI8clg2s=
 -----END CERTIFICATE-----
 services.sveadirekt.se:443

commit 747df125b48b99faa335cba7d4fd351352f2a1d0
Merge: 1e3449a d9c9bb5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 21 13:05:48 2016 +0100

    Merge pull request #602 from jonasgroth/master
    
    Fixes for OKQ8, fixes #597

commit d9c9bb57a32bd5dde9fecdc21fd4af8baf63d8f9
Author: Jonas Groth <jonas@groth.im>
Date:   Sun Mar 20 17:12:15 2016 +0100

    Fixes for OKQ8

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index dcc343f..bfb87ee 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -65,6 +65,8 @@ public class OKQ8 extends Bank {
 
     private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
 
+    private Pattern reSessionId = Pattern.compile("action=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
+
     private Pattern reBalance = Pattern
             .compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
 
@@ -99,16 +101,24 @@ public class OKQ8 extends Bank {
         Date d = new Date();
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         response = urlopen
-                .open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
+                .open("https://nettbank.edb.com/authenticate/login/basicauth?configKey=okq8");
         //p_tranid is the epoch time in milliseconds
-        postData.add(new BasicNameValuePair("p_tranid", Long.toString(d.getTime())));
-        postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
-        postData.add(new BasicNameValuePair("n_bank", ""));
-        postData.add(new BasicNameValuePair("empty_pwd", ""));
-        postData.add(new BasicNameValuePair("user_id", getUsername().toUpperCase()));
+        Matcher matcher;
+        matcher = reSessionId.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException("Could not find post action.");
+        }
+        String postAction = matcher.group(1);
+        postData.add(new BasicNameValuePair("javax.faces.ViewState",
+                postAction.substring(postAction.length()-5,postAction.length()-1)));
+        postData.add(new BasicNameValuePair("loginForm", "loginForm"));
+        postData.add(new BasicNameValuePair("button", "Logga in"));
+
+        postData.add(new BasicNameValuePair("userid", getUsername().toUpperCase()));
+        postData.add(new BasicNameValuePair("useridInput", getUsername().toUpperCase()));
         postData.add(new BasicNameValuePair("password", getPassword()));
         return new LoginPackage(urlopen, postData, response,
-                "https://nettbank.edb.com/Logon/logon/step1");
+                "https://nettbank.edb.com" + postAction);
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
@@ -118,7 +128,7 @@ public class OKQ8 extends Bank {
         LoginPackage lp = preLogin();
         List<NameValuePair> postData = lp.getPostData();
         response = urlopen.open(lp.getLoginTarget(), postData);
-        if (!response.contains("LOGON_OK")) {
+        if (!response.contains("Please wait")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -157,7 +167,7 @@ public class OKQ8 extends Bank {
         postData.add(new BasicNameValuePair("login_service_url", value));
 
         response = urlopen
-                .open("https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8", postData);
+                .open("https://nettbank.edb.com/payment/transigo/logon/done/okq8", postData);
 
         if (response.contains("HTML REDIRECT")) {
             throw new LoginException("Login failed.");
@@ -204,7 +214,7 @@ public class OKQ8 extends Bank {
         }
 
         response = urlopen
-                .open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
+                .open("https://nettbank.edb.com/payment/transigo/card/overview/lastTransactionsAccount");
 
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();

commit 1e3449ae6d4e7fd7e5b502d5996b7c5aa20f54af (tag: v1.9.10.4)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 25 22:36:57 2016 +0100

    Create release 1.9.10.4

diff --git CHANGELOG CHANGELOG
index 19d7e35..a7ba190 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,6 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-pending
+v1.9.10.4 (2016-02-25)
 * Removes support for EspressoHouse
 * Adds support Högskolerestaurangers kund-/studentkort
 * Update certificates for American Express, Marginalen, PayPal, Ticket Rikskortet, Zidisha, Östgötatrafiken
diff --git app/build.gradle app/build.gradle
index 4900367..6ed66cf 100644
--- app/build.gradle
+++ app/build.gradle
@@ -28,8 +28,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 23
-        versionCode 219
-        versionName "1.9.10.3"
+        versionCode 220
+        versionName "1.9.10.4"
     }
 
     signingConfigs {

commit 4f48f58739715fc0c023e4012f41247fd573e5c5
Merge: a1d39e5 e8bf70f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 25 22:33:54 2016 +0100

    Merge pull request #600 from robho/cert_update_2016-02-19
    
    Update certificate for Ticket Rikskortet

commit e8bf70f517fd46a7c5c0a57c45b5bf07d92fc218
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Fri Feb 19 18:44:29 2016 +0100

    Update certificate for Ticket Rikskortet

diff --git CHANGELOG CHANGELOG
index 6ea026e..19d7e35 100644
--- CHANGELOG
+++ CHANGELOG
@@ -3,7 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 pending
 * Removes support for EspressoHouse
 * Adds support Högskolerestaurangers kund-/studentkort
-* Update certificates for American Express, Marginalen, Östgötatrafiken, PayPal, Zidisha
+* Update certificates for American Express, Marginalen, PayPal, Ticket Rikskortet, Zidisha, Östgötatrafiken
 
 v1.9.10.3 (2015-12-24)
 * Fix for Länsförsäkringar
diff --git bankdroid-legacy/src/main/res/raw/cert_marginalen.pem bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
index d8b1704..ac9c03f 100644
--- bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
+++ bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
@@ -1,30 +1,36 @@
 -----BEGIN CERTIFICATE-----

-ttWldzbP0tD949p8qRZlzK7oUzO1gn2qo5MJJg==

+Qed25gfl
 -----END CERTIFICATE-----
 secure1.marginalen.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
index 5a084a1..eba3e6f 100644
--- bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
@@ -1,17 +1,17 @@
 -----BEGIN CERTIFICATE-----
-MIIFOTCCBCGgAwIBAgISESEKBmfZ1abMQsp2Zyzh1yHFMA0GCSqGSIb3DQEBCwUA
+MIIFOTCCBCGgAwIBAgISESFqmv9qazcTAAxXLzgtX5bJMA0GCSqGSIb3DQEBCwUA
 MGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTwwOgYD
 VQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gU0hB
-MjU2IC0gRzIwHhcNMTUwMjE4MDkzMTAyWhcNMTYwMzI4MTMwMDAwWjBnMQswCQYD
+MjU2IC0gRzIwHhcNMTYwMjE1MTAzNjA0WhcNMTcwNDI4MTMwMDAwWjBnMQswCQYD
 VQQGEwJGUjEXMBUGA1UECBMOSGF1dHMtZGUtU2VpbmUxETAPBgNVBAcTCE1hbGFr
 b2ZmMRMwEQYDVQQKEwpFREVOUkVEIFNBMRcwFQYDVQQDEw53d3cuZWRlbnJlZC5z

 DAECAjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9y
 ZXBvc2l0b3J5LzAlBgNVHREEHjAcgg53d3cuZWRlbnJlZC5zZYIKZWRlbnJlZC5z
 ZTAJBgNVHRMEAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNV
@@ -20,12 +20,12 @@ YW5pemF0aW9udmFsc2hhMmcyLmNybDCBoAYIKwYBBQUHAQEEgZMwgZAwTQYIKwYB
 BQUHMAKGQWh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2dzb3Jn
 YW5pemF0aW9udmFsc2hhMmcycjEuY3J0MD8GCCsGAQUFBzABhjNodHRwOi8vb2Nz
 cDIuZ2xvYmFsc2lnbi5jb20vZ3Nvcmdhbml6YXRpb252YWxzaGEyZzIwHQYDVR0O

 -----END CERTIFICATE-----
 www.edenred.se:443

commit a1d39e5b96ebf03643a5cc6fd4ce4705d26ef759
Merge: d5126d9 4eabc0f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 14 21:14:42 2016 +0100

    Merge pull request #599 from liato/feature/remove-espressoHouse
    
    Removed support for EspressoHouse

commit 4eabc0ff92fef60f95a5e0b1959363ed418a1942
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Feb 14 07:38:02 2016 +0100

    Removed support for EspressoHouse

diff --git CHANGELOG CHANGELOG
index 979b164..6ea026e 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,7 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 pending
+* Removes support for EspressoHouse
 * Adds support Högskolerestaurangers kund-/studentkort
 * Update certificates for American Express, Marginalen, Östgötatrafiken, PayPal, Zidisha
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index c25ba78..4efc9dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -19,7 +19,6 @@ import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.EasyCard;
-import com.liato.bankdroid.banking.banks.EspressoHouse;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.Hemkop;
@@ -232,8 +231,8 @@ public class LegacyBankFactory {
                 return new Ostgotatrafiken(context);
             case IBankTypes.BREDBAND2VOIP:
                 return new Bredband2VoIP(context);
-            case IBankTypes.ESPRESSOHOUSE:
-                return new EspressoHouse(context);
+            // case IBankTypes.ESPRESSOHOUSE:
+            //    return new EspressoHouse(context);
             case IBankTypes.MINPENSION:
                 return new MinPension(context);
             // case IBankTypes.SPARBANKERNA_CORPORATE:
@@ -332,7 +331,7 @@ public class LegacyBankFactory {
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
         banks.add(new Bredband2VoIP(context));
-        banks.add(new EspressoHouse(context));
+        // banks.add(new EspressoHouse(context));
         banks.add(new MinPension(context));
         // banks.add(new SparbankernaCorporate(context));
         // banks.add(new SparbankernaYouth(context));

commit d5126d98bf766ec95c8ccbe02f1631fed1afb1e8
Merge: ace0e51 10bdb15
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 11 08:41:53 2016 +0100

    Merge pull request #598 from robho/cert_update_2016-02-10
    
    Update bank certificates

commit 10bdb152509e2f47c41cbba346834f9e969985d7
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Wed Feb 10 20:40:46 2016 +0100

    Update bank certificates

diff --git CHANGELOG CHANGELOG
index c1ffb94..979b164 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 pending
 * Adds support Högskolerestaurangers kund-/studentkort
+* Update certificates for American Express, Marginalen, Östgötatrafiken, PayPal, Zidisha
 
 v1.9.10.3 (2015-12-24)
 * Fix for Länsförsäkringar
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
index c680add..516f2c0 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
@@ -1,33 +1,40 @@
 -----BEGIN CERTIFICATE-----
-MIIFjjCCBHagAwIBAgIQJswJWtrh4XqrjdJTKcmUijANBgkqhkiG9w0BAQsFADB3
+MIIG6jCCBdKgAwIBAgIQMMievVyROVhb96XpEOBsbDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj

-Sh3UmBWpiuWsR+Wp2+geW7Lc2ULeyeTWM9CVCUNUtXskjg==

 -----END CERTIFICATE-----
 global.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_marginalen.pem bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
index 19aff72..d8b1704 100644
--- bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
+++ bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
@@ -1,38 +1,30 @@
 -----BEGIN CERTIFICATE-----
-MIIGiTCCBXGgAwIBAgIQHZ9Kz/deg5Ugdw5qg8rTPTANBgkqhkiG9w0BAQsFADB3
+MIIE+DCCA+CgAwIBAgIQIMsDZ0ttvaDAJmgAZ7hANTANBgkqhkiG9w0BAQsFADB+
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd

+ttWldzbP0tD949p8qRZlzK7oUzO1gn2qo5MJJg==
 -----END CERTIFICATE-----
 secure1.marginalen.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
index 8e4ae92..591a187 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -1,33 +1,33 @@
 -----BEGIN CERTIFICATE-----

-SOlRJmKO6ynrIcdfP40A4IqN9iFEEayhGdnC0UY=

+FKRv1EBIx1ZFS0Q+XfGY4rhcAApBVFvuAG9CgnAoa7RHNr4ya95b
 -----END CERTIFICATE-----
 www.ostgotatrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
index 10b7315..53c5c43 100644
--- bankdroid-legacy/src/main/res/raw/cert_paypal.pem
+++ bankdroid-legacy/src/main/res/raw/cert_paypal.pem
@@ -1,43 +1,43 @@
 -----BEGIN CERTIFICATE-----
-MIIHTTCCBjWgAwIBAgIQf8Ays2+fnhrB7auXE2UpNTANBgkqhkiG9w0BAQsFADB3
+MIIHWTCCBkGgAwIBAgIQLNGVEFQ30N5KOSAFavbCfzANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwOTAyMDAwMDAwWhcNMTcxMDMw
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTYwMjAyMDAwMDAwWhcNMTcxMDMw
 MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
 AgwIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
 VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEEQwKOTUxMzEtMjAyMTET
 MBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIU2FuIEpvc2UxFjAUBgNVBAkM
 DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoMDFBheVBhbCwgSW5jLjEUMBIGA1UECwwL
 Q0ROIFN1cHBvcnQxFzAVBgNVBAMMDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG

-nA==

+NeQitYiySDIepHGnng==
 -----END CERTIFICATE-----
 www.paypal.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_zidisha.pem bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
index 91c14c4..efb900a 100644
--- bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
+++ bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
@@ -1,32 +1,32 @@
 -----BEGIN CERTIFICATE-----

-DpTT/zON250=

+ZOxgmUzR3DLJ
 -----END CERTIFICATE-----
 www.zidisha.org:443

commit ace0e51a9311ee5ab5ea97f2bec0346a33d81960
Merge: 10dc0e8 3340e05
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Jan 10 16:16:58 2016 +0100

    Merge pull request #594 from liato/feature/hors
    
    Add support for Högskolerestaurangers kund-/studentkort

commit 3340e05d0c75c3bda21ced2174a88b8be314e68e
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Jan 9 14:01:07 2016 +0100

    Add support for Högskolerestaurangers kund-/studentkort

diff --git CHANGELOG CHANGELOG
index ded0a03..c1ffb94 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+pending
+* Adds support Högskolerestaurangers kund-/studentkort
+
 v1.9.10.3 (2015-12-24)
 * Fix for Länsförsäkringar
 
diff --git app/src/main/res/drawable/logo_hors.png app/src/main/res/drawable/logo_hors.png
new file mode 100644
index 0000000..17e381b
Binary files /dev/null and app/src/main/res/drawable/logo_hors.png differ
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 3d8ed69..c25ba78 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -1,5 +1,9 @@
 package com.liato.bankdroid.banking;
 
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
@@ -19,6 +23,7 @@ import com.liato.bankdroid.banking.banks.EspressoHouse;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.Hemkop;
+import com.liato.bankdroid.banking.banks.Hors;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
@@ -60,10 +65,6 @@ import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -243,6 +244,8 @@ public class LegacyBankFactory {
             //    return new SwedbankCorporate(context);
             // case IBankTypes.SWEDBANK_YOUTH:
             //    return new SwedbankYouth(context);
+            case IBankTypes.HORS:
+                return new Hors(context);
             default:
                 throw new BankException("BankType id not found.");
         }
@@ -335,6 +338,7 @@ public class LegacyBankFactory {
         // banks.add(new SparbankernaYouth(context));
         // banks.add(new SwedbankCorporate(context));
         // banks.add(new SwedbankYouth(context));
+        banks.add(new Hors(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
new file mode 100644
index 0000000..1709cfb
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hors.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Hors extends Bank {
+
+    private static final String TAG = "Hors";
+
+    private static final String NAME = "Hörs";
+
+    private static final String NAME_SHORT = "hors";
+
+    private static final String URL = "http://www.dittkort.se/hors/";
+
+    private static final int BANKTYPE_ID = IBankTypes.HORS;
+
+    private static final boolean DISPLAY_DECIMALS = false;
+
+    private String response = null;
+
+    public Hors(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.DISPLAY_DECIMALS = DISPLAY_DECIMALS;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+                | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+        super.INPUT_HINT_USERNAME = context.getString(R.string.card_id);
+        super.INPUT_HIDDEN_PASSWORD = true;
+    }
+
+    public Hors(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context);
+        urlopen.setAllowCircularRedirects(true);
+        response = urlopen.open("https://www.dittkort.se//q/?p=7EB4F129-0A41-417F-8FEA-51B2B75B9D24");
+
+        Document d = Jsoup.parse(response);
+        Element e = d.getElementById("__VIEWSTATE");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String viewState = e.attr("value");
+
+        e = d.getElementById("__EVENTVALIDATION");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+        }
+        String eventValidation = e.attr("value");
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__VIEWSTATEGENERATOR", "D7823E0B"));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair("_ctl0:cphMain:SmartpassTextbox", getUsername()));
+        postData.add(new BasicNameValuePair("_ctl0:cphMain:SubmitButton", "OK"));
+        postData.add(new BasicNameValuePair("_ctl0:cphMain:chbRememberSmartPassCode", "on"));
+        postData.add(new BasicNameValuePair("_ctl0:cphMain:cookieEnabled", "true"));
+        return new LoginPackage(urlopen, postData, response, "https://www.dittkort.se//q/?p=7EB4F129-0A41-417F-8FEA-51B2B75B9D24");
+    }
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("cphMain_txtGeneralCardError")) {
+            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        urlopen = login();
+        Document document = Jsoup.parse(response);
+        Element balanceElement = document.getElementById("cphMain_lblAmount");
+        if (balanceElement == null) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + res.getText(R.string.balance).toString());
+        }
+
+        Element nameElement = document.getElementById("lblCardName");
+        String accountName = nameElement == null ? NAME.toUpperCase() : nameElement.text();
+        if (this.getCustomName().isEmpty()) {
+            this.setCustomName(accountName);
+        }
+
+        Account account = new Account(accountName, Helpers.parseBalance(balanceElement.text()), "0");
+        accounts.add(account);
+        balance = balance.add(account.getBalance());
+
+        document = Jsoup.parse(urlopen.open("https://www.dittkort.se/q/Partial/Transactions.aspx?cnt=20"));
+        Elements transactionElements = document.select("tr");
+        List<Transaction> transactions = new ArrayList<Transaction>();
+        if (transactionElements != null) {
+            for (Element element : transactionElements) {
+                transactions.add(asTransaction(element));
+            }
+        }
+        account.setTransactions(transactions);
+        super.updateComplete();
+    }
+
+    private Transaction asTransaction(Element element) {
+        return new Transaction(element.child(0).text().trim(), element.child(1).text().trim(),
+                Helpers.parseBalance(element.child(2).text()));
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index df6a882..1a7a018 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -108,4 +108,5 @@ public interface IBankTypes {
     public final static int SWEDBANK_CORPORATE = 83;
     public final static int SPARBANKERNA_YOUTH = 84;
     public final static int SPARBANKERNA_CORPORATE = 85;
+    public final static int HORS = 86;
 }

commit 10dc0e89c24ff8acd885b8bef52a8ce23f80f2bc (tag: v1.9.10.3)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Dec 24 13:54:36 2015 +0100

    Creates release 1.9.10.3

diff --git CHANGELOG CHANGELOG
index e86a650..ded0a03 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.3 (2015-12-24)
+* Fix for Länsförsäkringar
+
 v1.9.10.2 (2015-12-22)
 * Fixes for Coop login.
 * Removes support for Forex Bank due to BankId requirement.
diff --git app/build.gradle app/build.gradle
index f9310c5..4900367 100644
--- app/build.gradle
+++ app/build.gradle
@@ -28,8 +28,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 23
-        versionCode 218
-        versionName "1.9.10.2"
+        versionCode 219
+        versionName "1.9.10.3"
     }
 
     signingConfigs {

commit 1d152a2cd7be328f5501c38b845d23f8d611215e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Dec 24 13:53:20 2015 +0100

    Fixes Länsförsäkringar by adding Accept header.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index f0e398d..463e25d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -155,6 +155,7 @@ public class Lansforsakringar extends Bank {
         urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
         urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
         urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
+        urlopen.addHeader("Accept", "application/json; charset=UTF-8");
         //TODO: Change user-agent to "lf-android-app" if they block Bankdroid
         //urlopen.setUserAgent("lf-android-app");
 

commit 6623a53beea6260693260ee9a0f0e77991c1c66d (tag: v1.9.10.2)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Dec 22 08:34:29 2015 +0100

    Create release 1.9.10.2

diff --git app/build.gradle app/build.gradle
index 9a70b48..f9310c5 100644
--- app/build.gradle
+++ app/build.gradle
@@ -28,8 +28,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 23
-        versionCode 217
-        versionName "1.9.10.1"
+        versionCode 218
+        versionName "1.9.10.2"
     }
 
     signingConfigs {

commit b2dd3662322043d2ae1ec1a2d2020d3abffded50
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Dec 22 08:34:09 2015 +0100

    Update cert for Meniga

diff --git CHANGELOG CHANGELOG
index f06eeb4..e86a650 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,10 +1,10 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-Pending
+v1.9.10.2 (2015-12-22)
 * Fixes for Coop login.
 * Removes support for Forex Bank due to BankId requirement.
 * Fixes for MinPension login.
-* Update certificates for Coop, ICA, Osuuspankki, PlusGirot, SevenDay & Steam.
+* Update certificates for Coop, ICA, Osuuspankki, PlusGirot, SevenDay, Meniga & Steam.
 * Fixes for Bredband2.
 * Added support for Android 6.0 Marshmallow.
 
diff --git bankdroid-legacy/src/main/res/raw/cert_meniga.pem bankdroid-legacy/src/main/res/raw/cert_meniga.pem
index a1d12c3..828d693 100644
--- bankdroid-legacy/src/main/res/raw/cert_meniga.pem
+++ bankdroid-legacy/src/main/res/raw/cert_meniga.pem
@@ -1,33 +1,31 @@
 -----BEGIN CERTIFICATE-----

-dUrs

+83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0=
 -----END CERTIFICATE-----
 www.meniga.is:443

commit b360a688fd54e55b94b63f84e81d3a8d15ab3336
Merge: 99b7ab0 e11808c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Dec 22 08:31:08 2015 +0100

    Merge pull request #592 from liato/feature/marshmallow
    
    Added support for Android 6.0 Marshmallow

commit e11808c789aac70484400025e332769f6524f310
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Dec 22 07:29:43 2015 +0100

    Updated theme name to support API level 23

diff --git app/src/main/res/values/themes.xml app/src/main/res/values/themes.xml
index 71f0665..250bf7a 100644
--- app/src/main/res/values/themes.xml
+++ app/src/main/res/values/themes.xml
@@ -9,7 +9,7 @@
 
         <style name="BankdroidTheme" parent="BaseTheme"/>
 
-        <style name="BaseTheme" parent="Theme.AppCompat">
+        <style name="BaseTheme" parent="Theme.AppCompat.NoActionBar">
             <item name="colorPrimary">@color/colorPrimary</item>
             <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
             <item name="android:windowNoTitle">true</item>

commit cc2647dfddc6e57d294186f3a05b30a21cb1b992
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Dec 21 23:54:27 2015 +0100

    Updated notifications to comply with depricated and removed setLatestEventInfo() in API level 23

diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index d04a3db..ad350ec 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -16,20 +16,6 @@
 
 package com.liato.bankdroid.appwidget;
 
-import com.crashlytics.android.Crashlytics;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.MainActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.liveview.LiveViewService;
-
-import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -46,8 +32,22 @@ import android.os.AsyncTask;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
 import android.util.Log;
 
+import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.liveview.LiveViewService;
+
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
@@ -94,42 +94,40 @@ public class AutoRefreshService extends Service {
 
         final NotificationManager notificationManager = (NotificationManager) context
                 .getSystemService(NOTIFICATION_SERVICE);
-        final Notification notification = new Notification(bank.getImageResource(), text,
-                System.currentTimeMillis());
+        final NotificationCompat.Builder notification = new NotificationCompat.Builder(context)
+                .setSmallIcon(bank.getImageResource())
+                .setContentTitle(bank.getDisplayName())
+                .setContentText(text);
+
         // Remove notification from statusbar when clicked
-        notification.flags |= Notification.FLAG_AUTO_CANCEL;
+        notification.setAutoCancel(true);
 
         // http://www.freesound.org/samplesViewSingle.php?id=75235
         // http://www.freesound.org/samplesViewSingle.php?id=91924
         if (prefs.getString("notification_sound", null) != null) {
-            notification.sound = Uri.parse(prefs.getString(
-                    "notification_sound", null));
+            notification.setSound(Uri.parse(prefs.getString(
+                    "notification_sound", null)));
         }
         if (prefs.getBoolean("notify_with_vibration", true)) {
             final long[] vib = {0, 90, 130, 80, 350, 190, 20, 380};
-            notification.vibrate = vib;
-            // notification.defaults |= Notification.DEFAULT_VIBRATE;
+            notification.setVibrate(vib);
         }
 
         if (prefs.getBoolean("notify_with_led", true)) {
-            notification.ledARGB = prefs.getInt("notify_with_led_color",
-                    context.getResources().getColor(R.color.default_led_color));
-            notification.flags |= Notification.FLAG_SHOW_LIGHTS;
-            notification.ledOnMS = 700;
-            notification.ledOffMS = 200;
+            notification.setLights(prefs.getInt("notify_with_led_color",
+                    context.getResources().getColor(R.color.default_led_color)), 700, 200);
         }
 
         final PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                 new Intent(context, MainActivity.class), 0);
-
-        notification.setLatestEventInfo(context, bank.getDisplayName(), text, contentIntent);
+        notification.setContentIntent(contentIntent);
 
         String numNotifications = prefs.getString("num_notifications", "total");
         int notificationId = (int) (numNotifications.equals("total") ? 0
                 : numNotifications.equals("bank") ? bank.getDbId()
                         : numNotifications.equals("account") ? account.getId().hashCode()
                                 : SystemClock.elapsedRealtime());
-        notificationManager.notify(notificationId, notification);
+        notificationManager.notify(notificationId, notification.build());
 
         // Broadcast to Remote Notifier if enabled
         // http://code.google.com/p/android-notifier/

commit d04094e1223c1a23b8d7de84ef1264501fec7fbb
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Dec 21 08:19:43 2015 +0100

    Added support for Android 6.0 Marshmallow

diff --git .travis.yml .travis.yml
index b0adc4b..6ddd7f4 100644
--- .travis.yml
+++ .travis.yml
@@ -2,13 +2,13 @@ language: android
 jdk: oraclejdk7
 env:
   matrix:
-    - ANDROID_TARGET=android-22  ANDROID_ABI=armeabi-v7a
+    - ANDROID_TARGET=android-23  ANDROID_ABI=armeabi-v7a
 
 android:
   components:
-    - build-tools-22.0.0
+    - build-tools-23.0.0
     - extra-android-m2repository
-    - android-22
+    - android-23
 
 script: ./gradlew assembleDebug check
 
diff --git CHANGELOG CHANGELOG
index c9eb7b8..f06eeb4 100644
--- CHANGELOG
+++ CHANGELOG
@@ -6,6 +6,7 @@ Pending
 * Fixes for MinPension login.
 * Update certificates for Coop, ICA, Osuuspankki, PlusGirot, SevenDay & Steam.
 * Fixes for Bredband2.
+* Added support for Android 6.0 Marshmallow.
 
 v1.9.10.1 (2015-11-22)
 * Update certificate for ICA.
diff --git app/build.gradle app/build.gradle
index 1a4bdf2..9a70b48 100644
--- app/build.gradle
+++ app/build.gradle
@@ -20,13 +20,14 @@ repositories {
 
 
 android {
-    compileSdkVersion 22
-    buildToolsVersion "22.0.0"
+    compileSdkVersion 23
+    buildToolsVersion "23.0.0"
 
+    useLibrary 'org.apache.http.legacy'
     defaultConfig {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
-        targetSdkVersion 22
+        targetSdkVersion 23
         versionCode 217
         versionName "1.9.10.1"
     }
@@ -91,7 +92,7 @@ dependencies {
     compile project(':bankdroid-legacy')
     compile project(':bankdroid-core')
     compile 'com.jakewharton:butterknife:6.1.0'
-    compile "com.android.support:appcompat-v7:22.0.+"
+    compile "com.android.support:appcompat-v7:23.1.1"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
         transitive = true;
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index a8114d8..be66594 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -2,12 +2,13 @@ apply plugin: 'com.android.library'
 apply from: '../config/quality/quality.gradle'
 
 android {
-    compileSdkVersion 22
-    buildToolsVersion "22.0.0"
+    compileSdkVersion 23
+    buildToolsVersion "23.0.0"
 
+    useLibrary 'org.apache.http.legacy'
     defaultConfig {
         minSdkVersion 9
-        targetSdkVersion 22
+        targetSdkVersion 23
         versionCode 1
         versionName "1.0"
     }
@@ -26,8 +27,8 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-interface')
-    compile 'com.android.support:appcompat-v7:22.0.+'
-    compile 'org.apache.commons:commons-io:1.3.2'
+    compile 'com.android.support:appcompat-v7:23.1.1'
+    compile ('org.apache.commons:commons-io:1.3.2') {exclude module: 'commons-io'}
     compile 'org.jsoup:jsoup:1.7.3'
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
     compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
diff --git build.gradle build.gradle
index 365bea0..c80e45c 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
+        classpath 'com.android.tools.build:gradle:1.5.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index bf15a1e..527b1f9 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Sun May 24 19:44:46 CEST 2015
+#Mon Dec 21 08:16:02 CET 2015
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME

commit 99b7ab06213d9da6df35d8b441aac7e176dadc15
Merge: 5bd3765 9e069de
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Dec 16 23:54:07 2015 +0100

    Merge pull request #590 from liato/feature/bredband2
    
    Fixes for Bredband2

commit 9e069deb3c7285723a0a5c6063594e20d7da48cc
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Dec 16 22:16:49 2015 +0100

    Fixes for Bredband2

diff --git CHANGELOG CHANGELOG
index 0f4587a..c9eb7b8 100644
--- CHANGELOG
+++ CHANGELOG
@@ -5,6 +5,7 @@ Pending
 * Removes support for Forex Bank due to BankId requirement.
 * Fixes for MinPension login.
 * Update certificates for Coop, ICA, Osuuspankki, PlusGirot, SevenDay & Steam.
+* Fixes for Bredband2.
 
 v1.9.10.1 (2015-11-22)
 * Update certificate for ICA.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 0b1666f..6915d7d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -16,6 +16,10 @@
 
 package com.liato.bankdroid.banking.banks;
 
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -29,10 +33,6 @@ import com.liato.bankdroid.provider.IBankTypes;
 import org.apache.http.NameValuePair;
 import org.apache.http.message.BasicNameValuePair;
 
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -46,17 +46,18 @@ public class Bredband2VoIP extends Bank {
 
     private static final String API_URL = "https://portal.bredband2.com/";
 
+    //<a href="/services/digisipbalance/iServiceID/~ID~/" class="digisipBalance" target="_blank">Saldo</a>
     private Pattern reSaldoUrl = Pattern.compile(
-            "<a href=\"/voip/digisipbalance/iPhoneProviderID/(\\d+)/\" class=\"digisipBalance\" target=\"_blank\">Saldo</a>",
+            "<a href=\"/services/digisipbalance/iServiceID/(\\d+)/\" class=\"digisipBalance\" target=\"_blank\">Saldo</a>",
             Pattern.CASE_INSENSITIVE);
 
-    private Pattern reSaldo = Pattern.compile("<td class=\"white\">(\\d+.\\d{2}) kr",
+    private Pattern reSaldo = Pattern.compile("<td class=\"white\">\\s+(\\d+.\\d{2}) kr",
             Pattern.CASE_INSENSITIVE);
 
-    private Pattern reInvoiceUrl = Pattern.compile("<a href=\"([^\"]+)\"/\" class=\"invoice\"");
+    private Pattern reInvoiceUrl = Pattern.compile("<a href=\"([^\"]+)\" class=\"invoice\"");
 
     private Pattern reTransactions = Pattern.compile(
-            "^\\s+([\\d-]+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)", Pattern.MULTILINE);
+            "^      ([\\d-]+)\\s+([\\S]+)\\s+([\\S]+)\\s+([\\d:]+)\\s+([\\d\\.]+)", Pattern.MULTILINE);
 
     private String response = null;
 
@@ -86,7 +87,7 @@ public class Bredband2VoIP extends Bank {
         postData.add(new BasicNameValuePair("bIsCompany", "0"));
         postData.add(new BasicNameValuePair("submit", "Logga in"));
         response = urlopen.open(API_URL + "index/", postData, true);
-        LoginPackage lp = new LoginPackage(urlopen, postData, response, API_URL + "index/");
+        LoginPackage lp = new LoginPackage(urlopen, postData, response, API_URL + "start");
         if (response.contains("Logga ut")) {
             lp.setIsLoggedIn(true);
         }
@@ -115,7 +116,7 @@ public class Bredband2VoIP extends Bank {
         while (mSaldoUrl.find()) {
             String account = mSaldoUrl.group(1);
             String r = urlopen.open(
-                    API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
+                    API_URL + "/services/digisipbalance/iServiceID/" + account + "/");
             Matcher mSaldo = reSaldo.matcher(r);
             if (mSaldo.find()) {
                 accounts.add(new Account(account,
@@ -131,11 +132,12 @@ public class Bredband2VoIP extends Bank {
             BankException, IOException {
         super.updateTransactions(account, urlopen);
 
-        response = urlopen.open(API_URL + "voip/invoicelist/iPhoneProviderID/" + account.getId());
+        //<a href="/services/invoicelist/iServiceID/~ID~/">Samtal</a>
+        response = urlopen.open(API_URL + "services/invoicelist/iServiceID/" + account.getId());
         Matcher mInvoiceUrl = reInvoiceUrl.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         int i = 1;
-        while (mInvoiceUrl.find() && i++ <= 2) {
+        while (mInvoiceUrl.find() && (i++ <= 4 || transactions.size() <= 30)) {
             try {
                 String url = mInvoiceUrl.group(1);
                 String sInvoice = urlopen.open(API_URL + url);

commit 5bd37651a92b44a280e7b9e844c99c61f362e4cc
Merge: 9103c45 0701600
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Dec 16 22:01:49 2015 +0100

    Merge pull request #589 from liato/feature/certUpdate
    
    Update certificates

commit 0701600cf024d1fdb49fc381332c1d159453392a
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Dec 16 19:04:54 2015 +0100

    Update certificates for Coop, ICA, Osuuspankki, PlusGirot, SevenDay & Steam.

diff --git CHANGELOG CHANGELOG
index 8aab0ab..0f4587a 100644
--- CHANGELOG
+++ CHANGELOG
@@ -4,6 +4,7 @@ Pending
 * Fixes for Coop login.
 * Removes support for Forex Bank due to BankId requirement.
 * Fixes for MinPension login.
+* Update certificates for Coop, ICA, Osuuspankki, PlusGirot, SevenDay & Steam.
 
 v1.9.10.1 (2015-11-22)
 * Update certificate for ICA.
diff --git bankdroid-legacy/src/main/res/raw/cert_coop.pem bankdroid-legacy/src/main/res/raw/cert_coop.pem
index e8b64aa..808a4d0 100644
--- bankdroid-legacy/src/main/res/raw/cert_coop.pem
+++ bankdroid-legacy/src/main/res/raw/cert_coop.pem
@@ -1,33 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIFcjCCBFqgAwIBAgIQJ5Frf2WYTjk+myqOUco8ZDANBgkqhkiG9w0BAQUFADB7
+MIIGfzCCBWegAwIBAgIQE5zdq5ZwHaepzP86A5rUcjANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd

-jCsIfvDy

+F4EcgP8rjJT4pM3jnw0hWoGw4ll1u1dpc/QuYWAu5EQllo8=
 -----END CERTIFICATE-----
 www.coop.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_icabanken.pem bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
index 21acf2a..d87afbb 100644
--- bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
+++ bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIGizCCBXOgAwIBAgIQFxR+RweMUNDbt01lAxKauTANBgkqhkiG9w0BAQUFADB7
+MIIGbjCCBVagAwIBAgIQI1Q0WLKKEQ1tzbGTYWdBzTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd

+5b5dbNyAM/HjoZ09ARu3cBJN
 -----END CERTIFICATE-----
 appserver.icabanken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
index 3700ce3..49f5f1b 100644
--- bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
+++ bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
@@ -1,37 +1,37 @@
 -----BEGIN CERTIFICATE-----
-MIIGQzCCBSugAwIBAgIQKXSueuJzPFfQEvy1Nv7RZTANBgkqhkiG9w0BAQUFADB3
+MIIGQjCCBSqgAwIBAgIQP5hSiLJfDuQhp1cXs/mT1DANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzIwHhcNMTQxMjExMDAwMDAwWhcNMTUxMjEy
-MjM1OTU5WjCB1TETMBEGCysGAQQBgjc8AgEDEwJGSTEdMBsGA1UEDxMUUHJpdmF0
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUxMjExMDAwMDAwWhcNMTYxMjEx
+MjM1OTU5WjCB0jETMBEGCysGAQQBgjc8AgEDEwJGSTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xEjAQBgNVBAUTCTAyNDI1MjItMTELMAkGA1UEBhMCRkkx

-N7hoKxb3BouwbQLgoBmuRL0GQ1hJdNI=

+/aCGL94jL5MWifVSVGvNLkogJSPiiA==
 -----END CERTIFICATE-----
 www.op.fi:443
diff --git bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
index db17b74..dab3079 100644
--- bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
+++ bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
@@ -1,10 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIIFSzCCBDOgAwIBAgIQaSTk7yughaFPx8ots0SOszANBgkqhkiG9w0BAQUFADCB
+MIIFRzCCBC+gAwIBAgIQN6N70S/YZJ1IsI3RimJCNzANBgkqhkiG9w0BAQUFADCB
 vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMt
 VmVyaVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMB4X
-DTE0MTIxMTAwMDAwMFoXDTE2MDEyMzIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIw
+DTE1MTExNzAwMDAwMFoXDTE2MTIzMTIzNTk1OVowgYUxCzAJBgNVBAYTAlNFMRIw
 EAYDVQQIEwlTdG9ja2hvbG0xEjAQBgNVBAcUCVN0b2NraG9sbTEXMBUGA1UEChQO
 Tm9yZGVhIEJhbmsgQUIxEjAQBgNVBAsUCVBsdXNnaXJvdDEhMB8GA1UEAxQYa29u
 dG91dGRyYWcucGx1c2dpcm90LnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
@@ -13,20 +13,20 @@ Jo098s+gqlqINUwAU7At4nn9z4+4JSJ4+tqK/xZVjLvzC9Y0enVXfvsmaOy9jp+o
 A5riJf5378ta+QHjLwU2m9kglEE7FiXJ7gNV8TaTpVTmKDvDCIrtG1pQPMNE4zAs
 EWtDSAjwe68Mkl2ZKbcqa+k+LfIy/Yyhi65RJVtRN9o99bq+ZrBoLZ6eFX4Tu9Tk
 zlMj5YN370Hz0tT7VuezEXLn70rJMPzxEfgwox/PYMccStviIc0++3tkgP3rAgjr
-tyCPL4lknsx+Ki8hgvIqz6T+jWB2HQIDAQABo4IBfDCCAXgwIwYDVR0RBBwwGoIY
+tyCPL4lknsx+Ki8hgvIqz6T+jWB2HQIDAQABo4IBeDCCAXQwIwYDVR0RBBwwGoIY
 a29udG91dGRyYWcucGx1c2dpcm90LnNlMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQD

-LXXg08b96tbNjynAlWNK

+hA6n1bvE4ifRPUE=
 -----END CERTIFICATE-----
 kontoutdrag.plusgirot.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_sevenday.pem bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
index 86541f3..bc6eabb 100644
--- bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
+++ bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
@@ -1,28 +1,29 @@
 -----BEGIN CERTIFICATE-----

-ETEyMuB5fsINZXXfHm6F2x4e0+b8aQ==

+bxGM
 -----END CERTIFICATE-----
 www.sevenday.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_steam.pem bankdroid-legacy/src/main/res/raw/cert_steam.pem
index b711eaa..0e381dc 100644
--- bankdroid-legacy/src/main/res/raw/cert_steam.pem
+++ bankdroid-legacy/src/main/res/raw/cert_steam.pem
@@ -1,51 +1,52 @@
 -----BEGIN CERTIFICATE-----
-MIII+zCCB+OgAwIBAgIQCp81Wa96aMdajhHH7BidVjANBgkqhkiG9w0BAQUFADBp
+MIIJIDCCCAigAwIBAgIQCS7hWqFgX+M1Zl1OfsONTjANBgkqhkiG9w0BAQsFADB1
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3

+PEm1FqE12j/eVQpWpnubOHsPp3pc5q+n0RyCaBzTH1yMvykr
 -----END CERTIFICATE-----
 store.steampowered.com:443

commit 9103c450e08b318fbbeb0e515a021d5318b03367
Merge: 1539469 76c239a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Dec 16 08:21:21 2015 +0100

    Merge pull request #588 from liato/feature/minpension
    
    Fix for login issues with "Min Pension.se"

commit 76c239a82465d90c3c90315f005d2c8b76430a75
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Dec 15 21:25:31 2015 +0100

    Fix for login issues with "Min Pension.se"

diff --git CHANGELOG CHANGELOG
index 83601bd..8aab0ab 100644
--- CHANGELOG
+++ CHANGELOG
@@ -3,6 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 Pending
 * Fixes for Coop login.
 * Removes support for Forex Bank due to BankId requirement.
+* Fixes for MinPension login.
 
 v1.9.10.1 (2015-11-22)
 * Update certificate for ICA.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index 817bb6a..3c7b5d6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -16,6 +16,9 @@
 
 package com.liato.bankdroid.banking.banks;
 
+import android.content.Context;
+import android.text.InputType;
+
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -33,9 +36,6 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
-import android.content.Context;
-import android.text.InputType;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -70,7 +70,7 @@ public class MinPension extends Bank {
         List<NameValuePair> postData = new ArrayList<>();
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_minpension));
-        String response = urlopen.open("https://www.minpension.se/AjaxifyContent/795");
+        String response = urlopen.open("https://www.minpension.se/inloggning");
         Document jDoc = Jsoup.parse(response);
         Element el = jDoc.select("input[name=__RequestVerificationToken]").first();
         if (el == null) {

commit 1539469650228409a3a3690a0804d1110c2ba64e
Merge: c2eaae8 d1d2794
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Dec 13 11:40:23 2015 +0100

    Merge pull request #587 from liato/feature/remove-forex
    
    Removes support for Forex Bank

commit d1d2794345336e59ffcdbc31f84b207189a34e43
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Dec 13 10:25:11 2015 +0100

    Removes support for Forex Bank

diff --git CHANGELOG CHANGELOG
index bc1dc55..83601bd 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,7 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-pending
+Pending
 * Fixes for Coop login.
+* Removes support for Forex Bank due to BankId requirement.
 
 v1.9.10.1 (2015-11-22)
 * Update certificate for ICA.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index b19a06c..3d8ed69 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -18,7 +18,6 @@ import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.EspressoHouse;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
-import com.liato.bankdroid.banking.banks.ForexBank;
 import com.liato.bankdroid.banking.banks.Hemkop;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
@@ -39,7 +38,6 @@ import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skoda;
-import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
@@ -217,8 +215,8 @@ public class LegacyBankFactory {
                 return new Zidisha(context);
             case IBankTypes.BETTERGLOBE:
                 return new BetterGlobe(context);
-            case IBankTypes.FOREX:
-                return new ForexBank(context);
+           // case IBankTypes.FOREX:
+           //     return new ForexBank(context);
             case IBankTypes.BITCOIN:
                 return new Bitcoin(context);
             case IBankTypes.SVEADIREKT:
@@ -321,7 +319,7 @@ public class LegacyBankFactory {
         banks.add(new AppeakPoker(context));
         banks.add(new Zidisha(context));
         banks.add(new BetterGlobe(context));
-        banks.add(new ForexBank(context));
+        //banks.add(new ForexBank(context));
         // banks.add(new EurobonusMastercardNo(context));
         banks.add(new Bitcoin(context));
         // banks.add(new EurobonusMastercardDk(context));

commit c2eaae89cf8e1545d79d86198ef0589b0f4d67a0
Merge: 9fcb40a 2f70d47
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Dec 11 14:38:51 2015 +0100

    Merge pull request #584 from liato/feature/coop
    
    Adds support for coop login token, fixes #583

commit 2f70d47618b6a20cd38004bf754a1ed62cd58b2f
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Dec 8 14:13:26 2015 +0100

    Adds support for coop login token, fixes #583

diff --git CHANGELOG CHANGELOG
index 9cf7494..bc1dc55 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+pending
+* Fixes for Coop login.
+
 v1.9.10.1 (2015-11-22)
 * Update certificate for ICA.
 * Fixes bug where banks without password could not be added.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 9efb4c3..7d18694 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -16,6 +16,9 @@
 
 package com.liato.bankdroid.banking.banks.coop;
 
+import android.content.Context;
+import android.text.TextUtils;
+
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
@@ -37,9 +40,6 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
-import android.content.Context;
-import android.text.TextUtils;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
@@ -104,10 +104,16 @@ public class Coop extends Bank {
     protected LoginPackage preLogin() throws BankException,
             IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
+
+        String response = urlopen.open("https://www.coop.se");
+        Document dResponse = Jsoup.parse(response);
+        String token = dResponse.select("[name=token]").attr("value");
+
         urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
         HttpResponse httpResponse = urlopen
                 .openAsHttpResponse("https://www.coop.se/Personliga-Baren/Logga-in/?method=Login",
-                        new StringEntity("{\"isBar\":\"true\",\"username\":\"" + getUsername()
+                        new StringEntity("{\"isBar\":\"true\",\"token\":\"" + token
+                                 + "\",\"username\":\"" + getUsername()
                                 + "\",\"password\":\"" + getPassword() + "\"}"),
                         true);
         urlopen.removeHeader("X-Requested-With");

commit 9fcb40afc5cead0438bccffd8370defac3187781 (tag: v1.9.10.1)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 22 12:00:26 2015 +0100

    Create release 1.9.10.1

diff --git CHANGELOG CHANGELOG
index 3b32a45..9cf7494 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.10.1 (2015-11-22)
+* Update certificate for ICA.
+* Fixes bug where banks without password could not be added.
+
 v1.9.10.0 (2015-11-06)
 * Removes support for PayPal due to complex web-login.
 * Removes support for Swedbank, Sparbankerna, Marginalen and NordeaDK due to BankId requirement.
diff --git app/build.gradle app/build.gradle
index 46e1d0b..1a4bdf2 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 216
-        versionName "1.9.10.0"
+        versionCode 217
+        versionName "1.9.10.1"
     }
 
     signingConfigs {

commit 424d1da55ac0ac48d0ef904a48e3bbc5393ce560
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 22 11:57:40 2015 +0100

    Only require password if field is not hidden. Fixes #579

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
index b180cf6..bc1f550 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
@@ -45,7 +45,7 @@ public class LegacyProviderConfiguration implements ProviderConfiguration {
                 .label(mLegacyBank.getContext().getString(mLegacyBank.getInputTitlePassword()))
                 .hidden(mLegacyBank.isInputPasswordHidden())
                 .secret(true)
-                .required(true)
+                .required(!mLegacyBank.isInputPasswordHidden())
                 .fieldType(FieldTypeMapper.toFieldType(mLegacyBank.getInputTypePassword()))
                 .build());
 

commit e665506ddb0901e8dca452212e5f114e4f406c8a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 22 11:33:44 2015 +0100

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_ica.pem bankdroid-legacy/src/main/res/raw/cert_ica.pem
index 52a0eb8..36cb10d 100644
--- bankdroid-legacy/src/main/res/raw/cert_ica.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ica.pem
@@ -1,30 +1,31 @@
 -----BEGIN CERTIFICATE-----

+Be2TKW8A9Zy/ke8Z3LCOsj6BVQIeAyMuZsIcvGGsEg==
 -----END CERTIFICATE-----
 api.ica.se:443

commit b2f9faab9317afd4287772531c32bec654a0035c (tag: v1.9.10.0)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Nov 6 21:53:56 2015 +0100

    Create release 1.9.10.0

diff --git CHANGELOG CHANGELOG
index f1b99da..3b32a45 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,9 +1,10 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-Unreleased
+v1.9.10.0 (2015-11-06)
 * Removes support for PayPal due to complex web-login.
 * Removes support for Swedbank, Sparbankerna, Marginalen and NordeaDK due to BankId requirement.
 * Updates certificates for Bredband2, EasyCard, Nordea DK, Nordnet, Östgötatrafiken, Osuuspankki, PayPal, Villabanken
+* Adds support for custom properties for bank implementations.
 
 v1.9.9.5 (2015-07-18)
 * Updates certificates for Akelius Spar, Akelius Invest, Hemköp and Resurs Bank
diff --git app/build.gradle app/build.gradle
index 450fbfd..46e1d0b 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 215
-        versionName "1.9.9.5"
+        versionCode 216
+        versionName "1.9.10.0"
     }
 
     signingConfigs {

commit 8703aa5ddbe42e0a9029735e86aa82a5d1dfa409
Merge: 3757ac3 caebc98
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Nov 3 08:05:03 2015 +0100

    Merge pull request #576 from liato/feature/disable-paypal
    
    deactivation of PayPal due to complex web-login

commit 3757ac31cc32b886692992e4e4410c58335dc4b5
Merge: 3f3450c c6bb35d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Nov 3 08:04:33 2015 +0100

    Merge pull request #574 from liato/feature/update-certs
    
    New certs, fixes #572

commit 3f3450c663f0df0735928e892c36ac554c60d908
Merge: 03dae2b 5daa100
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Nov 2 17:40:09 2015 +0100

    Merge pull request #564 from mhagander/amexreplace
    
    Shorten Amex card titles

commit 03dae2b28f7b0649f0ff459affbec22d5d32a2e9
Merge: 1c0c31b 0d0f683
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Nov 2 15:00:15 2015 +0100

    Merge pull request #578 from mhagander/amexdateparse
    
    Fix Amex date parsing

commit 0d0f683c8484a99c5a07ff94a4fdff2304fc7f66
Author: Magnus Hagander <magnus@hagander.net>
Date:   Mon Nov 2 14:34:10 2015 +0100

    Fix Amex date parsing
    
    It appears Marshmallow (at least) does not support the way the parser
    was initialized anymore.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 122da2b..89bfbbb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -170,7 +170,7 @@ public class AmericanExpress extends Bank {
         Matcher matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 
-        SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
+        SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv","SE"));
         SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
         Date transactionDate;
 
@@ -198,6 +198,7 @@ public class AmericanExpress extends Bank {
                         amount));
             } catch (ParseException e) {
                 Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                Log.w(TAG, e);
             }
         }
         account.setTransactions(transactions);

commit c6bb35da792d456e9d51b8405a3e82018e15d2cc
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 12:25:44 2015 +0100

    New certs, fixes #572

diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
index 479b83c..8e4ae92 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -1,35 +1,33 @@
 -----BEGIN CERTIFICATE-----

-+W9zI0a2C+KlAO8229IrWrtORFU=

+SOlRJmKO6ynrIcdfP40A4IqN9iFEEayhGdnC0UY=
 -----END CERTIFICATE-----
 www.ostgotatrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
index 1ee0d09..10b7315 100644
--- bankdroid-legacy/src/main/res/raw/cert_paypal.pem
+++ bankdroid-legacy/src/main/res/raw/cert_paypal.pem
@@ -1,23 +1,4 @@
 -----BEGIN CERTIFICATE-----
-<<<<<<< HEAD

-=======
 MIIHTTCCBjWgAwIBAgIQf8Ays2+fnhrB7auXE2UpNTANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
@@ -35,29 +16,11 @@ BaYLv7YREjTq1yPOPmAhvv7N22Ucr2KWPnO9CAVu6jMe1VnCcaXlIs7QF6XSrHzc
 pO9XrGwlzXx81DQkIAfdDQlFvZip7oPV8osFoik3DPRiF8InV53jA+OrAp36yf+B
 FqsqlJs+BLd4L+l9djsihbZFn0JVNirLSQrA+7gPW4XRhyYb6QIDAQABo4IDPzCC
 AzswbgYDVR0RBGcwZYIMYy5wYXlwYWwuY29tgg1jNi5wYXlwYWwuY29tghRkZXZl
->>>>>>> 149359b... Certificate update 2015-10-18
 bG9wZXIucGF5cGFsLmNvbYISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5j
 b22CDnd3dy5wYXlwYWwuY29tMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0G
 A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBmBgNVHSAEXzBdMFsGC2CGSAGG
 +EUBBxcGMEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUG
 CCsGAQUFBwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaA
-<<<<<<< HEAD

-Gp3OLqh4jMEbNLobkIdLkZ2F9jYMDw==
-=======
 FAFZq+fdOgtZpmRj1s8gB1fVkedqMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
 ci5zeW1jYi5jb20vc3IuY3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYT
 aHR0cDovL3NyLnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3NyLnN5bWNi
@@ -76,6 +39,5 @@ jtn19UGev1qLvOrmyugKDVjcsaP9WD1M3WUcQxPpOJ9Dx3KyGe8qUuOH1GPpWjfr
 3iHPxRDtcejvdKLWvB/K2lCfef8TXSja+a5ml0ATYNQDRJwmZFzobM/GLrl4modk
 JdIGuJhwGjvYvVfglJ+dXEFcThb76lJ1/A3p5ieSNpPCjIBAK0To1RS/RRiNWcfI
 nA==
->>>>>>> 149359b... Certificate update 2015-10-18
 -----END CERTIFICATE-----
 www.paypal.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
index db32543..74b9e17 100644
--- bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
+++ bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
@@ -1,31 +1,29 @@
 -----BEGIN CERTIFICATE-----

-UU9mph83MDGlCY1EwuHPGorjoqGjYjXl/63EOvKmXEKYMCd6fb4Dfq2F

+mrN/2dgPDQ==
 -----END CERTIFICATE-----
 www.rikslunchen.se:443

commit caebc98359527337ff0a0b737f891161ac33c445
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 17:12:13 2015 +0100

    deactivation of PayPal due to complex web-login

diff --git CHANGELOG CHANGELOG
index 4a61cad..f1b99da 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,7 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 Unreleased
+* Removes support for PayPal due to complex web-login.
 * Removes support for Swedbank, Sparbankerna, Marginalen and NordeaDK due to BankId requirement.
 * Updates certificates for Bredband2, EasyCard, Nordea DK, Nordnet, Östgötatrafiken, Osuuspankki, PayPal, Villabanken
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 0a83468..b19a06c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -31,7 +31,6 @@ import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
-import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
@@ -108,8 +107,8 @@ public class LegacyBankFactory {
             //     return new Eurocard(context);
             case IBankTypes.FIRSTCARD:
                 return new FirstCard(context);
-            case IBankTypes.PAYPAL:
-                return new PayPal(context);
+            // case IBankTypes.PAYPAL:
+            //     return new PayPal(context);
             case IBankTypes.PAYSON:
                 return new Payson(context);
             case IBankTypes.JOJO:
@@ -271,7 +270,7 @@ public class LegacyBankFactory {
         banks.add(new OKQ8(context));
         // banks.add(new Eurocard(context));
         banks.add(new FirstCard(context));
-        banks.add(new PayPal(context));
+        // banks.add(new PayPal(context));
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
         // banks.add(new Steam(context));

commit 1c0c31bd197ac34830ab8cb1b7c86fadf2a46121
Merge: c42a23e 1f7d877
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 29 16:58:24 2015 +0100

    Merge pull request #575 from liato/feature/disable-bankid-banks
    
    Deactivated banks requiring BankId

commit 1f7d877739b7d71eb5df93df1f33c4f09b1e7242
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 12:38:40 2015 +0100

    Deactivated banks requiring BankId (Swedbank, Sparbankerna, Marginalen and NordeaDK)

diff --git CHANGELOG CHANGELOG
index 81dd188..4a61cad 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,7 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 Unreleased
+* Removes support for Swedbank, Sparbankerna, Marginalen and NordeaDK due to BankId requirement.
 * Updates certificates for Bredband2, EasyCard, Nordea DK, Nordnet, Östgötatrafiken, Osuuspankki, PayPal, Villabanken
 
 v1.9.9.5 (2015-07-18)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 68e47f4..0a83468 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -23,11 +23,9 @@ import com.liato.bankdroid.banking.banks.Hemkop;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
-import com.liato.bankdroid.banking.banks.Marginalen;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Meniga;
 import com.liato.bankdroid.banking.banks.MinPension;
-import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
@@ -62,12 +60,6 @@ import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
-import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
-import com.liato.bankdroid.banking.banks.swedbank.SparbankernaCorporate;
-import com.liato.bankdroid.banking.banks.swedbank.SparbankernaYouth;
-import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
-import com.liato.bankdroid.banking.banks.swedbank.SwedbankCorporate;
-import com.liato.bankdroid.banking.banks.swedbank.SwedbankYouth;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.provider.IBankTypes;
 
@@ -88,8 +80,8 @@ public class LegacyBankFactory {
                 return new AkeliusInvest(context);
             case IBankTypes.AKELIUSSPAR:
                 return new AkeliusSpar(context);
-            case IBankTypes.SWEDBANK:
-                return new Swedbank(context);
+            // case IBankTypes.SWEDBANK:
+            //     return new Swedbank(context);
             case IBankTypes.NORDEA:
                 return new Nordea(context);
             case IBankTypes.LANSFORSAKRINGAR:
@@ -186,8 +178,8 @@ public class LegacyBankFactory {
                 return new Skoda(context);
             case IBankTypes.IKEA:
                 return new IKEA(context);
-            case IBankTypes.SPARBANKEN_SYD:
-                return new SparbankenSyd(context);
+            // case IBankTypes.SPARBANKEN_SYD:
+            //     return new SparbankenSyd(context);
             // case IBankTypes.SPARBANKEN_ORESUND:
             //    return new SparbankenOresund(context);
             case IBankTypes.NORDNETDIREKT:
@@ -196,8 +188,8 @@ public class LegacyBankFactory {
             //    return new Skandiabanken(context);
             case IBankTypes.DANSKEBANK:
                 return new DanskeBank(context);
-            case IBankTypes.NORDEA_DK:
-                return new NordeaDK(context);
+            // case IBankTypes.NORDEA_DK:
+            //     return new NordeaDK(context);
             case IBankTypes.VASTTRAFIK:
                 return new Vasttrafik(context);
             case IBankTypes.EVERYDAYCARD:
@@ -210,8 +202,8 @@ public class LegacyBankFactory {
                 return new Bioklubben(context);
             case IBankTypes.CHALMREST:
                 return new Chalmrest(context);
-            case IBankTypes.MARGINALEN:
-                return new Marginalen(context);
+            // case IBankTypes.MARGINALEN:
+            //     return new Marginalen(context);
             case IBankTypes.SVENSKASPEL:
                 return new SvenskaSpel(context);
             case IBankTypes.EASYCARD:
@@ -234,8 +226,8 @@ public class LegacyBankFactory {
                 return new SveaDirekt(context);
             case IBankTypes.SUPREMECARD:
                 return new SupremeCard(context);
-            case IBankTypes.SPARBANKERNA:
-                return new Sparbankerna(context);
+            // case IBankTypes.SPARBANKERNA:
+            //     return new Sparbankerna(context);
             case IBankTypes.BLEKINGETRAFIKEN:
                 return new BlekingeTrafiken(context);
             case IBankTypes.OSTGOTATRAFIKEN:
@@ -265,7 +257,7 @@ public class LegacyBankFactory {
         banks.add(new AkeliusSpar(context));
         banks.add(new TrustBuddy(context));
         banks.add(new BrummerKF(context));
-        banks.add(new Swedbank(context));
+        // banks.add(new Swedbank(context));
         banks.add(new Nordea(context));
         banks.add(new ICABanken(context));
         banks.add(new Lansforsakringar(context));
@@ -297,7 +289,7 @@ public class LegacyBankFactory {
         banks.add(new ResursBank(context));
         banks.add(new McDonalds(context));
         // banks.add(new SJPrio(context));
-        banks.add(new SparbankenSyd(context));
+        // banks.add(new SparbankenSyd(context));
         // banks.add(new SparbankenOresund(context));
         // banks.add(new Opel(context));
         // banks.add(new Skandiabanken(context));
@@ -317,14 +309,14 @@ public class LegacyBankFactory {
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
         // banks.add(new DanskeBank(context));
-        banks.add(new NordeaDK(context));
+        // banks.add(new NordeaDK(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
         banks.add(new Meniga(context));
         banks.add(new TicketRikskortet(context));
         banks.add(new Bioklubben(context));
         banks.add(new Chalmrest(context));
-        banks.add(new Marginalen(context));
+        // banks.add(new Marginalen(context));
         banks.add(new SvenskaSpel(context));
         banks.add(new EasyCard(context));
         banks.add(new AppeakPoker(context));
@@ -336,7 +328,7 @@ public class LegacyBankFactory {
         // banks.add(new EurobonusMastercardDk(context));
         banks.add(new SveaDirekt(context));
         banks.add(new SupremeCard(context));
-        banks.add(new Sparbankerna(context));
+        // banks.add(new Sparbankerna(context));
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
         banks.add(new Bredband2VoIP(context));

commit c42a23e8f4949975036cda20bf817309d6db792f
Merge: 8c3a157 2d42f32
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 11:48:04 2015 +0100

    Merge pull request #573 from YoX89/fix_jojo
    
    Fixes #553 Updating Jojo cards to the new Skånetrafiken website

commit 8c3a1574938e5704b5fb4b70623a9870d1bc25ec
Merge: 186a0b1 de9aab9
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 11:35:09 2015 +0100

    Merge pull request #567 from robho/new_certs_2015-10-18
    
    Certificate update 2015-10-18

commit 186a0b194d483ab03d653adb91780416baf67b15
Merge: 5f84c68 76be966
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 11:34:09 2015 +0100

    Merge pull request #565 from liato/feature/domain-model
    
    Adds new domain model

commit 5f84c684df5a6c8542297e0e96d8d022cde950c9
Merge: 3772259 7c4437b
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Oct 29 11:30:43 2015 +0100

    Merge pull request #562 from liato/feature/fields-refactor
    
    Refactor BankEditActivity to use the new Field interface.

commit de9aab907f1e89e84e6c652219b799ee82ac3d5b
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Mon Oct 19 00:20:09 2015 +0200

    Certificate update 2015-10-18
    
    Removing expired certificates americanexpress2 and marginalen2 which I don't
    know how to refresh (I think they're actually unused)

diff --git CHANGELOG CHANGELOG
index 5e4a96f..81dd188 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,7 +1,10 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+Unreleased
+* Updates certificates for Bredband2, EasyCard, Nordea DK, Nordnet, Östgötatrafiken, Osuuspankki, PayPal, Villabanken
+
 v1.9.9.5 (2015-07-18)
-* Upates certificates for Akelius Spar, Akelius Invest, Hemköp and Resurs Bank
+* Updates certificates for Akelius Spar, Akelius Invest, Hemköp and Resurs Bank
 
 v1.9.9.4 (2015-06-12)
 * Fixes parsing of incoming payments for American Express (thanks to mhagander)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 0c344f3..122da2b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -88,8 +88,7 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context,
-                R.raw.cert_americanexpress, R.raw.cert_americanexpress2,
-                R.raw.cert_americanexpress_global));
+                R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index a27a8c0..90033c5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -82,7 +82,7 @@ public class Marginalen extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader
-                .getCertificates(context, R.raw.cert_marginalen, R.raw.cert_marginalen2));
+                .getCertificates(context, R.raw.cert_marginalen));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open(BASE_URL + "engine");
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
deleted file mode 100644
index 9307b5a..0000000
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
+++ /dev/null
@@ -1,37 +0,0 @@
------BEGIN CERTIFICATE-----

-WU5uJfphUKkLRvc=
------END CERTIFICATE-----
\ No newline at end of file
diff --git bankdroid-legacy/src/main/res/raw/cert_bredband2.pem bankdroid-legacy/src/main/res/raw/cert_bredband2.pem
index 70bd81b..8ce84de 100644
--- bankdroid-legacy/src/main/res/raw/cert_bredband2.pem
+++ bankdroid-legacy/src/main/res/raw/cert_bredband2.pem
@@ -1,31 +1,29 @@
 -----BEGIN CERTIFICATE-----

-euHPQ+ReZHHFHgtYW244JPa1YzxUj+0pA7j3gTbf+dCDiLCzn+eW

+YMG1
 -----END CERTIFICATE-----
 portal.bredband2.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_easycard.pem bankdroid-legacy/src/main/res/raw/cert_easycard.pem
index 046878c..b692c7f 100644
--- bankdroid-legacy/src/main/res/raw/cert_easycard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_easycard.pem
@@ -1,33 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIFezCCBGOgAwIBAgIQJ5Bs7UjNyuX5jACYuvZAOjANBgkqhkiG9w0BAQUFADB7
+MIIGcDCCBVigAwIBAgIQIBLV1aMHhwIvpDSH8jsnLDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd

-9zMG3j0JdTv4xPZSSQHq

+XFEii/wZ3VLPyzEJ0WXObbtjE3Y=
 -----END CERTIFICATE-----
 kundportal.cerdo.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
deleted file mode 100644
index 91fceba..0000000
--- bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
diff --git bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
index 51851d2..99b6565 100644
--- bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
+++ bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
@@ -1,8 +1,8 @@
 -----BEGIN CERTIFICATE-----
-MIIFdjCCBF6gAwIBAgIQGP9My+g0anK99vx0hBXdSzANBgkqhkiG9w0BAQsFADB3
+MIIG9zCCBd+gAwIBAgIQNbf9NhCle6o26BwNVVbfTDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTQwOTE2MDAwMDAwWhcNMTUwOTE3
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzMwHhcNMTUwNjI2MDAwMDAwWhcNMTYwOTE3
 MjM1OTU5WjCCAQIxEzARBgsrBgEEAYI3PAIBAxMCREsxHTAbBgNVBA8TFFByaXZh
 dGUgT3JnYW5pemF0aW9uMREwDwYDVQQFEwgxMzUyMjE5NzELMAkGA1UEBhMCREsx
 DTALBgNVBBEMBDE0MDExEzARBgNVBAgMCkNvcGVuaGFnZW4xEzARBgNVBAcMCkNv
@@ -14,7 +14,7 @@ bLx1jG6PWnKJHwmOjx+cuYOdESBKpxJKvJeiN7S0EAWdPu/iOFmBB0z+aYi/gxwz
 eRz9s4iAgoZM/krLZcclqF4+rDDutQq+pOml7f8DPMO2SNDRxMc+6M5pfWvfaCRT
 6+BngRac2IigSYjIclc4S7bxX07O3/SbfONPPPEpAoOmNDJ123FFt7MOzFQ4yMw7
 +9dPimG1Zox495xpWpkC9Q6gMg/R4LfpmN/QRYbQjIyEkBVPRi/qmKHBVKTpXjPB
-xE0CEy8XpY8oe4KgosSP0vjCXAt4tTK0fip8nvrpAgMBAAGjggFvMIIBazAgBgNV
+xE0CEy8XpY8oe4KgosSP0vjCXAt4tTK0fip8nvrpAgMBAAGjggLwMIIC7DAgBgNV
 HREEGTAXghV3d3cubmV0YmFuay5ub3JkZWEuZGswCQYDVR0TBAIwADAOBgNVHQ8B
 Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMGYGA1UdIARf
 MF0wWwYLYIZIAYb4RQEHFwYwTDAjBggrBgEFBQcCARYXaHR0cHM6Ly9kLnN5bWNi
@@ -22,12 +22,20 @@ LmNvbS9jcHMwJQYIKwYBBQUHAgIwGRoXaHR0cHM6Ly9kLnN5bWNiLmNvbS9ycGEw
 HwYDVR0jBBgwFoAUAVmr5906C1mmZGPWzyAHV9WR52owKwYDVR0fBCQwIjAgoB6g
 HIYaaHR0cDovL3NyLnN5bWNiLmNvbS9zci5jcmwwVwYIKwYBBQUHAQEESzBJMB8G
 CCsGAQUFBzABhhNodHRwOi8vc3Iuc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRw
-Oi8vc3Iuc3ltY2IuY29tL3NyLmNydDANBgkqhkiG9w0BAQsFAAOCAQEAiVkbYlQ6
-2c2WjqOJRTWyylOinZK5HXeEDtJIs8fL07Cfjj4HebmzGSRwRbyXreI2yqeTffPP
-W3ZGSObN8+VLl4Q/0KIP636XomPyjC9y7U3aA1k1Q4Ss4WayhUW3lUKhLN++FMRn
-ptObL7m7vN1HI6rG+C2xYp+3KU0MlSZnms/bvobc4qmKp+E669+kF/4gNai4RqS4
-VDm7xPll99weaRaqhEBD826D0hdflI1EZIX9T2V79WAzlwdQd4/D0Lf5S2xEsWEm
-3VkUWGaACDAFtJsh1QfsSzVaf9BE2x1E5Ack4Rzdc4pWn9fz2UuV7ZyaRf3uj1cS
-K3OZVKYhUxpbYw==

+eT3tiWPk6FAVE7Q=
 -----END CERTIFICATE-----
 www.netbank.nordea.dk:443
diff --git bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
index c883cf3..356b023 100644
--- bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
+++ bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
@@ -1,34 +1,43 @@
 -----BEGIN CERTIFICATE-----
-MIIFuTCCBKGgAwIBAgIQDqKAXZL/2WCgqCigR1SfMDANBgkqhkiG9w0BAQUFADBp
+MIIHbTCCBlWgAwIBAgIQBXEr13mQ6UDllbI9kqHF4jANBgkqhkiG9w0BAQsFADB1
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3

-jDDzXCaMqI+kp/U034Taez46yNgJp0QDzs2CSNQ=

+tuhEbaCLdLWID2yLn3NMtdkabXtgfWq+kE5lOCKGseEm
 -----END CERTIFICATE-----
 www.nordnetdirekt.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
index 4e09fac..479b83c 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -1,8 +1,8 @@
 -----BEGIN CERTIFICATE-----
-MIIF4DCCBMigAwIBAgISESErfEKxvlodbbGgo7upeLUjMA0GCSqGSIb3DQEBBQUA
+MIIF4DCCBMigAwIBAgISESHU0j8HKqulWJrhbOrUUL3hMA0GCSqGSIb3DQEBBQUA
 MF0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTMwMQYD
 VQQDEypHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gRzIw
-HhcNMTQxMjE4MDUzMjM0WhcNMTUxMTIwMTU0MzA1WjB3MQswCQYDVQQGEwJVUzET
+HhcNMTUxMDE2MTk1NTE4WhcNMTUxMjMxMjM1OTU5WjB3MQswCQYDVQQGEwJVUzET
 MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcG
 A1UEChMQQ2xvdWRGbGFyZSwgSW5jLjEgMB4GA1UEAxMXc3NsODIxMzAuY2xvdWRm
 bGFyZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqmWEKn7/6
@@ -14,10 +14,10 @@ hLxKQSXfBqQ/vdZTzyvJcfEN3aVFx80aiBNtYkFwNXqw5ovGEaN+SrMkx53d9J7M
 KBPZiybZ+rlrAgMBAAGjggJ+MIICejAOBgNVHQ8BAf8EBAMCBaAwSQYDVR0gBEIw
 QDA+BgZngQwBAgIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2ln
 bi5jb20vcmVwb3NpdG9yeS8wgdIGA1UdEQSByjCBx4IXc3NsODIxMzAuY2xvdWRm

 ADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwRQYDVR0fBD4wPDA6oDig
 NoY0aHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9ncy9nc29yZ2FuaXphdGlvbnZh
 bGcyLmNybDCBlgYIKwYBBQUHAQEEgYkwgYYwRwYIKwYBBQUHMAKGO2h0dHA6Ly9z
@@ -25,11 +25,11 @@ ZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2dzb3JnYW5pemF0aW9udmFsZzIu
 Y3J0MDsGCCsGAQUFBzABhi9odHRwOi8vb2NzcDIuZ2xvYmFsc2lnbi5jb20vZ3Nv
 cmdhbml6YXRpb252YWxnMjAdBgNVHQ4EFgQU4v/j8+P4UyC1bktyLH5EA3RYdUIw
 HwYDVR0jBBgwFoAUXUayjcRLdBy77fVztjq3OI91nn4wDQYJKoZIhvcNAQEFBQAD
-ggEBAGanHYAclvh/HFlWyMhd/bX5FKGxrDY8X8eYogtNEfVYMK9Pc/oaDCbkAjJe
-gnI4B812cKgBwh0cLTiyqpJ6O8LIXbDCaZakQYecmUtdTsJsO5H/stK68fN3iB8D
-doaAeGAPWUzER3HUqqooiZGM0qjzcH8xUO2mZA94L4+CU4YP5eWro4NZz4iCBSKn
-rVo0Xm/3OmDdb9rAqi5nC2MN1TgPMjIQMkIImHp/AKpLVIyRI6nBFzB8F4qP4aJN
-lhcUS4Fe45NjePsuyo0VGhuRVLpAv4ipN7dqPL1Fjh7nEfj2hoEc3NvseoFk3Jvi
-MCe7Jchh43bGAvJhOzi706Enkio=
+ggEBAAyrht07fUMMdmcAXU5ix2bteBASZGXaQ/wfUCqRWfnVxKtJrFC1jU/ZBAw+
+cvqmi6MkOJWTSdar5HC/H65Gq3JJDkXP+VXphCOirs45eNjpt9ld2xinZMAQFHmk
+Be4vi0Ubmwagi3W15JALRz+tHGVGiEksnoLwzI+D82qRmimY81fxb9viHXO7+oTE
+unG0z5jur85Z49hpscXakv2DatfyJlvvXcyAV3Q29TlV13IV126CAJynSftaQeSk
+Xkvj4J6pE7H0WBRKxyxoKU7RkxQlWSrczGX0Phu2bGoLRRlHtjbwqqYrbGuxRqsY
++W9zI0a2C+KlAO8229IrWrtORFU=
 -----END CERTIFICATE-----
 www.ostgotatrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
index dea6f73..c9e5693 100644
--- bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
+++ bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
@@ -1,30 +1,29 @@
 -----BEGIN CERTIFICATE-----

-vKHI1z2ijHtap/OBlU9IDHUddFf92Av/6nDh1gxaYUxD5oHy

+bCeldzB9nAQ/I/ibHX6t+93A5AEkpw==
 -----END CERTIFICATE-----
 m.op.fi:443
diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
index d0ccbb3..1ee0d09 100644
--- bankdroid-legacy/src/main/res/raw/cert_paypal.pem
+++ bankdroid-legacy/src/main/res/raw/cert_paypal.pem
@@ -1,4 +1,5 @@
 -----BEGIN CERTIFICATE-----
+<<<<<<< HEAD
 MIIG0jCCBbqgAwIBAgIQB2T3ui0CFx+cSA3+e2W7bzANBgkqhkiG9w0BAQUFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
@@ -16,11 +17,31 @@ almQzTrfmN7RPjosfGJrQzCnMATT0Up94yIt1Imv5yCavWrIY1ImcuSjUMxTHaRy
 D3jtnp2aBC+jhfoZYJ8a2uM6+j5h0gYpaEsLq5ilFWpvsHoKa1ZQit2/p/yE9+6U
 oCAuJHYJRicHMNv3EdZMt7xVi5MKFCX7H+ZOmHHuZidDeL0gUQIDAQABo4ICxDCC
 AsAwbgYDVR0RBGcwZYIMYy5wYXlwYWwuY29tgg1jNi5wYXlwYWwuY29tghRkZXZl
+=======

+>>>>>>> 149359b... Certificate update 2015-10-18
 bG9wZXIucGF5cGFsLmNvbYISaGlzdG9yeS5wYXlwYWwuY29tggx0LnBheXBhbC5j
 b22CDnd3dy5wYXlwYWwuY29tMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0G
 A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBmBgNVHSAEXzBdMFsGC2CGSAGG
 +EUBBxcGMEwwIwYIKwYBBQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUG
 CCsGAQUFBwICMBkaF2h0dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaA
+<<<<<<< HEAD
 FEv6LeTuMzLi3w0BoYbToDs6uayuMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9z
 dC5zeW1jYi5jb20vc3QuY3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYT
 aHR0cDovL3N0LnN5bWNkLmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3N0LnN5bWNi
@@ -36,5 +57,25 @@ CaoNT4yYOdT2wyswOzHLaQJhNNcTlbxy0lEh3f3S04MnhpB4jVCakRvORlU0FD2R
 G4oHGhNJqthJc54f5yvlvhXi5ac9hHd8n+G86dS6QI/QWvkg2EXm0/6huSLP2Bvt
 z6CSbS+tefVGVei0hvFvlM/ZVkaWGyJvQXli9MnQd1Fh+CkhGgOJSaGJ2/PM47zz
 Gp3OLqh4jMEbNLobkIdLkZ2F9jYMDw==
+=======

+nA==
+>>>>>>> 149359b... Certificate update 2015-10-18
 -----END CERTIFICATE-----
 www.paypal.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_villabanken.pem bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
index 046878c..b692c7f 100644
--- bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
+++ bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
@@ -1,33 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIFezCCBGOgAwIBAgIQJ5Bs7UjNyuX5jACYuvZAOjANBgkqhkiG9w0BAQUFADB7
+MIIGcDCCBVigAwIBAgIQIBLV1aMHhwIvpDSH8jsnLDANBgkqhkiG9w0BAQsFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd

-9zMG3j0JdTv4xPZSSQHq

+XFEii/wZ3VLPyzEJ0WXObbtjE3Y=
 -----END CERTIFICATE-----
 kundportal.cerdo.se:443

commit 76be9667313798016569b30de4d7c06db99a7195 (walles/feature/domain-model, origin/feature/domain-model)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 23:49:40 2015 +0200

    Adds some todo comments

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java
index 6b5ab8d..5016d87 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java
@@ -24,7 +24,7 @@ public interface EquityAccount extends Account {
      * Returns the total revenue for all equities in the account, in percent.
      * @return Total revenue in percent, in 1/100.
      */
-    double getRevenueInPercent();
+    double getRevenueAsPercentage();
 
     /**
      * Returns all equities for the account.
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
index 5dc402e..67abd33 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
@@ -70,19 +70,27 @@ public class EquityAccountBuilder extends AbstractAccountBuilder<EquityAccountBu
             mEquities = equities;
         }
 
+        @Override
+        public BigDecimal getBalance() {
+            //TODO calculate balance from getCost() and getRevenue()
+            return super.getBalance();
+        }
+
         @Override
         public BigDecimal getCost() {
+            //TODO calculate cost by summarizing cost of equities collection.
             return mCost == null ? BigDecimal.ZERO : mCost;
         }
 
         @Override
         public BigDecimal getRevenue() {
+            //TODO calculate revenue by summarizing revenue of equities collection.
             return mRevenue == null ? BigDecimal.ZERO : mRevenue;
         }
 
         @Override
-        public double getRevenueInPercent() {
-            return getRevenue().equals(BigDecimal.ZERO) ? 0 : getCost().doubleValue() / getRevenue().doubleValue();
+        public double getRevenueAsPercentage() {
+            return 1 + getRevenue().divide(getCost()).doubleValue();
         }
 
         @Override

commit ad6985066feba181e8ac8b26768baa288cdab18a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 23:34:58 2015 +0200

    Removes unused method and imports.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
index 6c94e82..44c8e9b 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
@@ -1,9 +1,6 @@
 package com.liato.bankdroid.api.domain.account.impl;
 
-import com.liato.bankdroid.api.domain.account.Account;
-
 import java.math.BigDecimal;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
index 05d3078..8dff297 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
@@ -3,9 +3,7 @@ package com.liato.bankdroid.api.domain.account.impl;
 import com.liato.bankdroid.api.domain.account.Account;
 
 import java.math.BigDecimal;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 
 public class AccountBuilder extends AbstractAccountBuilder<AccountBuilder> {
@@ -22,7 +20,6 @@ public class AccountBuilder extends AbstractAccountBuilder<AccountBuilder> {
         return new BasicAccount(mId, mName, mCurrency, mBalance, mCustomAttributes);
     }
 
-
     static class BasicAccount implements Account {
 
         private String mId;
@@ -54,10 +51,6 @@ public class AccountBuilder extends AbstractAccountBuilder<AccountBuilder> {
             return mBalance == null ? BigDecimal.ZERO : mBalance;
         }
 
-        void setBalance(BigDecimal balance) {
-            mBalance = balance;
-        }
-
         @Override
         public String getCurrency() {
             return mCurrency;
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
index bbc76a9..f837bab 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
@@ -61,4 +61,4 @@ public class CreditCardAccountBuilder extends AbstractAccountBuilder<CreditCardA
             return mTransactions == null ? Collections.<Transaction>emptyList() : mTransactions;
         }
     }
-}
\ No newline at end of file
+}

commit caa5c72b147e6904b7066bbfe209dc6517f2e44b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 23:24:24 2015 +0200

    Fixes compilation failure

diff --git app/build.gradle app/build.gradle
index a4ffb04..d8a9cbf 100644
--- app/build.gradle
+++ app/build.gradle
@@ -45,6 +45,11 @@ android {
         targetCompatibility JavaVersion.VERSION_1_7
     }
 
+    packagingOptions {
+        exclude 'META-INF/LICENSE.txt'
+        exclude 'META-INF/NOTICE.txt'
+    }
+
     lintOptions {
         disable 'InvalidPackage'
     }

commit 747718ed7389d49109041f55e819c125d316578e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 23:16:58 2015 +0200

    Adds missing calculations.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java
index 7a1d5c1..1fc239e 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java
@@ -38,10 +38,12 @@ public interface Equity {
     BigDecimal getRevenue();
 
     /**
-     * Returns the total revenue for this equity, in percent.
-     * @return Total revenue in percent, in 1/100.
+     * Returns the total revenue for this equity, as percentage. A value less than {@code 1} is a
+     * loss and a value greater than one is a profit. e.g. {@code 0.75} represents a 25 % loss,
+     * while {@code 1.5} is 50 % profit.
+     * @return Total revenue as percentage.
      */
-    double getRevenueInPercent();
+    double getRevenueAsPercentage();
 
     /**
      * Returns the current balance for the equity.
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
index eaf4523..92ed3ac 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
@@ -14,12 +14,14 @@ public class EquityBuilder {
     /**
      *
      * @param balance Current balance of the equity.
-     * @param decimalRevenue The revenue in percentage as a decimal.
+     * @param revenue The revenue in percentage. A value less than 1 is a loss
+     *                       and a value greater than one is a profit. e.g. {@code 0.75} represents
+     *                       a 25 % loss, while {@code 1.5} is 50 % profit.
      * @param currency The currency of the equity.
      */
-    public EquityBuilder(BigDecimal balance, double decimalRevenue, String currency){
-        mEquity = new BasicEquity(costFromBalanceAndRevenue(balance, decimalRevenue),
-                revenueFromBalanceAndPercentageRevenue(balance, decimalRevenue),currency);
+    public EquityBuilder(BigDecimal balance, double revenue, String currency){
+        mEquity = new BasicEquity(costFromBalanceAndRevenue(balance, revenue),
+                revenueFromBalanceAndRevenueAsPerecntage(balance, revenue),currency);
     }
 
     public EquityBuilder name(String name) {
@@ -32,14 +34,16 @@ public class EquityBuilder {
         return this;
     }
 
+    public Equity build() {
+        return mEquity;
+    }
+
     private BigDecimal costFromBalanceAndRevenue(BigDecimal balance, double revenue) {
-        // TODO Implementation
-        return null;
+        return balance.divide(BigDecimal.valueOf(revenue));
     }
 
-    private BigDecimal revenueFromBalanceAndPercentageRevenue(BigDecimal balance, double revenue) {
-        //TODO implementation
-        return null;
+    private BigDecimal revenueFromBalanceAndRevenueAsPerecntage(BigDecimal balance, double revenue) {
+       return balance.subtract(balance.divide(BigDecimal.valueOf(revenue)));
     }
 
 
@@ -87,8 +91,8 @@ public class EquityBuilder {
         }
 
         @Override
-        public double getRevenueInPercent() {
-            return getRevenue().equals(BigDecimal.ZERO) ? 0 : getCost().doubleValue() / getRevenue().doubleValue();
+        public double getRevenueAsPercentage() {
+            return 1 + getRevenue().divide(getCost()).doubleValue();
         }
 
         @Override

commit 6eeaec0c53f038e966eeb9020dd1f088ae16fb71
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 22:23:18 2015 +0200

    Update documentation.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java
index 52238bd..be6fc02 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java
@@ -6,7 +6,7 @@ import java.util.Set;
 
 /**
  * The service loader is responsible for loading all available {@link ProviderFactory} known to the
- * application. This is the single point of creating new {@link com.liato.bankdroid.api.Provider}s.
+ * application. This is the single point of creating new {@link com.liato.bankdroid.api.ProviderFactory}s.
  */
 public interface ServiceLoader {
 

commit 3e654ea1ea91f28b4adcdbc3f6152773d489c851
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 22:22:01 2015 +0200

    Adds provider interface.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/Provider.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/Provider.java
new file mode 100644
index 0000000..8887f22
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/Provider.java
@@ -0,0 +1,34 @@
+package com.liato.bankdroid.api;
+
+import com.liato.bankdroid.api.configuration.ProviderConfiguration;
+
+/**
+ * Represents a provider. e.g. a bank, stock broker, bus company etc.
+ */
+public interface Provider {
+
+    /**
+     * Returns a unique identifier for the provider.
+     * @return the provider id.
+     */
+    String getId();
+
+    /**
+     * Returns the name of the provider.
+     * @return The provider's name.
+     */
+    String getName();
+
+    /**
+     * Indicates if a provider implementation is currently broken.
+     * @return {@code true} if the provider implementation is broken. Otherwise {@false}.
+     */
+    boolean isBroken();
+
+    /**
+     * Returns the configuration available for the provider.
+     * @return the provider configuration.
+     */
+    ProviderConfiguration getConfiguration();
+
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/ProviderFactory.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/ProviderFactory.java
new file mode 100644
index 0000000..5c5c4bc
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/ProviderFactory.java
@@ -0,0 +1,14 @@
+package com.liato.bankdroid.api;
+
+/**
+ * Is responsible for creating new instances of {@link Provider} objects. This should be the single
+ * point of where {@link Provider} objects are created.
+ */
+public interface ProviderFactory {
+
+    /**
+     * Create a new {@link Provider} instance.
+     * @return a new instance of a {@link Provider}.
+     */
+    Provider create();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/ProviderConnection.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/ProviderConnection.java
new file mode 100644
index 0000000..da1d0db
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/ProviderConnection.java
@@ -0,0 +1,39 @@
+package com.liato.bankdroid.api.domain;
+
+import com.liato.bankdroid.api.domain.account.Account;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+
+/**
+ * Represents a single connection to the {@link com.liato.bankdroid.api.Provider}.
+ */
+public interface ProviderConnection {
+
+    /**
+     * Returns the name of the connection.
+     * @return The connection name.
+     */
+    String getName();
+
+    /**
+     * Returns the total balance for all accounts associated with the connection. In the case the
+     * accounts have multiple currencies, these will be converted to the currency returned by the
+     * {@link #getDefaultCurrency()}.
+     *
+     * @return The total balance for the connection.
+     */
+    BigDecimal getTotalBalance();
+
+    /**
+     * Returns the default currency for the connection.
+     * @return The default currency for the connection.
+     */
+    String getDefaultCurrency();
+
+    /**
+     * Returns a collection of all accounts associated with the connection.
+     * @return All accounts for the connection.
+     */
+    Collection<Account> getAccounts();
+}

commit 8635505d282871f32c103d827c31968ad51fa82f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 22:20:42 2015 +0200

    Adds builders for accounts domain model.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
new file mode 100644
index 0000000..6c94e82
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AbstractAccountBuilder.java
@@ -0,0 +1,51 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.Account;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+abstract class AbstractAccountBuilder<T extends AbstractAccountBuilder<T>> {
+
+    protected String mId;
+    protected String mName;
+    protected BigDecimal mBalance;
+    protected String mCurrency;
+    protected Map<String, String> mCustomAttributes;
+
+    protected AbstractAccountBuilder(String id, String name, String currency) {
+        if (id == null || id.isEmpty() || currency == null || currency.isEmpty() || name == null || name.isEmpty()) {
+            throw new IllegalArgumentException("Id, name and currency cannot be null or empty");
+        }
+        mId = id;
+        mName = name;
+        mCurrency = currency;
+    }
+
+    protected abstract T self();
+
+    public T name(String name) {
+        mName = name;
+        return self();
+    }
+
+    public T balance(BigDecimal balance) {
+        mBalance = balance;
+        return self();
+    }
+
+    public T addCustomAttribute(String key, String value) {
+        if(mCustomAttributes == null) {
+            mCustomAttributes = new HashMap<>();
+        }
+        mCustomAttributes.put(key, value);
+        return self();
+    }
+
+    public T customAttributes(Map<String, String> customAttributes) {
+        mCustomAttributes = customAttributes;
+        return self();
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
new file mode 100644
index 0000000..05d3078
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/AccountBuilder.java
@@ -0,0 +1,71 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.Account;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AccountBuilder extends AbstractAccountBuilder<AccountBuilder> {
+
+    public AccountBuilder(String id, String name, String currency) {
+       super(id, name, currency);
+    }
+
+    protected AccountBuilder self() {
+        return this;
+    }
+
+    public Account build() {
+        return new BasicAccount(mId, mName, mCurrency, mBalance, mCustomAttributes);
+    }
+
+
+    static class BasicAccount implements Account {
+
+        private String mId;
+        private String mName;
+        private BigDecimal mBalance;
+        private String mCurrency;
+        private Map<String, String> mCustomAttributes;
+
+        protected BasicAccount(String id, String name, String currency, BigDecimal balance, Map<String, String> customAttributes) {
+            mId = id;
+            mCurrency = currency;
+            mName = name;
+            mBalance = balance;
+            mCustomAttributes = customAttributes;
+        }
+
+        @Override
+        public String getId() {
+            return mId;
+        }
+
+        @Override
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public BigDecimal getBalance() {
+            return mBalance == null ? BigDecimal.ZERO : mBalance;
+        }
+
+        void setBalance(BigDecimal balance) {
+            mBalance = balance;
+        }
+
+        @Override
+        public String getCurrency() {
+            return mCurrency;
+        }
+
+        @Override
+        public Map<String, String> getCustomAttributes() {
+            return mCustomAttributes == null ? Collections.<String,String>emptyMap() : mCustomAttributes;
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
new file mode 100644
index 0000000..bbc76a9
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/CreditCardAccountBuilder.java
@@ -0,0 +1,64 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.CreditCardAccount;
+import com.liato.bankdroid.api.domain.account.Transaction;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
+
+public class CreditCardAccountBuilder extends AbstractAccountBuilder<CreditCardAccountBuilder>{
+
+    private BigDecimal mCreditLimit;
+
+    private Collection<Transaction> mTransactions;
+
+    public CreditCardAccountBuilder(String id, String name, String currency) {
+       super(id, name, currency);
+    }
+
+    protected CreditCardAccountBuilder self() {
+        return this;
+    }
+
+    public CreditCardAccountBuilder creditLimit(BigDecimal creditLimit) {
+        mCreditLimit = creditLimit;
+        return this;
+    }
+
+    public CreditCardAccountBuilder transactions(Collection<Transaction> transactions) {
+        mTransactions = transactions;
+        return this;
+    }
+
+    public CreditCardAccount build()   {
+        return new BasicCreditCardAccount(mId, mName, mCurrency, mBalance, mCustomAttributes,
+                mCreditLimit, mTransactions);
+    }
+
+    private class BasicCreditCardAccount extends BasicAccount implements CreditCardAccount {
+
+        private BigDecimal mCreditLimit;
+        private Collection<Transaction> mTransactions;
+
+        BasicCreditCardAccount(String id, String name, String currency, BigDecimal balance,
+                Map<String, String> customAttributes, BigDecimal creditLimit,
+                Collection<Transaction> transactions) {
+            super(id, name, currency, balance, customAttributes);
+            mCreditLimit = creditLimit;
+            mTransactions = transactions;
+        }
+
+        @Override
+        public BigDecimal getCreditLimit() {
+            return mCreditLimit == null ? BigDecimal.ZERO : mCreditLimit;
+        }
+
+        public Collection<Transaction> getTransactions() {
+            return mTransactions == null ? Collections.<Transaction>emptyList() : mTransactions;
+        }
+    }
+}
\ No newline at end of file
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
new file mode 100644
index 0000000..5dc402e
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityAccountBuilder.java
@@ -0,0 +1,93 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.Equity;
+import com.liato.bankdroid.api.domain.account.EquityAccount;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
+
+public class EquityAccountBuilder extends AbstractAccountBuilder<EquityAccountBuilder>{
+
+    private BigDecimal mCost;
+
+    private BigDecimal mRevenue;
+
+    private Collection<Equity> mEquities;
+
+    public EquityAccountBuilder(String id, String name, String currency) {
+        super(id, name, currency);
+    }
+
+    protected EquityAccountBuilder self() {
+        return this;
+    }
+
+    public EquityAccountBuilder cost(BigDecimal cost) {
+        mCost = cost;
+        return this;
+    }
+
+    public EquityAccountBuilder revenue(BigDecimal revenue) {
+        mRevenue = revenue;
+        return this;
+    }
+
+    public EquityAccountBuilder addEquity(Equity equity) {
+        if(mEquities == null) {
+            mEquities = new ArrayList<>();
+        }
+        mEquities.add(equity);
+        return this;
+    }
+
+    public EquityAccountBuilder equities(Collection<Equity> equities) {
+        mEquities = equities;
+        return this;
+    }
+
+    public EquityAccount build() {
+        return new BasicEquityAccount(mId, mName, mCurrency, mBalance, mCustomAttributes, mCost,
+                mRevenue, mEquities);
+    }
+
+    private class BasicEquityAccount extends BasicAccount implements EquityAccount {
+
+        private BigDecimal mCost;
+        private BigDecimal mRevenue;
+        private Collection<Equity> mEquities;
+
+        private BasicEquityAccount(String id, String name, String currency, BigDecimal balance,
+                Map<String, String> customAttributes, BigDecimal cost, BigDecimal revenue,
+                Collection<Equity> equities) {
+            super(id, name, currency, balance, customAttributes);
+            mCost = cost;
+            mRevenue = revenue;
+            mEquities = equities;
+        }
+
+        @Override
+        public BigDecimal getCost() {
+            return mCost == null ? BigDecimal.ZERO : mCost;
+        }
+
+        @Override
+        public BigDecimal getRevenue() {
+            return mRevenue == null ? BigDecimal.ZERO : mRevenue;
+        }
+
+        @Override
+        public double getRevenueInPercent() {
+            return getRevenue().equals(BigDecimal.ZERO) ? 0 : getCost().doubleValue() / getRevenue().doubleValue();
+        }
+
+        @Override
+        public Collection<Equity> getEquities() {
+            return mEquities == null ? Collections.<Equity>emptyList() : mEquities;
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
new file mode 100644
index 0000000..eaf4523
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/EquityBuilder.java
@@ -0,0 +1,99 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.Equity;
+import java.math.BigDecimal;
+
+public class EquityBuilder {
+
+    private BasicEquity mEquity;
+
+    public EquityBuilder(BigDecimal cost, BigDecimal revenue, String currency) {
+        mEquity = new BasicEquity(cost, revenue, currency);
+    }
+
+    /**
+     *
+     * @param balance Current balance of the equity.
+     * @param decimalRevenue The revenue in percentage as a decimal.
+     * @param currency The currency of the equity.
+     */
+    public EquityBuilder(BigDecimal balance, double decimalRevenue, String currency){
+        mEquity = new BasicEquity(costFromBalanceAndRevenue(balance, decimalRevenue),
+                revenueFromBalanceAndPercentageRevenue(balance, decimalRevenue),currency);
+    }
+
+    public EquityBuilder name(String name) {
+        mEquity.mName = name;
+        return this;
+    }
+
+    public EquityBuilder quantity(double quantity) {
+        mEquity.mQuantity = quantity;
+        return this;
+    }
+
+    private BigDecimal costFromBalanceAndRevenue(BigDecimal balance, double revenue) {
+        // TODO Implementation
+        return null;
+    }
+
+    private BigDecimal revenueFromBalanceAndPercentageRevenue(BigDecimal balance, double revenue) {
+        //TODO implementation
+        return null;
+    }
+
+
+    private class BasicEquity implements Equity {
+
+        private String mName;
+
+        private String mCurrency;
+
+        private double mQuantity;
+
+        private BigDecimal mCost;
+
+        private BigDecimal mRevenue;
+
+        private BasicEquity(BigDecimal cost, BigDecimal revenue, String currency) {
+            mCost = cost;
+            mRevenue = revenue;
+            mCurrency = currency;
+        }
+
+        @Override
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public String getCurrency() {
+            return mCurrency;
+        }
+
+        @Override
+        public double getQuantity() {
+            return mQuantity;
+        }
+
+        @Override
+        public BigDecimal getCost() {
+            return mCost == null ? BigDecimal.ZERO : mCost;
+        }
+
+        @Override
+        public BigDecimal getRevenue() {
+            return mRevenue == null ? BigDecimal.ZERO : mRevenue;
+        }
+
+        @Override
+        public double getRevenueInPercent() {
+            return getRevenue().equals(BigDecimal.ZERO) ? 0 : getCost().doubleValue() / getRevenue().doubleValue();
+        }
+
+        @Override
+        public BigDecimal getBalance() {
+            return getCost().add(getRevenue());
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
new file mode 100644
index 0000000..658b8fa
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/LiabilityAccountBuilder.java
@@ -0,0 +1,72 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.LiabilityAccount;
+import com.liato.bankdroid.api.domain.account.Payment;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
+
+public class LiabilityAccountBuilder extends AbstractAccountBuilder<LiabilityAccountBuilder> {
+
+    private double mInterest;
+    private Collection<Payment> mPayments;
+
+    public LiabilityAccountBuilder(String id, String name, String currency) {
+        super(id, name, currency);
+    }
+
+    protected LiabilityAccountBuilder self() {
+        return this;
+    }
+
+    public LiabilityAccountBuilder interest(double interest) {
+        mInterest = interest;
+        return this;
+    }
+
+    public LiabilityAccountBuilder addPayment(Payment payment) {
+        if(mPayments == null) {
+            mPayments = new ArrayList<>();
+        }
+        mPayments.add(payment);
+        return this;
+    }
+
+    public LiabilityAccountBuilder payments(Collection<Payment> payments) {
+        mPayments = payments;
+        return this;
+    }
+
+    public LiabilityAccount build() {
+        return new BasicLiabilityAccount(mId, mName, mCurrency, mBalance, mCustomAttributes,
+                mInterest, mPayments);
+    }
+
+    private class BasicLiabilityAccount extends BasicAccount implements LiabilityAccount {
+
+        private double mInterest;
+        private Collection<Payment> mPayments;
+
+        private BasicLiabilityAccount(String id, String name, String currency, BigDecimal balance,
+                Map<String, String> customAttributes, double interest, Collection<Payment> payments) {
+            super(id, name, currency, balance, customAttributes);
+            mInterest = interest;
+            mPayments = payments;
+        }
+
+        @Override
+        public double getInterest() {
+            return mInterest;
+        }
+
+        @Override
+        public Collection<Payment> getPayments() {
+            return mPayments == null ? Collections.<Payment>emptyList() : mPayments;
+        }
+    }
+}
\ No newline at end of file
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
new file mode 100644
index 0000000..4310d90
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/PrePaidCardAccountBuilder.java
@@ -0,0 +1,61 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.PrePaidCardAccount;
+
+import org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+import java.util.Map;
+
+import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
+
+public class PrePaidCardAccountBuilder extends AbstractAccountBuilder<PrePaidCardAccountBuilder>{
+
+    private DateTime mValidFrom;
+    private DateTime mExpirationDate;
+
+    public PrePaidCardAccountBuilder(String id, String name, String currency) {
+        super(id, name, currency);
+    }
+
+    protected PrePaidCardAccountBuilder self() {
+        return this;
+    }
+
+    public PrePaidCardAccountBuilder validFrom(DateTime validFrom) {
+        mValidFrom = validFrom;
+        return this;
+    }
+    public PrePaidCardAccountBuilder expirationDate(DateTime expirationDate) {
+        mExpirationDate = expirationDate;
+        return this;
+    }
+
+    public PrePaidCardAccount build() {
+        return new BasicPrePaidCardAccount(mId, mName, mCurrency, mBalance, mCustomAttributes,
+                mExpirationDate, mValidFrom);
+    }
+
+    private class BasicPrePaidCardAccount extends BasicAccount implements PrePaidCardAccount {
+
+        private DateTime mExpirationDate;
+        private DateTime mValidFrom;
+
+        private BasicPrePaidCardAccount(String id, String name, String currency, BigDecimal balance,
+                Map<String, String> customAttributes, DateTime expirationDate, DateTime validFrom) {
+            super(id, name, currency, balance, customAttributes);
+            mExpirationDate = expirationDate;
+            mValidFrom = validFrom;
+        }
+
+        @Override
+        public DateTime getExpirationDate() {
+            return mExpirationDate;
+        }
+
+        @Override
+        public DateTime getValidFrom() {
+            return mValidFrom;
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
new file mode 100644
index 0000000..e42d107
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionAccountBuilder.java
@@ -0,0 +1,59 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+import com.liato.bankdroid.api.domain.account.Transaction;
+import com.liato.bankdroid.api.domain.account.TransactionAccount;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import static com.liato.bankdroid.api.domain.account.impl.AccountBuilder.BasicAccount;
+
+public class TransactionAccountBuilder extends AbstractAccountBuilder<TransactionAccountBuilder> {
+
+    private Collection<Transaction> mTransactions;
+
+    public TransactionAccountBuilder(String id, String name, String currency) {
+        super(id, name, currency);
+    }
+
+    protected TransactionAccountBuilder self() {
+        return this;
+    }
+
+    public TransactionAccountBuilder addTransaction(Transaction transaction) {
+        if(mTransactions == null) {
+            mTransactions = new ArrayList<>();
+        }
+        mTransactions.add(transaction);
+        return this;
+    }
+
+    public TransactionAccountBuilder transactions(Collection<Transaction> transactions) {
+        mTransactions = transactions;
+        return this;
+    }
+
+    public TransactionAccount build() {
+        return new BasicTransactionAccount(mId, mName, mCurrency, mBalance, mCustomAttributes,
+                mTransactions);
+    }
+
+    private class BasicTransactionAccount extends BasicAccount implements TransactionAccount {
+
+        private Collection<Transaction> mTransactions;
+
+        private BasicTransactionAccount(String id, String name, String currency, BigDecimal balance,
+                Map<String, String> customAttributes, Collection<Transaction> transactions) {
+            super(id, name, currency, balance, customAttributes);
+            mTransactions = transactions;
+        }
+
+        @Override
+        public Collection<Transaction> getTransactions() {
+            return mTransactions == null ? Collections.<Transaction>emptyList() : mTransactions;
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java
new file mode 100644
index 0000000..194dfe3
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/impl/TransactionBuilder.java
@@ -0,0 +1,71 @@
+package com.liato.bankdroid.api.domain.account.impl;
+
+
+import com.liato.bankdroid.api.domain.account.Transaction;
+
+import org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+
+public class TransactionBuilder {
+
+    private BasicTransaction mTransaction;
+
+    public TransactionBuilder(BigDecimal amount, String currency, DateTime transactionDate) {
+        this.mTransaction = new BasicTransaction(amount, currency, transactionDate);
+    }
+
+    public TransactionBuilder description(String description) {
+        mTransaction.description = description;
+        return this;
+    }
+
+    public TransactionBuilder pending(boolean pending) {
+        mTransaction.pending = pending;
+        return this;
+    }
+
+    public Transaction build() {
+        return mTransaction;
+    }
+
+    private class BasicTransaction implements Transaction {
+
+        private BigDecimal amount;
+        private String description;
+        private String currency;
+        private DateTime transactionDate;
+        private boolean pending;
+
+        private BasicTransaction(BigDecimal amount, String currency, DateTime transactionDate) {
+            this.amount = amount;
+            this.currency = currency;
+            this.transactionDate = transactionDate;
+        }
+
+        @Override
+        public BigDecimal getAmount() {
+            return amount;
+        }
+
+        @Override
+        public String getDescription() {
+            return description;
+        }
+
+        @Override
+        public String getCurrency() {
+            return currency;
+        }
+
+        @Override
+        public DateTime getTransactionDate() {
+            return transactionDate;
+        }
+
+        @Override
+        public boolean isPending() {
+            return pending;
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java
new file mode 100644
index 0000000..52238bd
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/service/ServiceLoader.java
@@ -0,0 +1,18 @@
+package com.liato.bankdroid.api.service;
+
+import com.liato.bankdroid.api.ProviderFactory;
+
+import java.util.Set;
+
+/**
+ * The service loader is responsible for loading all available {@link ProviderFactory} known to the
+ * application. This is the single point of creating new {@link com.liato.bankdroid.api.Provider}s.
+ */
+public interface ServiceLoader {
+
+    /**
+     * Loads all available {@link ProviderFactory}.
+     * @return A set of all available {@link ProviderFactory} within the application.
+     */
+    Set<ProviderFactory> load();
+}

commit 9fbf74aab463dd9ac18c48db437699905ab1aad5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 22:20:04 2015 +0200

    Adds domain model

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java
new file mode 100644
index 0000000..d1bf8b8
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Account.java
@@ -0,0 +1,42 @@
+package com.liato.bankdroid.api.domain.account;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A parent interface for all account types.
+ */
+public interface Account {
+
+    /**
+     * Returns the account id.
+     * @return Returns the account id.
+     */
+    String getId();
+
+    /**
+     * Returns the account's name.
+     * @return the account name.
+     */
+    String getName();
+
+    /**
+     * Returns the total balance for the account.
+     * @return The total balance for the account.
+     */
+    BigDecimal getBalance();
+
+    /**
+     * The ISO 4217 currency representation, when possible.
+     * @return The main currency for the account.
+     */
+    String getCurrency();
+
+    /**
+     * Returns a collection of extra attributes that can be set on an account.
+     * @return A collection of custom attributes, or an empty collection if no custom
+     * attributes exist.
+     */
+    Map<String, String> getCustomAttributes();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/CreditCardAccount.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/CreditCardAccount.java
new file mode 100644
index 0000000..8a1bfed
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/CreditCardAccount.java
@@ -0,0 +1,22 @@
+package com.liato.bankdroid.api.domain.account;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+
+/**
+ * Represents a Credit Card Account.
+ */
+public interface CreditCardAccount extends Account {
+
+    /**
+     * Returns the credit limit for the account.
+     * @return the credit limit.
+     */
+    BigDecimal getCreditLimit();
+
+    /**
+     * Returns all transactions for the account.
+     * @return All transactions for the account.
+     */
+    Collection<Transaction> getTransactions();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java
new file mode 100644
index 0000000..7a1d5c1
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Equity.java
@@ -0,0 +1,51 @@
+package com.liato.bankdroid.api.domain.account;
+
+import java.math.BigDecimal;
+
+/**
+ * Represent a single equity, could be a share, fund etc.
+ */
+public interface Equity {
+
+    /**
+     * Returns the equity name.
+     * @return the equity name.
+     */
+    String getName();
+
+    /**
+     * The ISO 4217 currency representation, when possible.
+     * @return The equity's currency.
+     */
+    String getCurrency();
+
+    /**
+     * Returns the number of shares for this equity.
+     * @return The quantity of equities.
+     */
+    double getQuantity();
+
+    /**
+     * Returns the total cost for this equity.
+     * @return Cost for the entity.
+     */
+    BigDecimal getCost();
+
+    /**
+     * Returns the total revenue for this equity.
+     * @return Equity revenue.
+     */
+    BigDecimal getRevenue();
+
+    /**
+     * Returns the total revenue for this equity, in percent.
+     * @return Total revenue in percent, in 1/100.
+     */
+    double getRevenueInPercent();
+
+    /**
+     * Returns the current balance for the equity.
+     * @return the equity's balance.
+     */
+    BigDecimal getBalance();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java
new file mode 100644
index 0000000..6b5ab8d
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/EquityAccount.java
@@ -0,0 +1,34 @@
+package com.liato.bankdroid.api.domain.account;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+
+/**
+ * Represent an Equity Account. An equity account is a collection of shares, funds etc.
+ */
+public interface EquityAccount extends Account {
+
+    /**
+     * Returns the total cost for all equities included in the account.
+     * @return Total cost.
+     */
+    BigDecimal getCost();
+
+    /**
+     * Returns the total revenue for all equities in the account.
+     * @return Total revenue.
+     */
+    BigDecimal getRevenue();
+
+    /**
+     * Returns the total revenue for all equities in the account, in percent.
+     * @return Total revenue in percent, in 1/100.
+     */
+    double getRevenueInPercent();
+
+    /**
+     * Returns all equities for the account.
+     * @return All account equities.
+     */
+    Collection<Equity> getEquities();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/LiabilityAccount.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/LiabilityAccount.java
new file mode 100644
index 0000000..777c865
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/LiabilityAccount.java
@@ -0,0 +1,21 @@
+package com.liato.bankdroid.api.domain.account;
+
+import java.util.Collection;
+
+/**
+ * Represents a liability account. A liability can for example be a loan.
+ */
+public interface LiabilityAccount extends Account {
+
+    /**
+     * Returns the interest as a number less than 1, representing the interest in percentage.
+     * @return the interest in percent.
+     */
+    double getInterest();
+
+    /**
+     * Returns a collection of payments, could be both historical and upcoming payments.
+     * @return A collection of payments.
+     */
+    Collection<Payment> getPayments();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Payment.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Payment.java
new file mode 100644
index 0000000..98d1e4b
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Payment.java
@@ -0,0 +1,35 @@
+package com.liato.bankdroid.api.domain.account;
+
+import org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+
+/**
+ * Represents a Liability payment.
+ */
+public interface Payment {
+
+    /**
+     * Returns the date when the payment is due.
+     * @return the payment's due date.
+     */
+    DateTime getDueDate();
+
+    /**
+     * Returns the payment amount.
+     * @return the payment amount.
+     */
+    BigDecimal getAmount();
+
+    /**
+     * The ISO 4217 currency representation, when possible.
+     * @return The main currency for the account.
+     */
+    String getCurrency();
+
+    /**
+     * A description of the payment.
+     * @return payment description.
+     */
+    String getDescription();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/PrePaidCardAccount.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/PrePaidCardAccount.java
new file mode 100644
index 0000000..fb99a43
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/PrePaidCardAccount.java
@@ -0,0 +1,21 @@
+package com.liato.bankdroid.api.domain.account;
+
+import org.joda.time.DateTime;
+
+/**
+ * Represents a prepaid card. e.g. a bus card, cash card etc.
+ */
+public interface PrePaidCardAccount extends Account {
+
+    /**
+     * Returns the date when the card expired.
+     * @return the expiration date.
+     */
+    DateTime getExpirationDate();
+
+    /**
+     * Returns the date from when the card is valid.
+     * @return the valid from date.
+     */
+    DateTime getValidFrom();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Transaction.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Transaction.java
new file mode 100644
index 0000000..6667393
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/Transaction.java
@@ -0,0 +1,41 @@
+package com.liato.bankdroid.api.domain.account;
+
+import org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+
+/**
+ * Represents a single transaction.
+ */
+public interface Transaction {
+
+    /**
+     * Returns the transaction amount.
+     * @return the transaction amount.
+     */
+    BigDecimal getAmount();
+
+    /**
+     * Returns the currency for the transaction, conforming to ISO 4217 when possible.
+     * @return the transaction currency.
+     */
+    String getCurrency();
+
+    /**
+     * Returns a short description of the transaction.
+     * @return the transaction description.
+     */
+    String getDescription();
+
+    /**
+     * Returns the date when the transaction was initiated.
+     * @return the transaction date.
+     */
+    DateTime getTransactionDate();
+
+    /**
+     * Returns {@code true} if, and only if, the transaction is still pending.
+     * @return {@code true} if the transaction is pending, otherwise {@code false}.
+     */
+    boolean isPending();
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/TransactionAccount.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/TransactionAccount.java
new file mode 100644
index 0000000..d5e7301
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/domain/account/TransactionAccount.java
@@ -0,0 +1,15 @@
+package com.liato.bankdroid.api.domain.account;
+
+import java.util.Collection;
+
+/**
+ * Represents a transaction account. Holds multiple transactions.
+ */
+public interface TransactionAccount extends Account {
+
+    /**
+     * Returns a collection of transaction.
+     * @return All transactions.
+     */
+    Collection<Transaction> getTransactions();
+}

commit 13acf1bd6915d990bf7d44f4335f939ce28db40e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Sep 3 22:18:34 2015 +0200

    Adds jodatime

diff --git bankdroid-interface/build.gradle bankdroid-interface/build.gradle
index 68b6180..248d29c 100644
--- bankdroid-interface/build.gradle
+++ bankdroid-interface/build.gradle
@@ -4,5 +4,6 @@ sourceCompatibility = JavaVersion.VERSION_1_7
 targetCompatibility = JavaVersion.VERSION_1_7
 
 dependencies {
+    compile 'joda-time:joda-time:2.8.2'
     testCompile 'junit:junit:4.12'
 }

commit 5daa10067526c64c88cc9f03b398eef3e2e62b02
Author: Magnus Hagander <magnus@hagander.net>
Date:   Mon Aug 31 12:36:39 2015 +0200

    Shorten Amex card titles
    
    Many (most?) of the Amex card titles parsed from the site end up
    being very long, which makes the amount included in the notifications
    end up outside the screen.
    
    Replace "American Express" with "Amex" and "EuroBonus" with "EB" in
    order to shorten these down, while keeping them unique and easy
    to identify.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 0c344f3..836a584 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -148,7 +148,10 @@ public class AmericanExpress extends Bank {
              * 4: Amount                1.111,11 kr
              * 
              */
-            accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
+            accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString()
+                    .replace("American Express", "Amex")
+                    .replace("EuroBonus", "EB")
+                    .trim(),
                     Helpers.parseBalance(matcher.group(4)).negate(),
                     matcher.group(2).trim()));
             balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());

commit 7c4437bd730b4c7df82ae1a11a506bbfa695dab4 (walles/feature/fields-refactor, origin/feature/fields-refactor)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Aug 29 20:17:00 2015 +0200

    Move Default configuration into core module.

diff --git app/build.gradle app/build.gradle
index a4ffb04..e89a697 100644
--- app/build.gradle
+++ app/build.gradle
@@ -84,6 +84,7 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-legacy')
+    compile project(':bankdroid-core')
     compile 'com.jakewharton:butterknife:6.1.0'
     compile "com.android.support:appcompat-v7:22.0.+"
     compile 'com.google.collections:google-collections:1.0'
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 99e14f2..d05721a 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -26,10 +26,10 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankChoice;
 import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.DefaultConnectionConfiguration;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.configuration.DefaultConnectionConfiguration;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.utils.FieldTypeMapper;
 import com.liato.bankdroid.utils.NetworkUtils;
diff --git bankdroid-core/build.gradle bankdroid-core/build.gradle
new file mode 100644
index 0000000..e31a6ba
--- /dev/null
+++ bankdroid-core/build.gradle
@@ -0,0 +1,8 @@
+apply plugin: 'java'
+
+sourceCompatibility = JavaVersion.VERSION_1_7
+targetCompatibility = JavaVersion.VERSION_1_7
+
+dependencies {
+	compile project(':bankdroid-interface')
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/DefaultConnectionConfiguration.java bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
similarity index 95%
rename from app/src/main/java/com/liato/bankdroid/banking/DefaultConnectionConfiguration.java
rename to bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
index d909a75..62a1b46 100644
--- app/src/main/java/com/liato/bankdroid/banking/DefaultConnectionConfiguration.java
+++ bankdroid-core/src/main/java/com/liato/bankdroid/configuration/DefaultConnectionConfiguration.java
@@ -1,4 +1,4 @@
-package com.liato.bankdroid.banking;
+package com.liato.bankdroid.configuration;
 
 import com.liato.bankdroid.api.configuration.Field;
 import com.liato.bankdroid.api.configuration.FieldBuilder;
diff --git app/src/main/resources/i18n/application.properties bankdroid-core/src/main/resources/i18n/application.properties
similarity index 100%
rename from app/src/main/resources/i18n/application.properties
rename to bankdroid-core/src/main/resources/i18n/application.properties
diff --git app/src/main/resources/i18n/application_sv_SE.properties bankdroid-core/src/main/resources/i18n/application_sv_SE.properties
similarity index 100%
rename from app/src/main/resources/i18n/application_sv_SE.properties
rename to bankdroid-core/src/main/resources/i18n/application_sv_SE.properties
diff --git settings.gradle settings.gradle
index 2a20750..37901dc 100644
--- settings.gradle
+++ settings.gradle
@@ -1 +1 @@
-include ':app', ':bankdroid-legacy', ':bankdroid-interface'
+include ':app', ':bankdroid-core', ':bankdroid-legacy', ':bankdroid-interface'

commit 3772259a6c4279032561037494a4ab1b9be2fdd6
Merge: 25abba4 4f5e8e8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Aug 28 17:47:00 2015 +0200

    Merge pull request #563 from jonasgroth/master
    
    Adapt to new site for Chalmrest

commit 394d4705ea6452c0cb8ccfa8cf31d3196845fb64
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Aug 28 17:46:22 2015 +0200

    Adds i18n support for BasicProviderConfiguration

diff --git app/src/main/resources/i18n/application.properties app/src/main/resources/i18n/application.properties
index 5749c98..93d1a04 100644
--- app/src/main/resources/i18n/application.properties
+++ app/src/main/resources/i18n/application.properties
@@ -1 +1,3 @@
 field.provider.configuration.name.label=Custom Name
+field.provider.configuration.username.label=Username
+field.provider.configuration.password.label=Password
diff --git app/src/main/resources/i18n/application_sv_SE.properties app/src/main/resources/i18n/application_sv_SE.properties
index ab04ed7..6660e62 100644
--- app/src/main/resources/i18n/application_sv_SE.properties
+++ app/src/main/resources/i18n/application_sv_SE.properties
@@ -1 +1,3 @@
 field.provider.configuration.name.label=Eget Namn
+field.provider.configuration.username.label=Användarnamn
+field.provider.configuration.password.label=Lösenord
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
index 3662f7b..2db1be0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
@@ -9,14 +9,15 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.ResourceBundle;
 
 public class BasicProviderConfiguration implements ProviderConfiguration {
 
     public static final String FIELD_USERNAME = "username";
     public static final String FIELD_PASSWORD = "password";
 
-    public static final String PROPERTY_USERNAME = "provider.default.config.label.username";
-    public static final String PROPERTY_PASSWORD = "provider.default.config.label.password";
+    private static final ResourceBundle LOCALE = ResourceBundle.getBundle("i18n.application");
+
     private final List<Field> mFields;
 
     public BasicProviderConfiguration() {
@@ -29,18 +30,19 @@ public class BasicProviderConfiguration implements ProviderConfiguration {
     }
 
     private List<Field> createConfiguration() {
+
         List<Field> fields = new LinkedList<>();
 
-        fields.add(new FieldBuilder(FIELD_USERNAME)
+        fields.add(new FieldBuilder(FIELD_USERNAME, LOCALE)
                 .fieldType(FieldType.TEXT)
-                .label(PROPERTY_USERNAME)
+                .placeholder("")
                 .required(true)
                 .build()
         );
 
-        fields.add(new FieldBuilder(FIELD_PASSWORD)
+        fields.add(new FieldBuilder(FIELD_PASSWORD, LOCALE)
                         .fieldType(FieldType.TEXT)
-                        .label(PROPERTY_PASSWORD)
+                        .placeholder("")
                         .secret(true)
                         .required(true)
                         .build()

commit 4f5e8e82f4ffef57f3f391c94cb7c161241df8c9
Author: Jonas Groth <jonas@groth.im>
Date:   Fri Aug 28 15:36:00 2015 +0200

    Adapt to new site for Chalmrest
    
    Adapt to new site for "Chalmers Konferens & Restauranger" (Chalmrest).

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 1205120..a5a0314 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -1,5 +1,6 @@
 package com.liato.bankdroid.banking.banks;
 
+import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
@@ -8,21 +9,21 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.util.EntityUtils;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.text.Html;
 import android.text.InputType;
 
 import java.io.IOException;
-import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import eu.nullbyte.android.urllib.Urllib;
+
 public class Chalmrest extends Bank {
 
     private static final String TAG = "Chalmrest";
@@ -33,6 +34,19 @@ public class Chalmrest extends Bank {
 
     private static final int BANKTYPE_ID = IBankTypes.CHALMREST;
 
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+
+    private Pattern reAccount = Pattern
+            .compile("<span id=\"txtPTMCardName\">(.*?)</span>",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+
+    private Pattern reBalance = Pattern.compile(
+            "<span id=\"txtPTMCardValue\">(.*?)</span>",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+
+    private String response = null;
+
     public Chalmrest(Context context) {
         super(context);
 
@@ -53,54 +67,84 @@ public class Chalmrest extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException, IOException {
-        super.update();
-        if (getUsername().isEmpty()) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context);
+        response = urlopen.open("http://kortladdning3.chalmerskonferens.se/Default.aspx");
+
+        Matcher matcherView = reViewState.matcher(response);
+        if (!matcherView.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
+        String strViewState = matcherView.group(1);
 
-        String cardNr = getUsername();
-
-        HttpClient httpclient = new DefaultHttpClient();
-        HttpGet httpget = new HttpGet(
-                "http://kortladdning.chalmerskonferens.se/bgw.aspx?type=getCardAndArticles&card="
-                        + cardNr);
-        HttpResponse response = httpclient.execute(httpget);
-        HttpEntity entity = response.getEntity();
-        if (entity == null) {
-            throw new BankException("Couldn't connect!");
+        Matcher matcherEvent = reEventValidation.matcher(response);
+        if (!matcherEvent.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
+        String strEvent = matcherEvent.group(1);
 
-        String s1 = EntityUtils.toString(entity);
-        Pattern pattern = Pattern.compile(
-                "<ExtendedInfo Name=\"Kortvarde\" Type=\"System.Double\" >(.*?)</ExtendedInfo>");
-        Matcher matcher = pattern.matcher(s1);
-
-        if (!matcher.find()) {
-            throw new BankException("Couldn't parse value!");
-        }
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEvent));
+        postData.add(new BasicNameValuePair("txtCardNumber", getUsername()));
+        postData.add(new BasicNameValuePair("btnNext", "Nästa"));
+        postData.add(new BasicNameValuePair("hiddenIsMobile", "desktop"));
 
-        String value = matcher.group(1);
+        return new LoginPackage(urlopen, postData, response,
+                "http://kortladdning3.chalmerskonferens.se/Default.aspx");
+    }
 
-        StringBuilder sb = new StringBuilder();
-        int last = 0;
-        Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
-        while (match.find()) {
-            sb.append(value.substring(last, match.start()));
-            int i = Integer.parseInt(match.group(1), 16);
-            sb.append((char) i);
-            last = match.end();
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (!response.contains("Logga ut")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-        sb.append(value.substring(last));
-        value = sb.toString().replace(',', '.');
+        return urlopen;
+    }
 
-        matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
-        if (!matcher.find()) {
-            throw new BankException("Coldn't parse name!");
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (getUsername().isEmpty()) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        response = urlopen.open("http://kortladdning3.chalmerskonferens.se/CardLoad_Order.aspx");
+        Matcher matcher;
+        Matcher matcher_b;
+
+        matcher = reAccount.matcher(response);
+        if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Name              Kalle Karlsson
+             */
+
+            matcher_b = reBalance.matcher(response);
+            if (matcher_b.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Balance              118 kr
+                 */
+
+                String balanceString = matcher_b.group(1).replaceAll("\\<a[^>]*>", "")
+                        .replaceAll("\\<[^>]*>", "").trim();
+
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(balanceString), matcher.group(1)));
+                balance = balance.add(Helpers.parseBalance(balanceString));
+            }
         }
-        String name = matcher.group(1);
 
-        accounts.add(new Account(name, BigDecimal.valueOf(Double.parseDouble(value)), "1"));
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
 
         super.updateComplete();
     }

commit ce0b8b801780c8f57fda2369267592b60ac5188b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Aug 28 14:45:51 2015 +0200

    Refactoring

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 068f166..99e14f2 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -157,36 +157,48 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
     private void createForm(List<Field>... configurations) {
         for(List<Field> fields : configurations) {
             for (Field field : fields) {
-                TextView fieldText = new TextView(this);
-                String label = field.getLabel() + (field.isRequired() ? "" : " " + getString(R.string.optional_field));
-                fieldText.setText(label);
-                fieldText.setVisibility(field.isHidden() ? View.GONE : View.VISIBLE);
-                mFormContainer.addView(fieldText);
-
+                createLabel(field);
                 if(field.getValues().isEmpty()) {
-                    EditText inputField = new EditText(this);
-                    inputField.setHint(field.getPlaceholder());
-                    if (field.isSecret()) {
-                        inputField.setTransformationMethod(
-                                PasswordTransformationMethod.getInstance());
-                    } else {
-                        inputField
-                                .setInputType(FieldTypeMapper.fromFieldType(field.getFieldType()));
-                    }
-                    inputField.setVisibility(field.isHidden() ? View.GONE : View.VISIBLE);
-                    inputField.setTag(field.getReference());
-
-                    mFormContainer.addView(inputField);
+                    createField(field);
                 } else {
-                    Spinner spinner = new Spinner(this);
-                    spinner.setAdapter(new ArrayAdapter<Entry>(this, android.R.layout.simple_spinner_item , field.getValues()));
-                    spinner.setTag(field.getReference());
-                    mFormContainer.addView(spinner);
+                    createSpinner(field);
                 }
             }
         }
     }
 
+    private void createLabel(Field field) {
+        TextView fieldText = new TextView(this);
+        String label = field.getLabel() + (field.isRequired() ? "" : " " + getString(R.string.optional_field));
+        fieldText.setText(label);
+        fieldText.setVisibility(field.isHidden() ? View.GONE : View.VISIBLE);
+        mFormContainer.addView(fieldText);
+    }
+
+    private void createField(Field field) {
+        EditText inputField = new EditText(this);
+        inputField.setHint(field.getPlaceholder());
+        if (field.isSecret()) {
+            inputField.setTransformationMethod(
+                    PasswordTransformationMethod.getInstance());
+        } else {
+            inputField
+                    .setInputType(FieldTypeMapper.fromFieldType(field.getFieldType()));
+        }
+        inputField.setVisibility(field.isHidden() ? View.GONE : View.VISIBLE);
+        inputField.setTag(field.getReference());
+
+        mFormContainer.addView(inputField);
+    }
+
+    private void createSpinner(Field field) {
+        Spinner spinner = new Spinner(this);
+        spinner.setAdapter(new ArrayAdapter<Entry>(this, android.R.layout.simple_spinner_item,
+                field.getValues()));
+        spinner.setTag(field.getReference());
+        mFormContainer.addView(spinner);
+    }
+
     private void populateForm(Bank bank) {
         EditText customName = (EditText) mFormContainer.findViewWithTag(
                 DefaultConnectionConfiguration.NAME);

commit d36af84b78a28b40516c07f205710e8dc6c4025d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Aug 28 14:39:36 2015 +0200

    Refactor BankEditActivity to use the new Field interface.

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index e96e30e..068f166 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -16,16 +16,22 @@
 
 package com.liato.bankdroid;
 
+import com.google.common.collect.Iterators;
+
 import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.api.configuration.Entry;
+import com.liato.bankdroid.api.configuration.Field;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankChoice;
 import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.DefaultConnectionConfiguration;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.FieldTypeMapper;
 import com.liato.bankdroid.utils.NetworkUtils;
 
 import android.app.AlertDialog;
@@ -34,15 +40,12 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
-import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.text.InputType;
 import android.text.method.PasswordTransformationMethod;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.AdapterView;
@@ -50,13 +53,17 @@ import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.Spinner;
 import android.widget.TextView;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import butterknife.ButterKnife;
 import butterknife.InjectView;
@@ -67,26 +74,8 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
     @InjectView(R.id.spnBankeditBanklist)
     Spinner mBankSpinner;
 
-    @InjectView(R.id.edtBankeditUsername)
-    EditText mUsernameField;
-
-    @InjectView(R.id.txtBankeditUsername)
-    TextView mUsernameLabel;
-
-    @InjectView(R.id.edtBankeditPassword)
-    EditText mPasswordField;
-
-    @InjectView(R.id.txtBankeditPassword)
-    TextView mPasswordLabel;
-
-    @InjectView(R.id.edtBankeditCustomName)
-    EditText mCustomNameField;
-
-    @InjectView(R.id.edtBankeditExtras)
-    EditText mExtrasField;
-
-    @InjectView(R.id.txtBankeditExtras)
-    TextView mExtrasLabel;
+    @InjectView(R.id.layoutBankConfiguration)
+    LinearLayout mFormContainer;
 
     @InjectView(R.id.txtErrorDesc)
     TextView mErrorDescription;
@@ -109,7 +98,7 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
         Collections.sort(items);
         BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<>(this, items);
         mBankSpinner.setAdapter(adapter);
-        mBankSpinner.setOnItemSelectedListener(this);
+
 
         Bundle extras = getIntent().getExtras();
         if (extras != null) {
@@ -117,34 +106,28 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
             if (BANKID != -1) {
                 Bank bank = BankFactory.bankFromDb(BANKID, this, false);
                 if (bank != null) {
-                    mUsernameField.setText(bank.getUsername());
-                    mPasswordField.setText(bank.getPassword());
-                    mCustomNameField.setText(bank.getCustomName());
-                    if (bank.getExtras() != null) {
-                        mExtrasField.setText(bank.getExtras());
-                    }
-
-                    mErrorDescription.setVisibility(bank.isDisabled() ? View.VISIBLE : View.INVISIBLE);
+                    mErrorDescription.setVisibility(
+                            bank.isDisabled() ? View.VISIBLE : View.INVISIBLE);
+                    mBankSpinner.setEnabled(false);
                     mBankSpinner.setSelection(adapter.getPosition(bank));
                     SELECTED_BANK = bank;
+                    createForm(SELECTED_BANK.getConnectionConfiguration(),
+                            DefaultConnectionConfiguration.fields()
+                    );
+                    populateForm(bank);
                 }
             }
         }
+        mBankSpinner.setOnItemSelectedListener(this);
     }
 
     @OnClick(R.id.btnSettingsOk)
     public void onSubmit(View v) {
-        SELECTED_BANK.setUsername(
-                mUsernameField.getText().toString()
-                        .trim());
-        SELECTED_BANK.setPassword(
-                mPasswordField.getText().toString()
-                        .trim());
-        SELECTED_BANK.setCustomName(
-                mCustomNameField.getText().toString()
-                        .trim());
-        SELECTED_BANK.setExtras(
-                mExtrasField.getText().toString().trim());
+        if(!validate()) {
+            return;
+        }
+        SELECTED_BANK.setProperties(getFormParameters(SELECTED_BANK.getConnectionConfiguration()));
+        SELECTED_BANK.setCustomName(getFormParameter(DefaultConnectionConfiguration.NAME));
         SELECTED_BANK.setDbid(BANKID);
         new DataRetrieverTask(this, SELECTED_BANK).execute();
     }
@@ -156,52 +139,101 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
 
     @Override
     public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-        SELECTED_BANK = (Bank) parentView.getItemAtPosition(pos);
-
-        mUsernameField.setInputType(SELECTED_BANK.getInputTypeUsername());
-        mUsernameField.setHint(SELECTED_BANK.getInputHintUsername());
-        mUsernameLabel.setText(SELECTED_BANK.getInputTitleUsername());
-
-        mPasswordField.setInputType(SELECTED_BANK.getInputTypePassword());
-        mPasswordField.setTransformationMethod(PasswordTransformationMethod.getInstance());
-        mPasswordField.setTypeface(Typeface.MONOSPACE);
-        mPasswordLabel.setText(SELECTED_BANK.getInputTitlePassword());
-
-        mExtrasField.setInputType(SELECTED_BANK.getInputTypeExtras());
-        if ((SELECTED_BANK.getInputTypeExtras() & InputType.TYPE_TEXT_VARIATION_PASSWORD)
-                == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
-            mExtrasField.setTransformationMethod(PasswordTransformationMethod.getInstance());
-            mExtrasField.setTypeface(Typeface.MONOSPACE);
+        Bank selectedBank = (Bank) parentView.getItemAtPosition(pos);
+        if(SELECTED_BANK == null || !SELECTED_BANK.equals(selectedBank)) {
+            SELECTED_BANK = selectedBank;
+                    mFormContainer.removeAllViewsInLayout();
+            createForm(SELECTED_BANK.getConnectionConfiguration(),
+                    DefaultConnectionConfiguration.fields()
+            );
         }
-        mExtrasLabel.setText(SELECTED_BANK.getInputTitleExtras());
+    }
 
-        if (SELECTED_BANK.isInputUsernameHidden()) {
-            mUsernameField.setVisibility(View.GONE);
-            mUsernameLabel.setVisibility(View.GONE);
-        } else {
-            mUsernameField.setVisibility(View.VISIBLE);
-            mUsernameLabel.setVisibility(View.VISIBLE);
+    @Override
+    public void onNothingSelected(AdapterView<?> arg) {
+    }
+
+
+    private void createForm(List<Field>... configurations) {
+        for(List<Field> fields : configurations) {
+            for (Field field : fields) {
+                TextView fieldText = new TextView(this);
+                String label = field.getLabel() + (field.isRequired() ? "" : " " + getString(R.string.optional_field));
+                fieldText.setText(label);
+                fieldText.setVisibility(field.isHidden() ? View.GONE : View.VISIBLE);
+                mFormContainer.addView(fieldText);
+
+                if(field.getValues().isEmpty()) {
+                    EditText inputField = new EditText(this);
+                    inputField.setHint(field.getPlaceholder());
+                    if (field.isSecret()) {
+                        inputField.setTransformationMethod(
+                                PasswordTransformationMethod.getInstance());
+                    } else {
+                        inputField
+                                .setInputType(FieldTypeMapper.fromFieldType(field.getFieldType()));
+                    }
+                    inputField.setVisibility(field.isHidden() ? View.GONE : View.VISIBLE);
+                    inputField.setTag(field.getReference());
+
+                    mFormContainer.addView(inputField);
+                } else {
+                    Spinner spinner = new Spinner(this);
+                    spinner.setAdapter(new ArrayAdapter<Entry>(this, android.R.layout.simple_spinner_item , field.getValues()));
+                    spinner.setTag(field.getReference());
+                    mFormContainer.addView(spinner);
+                }
+            }
         }
+    }
 
-        if (SELECTED_BANK.isInputPasswordHidden()) {
-            mPasswordField.setVisibility(View.GONE);
-            mPasswordLabel.setVisibility(View.GONE);
-        } else {
-            mPasswordField.setVisibility(View.VISIBLE);
-            mPasswordLabel.setVisibility(View.VISIBLE);
+    private void populateForm(Bank bank) {
+        EditText customName = (EditText) mFormContainer.findViewWithTag(
+                DefaultConnectionConfiguration.NAME);
+        customName.setText(bank.getCustomName());
+
+        for(Map.Entry<String, String> property : bank.getProperties().entrySet()) {
+            EditText propertyInput = (EditText) mFormContainer.findViewWithTag(property.getKey());
+            propertyInput.setText(property.getValue());
         }
+    }
 
-        if (SELECTED_BANK.isInputExtrasHidden()) {
-            mExtrasField.setVisibility(View.GONE);
-            mExtrasLabel.setVisibility(View.GONE);
+    private Map<String, String> getFormParameters(List<Field> fields) {
+        Map<String, String> properties = new HashMap<>();
+        for(Field field : fields) {
+            properties.put(field.getReference(), getFormParameter(field.getReference()));
+        }
+        return properties;
+    }
+
+    private String getFormParameter(String property) {
+        View propertyView = mFormContainer.findViewWithTag(property);
+        if(propertyView instanceof EditText) {
+            EditText propertyInput = (EditText) propertyView;
+            return propertyInput.getText().toString().trim();
+        } else if(propertyView instanceof Spinner) {
+            Spinner spinnerProperty = (Spinner) propertyView;
+            Entry entry = (Entry) spinnerProperty.getSelectedItem();
+            return entry.getKey();
         } else {
-            mExtrasField.setVisibility(View.VISIBLE);
-            mExtrasLabel.setVisibility(View.VISIBLE);
+            return null;
         }
     }
 
-    @Override
-    public void onNothingSelected(AdapterView<?> arg) {
+    private boolean validate() {
+        boolean valid = true;
+        Iterator<Field> fields = Iterators.concat(SELECTED_BANK.getConnectionConfiguration().iterator(),
+                DefaultConnectionConfiguration.fields().iterator());
+        while(fields.hasNext()) {
+            Field field = fields.next();
+            try {
+                field.validate(getFormParameter(field.getReference()));
+            } catch (IllegalArgumentException e) {
+                valid = false;
+                ((EditText) mFormContainer.findViewWithTag(field.getReference())).setError(e.getMessage());
+            }
+        }
+        return valid;
     }
 
     private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
@@ -338,5 +370,4 @@ public class BankEditActivity extends LockableActivity implements OnItemSelected
             }
         }
     }
-
 }
diff --git app/src/main/java/com/liato/bankdroid/banking/DefaultConnectionConfiguration.java app/src/main/java/com/liato/bankdroid/banking/DefaultConnectionConfiguration.java
new file mode 100644
index 0000000..d909a75
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/DefaultConnectionConfiguration.java
@@ -0,0 +1,35 @@
+package com.liato.bankdroid.banking;
+
+import com.liato.bankdroid.api.configuration.Field;
+import com.liato.bankdroid.api.configuration.FieldBuilder;
+import com.liato.bankdroid.api.configuration.FieldType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+public enum DefaultConnectionConfiguration {
+
+    INSTANCE;
+
+    public static final String NAME = "provider.configuration.name";
+
+    private List<Field> configuration;
+
+    DefaultConnectionConfiguration() {
+        configuration = createConfiguration();
+    }
+
+    private List<Field> createConfiguration() {
+        List<Field> configuration = new ArrayList<>();
+        configuration.add(new FieldBuilder(NAME, ResourceBundle.getBundle("i18n.application"))
+                .placeholder("")
+                .fieldType(FieldType.TEXT)
+                .build());
+        return configuration;
+    }
+
+    public static List<Field> fields() {
+        return INSTANCE.configuration;
+    }
+}
diff --git app/src/main/res/layout/bank.xml app/src/main/res/layout/bank.xml
index 64a429b..1a30276 100644
--- app/src/main/res/layout/bank.xml
+++ app/src/main/res/layout/bank.xml
@@ -29,71 +29,18 @@
             <TextView
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
-                android:text="@string/bank"
-                android:textSize="20sp"
-                android:typeface="sans" />
+                android:text="@string/bank"/>
 
             <Spinner
                 android:id="@+id/spnBankeditBanklist"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"></Spinner>
 
-            <TextView
-                android:id="@+id/txtBankeditUsername"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/username"
-                android:textSize="20sp"
-                android:typeface="sans" />
-
-            <EditText
-                android:id="@+id/edtBankeditUsername"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:inputType="textEmailAddress"></EditText>
-
-            <TextView
-                android:id="@+id/txtBankeditPassword"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/password"
-                android:textSize="20sp"
-                android:typeface="sans" />
-
-            <EditText
-                android:id="@+id/edtBankeditPassword"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:inputType="textPassword"></EditText>
-
-            <TextView
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/custom_name"
-                android:textSize="20sp"
-                android:typeface="sans" />
-
-            <EditText
-                android:id="@+id/edtBankeditCustomName"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:inputType="textCapWords"></EditText>
-
-            <TextView
-                android:id="@+id/txtBankeditExtras"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/extras_field"
-                android:textSize="20sp"
-                android:typeface="sans"
-                android:visibility="gone" />
-
-            <EditText
-                android:id="@+id/edtBankeditExtras"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:inputType="textCapWords"
-                android:visibility="gone"></EditText>
+            <LinearLayout
+                    android:orientation="vertical"
+                    android:id="@+id/layoutBankConfiguration"
+                    android:layout_width="fill_parent"
+                    android:layout_height="wrap_content"></LinearLayout>
 
             <TextView
                 android:id="@+id/txtErrorDesc"
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 5bd1925..da83f0b 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -19,7 +19,7 @@
     <string name="add_account">Lägg till konto</string>
 
     <string name="bank">Bank</string>
-    <string name="custom_name">Eget Namn (frivilligt)</string>
+    <string name="optional_field">(frivilligt)</string>
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
     <string name="cancel">AVBRYT</string>
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index 461b50d..c6e9a5f 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -18,7 +18,7 @@
     <string name="add_account">Add account</string>
 
 
-    <string name="custom_name">Custom Name (optional)</string>
+    <string name="optional_field">(optional)</string>
 
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
diff --git app/src/main/resources/i18n/application.properties app/src/main/resources/i18n/application.properties
new file mode 100644
index 0000000..5749c98
--- /dev/null
+++ app/src/main/resources/i18n/application.properties
@@ -0,0 +1 @@
+field.provider.configuration.name.label=Custom Name
diff --git app/src/main/resources/i18n/application_sv_SE.properties app/src/main/resources/i18n/application_sv_SE.properties
new file mode 100644
index 0000000..ab04ed7
--- /dev/null
+++ app/src/main/resources/i18n/application_sv_SE.properties
@@ -0,0 +1 @@
+field.provider.configuration.name.label=Eget Namn
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 4c04870..0ee5f68 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -17,6 +17,8 @@
 package com.liato.bankdroid.banking;
 
 import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.api.configuration.Field;
+import com.liato.bankdroid.api.configuration.ProviderConfiguration;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -46,6 +48,8 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
+    private final ProviderConfiguration defaultConfiguration = new LegacyProviderConfiguration(this);
+
     protected String TAG = "Bank";
 
     protected String NAME = "Bank";
@@ -363,6 +367,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return this.getName().compareToIgnoreCase(another.getName());
     }
 
+    public List<Field> getConnectionConfiguration() {
+        return defaultConfiguration.getConnectionConfiguration();
+    }
+
     public void updateComplete() {
         for (Account a : this.accounts) {
             //Preserve hidden and notify settings from old accounts
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
new file mode 100644
index 0000000..3662f7b
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BasicProviderConfiguration.java
@@ -0,0 +1,50 @@
+package com.liato.bankdroid.banking;
+
+import com.liato.bankdroid.api.configuration.Field;
+import com.liato.bankdroid.api.configuration.FieldBuilder;
+import com.liato.bankdroid.api.configuration.FieldType;
+import com.liato.bankdroid.api.configuration.ProviderConfiguration;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class BasicProviderConfiguration implements ProviderConfiguration {
+
+    public static final String FIELD_USERNAME = "username";
+    public static final String FIELD_PASSWORD = "password";
+
+    public static final String PROPERTY_USERNAME = "provider.default.config.label.username";
+    public static final String PROPERTY_PASSWORD = "provider.default.config.label.password";
+    private final List<Field> mFields;
+
+    public BasicProviderConfiguration() {
+        mFields = createConfiguration();
+    }
+
+    @Override
+    public List<Field> getConnectionConfiguration() {
+        return mFields;
+    }
+
+    private List<Field> createConfiguration() {
+        List<Field> fields = new LinkedList<>();
+
+        fields.add(new FieldBuilder(FIELD_USERNAME)
+                .fieldType(FieldType.TEXT)
+                .label(PROPERTY_USERNAME)
+                .required(true)
+                .build()
+        );
+
+        fields.add(new FieldBuilder(FIELD_PASSWORD)
+                        .fieldType(FieldType.TEXT)
+                        .label(PROPERTY_PASSWORD)
+                        .secret(true)
+                        .required(true)
+                        .build()
+        );
+        return fields;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
new file mode 100644
index 0000000..82ad171
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankHelper.java
@@ -0,0 +1,48 @@
+package com.liato.bankdroid.banking;
+
+import com.liato.bankdroid.provider.IBankTypes;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+public class LegacyBankHelper {
+
+    private static Map<String, Integer> legacyProviderReferences;
+    private static Map<Integer, String> providerReferences;
+
+    public static String getReferenceFromLegacyId(int legacyId) {
+        if(providerReferences == null) {
+            generateLegacyProviderReferences();
+        }
+        return providerReferences.get(legacyId);
+    }
+
+    // TODO Used during refactoring. Remove before 2.0
+    public static int getLegacyIdFromReference(String reference) {
+        if(legacyProviderReferences == null) {
+            generateLegacyProviderReferences();
+        }
+        return legacyProviderReferences.get(reference);
+    }
+
+    private static void generateLegacyProviderReferences() {
+        Map<Integer, String> references = new HashMap<>();
+        Map<String, Integer> legacyIds = new HashMap<>();
+        Field[] fields = IBankTypes.class.getFields();
+        for(int i = 0 ; i < fields.length; i++) {
+            Field field = fields[i];
+            try {
+                String reference = field.getName().toLowerCase().replaceAll("_", "-");
+                Integer legacyId = field.getInt(new IBankTypes() {
+                });
+                references.put(legacyId, reference);
+                legacyIds.put(reference, legacyId);
+            } catch(IllegalAccessException e) {
+                //TODO log if provider could not be mapped.
+            }
+        }
+        legacyProviderReferences = legacyIds;
+        providerReferences = references;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
index 47d9195..b180cf6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
@@ -1,9 +1,60 @@
 package com.liato.bankdroid.banking;
+import com.liato.bankdroid.api.configuration.Field;
+import com.liato.bankdroid.api.configuration.FieldBuilder;
+import com.liato.bankdroid.api.configuration.ProviderConfiguration;
+import com.liato.bankdroid.utils.FieldTypeMapper;
 
-public interface LegacyProviderConfiguration {
+import java.util.LinkedList;
+import java.util.List;
 
-    String USERNAME = "legacy.username";
-    String PASSWORD = "legacy.password";
-    String EXTRAS = "legacy.extras";
+public class LegacyProviderConfiguration implements ProviderConfiguration {
 
+    public static final String USERNAME = "legacy.username";
+
+    public static final String PASSWORD = "legacy.password";
+
+    public static final String EXTRAS = "legacy.extras";
+
+    private List<Field> mConfiguration;
+
+    private Bank mLegacyBank;
+
+    public LegacyProviderConfiguration(Bank legacyBank) {
+        mLegacyBank = legacyBank;
+    }
+
+    @Override
+    public List<Field> getConnectionConfiguration() {
+        if (mConfiguration == null) {
+            mConfiguration = createConfiguration();
+        }
+        return mConfiguration;
+    }
+
+    private List<Field> createConfiguration() {
+        List<Field> configuration = new LinkedList<>();
+        configuration.add(new FieldBuilder(USERNAME)
+                .label(mLegacyBank.getContext().getString(mLegacyBank.getInputTitleUsername()))
+                .placeholder(mLegacyBank.getInputHintUsername())
+                .hidden(mLegacyBank.isInputUsernameHidden())
+                .required(true)
+                .fieldType(FieldTypeMapper.toFieldType(mLegacyBank.getInputTypeUsername()))
+                .build());
+
+        configuration.add(new FieldBuilder(PASSWORD)
+                .label(mLegacyBank.getContext().getString(mLegacyBank.getInputTitlePassword()))
+                .hidden(mLegacyBank.isInputPasswordHidden())
+                .secret(true)
+                .required(true)
+                .fieldType(FieldTypeMapper.toFieldType(mLegacyBank.getInputTypePassword()))
+                .build());
+
+        configuration.add(new FieldBuilder(EXTRAS)
+                .label(mLegacyBank.getContext().getString(mLegacyBank.getInputTitleExtras()))
+                .hidden(mLegacyBank.isInputExtrasHidden())
+                .fieldType(FieldTypeMapper.toFieldType(mLegacyBank.getInputTypeExtras()))
+                .build());
+
+        return configuration;
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java
new file mode 100644
index 0000000..6436bdb
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/FieldTypeMapper.java
@@ -0,0 +1,34 @@
+package com.liato.bankdroid.utils;
+
+import com.liato.bankdroid.api.configuration.FieldType;
+
+import android.text.InputType;
+
+// TODO Move to app module when all legacy banks have been converted.
+public class FieldTypeMapper {
+
+    public static FieldType toFieldType(int androidFieldType) {
+        switch(androidFieldType) {
+            case InputType.TYPE_CLASS_NUMBER:
+                return FieldType.NUMBER;
+            case InputType.TYPE_CLASS_PHONE:
+                return FieldType.PHONE;
+            case InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS:
+                return FieldType.EMAIL;
+            default:
+                return FieldType.TEXT;
+        }
+    }
+    public static int fromFieldType(FieldType fieldType) {
+        switch(fieldType) {
+            case NUMBER:
+                return InputType.TYPE_CLASS_NUMBER;
+            case PHONE:
+                return InputType.TYPE_CLASS_PHONE;
+            case EMAIL:
+                return InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+            default:
+                return InputType.TYPE_CLASS_TEXT;
+        }
+    }
+}

commit 25abba4e547f237c4fcc159fa409a854ca90c274
Merge: 2312c04 701c31a
Author: liato <x@x00.us>
Date:   Fri Aug 28 12:54:21 2015 +0200

    Merge pull request #561 from liato/feature/fields
    
    Adds interface for creating bank configuration.

commit 701c31afcbd7c8ed75cd1614be648dc90d07abfe
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 27 12:38:40 2015 +0200

    Remove redundant throw declaration

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
index 166f52a..23dd932 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
@@ -8,6 +8,5 @@ public interface FieldValidator {
      * @param value the value to be validated.
      * @throws IllegalArgumentException if the validation fails.
      */
-    void validate(String value) throws IllegalArgumentException;
-
+    void validate(String value);
 }

commit b9f9bb090ee1f578a6b8457d7adf405e5b846d48
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 27 12:27:24 2015 +0200

    Adds javadoc

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index 305f949..3bd978d 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -12,10 +12,25 @@ public class FieldBuilder {
 
     private BasicField field;
 
+    /**
+     * Create a new {@link Field} builder without i18n support. 
+     */
     public FieldBuilder(String reference) {
       this(reference, null);
     }
 
+    /**
+     * Create a new {@link Field} builder with i18n support for {@link Field#getLabel()} and {@link Field#getPlaceholder()}.
+     * The following keys needs to be in the ResourceBundle:
+     * {@code field.{reference}.label} - Locale label value
+     * {@code field.{reference}.placeholder} - Locale placeholder value.
+     * 
+     * Setting {@link #placeholder(String)} or {@link #label(String) specifically will override the i18n values.
+     * Otherwise they will be set to the value specified in the Locale bundle or in the default bundle if not present.
+     * If a key is not present at all in the ResourceBundle the key will will be returned.
+     * @param reference Field reference
+     * @param bundle The ResourceBundle to be used for i18n support.
+     */
     public FieldBuilder(String reference, ResourceBundle bundle) {
         if(reference == null || reference.trim().isEmpty()) {
             throw new IllegalArgumentException("reference must be provided.");

commit 43e5e1d0716fcda393292db8d42ad7d8191d386e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 27 10:44:50 2015 +0200

    Adds newlines

diff --git bankdroid-interface/build.gradle bankdroid-interface/build.gradle
index 4a7dd44..68b6180 100644
--- bankdroid-interface/build.gradle
+++ bankdroid-interface/build.gradle
@@ -5,4 +5,4 @@ targetCompatibility = JavaVersion.VERSION_1_7
 
 dependencies {
     testCompile 'junit:junit:4.12'
-}
\ No newline at end of file
+}
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
index c440f30..dceece7 100644
--- bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
+++ bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
@@ -1,2 +1,2 @@
 field.reference.placeholder=defaultPlaceholder
-field.reference.label=defaultLabel
\ No newline at end of file
+field.reference.label=defaultLabel
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
index fd790f6..2fe26f1 100644
--- bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
+++ bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
@@ -1 +1 @@
-field.reference.label=localeLabel
\ No newline at end of file
+field.reference.label=localeLabel
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
index 04609e1..9ff7001 100644
--- bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
+++ bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
@@ -1 +1 @@
-field.reference.placeholder=defaultPlaceholder
\ No newline at end of file
+field.reference.placeholder=defaultPlaceholder

commit aa826c23e23f8ddfdc9f19f8048cd089e538edc5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 27 10:42:54 2015 +0200

    Update FieldType.java
    
    Fixes typo

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java
index 550f1db..ec4bd65 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java
@@ -2,15 +2,15 @@ package com.liato.bankdroid.api.configuration;
 
 public enum FieldType {
     /**
-     * Represent a regular input text field.
+     * Represents a regular input text field.
      */
     TEXT,
     /**
-     * Represent an input field that only allows numbers.
+     * Represents an input field that only allows numbers.
      */
     NUMBER,
     /**
-     * Represent an input field that should contain a phone number.
+     * Represents an input field that should contain a phone number.
      */
     PHONE,
     /**

commit 3ab1ecdc8091f837f396706faf248a028408524b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Aug 27 08:39:11 2015 +0200

    Adds i18n support for fields.

diff --git bankdroid-interface/build.gradle bankdroid-interface/build.gradle
index eed9aa6..4a7dd44 100644
--- bankdroid-interface/build.gradle
+++ bankdroid-interface/build.gradle
@@ -2,3 +2,7 @@ apply plugin: 'java'
 
 sourceCompatibility = JavaVersion.VERSION_1_7
 targetCompatibility = JavaVersion.VERSION_1_7
+
+dependencies {
+    testCompile 'junit:junit:4.12'
+}
\ No newline at end of file
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index 0ebfb12..305f949 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -1,10 +1,10 @@
 package com.liato.bankdroid.api.configuration;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import java.util.ResourceBundle;
+
 /**
  * A builder for building {@link Field} objects.
  */
@@ -13,10 +13,14 @@ public class FieldBuilder {
     private BasicField field;
 
     public FieldBuilder(String reference) {
+      this(reference, null);
+    }
+
+    public FieldBuilder(String reference, ResourceBundle bundle) {
         if(reference == null || reference.trim().isEmpty()) {
             throw new IllegalArgumentException("reference must be provided.");
         }
-        field = new BasicField(reference);
+        field = new BasicField(reference, bundle);
     }
 
     public Field build() {
@@ -65,6 +69,8 @@ public class FieldBuilder {
 
     private class BasicField implements Field {
 
+        private ResourceBundle resourceBundle;
+
         private String reference;
 
         private String placeholder;
@@ -83,8 +89,9 @@ public class FieldBuilder {
 
         private FieldValidator validator;
 
-        public BasicField(String reference) {
+        BasicField(String reference, ResourceBundle bundle) {
             this.reference = reference;
+            this.resourceBundle = bundle;
         }
 
         @Override
@@ -94,12 +101,12 @@ public class FieldBuilder {
 
         @Override
         public String getPlaceholder() {
-            return placeholder;
+            return placeholder == null ? getLocaleString("placeholder") : placeholder;
         }
 
         @Override
         public String getLabel() {
-            return label;
+            return label == null ? getLocaleString("label") : label;
         }
 
         @Override
@@ -141,5 +148,18 @@ public class FieldBuilder {
                 }
             }
         }
+
+        private String getLocaleString(String key) {
+            if(!isLocale()) {
+                return null;
+            }
+            String propertyKey = String.format("field.%s.%s", getReference(), key);
+            return resourceBundle.containsKey(propertyKey) ? resourceBundle.getString(propertyKey)
+                    : propertyKey;
+        }
+
+        private boolean isLocale() {
+            return resourceBundle != null;
+        }
     }
 }
diff --git bankdroid-interface/src/test/java/com/liato/bankdroid/api/configuration/FieldBuilderTest.java bankdroid-interface/src/test/java/com/liato/bankdroid/api/configuration/FieldBuilderTest.java
new file mode 100644
index 0000000..9028b51
--- /dev/null
+++ bankdroid-interface/src/test/java/com/liato/bankdroid/api/configuration/FieldBuilderTest.java
@@ -0,0 +1,55 @@
+package com.liato.bankdroid.api.configuration;
+
+import org.junit.Test;
+
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class FieldBuilderTest {
+
+    private static final String PACKAGE = FieldBuilderTest.class.getPackage().getName();
+    private static final String REFERENCE = "reference";
+
+    private static final String DEFAULT_BUNDLE = "com.liato.bankdroid.api.configuration.defaultFieldBuilderTest";
+
+    private static final String MISSING_KEY_BUNDLE = "com.liato.bankdroid.api.configuration.missingKeyFieldBuilderTest";
+
+    @Test
+    public void testDefaultLocaleFieldBuilder() {
+        FieldBuilder builder = new FieldBuilder(REFERENCE, PropertyResourceBundle.getBundle(DEFAULT_BUNDLE));
+        Field field = builder.build();
+
+        assertEquals("defaultPlaceholder",field.getPlaceholder());
+        assertEquals("defaultLabel", field.getLabel());
+    }
+
+    @Test
+    public void testMissingKeyLocaleFieldBuilder() {
+        FieldBuilder builder = new FieldBuilder(REFERENCE, PropertyResourceBundle.getBundle(MISSING_KEY_BUNDLE));
+        Field field = builder.build();
+
+        assertEquals("defaultPlaceholder", field.getPlaceholder());
+        assertEquals("field.reference.label", field.getLabel());
+    }
+
+    @Test
+    public void testLocaleFieldBuilder() {
+        FieldBuilder builder = new FieldBuilder(REFERENCE, PropertyResourceBundle.getBundle(DEFAULT_BUNDLE, new Locale("sv_SE")));
+        Field field = builder.build();
+
+        assertEquals("defaultPlaceholder", field.getPlaceholder());
+        assertEquals("localeLabel", field.getLabel());
+    }
+
+    @Test
+    public void testFieldBuilder() {
+        FieldBuilder builder = new FieldBuilder(REFERENCE);
+        Field field = builder.build();
+
+        assertNull(field.getLabel());
+        assertNull(field.getPlaceholder());
+    }
+}
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
new file mode 100644
index 0000000..c440f30
--- /dev/null
+++ bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest.properties
@@ -0,0 +1,2 @@
+field.reference.placeholder=defaultPlaceholder
+field.reference.label=defaultLabel
\ No newline at end of file
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
new file mode 100644
index 0000000..fd790f6
--- /dev/null
+++ bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/defaultFieldBuilderTest_sv_se.properties
@@ -0,0 +1 @@
+field.reference.label=localeLabel
\ No newline at end of file
diff --git bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
new file mode 100644
index 0000000..04609e1
--- /dev/null
+++ bankdroid-interface/src/test/resources/com/liato/bankdroid/api/configuration/missingKeyFieldBuilderTest.properties
@@ -0,0 +1 @@
+field.reference.placeholder=defaultPlaceholder
\ No newline at end of file

commit 76c18511232e1d76a6f63bbb502b1c51307af10b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Aug 26 13:05:30 2015 +0200

    Rename encrypted property to secret.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
index 5feb857..98852de 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
@@ -55,13 +55,12 @@ public interface Field {
     boolean isHidden();
 
     /**
-     * Returns {@code true} if, and only if, the field value should be encrypted before it is
-     * stored. An encrypted field should be treated as a sensitive field and hence be rendered as a
-     * password field.
+     * Returns {@code true} if, and only if, the field value should be treated as a secret field.
+     * Secret fields should be rendered as a password field.
      * @return {@code true} if the field value should be encrypted before it is stored. Otherwise
      * {@code false}.
      */
-    boolean isEncrypted();
+    boolean isSecret();
 
     /**
      * Returns a list of available values for this field. If this list is not empty the field
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index 85dd65d..0ebfb12 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -48,8 +48,8 @@ public class FieldBuilder {
         return this;
     }
 
-    public FieldBuilder encrypted(boolean encrypted) {
-        field.encrypted = encrypted;
+    public FieldBuilder secret(boolean secret) {
+        field.secret = secret;
         return this;
     }
 
@@ -77,7 +77,7 @@ public class FieldBuilder {
 
         private boolean hidden;
 
-        private boolean encrypted;
+        private boolean secret;
 
         private List<Entry> values;
 
@@ -118,8 +118,8 @@ public class FieldBuilder {
         }
 
         @Override
-        public boolean isEncrypted() {
-            return encrypted;
+        public boolean isSecret() {
+            return secret;
         }
 
         @Override

commit 63e914f8769a4051895910dfa7fd968799a6d550
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 22:01:50 2015 +0200

    Rename parameter

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
index f8ab7e5..166f52a 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
@@ -5,9 +5,9 @@ public interface FieldValidator {
     /**
      * Validates a field value.
      *
-     * @param param the parameter to be validated.
+     * @param value the value to be validated.
      * @throws IllegalArgumentException if the validation fails.
      */
-    void validate(String param) throws IllegalArgumentException;
+    void validate(String value) throws IllegalArgumentException;
 
 }

commit 1f98bec2b75dfeff857137c99212a32cad6f3912
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 21:59:10 2015 +0200

    Use Collections.emptyList instead of creating a new ArrayList

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index bc35be9..85dd65d 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -2,6 +2,7 @@ package com.liato.bankdroid.api.configuration;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -124,7 +125,7 @@ public class FieldBuilder {
         @Override
         public List<Entry> getValues() {
             if(values == null) {
-                values = new ArrayList<>();
+                values = Collections.emptyList();
             };
             return values;
         }

commit 41d6e86a541df11e24e9adf65b7800d48647772f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 21:56:14 2015 +0200

    Makes sure space only values is treated as an empty value.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
index ab72674..bc35be9 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -132,7 +132,7 @@ public class FieldBuilder {
         @Override
         public void validate(String value) throws IllegalArgumentException {
             if(isRequired()) {
-                if(value == null || value.isEmpty()) {
+                if(value == null || value.trim().isEmpty()) {
                     throw new IllegalArgumentException(String.format("%s is required", getLabel()));
                 }
                 if(validator != null) {

commit 69f22ba9ba4abba845557120138d6167743976d6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 21:52:09 2015 +0200

    Removes unused code.

diff --git bankdroid-interface/build.gradle bankdroid-interface/build.gradle
index ccc4e4c..eed9aa6 100644
--- bankdroid-interface/build.gradle
+++ bankdroid-interface/build.gradle
@@ -2,7 +2,3 @@ apply plugin: 'java'
 
 sourceCompatibility = JavaVersion.VERSION_1_7
 targetCompatibility = JavaVersion.VERSION_1_7
-
-dependencies {
-
-}
\ No newline at end of file

commit 066e9d96300babdc0fd10c786091f38103db613c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 21:50:59 2015 +0200

    Adds clarifying javadoc for the encryption field type.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
index a048b6c..5feb857 100644
--- bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
@@ -56,7 +56,8 @@ public interface Field {
 
     /**
      * Returns {@code true} if, and only if, the field value should be encrypted before it is
-     * stored.
+     * stored. An encrypted field should be treated as a sensitive field and hence be rendered as a
+     * password field.
      * @return {@code true} if the field value should be encrypted before it is stored. Otherwise
      * {@code false}.
      */

commit cb5f06564c7700e094c2e8424eb5530e187022b8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 21:28:58 2015 +0200

    Adds configuration interface.

diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java
new file mode 100644
index 0000000..8201e43
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Entry.java
@@ -0,0 +1,45 @@
+package com.liato.bankdroid.api.configuration;
+
+public class Entry {
+
+    private final String mKey;
+    private final String mValue;
+
+    public Entry(String key, String value) {
+        if(key == null || key.trim().isEmpty()) {
+            throw new IllegalArgumentException("key cannot be null or empty.");
+        }
+        mKey = key;
+        mValue = value;
+    }
+
+    public String getKey() {
+        return mKey;
+    }
+
+    public String getValue() {
+        return mValue;
+    }
+
+    @Override
+    public String toString() {
+        return mValue;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj == null || obj.getClass() != this.getClass()) {
+            return false;
+        }
+        Entry other = (Entry) obj;
+        return mKey.equals(other.mKey);
+    }
+
+    @Override
+    public int hashCode() {
+        return mKey.hashCode();
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
new file mode 100644
index 0000000..a048b6c
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/Field.java
@@ -0,0 +1,81 @@
+package com.liato.bankdroid.api.configuration;
+
+import java.util.List;
+
+/**
+ * Represent an input field that is rendered for the user.
+ */
+public interface Field {
+
+    /**
+     * Returns the reference to this field. This value needs to be unique per configuration.
+     *
+     * @return the reference to this field.
+     */
+    String getReference();
+
+    /**
+     * Get the placeholder for this field.
+     * The placeholder specifies a short hint that describes the expected value of an
+     * field (e.g. a sample value or a short description of the expected format).
+     * The short hint is displayed in the input field before the user enters a value.
+     *
+     * @return the placeholder for this field.
+     */
+    String getPlaceholder();
+
+    /**
+     * Get the label for this field.
+     *
+     * @return the label for this field.
+     */
+    String getLabel();
+
+    /**
+     * Get the field type for this field.
+     *
+     * @return The field type for this field. Defaults to {@link FieldType#TEXT}.
+     */
+    FieldType getFieldType();
+
+    /**
+     * Returns {@code true} if the field is a required field.
+     *
+     * The {@link #validate(String)} will fail if this value is true and the string to be validated
+     * are empty or {@code null}.
+     * @return {@code true} if the field is a required field. Otherwise {@code false}.
+     */
+    boolean isRequired();
+
+    /**
+     * Returns {@code true} if the field should be hidden for the end user when it is rendered.
+     *
+     * @return {@code true} if the field should be hidden. Otherwise {@code false}.
+     */
+    boolean isHidden();
+
+    /**
+     * Returns {@code true} if, and only if, the field value should be encrypted before it is
+     * stored.
+     * @return {@code true} if the field value should be encrypted before it is stored. Otherwise
+     * {@code false}.
+     */
+    boolean isEncrypted();
+
+    /**
+     * Returns a list of available values for this field. If this list is not empty the field
+     * should be rendered as a combo box or a radio button group.
+     * @return A list of available values for the field.
+     */
+    List<Entry> getValues();
+
+    /**
+     * Validate the user input before changes are accepted by the system. This method should
+     * at least validate the {@link #isRequired()} method.
+     *
+     * @param value The value to be validated.
+     * @throws IllegalArgumentException is thrown if the validation fails. A detailed error message
+     * is included in the exception.
+     */
+    void validate(String value) throws IllegalArgumentException;
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
new file mode 100644
index 0000000..ab72674
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldBuilder.java
@@ -0,0 +1,144 @@
+package com.liato.bankdroid.api.configuration;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A builder for building {@link Field} objects.
+ */
+public class FieldBuilder {
+
+    private BasicField field;
+
+    public FieldBuilder(String reference) {
+        if(reference == null || reference.trim().isEmpty()) {
+            throw new IllegalArgumentException("reference must be provided.");
+        }
+        field = new BasicField(reference);
+    }
+
+    public Field build() {
+        return field;
+    }
+
+    public FieldBuilder label(String label) {
+        field.label = label;
+        return this;
+    }
+
+    public FieldBuilder placeholder(String placeholder) {
+        field.placeholder = placeholder;
+        return this;
+    }
+
+    public FieldBuilder fieldType(FieldType fieldType) {
+        field.fieldType = fieldType;
+        return this;
+    }
+
+    public FieldBuilder required(boolean required) {
+        field.required = required;
+        return this;
+    }
+
+    public FieldBuilder hidden(boolean hidden) {
+        field.hidden = hidden;
+        return this;
+    }
+
+    public FieldBuilder encrypted(boolean encrypted) {
+        field.encrypted = encrypted;
+        return this;
+    }
+
+    public FieldBuilder values(List<Entry> values) {
+        field.values = values;
+        return this;
+    }
+
+    public FieldBuilder validator(FieldValidator validator) {
+        field.validator = validator;
+        return this;
+    }
+
+    private class BasicField implements Field {
+
+        private String reference;
+
+        private String placeholder;
+
+        private String label;
+
+        private FieldType fieldType;
+
+        private boolean required;
+
+        private boolean hidden;
+
+        private boolean encrypted;
+
+        private List<Entry> values;
+
+        private FieldValidator validator;
+
+        public BasicField(String reference) {
+            this.reference = reference;
+        }
+
+        @Override
+        public String getReference() {
+            return reference;
+        }
+
+        @Override
+        public String getPlaceholder() {
+            return placeholder;
+        }
+
+        @Override
+        public String getLabel() {
+            return label;
+        }
+
+        @Override
+        public FieldType getFieldType() {
+            return fieldType;
+        }
+
+        @Override
+        public boolean isRequired() {
+            return required;
+        }
+
+        @Override
+        public boolean isHidden() {
+            return hidden;
+        }
+
+        @Override
+        public boolean isEncrypted() {
+            return encrypted;
+        }
+
+        @Override
+        public List<Entry> getValues() {
+            if(values == null) {
+                values = new ArrayList<>();
+            };
+            return values;
+        }
+
+        @Override
+        public void validate(String value) throws IllegalArgumentException {
+            if(isRequired()) {
+                if(value == null || value.isEmpty()) {
+                    throw new IllegalArgumentException(String.format("%s is required", getLabel()));
+                }
+                if(validator != null) {
+                    validator.validate(value);
+                }
+            }
+        }
+    }
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java
new file mode 100644
index 0000000..550f1db
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldType.java
@@ -0,0 +1,20 @@
+package com.liato.bankdroid.api.configuration;
+
+public enum FieldType {
+    /**
+     * Represent a regular input text field.
+     */
+    TEXT,
+    /**
+     * Represent an input field that only allows numbers.
+     */
+    NUMBER,
+    /**
+     * Represent an input field that should contain a phone number.
+     */
+    PHONE,
+    /**
+     * Represents an input field that should contain an email address.
+     */
+    EMAIL,
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
new file mode 100644
index 0000000..f8ab7e5
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/FieldValidator.java
@@ -0,0 +1,13 @@
+package com.liato.bankdroid.api.configuration;
+
+public interface FieldValidator {
+
+    /**
+     * Validates a field value.
+     *
+     * @param param the parameter to be validated.
+     * @throws IllegalArgumentException if the validation fails.
+     */
+    void validate(String param) throws IllegalArgumentException;
+
+}
diff --git bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/ProviderConfiguration.java bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/ProviderConfiguration.java
new file mode 100644
index 0000000..c8743ab
--- /dev/null
+++ bankdroid-interface/src/main/java/com/liato/bankdroid/api/configuration/ProviderConfiguration.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid.api.configuration;
+
+import java.util.List;
+
+/**
+ * Holds the configuration for a provider.
+ */
+public interface ProviderConfiguration {
+
+    /**
+     * Returns the fields that should be available for configuring a provider connection.
+     * @return Returns a list of available fields for provider connection configuration.
+     * If no configuration is available an empty list is returned.
+     */
+    List<Field> getConnectionConfiguration();
+}

commit 1da582e21ed17acd2d8f71c6e5d20ab950486b1c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Aug 25 20:28:54 2015 +0200

    Adds interface module

diff --git bankdroid-interface/build.gradle bankdroid-interface/build.gradle
new file mode 100644
index 0000000..ccc4e4c
--- /dev/null
+++ bankdroid-interface/build.gradle
@@ -0,0 +1,8 @@
+apply plugin: 'java'
+
+sourceCompatibility = JavaVersion.VERSION_1_7
+targetCompatibility = JavaVersion.VERSION_1_7
+
+dependencies {
+
+}
\ No newline at end of file
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index 344cb77..a8114d8 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -25,6 +25,7 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile project(':bankdroid-interface')
     compile 'com.android.support:appcompat-v7:22.0.+'
     compile 'org.apache.commons:commons-io:1.3.2'
     compile 'org.jsoup:jsoup:1.7.3'
diff --git settings.gradle settings.gradle
index 369e949..2a20750 100644
--- settings.gradle
+++ settings.gradle
@@ -1 +1 @@
-include ':app', ':bankdroid-legacy'
+include ':app', ':bankdroid-legacy', ':bankdroid-interface'

commit 2312c041fa1da79ad3cf4c27578c06a19782154d (tag: v1.9.9.5)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Jul 18 12:20:59 2015 +0200

    Creates release v1.9.9.5

diff --git CHANGELOG CHANGELOG
index 36d4711..5e4a96f 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.9.5 (2015-07-18)
+* Upates certificates for Akelius Spar, Akelius Invest, Hemköp and Resurs Bank
+
 v1.9.9.4 (2015-06-12)
 * Fixes parsing of incoming payments for American Express (thanks to mhagander)
 * Updates certificates for Nordnet, Avanza, Länsförsäkringar, Forex Bank, OKQ8 and Volvo Finans
diff --git app/build.gradle app/build.gradle
index 11f8a56..a4ffb04 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 214
-        versionName "1.9.9.4"
+        versionCode 215
+        versionName "1.9.9.5"
     }
 
     signingConfigs {

commit 14f00d8194675ba4e3a3c64f864baabb6f616e80
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Jul 18 12:18:15 2015 +0200

    Update certificates

diff --git bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
index c376aa2..37b586d 100644
--- bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
+++ bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
@@ -1,31 +1,34 @@
 -----BEGIN CERTIFICATE-----

-EeinVbKw

 -----END CERTIFICATE-----
 online.akeliusinvest.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
index 2432760..d7dcb05 100644
--- bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
+++ bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
@@ -1,32 +1,40 @@
 -----BEGIN CERTIFICATE-----

-8irFtCk8VpC+XNWWVdm0ib5peSsXcqaHOTKz00E=

+yXPFP60=
 -----END CERTIFICATE-----
 www.online.akeliusspar.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_hemkop.pem bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
index 63e4db4..73edac5 100644
--- bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
+++ bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
@@ -1,36 +1,43 @@
 -----BEGIN CERTIFICATE-----

-volhqsuGij2QcsZR2V5tF9iSsmo=

+0GTGAuIFeOxSpCD2yC9sG06gHnJJSQv1LzLJCZPg0IRJ59ei91vhLfmr
 -----END CERTIFICATE-----
 www.hemkop.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_resursbank.pem bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
index b768ea9..2cc361f 100644
--- bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
@@ -1,39 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIGrTCCBZWgAwIBAgIQDDVxfXJTkm35k7iF9dHJrjANBgkqhkiG9w0BAQUFADBm
+MIIFQzCCBCugAwIBAgIQCGQ0CJiJ7a5ssPAWwfXMrjANBgkqhkiG9w0BAQsFADBw
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3

-e+GhpRTaPL2e1wlLsHt3Pg4I8V2VikbNJwfPgscs5BeW

+F9FJrJeibg==
 -----END CERTIFICATE-----
 secure.resurs.se:443

commit 2d42f3296d479a4127471347917aeea4cdcfc26c
Author: Jonathan Hagberg <jonathan.hagberg89@gmail.com>
Date:   Sat Jul 11 22:12:28 2015 +0200

    Fixes #553 Updating Jojo cards to the new Skånetrafiken website

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index bde72f5..466bece 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -38,9 +38,7 @@ import android.text.InputType;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
-import java.util.NoSuchElementException;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -53,7 +51,7 @@ public class Jojo extends Bank {
 
     private static final String NAME_SHORT = "jojo";
 
-    private static final String URL = "https://www.shop.skanetrafiken.se";
+    private static final String URL = "https://www.skanetrafiken.se";
 
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
 
@@ -87,19 +85,19 @@ public class Jojo extends Bank {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_jojo));
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("GOTO", "/mobile/minakort.html"));
-        postData.add(new BasicNameValuePair("login", getUsername()));
-        postData.add(new BasicNameValuePair("password", getPassword()));
-        postData.add(new BasicNameValuePair("CUSTOMER_LOGIN", "LOGGA IN"));
-        return new LoginPackage(urlopen, postData, response, URL + "/mobile/customer.html");
+        postData.add(new BasicNameValuePair("loginInputModel.Email", getUsername()));
+        postData.add(new BasicNameValuePair("loginInputModel.Password", getPassword()));
+        postData.add(new BasicNameValuePair("loginInputModel.Role", "Private"));
+        return new LoginPackage(urlopen, postData, response, URL + "/inloggning/LoginPost/");
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (!response.contains("[Logga ut]")) {
+        if (!response.contains("window.location")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
+
         return urlopen;
     }
 
@@ -111,15 +109,12 @@ public class Jojo extends Bank {
         }
         urlopen = login();
 
-        Iterator<Account> it = new AccountIterator(response);
-        while (it.hasNext()) {
-            try {
-                Account account = it.next();
-                accounts.add(account);
-                balance.add(account.getBalance());
-            } catch (NoSuchElementException e) {
-                throw new BankException(res.getText(R.string.server_error_try_again).toString(), e);
-            }
+        response = urlopen.open(URL + "/mitt-konto/se-saldo-och-ladda-kort/");
+
+        Document document = Jsoup.parse(response);
+        Elements elements = document.select(".card-content");
+        for (Element element : elements) {
+            accounts.add(toAccount(element));
         }
 
         if (accounts.isEmpty()) {
@@ -128,88 +123,27 @@ public class Jojo extends Bank {
         super.updateComplete();
     }
 
+    private Account toAccount(Element card) {
+        String cardNumber = card.select(".card-number").text().trim();
+        BigDecimal balance = getBalance(cardNumber);
+        String name = card.select(".title").text().trim();
+        String displayName = NAME_NOT_SET.equals(name) ? cardNumber : name;
+        return new Account(displayName, balance, cardNumber);
+    }
 
-    private BigDecimal getSaldo(String cardNumber) {
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("cardno", cardNumber));
-        postData.add(new BasicNameValuePair("fromlist", "1"));
-        postData.add(new BasicNameValuePair("ST_CHECK_SALDO", "1"));
+    private BigDecimal getBalance(String cardNumber) {
         try {
-            String saldoData = urlopen.open(URL + "/saldodata.html", postData, true);
-            Document saldoDocument = Jsoup.parse(saldoData);
-            Elements saldo = saldoDocument.select("td.greenrow.right h3");
-            if (!saldo.isEmpty()) {
-                return Helpers.parseBalance(saldo.first().text().trim());
+            String balanceData = urlopen.open(URL +
+                    "/mitt-konto/se-saldo-och-ladda-kort/GetCardBalance/?cardId=" + cardNumber);
+            Document balanceDocument = Jsoup.parse(balanceData);
+            Elements balance = balanceDocument.select(".balance");
+
+            if (!balance.isEmpty()) {
+                return Helpers.parseBalance(balance.first().text().trim());
             }
         } catch (IOException e) {
             // Ignore and defaults to zero
         }
         return BigDecimal.ZERO;
     }
-
-    private class AccountIterator implements Iterator<Account> {
-
-        private Document mDocument;
-
-        private Iterator<Element> mCards;
-
-        private String mNextUrl;
-
-        public AccountIterator(String response) {
-            setDocument(response);
-        }
-
-        @Override
-        public boolean hasNext() {
-            return mCards.hasNext() || mNextUrl != null;
-        }
-
-        @Override
-        public Account next() {
-            if (!mCards.hasNext()) {
-                fetchNextPage();
-            }
-            return toAccount(mCards.next());
-        }
-
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException("Remove not supported");
-        }
-
-        private Elements parseCardElements() {
-            return mDocument.select(".my_cards_allinfo table tbody");
-        }
-
-        private String parseNextUrl() {
-            Element elem = mDocument.select("div.pageselector_pagenr a").last();
-            if (elem == null || elem.select("span.pageselect_prevnext_selected").isEmpty()) {
-                return null;
-            }
-            return elem.attr("href");
-        }
-
-        private void fetchNextPage() {
-            try {
-                String response = urlopen.open(URL + mNextUrl);
-                setDocument(response);
-            } catch (IOException e) {
-                throw new NoSuchElementException();
-            }
-        }
-
-        private void setDocument(String response) {
-            mDocument = Jsoup.parse(response);
-            mCards = parseCardElements().iterator();
-            mNextUrl = parseNextUrl();
-        }
-
-        private Account toAccount(Element card) {
-            String cardNumber = card.select("tr:first-child td").text().trim();
-            BigDecimal saldo = getSaldo(cardNumber);
-            String name = card.select("tr:nth-child(2) td").text().trim();
-            String displayName = NAME_NOT_SET.equals(name) ? cardNumber : name;
-            return new Account(displayName, saldo, cardNumber);
-        }
-    }
 }

commit 0430e51cacd2a769ad2a76c39141790998aa91c4 (tag: v1.9.9.4)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jun 12 21:46:35 2015 +0200

    Creates release 1.9.9.4

diff --git CHANGELOG CHANGELOG
index ca0f257..36d4711 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.9.4 (2015-06-12)
+* Fixes parsing of incoming payments for American Express (thanks to mhagander)
+* Updates certificates for Nordnet, Avanza, Länsförsäkringar, Forex Bank, OKQ8 and Volvo Finans
+
 v1.9.9.3 (2015-05-24)
 * Updates certificates for Paypal, AmericanExpress, Svenska spel
 
diff --git app/build.gradle app/build.gradle
index dc0e22c..11f8a56 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 213
-        versionName "1.9.9.3"
+        versionCode 214
+        versionName "1.9.9.4"
     }
 
     signingConfigs {

commit 6c5a0a62e8f4675fb829ab933234adfc161e8787
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jun 12 21:39:22 2015 +0200

    Updates cert for Nordent

diff --git bankdroid-legacy/src/main/res/raw/cert_nordnet.pem bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
index 87a82db..9f91575 100644
--- bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
+++ bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
@@ -1,34 +1,40 @@
 -----BEGIN CERTIFICATE-----

-eUOjBvU=

+rmjH7XVO3UTpgBRIpl/8UpVNm5cV
 -----END CERTIFICATE-----
 www.nordnet.se:443

commit c4068920fdbacf33bde210d853b947e8f8b63021
Merge: 57a8511 85b584e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jun 12 21:37:06 2015 +0200

    Merge pull request #556 from martach/master
    
    New certs

commit 85b584e40119ed68218830a9a579d8f2ab346261
Author: Johan Segerstedt <martach@users.noreply.github.com>
Date:   Sat Jun 6 14:09:18 2015 +0200

    New certs for Avanza, Forex bank, Länsförsäkringar, Steam and Volvo Finans.

diff --git bankdroid-legacy/src/main/res/raw/cert_avanza.pem bankdroid-legacy/src/main/res/raw/cert_avanza.pem
index a589201..0cea5a7 100644
--- bankdroid-legacy/src/main/res/raw/cert_avanza.pem
+++ bankdroid-legacy/src/main/res/raw/cert_avanza.pem
@@ -1,28 +1,29 @@
 -----BEGIN CERTIFICATE-----

-UJM2koY+ZtcwVM4YjfAIi2YzYdzYccsODhamwBVtpe38WcF1pQw=

+fIBstELLSRgDEJNBmd8N
 -----END CERTIFICATE-----
 iphone.avanza.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_forexbank.pem bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
index fe542c8..324d7e4 100644
--- bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
@@ -1,33 +1,36 @@
 -----BEGIN CERTIFICATE-----

-JpPqCokWT4kF

+tycBv7BN+iM2iBPW1SE/w8TqBWH7NPlqC9Dc3WYL5SspLkaKcV67
 -----END CERTIFICATE-----
 nettbank.edb.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
index ea2bf8b..c8d100c 100644
--- bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
+++ bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
@@ -1,36 +1,36 @@
 -----BEGIN CERTIFICATE-----

-TA==

+ZgcRC1dwwl2etmdYp6c4sz+6CugCoVCXWZav/wlQKnw7+k/jrA==
 -----END CERTIFICATE-----
 mobil.lansforsakringar.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_steam.pem bankdroid-legacy/src/main/res/raw/cert_steam.pem
index 3982d14..b711eaa 100644
--- bankdroid-legacy/src/main/res/raw/cert_steam.pem
+++ bankdroid-legacy/src/main/res/raw/cert_steam.pem
@@ -1,5 +1,5 @@
 -----BEGIN CERTIFICATE-----
-MIII4jCCB8qgAwIBAgIQAmmsGFJv+7KQAQmQFLn6tDANBgkqhkiG9w0BAQUFADBp
+MIII+zCCB+OgAwIBAgIQCp81Wa96aMdajhHH7BidVjANBgkqhkiG9w0BAQUFADBp
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMSgwJgYDVQQDEx9EaWdpQ2VydCBIaWdoIEFzc3VyYW5j
 ZSBFViBDQS0xMB4XDTE0MDQxNDAwMDAwMFoXDTE1MTIzMTEyMDAwMFowggEfMR0w
@@ -9,14 +9,14 @@ NzMxEjAQBgNVBAkTCVN1aXRlIDUwMDEYMBYGA1UECRMPMTA5MDAgTkUgNHRoIFN0
 MQ4wDAYDVQQREwU5ODAwNDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
 b24xETAPBgNVBAcTCEJlbGxldnVlMRQwEgYDVQQKEwtWYWx2ZSBDb3JwLjEOMAwG
 A1UECxMFU3RlYW0xHzAdBgNVBAMTFnN0b3JlLnN0ZWFtcG93ZXJlZC5jb20wggEi

 cmUuc3RlYW1wb3dlcmVkLmNvbYIUd3d3LnN0ZWFtcG93ZXJlZC5jb22CFGFwaS5z
 dGVhbXBvd2VyZWQuY29tghhzdXBwb3J0LnN0ZWFtcG93ZXJlZC5jb22CFGtncy5z
 dGVhbXBvd2VyZWQuY29tgh9wYXJ0bmVydXBsb2FkMC5zdGVhbXBvd2VyZWQuY29t
@@ -25,27 +25,27 @@ cG93ZXJlZC5jb22CFnBhcnRuZXIuc3RlYW1nYW1lcy5jb22CEnN0ZWFtY29tbXVu
 aXR5LmNvbYINd3d3LmRvdGEyLmNvbYIRcGFydG5lci5kb3RhMi5jb22CEXZhbHZl
 c29mdHdhcmUuY29tghV3d3cudmFsdmVzb2Z0d2FyZS5jb22CF2ZvcnVtcy5zdGVh
 bXBvd2VyZWQuY29tghZhcGkuc3RlYW1jb21tdW5pdHkuY29tghVoZWxwLnN0ZWFt

-78FajrewuEWWn1odnXbD+kbMumfU2g==

 -----END CERTIFICATE-----
 store.steampowered.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
index 1b09ae3..85c5676 100644
--- bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
+++ bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
@@ -1,39 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIGtjCCBZ6gAwIBAgIQBXbYsqgMcH1mQ8ycAQDRMTANBgkqhkiG9w0BAQUFADBm
+MIIFWDCCBECgAwIBAgIQCvPuSldRB34/4AN4GmVQ+TANBgkqhkiG9w0BAQsFADBw
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3

-sN/gfwvxMEN+/vG1PlRjDjlF2BkvnZhkt2Lc6GD552FhtLeYarLsgEiL

+0o5EzaTpvLKP25NYUQA7pjdUyGhu/8+xMT+oPA==
 -----END CERTIFICATE-----
 secure.volvofinans.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
index 1194d96..87e5e5e 100644
--- bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
+++ bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
@@ -1,42 +1,43 @@
 -----BEGIN CERTIFICATE-----
-MIIHNDCCBhygAwIBAgIQBkztGIvjnP8pUWKeaLlb/jANBgkqhkiG9w0BAQUFADBp
+MIIHXDCCBkSgAwIBAgIQDKaiNDu09ItQVAHQUpfKszANBgkqhkiG9w0BAQsFADB1
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3

-GxUHutMVEtqW9aCSv5wMdnDd/BKF1qHk

+wxPKg50QQRw8a0rHZ3EISw==
 -----END CERTIFICATE-----
 inloggad.volvofinans.se:443

commit 57a8511a8d0b1b34e7c2bdd605af5f9796810644
Merge: b229d50 6aedbf9
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat May 30 22:09:27 2015 +0200

    Merge pull request #555 from mhagander/fix_amex_positive
    
    Fix AmEx parsing for incoming payments

commit b229d507cc8b1b1cc7e63a51b45dc64725572ddc
Merge: dc983f8 5df36ab
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat May 30 22:08:47 2015 +0200

    Merge pull request #554 from martach/new_cert
    
    Updated certificate for OKQ8.

commit 6aedbf9e27b882909d67d7f0e4469b9d736f5cc9
Author: Magnus Hagander <magnus@hagander.net>
Date:   Fri May 29 16:14:17 2015 +0200

    Fix AmEx parsing for incoming payments
    
    Properly track positive numbers (invoices paid) and not just the
    expenses, on AmEx cards.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 3be6952..0c344f3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -35,6 +35,7 @@ import android.text.Html;
 import android.util.Log;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -64,7 +65,7 @@ public class AmericanExpress extends Bank {
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     private Pattern reTransactions = Pattern.compile(
-            "id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)",
+            "id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>.*?([0-9.,\\s]*kr|&nbsp;)</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr|&nbsp;)",
             Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     private String response = null;
@@ -180,15 +181,22 @@ public class AmericanExpress extends Bank {
              * GROUP                    EXAMPLE DATA
              * 1: Date                  17 jan 2011
              * 2: Specification         xx
-             * 3: Amount                1.582,00&nbsp;kr
+             * 3: Amount (if positive)  1.582,00 kr (else &nbsp)
+             * 4: Amount (if negative)  1.582,00 kr (else &nbsp)
              *
              */
             try {
                 transactionDate = sdfFrom.parse(matcher.group(1).trim());
                 String strDate = sdfTo.format(transactionDate);
+                BigDecimal amount;
+                if (matcher.group(3).trim().equals("&nbsp;"))
+                    amount = Helpers.parseBalance(matcher.group(4).trim()).negate();
+                else
+                    amount = Helpers.parseBalance(matcher.group(3).trim());
+
                 transactions.add(new Transaction(strDate,
                         Html.fromHtml(matcher.group(2)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(3).trim()).negate()));
+                        amount));
             } catch (ParseException e) {
                 Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
             }

commit 5df36ab56b59591d9bc716bbded53cb5c6d32f8e
Author: Johan Segerstedt <martach@users.noreply.github.com>
Date:   Thu May 28 21:46:09 2015 +0200

    Updated certificate for OKQ8.

diff --git bankdroid-legacy/src/main/res/raw/cert_okq8.pem bankdroid-legacy/src/main/res/raw/cert_okq8.pem
index fe542c8..324d7e4 100644
--- bankdroid-legacy/src/main/res/raw/cert_okq8.pem
+++ bankdroid-legacy/src/main/res/raw/cert_okq8.pem
@@ -1,33 +1,36 @@
 -----BEGIN CERTIFICATE-----

-JpPqCokWT4kF

+tycBv7BN+iM2iBPW1SE/w8TqBWH7NPlqC9Dc3WYL5SspLkaKcV67
 -----END CERTIFICATE-----
 nettbank.edb.com:443

commit dc983f8a3659c0d3c9483a099a7daf64fad7fe03 (tag: v1.9.9.3)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 24 20:17:05 2015 +0200

    Fixes build issues

diff --git build.gradle build.gradle
index 4833993..365bea0 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.0.0'
+        classpath 'com.android.tools.build:gradle:1.2.3'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files

commit f4166cd016b80f9e0a9e3d897e733810d7f0e869
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 24 20:00:19 2015 +0200

    Create release 1.9.9.3

diff --git app/build.gradle app/build.gradle
index f004c0d..dc0e22c 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 212
-        versionName "1.9.9.2"
+        versionCode 213
+        versionName "1.9.9.3"
     }
 
     signingConfigs {

commit 9199eec4573461523ecb91ebd2b09c0b3b199770
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 24 19:57:44 2015 +0200

    Create release v1.9.9.3

diff --git CHANGELOG CHANGELOG
index 63c4f38..ca0f257 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.9.3 (2015-05-24)
+* Updates certificates for Paypal, AmericanExpress, Svenska spel
+
 v1.9.9.2 (2015-04-16)
 * Updates certificates for AmericanExpress, MinPension, Swedbank and Sparbankerna
 * Adapt to new URLs used by Ticket Rikskortet

commit d201b2227085df7337fd2692f6806eacc4bc4f13
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 24 19:45:37 2015 +0200

    Fixes gradle wrapper artifacts

diff --git gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
index c97a8bd..b5166da 100644
Binary files gradle/wrapper/gradle-wrapper.jar and gradle/wrapper/gradle-wrapper.jar differ
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index ba0334e..bf15a1e 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Tue May 05 20:38:14 CEST 2015
+#Sun May 24 19:44:46 CEST 2015
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME

commit 96db732993e27b8f9c2abd6f179999ff19a4ad31
Merge: 3a659f5 70a34ee
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat May 23 08:59:28 2015 +0200

    Merge pull request #550 from liato/feature/code-improvements
    
    Code improvements

commit 3a659f5c34a0d86430110e3925d44b2672139b59
Merge: e58196d c54ebed
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat May 23 05:09:21 2015 +0200

    Merge pull request #549 from liato/feature/butterknife-improvements
    
    Improve usage of butterknife.

commit e58196dcc7944d80fe04226d9d4f335019032d10
Merge: f3ab262 3f3bdb8
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat May 23 05:04:20 2015 +0200

    Merge pull request #551 from liato/feature/upgrade-gradle
    
    Upgrade gradle to version 2.4

commit f3ab26259abe8eaf6d4bab168b49da9e8dfc2d85
Merge: 6185493 88b00a8
Author: liato <x@x00.us>
Date:   Thu May 21 11:09:07 2015 +0200

    Merge pull request #552 from liato/feature/update-certs
    
    Updates multiple certs.

commit 88b00a85f3e814507f5cdaded13539291d34f332
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue May 19 07:45:17 2015 +0200

    Updates multiple certs.

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index e274d30..4851b39 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,41 +1,40 @@
 -----BEGIN CERTIFICATE-----

-OWXrJnKvRfrsnl+zaEhCOM0oYsPVF4Np7Yw1Yw==

+bApazU27
 -----END CERTIFICATE-----
 www.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_eurocard.pem bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
index 1194e02..b143c62 100644
--- bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
+++ bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
@@ -1,34 +1,40 @@
 -----BEGIN CERTIFICATE-----

-NR3ikmS2NPy8Ftd0TdpyWp8X50dGZbZD7n9ZBBpqRiU=

 -----END CERTIFICATE-----
 secure.eurocard.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
index 97b34ef..fd38ff7 100644
--- bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
+++ bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
@@ -1,34 +1,38 @@
 -----BEGIN CERTIFICATE-----

-91AySnUbhs2yRijm12ZF8CAgfEPhK8Hu++/IdlffFhE=

+8py6j8xewRxlpn2m9wkZNhuu8mRb0w==
 -----END CERTIFICATE-----
 m.handelsbanken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_jojo.pem bankdroid-legacy/src/main/res/raw/cert_jojo.pem
index 3a270b5..9857527 100644
--- bankdroid-legacy/src/main/res/raw/cert_jojo.pem
+++ bankdroid-legacy/src/main/res/raw/cert_jojo.pem
@@ -1,33 +1,30 @@
 -----BEGIN CERTIFICATE-----
-MIIFdTCCBF2gAwIBAgIQODt+JxIgw6aAIYurpdpbhTANBgkqhkiG9w0BAQsFADB3
+MIIE/DCCA+SgAwIBAgIQIpOEjsBXxATU9+f3D5yYMjANBgkqhkiG9w0BAQsFADB+
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd

-8d7oaZCE7jQQ

+Y59Yey0ZXaN9jbXw0dj65mEto7jYfWwZkkccqyfO50k=
 -----END CERTIFICATE-----
 www.shop.skanetrafiken.se:443
diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
index 044eb09..d0ccbb3 100644
--- bankdroid-legacy/src/main/res/raw/cert_paypal.pem
+++ bankdroid-legacy/src/main/res/raw/cert_paypal.pem
@@ -1,40 +1,40 @@
 -----BEGIN CERTIFICATE-----
-MIIGvjCCBaagAwIBAgIQWK6vRldyZAffQNciCpwKZzANBgkqhkiG9w0BAQUFADB3
+MIIG0jCCBbqgAwIBAgIQB2T3ui0CFx+cSA3+e2W7bzANBgkqhkiG9w0BAQUFADB3
 MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAd
 BgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVj
-IENsYXNzIDMgRVYgU1NMIENBIC0gRzIwHhcNMTUwMzEyMDAwMDAwWhcNMTUxMDMx
+IENsYXNzIDMgRVYgU1NMIENBIC0gRzIwHhcNMTUwNDIyMDAwMDAwWhcNMTUxMDMx
 MjM1OTU5WjCCAQkxEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsrBgEEAYI3PAIB
 AhMIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYD
 VQQFEwczMDE0MjY3MQswCQYDVQQGEwJVUzETMBEGA1UEERQKOTUxMzEtMjAyMTET
 MBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxQIU2FuIEpvc2UxFjAUBgNVBAkU
 DTIyMTEgTiAxc3QgU3QxFTATBgNVBAoUDFBheVBhbCwgSW5jLjEUMBIGA1UECxQL
 Q0ROIFN1cHBvcnQxFzAVBgNVBAMUDnd3dy5wYXlwYWwuY29tMIIBIjANBgkqhkiG

-n64=

+Gp3OLqh4jMEbNLobkIdLkZ2F9jYMDw==
 -----END CERTIFICATE-----
 www.paypal.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_sebkort.pem bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
index 76f2b23..0008442 100644
--- bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
+++ bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
@@ -1,34 +1,41 @@
 -----BEGIN CERTIFICATE-----

+2mAtTkzsi6a7yg==
 -----END CERTIFICATE-----
 secure.sebkort.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_steam.pem bankdroid-legacy/src/main/res/raw/cert_steam.pem
index 8d6baac..3982d14 100644
--- bankdroid-legacy/src/main/res/raw/cert_steam.pem
+++ bankdroid-legacy/src/main/res/raw/cert_steam.pem
@@ -1,22 +1,22 @@
 -----BEGIN CERTIFICATE-----
-MIIIszCCB5ugAwIBAgIQAhvXaLz4rTpyIB5LeuYuqTANBgkqhkiG9w0BAQUFADBp
+MIII4jCCB8qgAwIBAgIQAmmsGFJv+7KQAQmQFLn6tDANBgkqhkiG9w0BAQUFADBp
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMSgwJgYDVQQDEx9EaWdpQ2VydCBIaWdoIEFzc3VyYW5j
 ZSBFViBDQS0xMB4XDTE0MDQxNDAwMDAwMFoXDTE1MTIzMTEyMDAwMFowggEfMR0w
-GwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysGAQQBgjc8AgEDEwJV
+GwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjETMBEGCysGAQQBgjc8AgEDEwJV
 UzEbMBkGCysGAQQBgjc8AgECEwpXYXNoaW5ndG9uMRIwEAYDVQQFEwk2MDIyOTA3
 NzMxEjAQBgNVBAkTCVN1aXRlIDUwMDEYMBYGA1UECRMPMTA5MDAgTkUgNHRoIFN0
 MQ4wDAYDVQQREwU5ODAwNDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
 b24xETAPBgNVBAcTCEJlbGxldnVlMRQwEgYDVQQKEwtWYWx2ZSBDb3JwLjEOMAwG
 A1UECxMFU3RlYW0xHzAdBgNVBAMTFnN0b3JlLnN0ZWFtcG93ZXJlZC5jb20wggEi

 cmUuc3RlYW1wb3dlcmVkLmNvbYIUd3d3LnN0ZWFtcG93ZXJlZC5jb22CFGFwaS5z
 dGVhbXBvd2VyZWQuY29tghhzdXBwb3J0LnN0ZWFtcG93ZXJlZC5jb22CFGtncy5z
 dGVhbXBvd2VyZWQuY29tgh9wYXJ0bmVydXBsb2FkMC5zdGVhbXBvd2VyZWQuY29t
@@ -24,27 +24,28 @@ gh9wYXJ0bmVydXBsb2FkMS5zdGVhbXBvd2VyZWQuY29tghhwYXJ0bmVyLnN0ZWFt
 cG93ZXJlZC5jb22CFnBhcnRuZXIuc3RlYW1nYW1lcy5jb22CEnN0ZWFtY29tbXVu
 aXR5LmNvbYINd3d3LmRvdGEyLmNvbYIRcGFydG5lci5kb3RhMi5jb22CEXZhbHZl
 c29mdHdhcmUuY29tghV3d3cudmFsdmVzb2Z0d2FyZS5jb22CF2ZvcnVtcy5zdGVh

-HkaHD0QgAJR/FOM+dAxTFElveUtaSoA=

+78FajrewuEWWn1odnXbD+kbMumfU2g==
 -----END CERTIFICATE-----
 store.steampowered.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
index 8ae5872..242dcf8 100644
--- bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
+++ bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
@@ -1,35 +1,39 @@
 -----BEGIN CERTIFICATE-----

-orkj7QfRvV5ZNIpCKDJdonffdb+PuSwzWBVLMT/N/g==

+IjJdqIKhnCyWbUVHbXNC9uc5NKk=
 -----END CERTIFICATE-----
 api.www.svenskaspel.se:443

commit 70a34eecb18b7ab6b24f3d576e94147998b6a954
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 17 20:25:30 2015 +0200

    Remove unused code

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index f887a00..7baa1b4 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -206,11 +206,6 @@ public class BankEditActivity extends LockableActivity
     public void onNothingSelected(AdapterView<?> arg) {
     }
 
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-    }
-
     private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
 
         private LayoutInflater inflater;

commit 3f3bdb848bf96e158fb37e4adb197f4430865053
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 17 14:24:27 2015 +0200

    Fix PMD rules after grade upgrade

diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
index cf02c4c..892ab08 100644
--- config/quality/pmd/pmd-ruleset.xml
+++ config/quality/pmd/pmd-ruleset.xml
@@ -9,12 +9,8 @@
     <exclude-pattern>.*/R.java</exclude-pattern>
     <exclude-pattern>.*/gen/.*</exclude-pattern>
 
-    <rule ref="rulesets/java/android.xml">
-        <!-- Config.LOGD deprecated in API level 4 !-->
-        <exclude name="ProtectLogD" />
-        <!-- Config.LOGV deprecated in API level 4 !-->
-        <exclude name="ProtectLogV" />
-    </rule>
+    <rule ref="rulesets/java/android.xml"/>
+
     <rule ref="rulesets/java/clone.xml" />
     <rule ref="rulesets/java/finalizers.xml" />
     <rule ref="rulesets/java/imports.xml" />
@@ -25,7 +21,6 @@
     <rule ref="rulesets/java/naming.xml">
         <exclude name="AbstractNaming" />
         <exclude name="LongVariable" />
-        <exclude name="LongMethodName" />
         <exclude name="ShortMethodName" />
         <exclude name="ShortVariable" />
         <exclude name="VariableNamingConventions" />

commit 097346345f4a392c216b0e75d83ec2f6a7742dd0
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 17 13:59:30 2015 +0200

    Improved bank selection

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 8dbe918..f887a00 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -105,10 +105,10 @@ public class BankEditActivity extends LockableActivity
         ButterKnife.inject(this);
         this.getWindow()
                 .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
-        ArrayList<Bank> items = BankFactory.listBanks(this);
-        Collections.sort(items);
 
-        BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, items);
+        List<Bank> items = BankFactory.listBanks(this);
+        Collections.sort(items);
+        BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<>(this, items);
         mBankSpinner.setAdapter(adapter);
         mBankSpinner.setOnItemSelectedListener(this);
 
@@ -126,14 +126,8 @@ public class BankEditActivity extends LockableActivity
                     }
 
                     mErrorDescription.setVisibility(bank.isDisabled() ? View.VISIBLE : View.INVISIBLE);
-
+                    mBankSpinner.setSelection(adapter.getPosition(bank));
                     SELECTED_BANK = bank;
-                    for (int i = 0; i < items.size(); i++) {
-                        if (bank.getBanktypeId() == items.get(i).getBanktypeId()) {
-                            mBankSpinner.setSelection(i);
-                            break;
-                        }
-                    }
                 }
             }
         }
@@ -212,16 +206,6 @@ public class BankEditActivity extends LockableActivity
     public void onNothingSelected(AdapterView<?> arg) {
     }
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-    }
-
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 7a28b6f..67ca09d 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -29,6 +29,7 @@ import android.database.Cursor;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class BankFactory {
@@ -38,7 +39,7 @@ public class BankFactory {
     }
 
 
-    public static ArrayList<Bank> listBanks(Context context) {
+    public static List<Bank> listBanks(Context context) {
         return LegacyBankFactory.listBanks(context);
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index fedeb0f..4c04870 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -513,4 +513,20 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         }
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj == null || obj.getClass() != this.getClass()) {
+            return false;
+        }
+        Bank bank = (Bank) obj;
+        return bank.getBanktypeId() == this.getBanktypeId();
+    }
+
+    @Override
+    public int hashCode() {
+        return getBanktypeId();
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 77f5c0b..68e47f4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -76,6 +76,7 @@ import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 
 import java.util.ArrayList;
+import java.util.List;
 
 public class LegacyBankFactory {
 
@@ -258,8 +259,8 @@ public class LegacyBankFactory {
         }
     }
 
-    public static ArrayList<Bank> listBanks(Context context) {
-        ArrayList<Bank> banks = new ArrayList<Bank>();
+    public static List<Bank> listBanks(Context context) {
+        List<Bank> banks = new ArrayList<>();
         banks.add(new AkeliusInvest(context));
         banks.add(new AkeliusSpar(context));
         banks.add(new TrustBuddy(context));

commit c54ebed287cd2e1e6a4bb72421a8e2f6d85c9faf
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 17 11:51:24 2015 +0200

    Improve usage of butterknife.

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 8dbe918..926e746 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -62,8 +62,7 @@ import butterknife.ButterKnife;
 import butterknife.InjectView;
 import butterknife.OnClick;
 
-public class BankEditActivity extends LockableActivity
-        implements OnClickListener, OnItemSelectedListener {
+public class BankEditActivity extends LockableActivity implements OnItemSelectedListener {
 
     @InjectView(R.id.spnBankeditBanklist)
     Spinner mBankSpinner;
@@ -139,27 +138,26 @@ public class BankEditActivity extends LockableActivity
         }
     }
 
-    @Override
-    @OnClick({R.id.btnSettingsCancel, R.id.btnSettingsOk})
-    public void onClick(View v) {
-        if (v.getId() == R.id.btnSettingsCancel) {
-            this.finish();
-        } else if (v.getId() == R.id.btnSettingsOk) {
-            SELECTED_BANK.setUsername(
-                    mUsernameField.getText().toString()
-                            .trim());
-            SELECTED_BANK.setPassword(
-                    mPasswordField.getText().toString()
-                            .trim());
-            SELECTED_BANK.setCustomName(
-                    mCustomNameField.getText().toString()
-                            .trim());
-            SELECTED_BANK.setExtras(
-                    mExtrasField.getText().toString().trim());
-            SELECTED_BANK.setDbid(BANKID);
-            new DataRetrieverTask(this, SELECTED_BANK).execute();
-        }
+    @OnClick(R.id.btnSettingsOk)
+    public void onSubmit(View v) {
+        SELECTED_BANK.setUsername(
+                mUsernameField.getText().toString()
+                        .trim());
+        SELECTED_BANK.setPassword(
+                mPasswordField.getText().toString()
+                        .trim());
+        SELECTED_BANK.setCustomName(
+                mCustomNameField.getText().toString()
+                        .trim());
+        SELECTED_BANK.setExtras(
+                mExtrasField.getText().toString().trim());
+        SELECTED_BANK.setDbid(BANKID);
+        new DataRetrieverTask(this, SELECTED_BANK).execute();
+    }
 
+    @OnClick(R.id.btnSettingsCancel)
+    public void onCancel(View v) {
+        this.finish();
     }
 
     @Override

commit d6bf8a73d4ae54b8b5393dc8e5350dff19365d0e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue May 5 20:41:29 2015 +0200

    Upgrade gradle to version 2.4

diff --git build.gradle build.gradle
index 5fdb7f6..4833993 100644
--- build.gradle
+++ build.gradle
@@ -19,5 +19,5 @@ allprojects {
 }
 
 task wrapper(type: Wrapper) {
-    gradleVersion = '2.3'
+    gradleVersion = '2.4'
 }
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index fa82012..ba0334e 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Mar 13 20:47:51 CET 2015
+#Tue May 05 20:38:14 CEST 2015
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip

commit 6185493c159561365d480b073c5d21ff23543e34
Merge: b8188ac 419814d
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun May 3 07:07:11 2015 +0200

    Merge pull request #546 from liato/feature/extra-properties
    
    Initial support for custom properties.

commit 419814d7538e5488acc5c6dffc7281efee63a125
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat May 2 22:56:35 2015 +0200

    Initial support for custom properties.
    
    Moves username, password and extras fields to the new properties table.
    Adds properties map to Bank class.

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 1d851ea..7a28b6f 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.banking;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.db.Database;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 
@@ -27,6 +28,8 @@ import android.database.Cursor;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 public class BankFactory {
 
@@ -47,23 +50,13 @@ public class BankFactory {
         if (c != null && c.getCount() > 0) {
             try {
                 bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-                String password = "";
-                try {
-                    password = SimpleCrypto
-                            .decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
-                } catch (Exception e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                }
+                bank.setProperties(loadProperties(id, context));
 
-                bank.setData(c.getString(c.getColumnIndex("username")),
-                        password,
-                        new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))),
                         (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
                         c.getLong(c.getColumnIndex("_id")),
                         c.getString(c.getColumnIndex("currency")),
                         c.getString(c.getColumnIndex("custname")),
-                        c.getString(c.getColumnIndex("extras")),
                         c.getInt(c.getColumnIndex("hideAccounts")));
                 if (loadAccounts) {
                     bank.setAccounts(accountsFromDb(context, bank.getDbId()));
@@ -89,23 +82,13 @@ public class BankFactory {
             c.moveToNext();
             try {
                 Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-
-                String password = "";
-                try {
-                    password = SimpleCrypto
-                            .decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
-                } catch (Exception e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                }
-                bank.setData(c.getString(c.getColumnIndex("username")),
-                        password,
-                        new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                long id = c.getLong(c.getColumnIndex("_id"));
+                bank.setProperties(loadProperties(id, context));
+                bank.setData(new BigDecimal(c.getString(c.getColumnIndex("balance"))),
                         (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-                        c.getLong(c.getColumnIndex("_id")),
+                        id,
                         c.getString(c.getColumnIndex("currency")),
                         c.getString(c.getColumnIndex("custname")),
-                        c.getString(c.getColumnIndex("extras")),
                         c.getInt(c.getColumnIndex("hideAccounts")));
                 if (loadAccounts) {
                     bank.setAccounts(accountsFromDb(context, bank.getDbId()));
@@ -188,4 +171,28 @@ public class BankFactory {
         return accounts;
     }
 
+    private static Map<String, String> loadProperties(long id, Context context) {
+        Map<String, String> properties = new HashMap<>();
+        DBAdapter db = new DBAdapter(context);
+        Cursor c = db.fetchProperties(Long.toString(id));
+        if(c == null || c.getCount() == 0) {
+            return properties;
+        }
+        while(!c.isLast() && !c.isAfterLast()) {
+            c.moveToNext();
+            String key = c.getString(c.getColumnIndex(Database.PROPERTY_KEY));
+            String value = c.getString(c.getColumnIndex(Database.PROPERTY_VALUE));
+            if(LegacyProviderConfiguration.PASSWORD.equals(key)) {
+                try {
+                    value = SimpleCrypto.decrypt(Crypto.getKey(), value);
+                } catch (Exception e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+            properties.put(key, value);
+        }
+        c.close();
+        return properties;
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index b1143e8..1fdd0b0 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.db;
 
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.LegacyProviderConfiguration;
 import com.liato.bankdroid.banking.Transaction;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
@@ -32,6 +33,7 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
+import java.util.Map;
 
 
 public class DBAdapter {
@@ -103,6 +105,11 @@ public class DBAdapter {
         return c;
     }
 
+    private int deleteProperties(long bankId) {
+        return mDb.delete(Database.PROPERTY_TABLE_NAME, Database.PROPERTY_CONNECTION_ID + "="
+                + bankId, null);
+    }
+
     /**
      * Return a Cursor over the list of all banks in the database
      *
@@ -110,8 +117,8 @@ public class DBAdapter {
      */
     public Cursor fetchBanks() {
         return mDb.query("banks",
-                new String[]{"_id", "balance", "banktype", "username", "password", "disabled",
-                        "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"},
+                new String[]{"_id", "balance", "banktype", "disabled",
+                        "custname", "updated", "sortorder", "currency", "hideAccounts"},
                 null, null, null, null, "_id asc");
     }
 
@@ -132,25 +139,21 @@ public class DBAdapter {
                 "account='" + account + "'", null, null, null, null);
     }
 
+    public Cursor fetchProperties(String bankId) {
+        return mDb.query(Database.PROPERTY_TABLE_NAME, null,
+                Database.PROPERTY_CONNECTION_ID+"='"+bankId+"'", null, null, null, null);
+    }
+
     public long updateBank(Bank bank) {
         Calendar cal = Calendar.getInstance();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
         ContentValues initialValues = new ContentValues();
         initialValues.put("banktype", bank.getBanktypeId());
-        initialValues.put("username", bank.getUsername());
-        String password = "";
-        try {
-            password = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
-        } catch (Exception e) {
-            Log.w(TAG, "SimpleCrypto error: " + e.getMessage());
-        }
-        initialValues.put("password", password);
         initialValues.put("disabled", 0);
         initialValues.put("balance", bank.getBalance().toPlainString());
         initialValues.put("currency", bank.getCurrency());
         initialValues.put("custname", bank.getCustomName());
-        initialValues.put("extras", bank.getExtras());
         initialValues.put("updated", sdf.format(cal.getTime()));
         initialValues.put("hideAccounts", bank.getHideAccounts() ? 1 : 0);
 
@@ -160,8 +163,28 @@ public class DBAdapter {
         } else {
             mDb.update("banks", initialValues, "_id=" + bankId, null);
             deleteAccounts(bankId);
+            deleteProperties(bankId);
         }
         if (bankId != -1) {
+            Map<String, String> properties = bank.getProperties();
+            for(Map.Entry<String,String> property : properties.entrySet()) {
+                String value = property.getValue();
+                if(value != null && !value.isEmpty()) {
+                    if (LegacyProviderConfiguration.PASSWORD.equals(property.getKey())) {
+                        try {
+                            value = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
+                        } catch (Exception e) {
+                            Log.w(TAG, "SimpleCrypto error: " + e.getMessage());
+                        }
+                    }
+                    ContentValues propertyValues = new ContentValues();
+                    propertyValues.put(Database.PROPERTY_KEY, property.getKey());
+                    propertyValues.put(Database.PROPERTY_VALUE, value);
+                    propertyValues.put(Database.PROPERTY_CONNECTION_ID, bankId);
+                    mDb.insert(Database.PROPERTY_TABLE_NAME, null, propertyValues);
+                }
+            }
+
             ArrayList<Account> accounts = bank.getAccounts();
             for (Account acc : accounts) {
                 ContentValues vals = new ContentValues();
@@ -207,8 +230,8 @@ public class DBAdapter {
 
     public Cursor getBank(String bankId) {
         Cursor c = mDb.query("banks",
-                new String[]{"_id", "balance", "banktype", "username", "password", "disabled",
-                        "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"},
+                new String[]{"_id", "balance", "banktype", "disabled",
+                        "custname", "updated", "sortorder", "currency", "hideAccounts"},
                 "_id=" + bankId, null, null, null, null);
         if (c != null) {
             c.moveToFirst();
diff --git app/src/main/java/com/liato/bankdroid/db/Database.java app/src/main/java/com/liato/bankdroid/db/Database.java
new file mode 100644
index 0000000..0558483
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/db/Database.java
@@ -0,0 +1,19 @@
+package com.liato.bankdroid.db;
+
+public class Database {
+
+    static final String DATABASE_NAME = "data";
+
+    static final int DATABASE_VERSION = 12;
+
+    static final String PROPERTY_TABLE_NAME = "connection_properties";
+    public static final String PROPERTY_CONNECTION_ID = "connection_id";
+    public static final String PROPERTY_KEY = "property";
+    public static final String PROPERTY_VALUE = "value";
+
+    static final String TABLE_CONNECTION_PROPERTIES = "CREATE TABLE " + PROPERTY_TABLE_NAME + " (" +
+            PROPERTY_CONNECTION_ID + " INTEGER REFERENCES " + LegacyDatabase.BANK_TABLE_NAME + "(" + LegacyDatabase.BANK_ID + ") ON DELETE CASCADE, " +
+            PROPERTY_KEY + " TEXT NOT NULL, " +
+            PROPERTY_VALUE + " TEXT, " +
+            "PRIMARY KEY (" + PROPERTY_CONNECTION_ID + "," + PROPERTY_KEY + "));";
+}
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index 5f67276..3dadcd4 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -16,11 +16,17 @@
 
 package com.liato.bankdroid.db;
 
+import com.liato.bankdroid.banking.LegacyProviderConfiguration;
+
+import android.content.ContentValues;
 import android.content.Context;
+import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.util.Log;
 
+import static com.liato.bankdroid.db.Database.*;
+
 /**
  * @since 8 jan 2011
  */
@@ -29,8 +35,8 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
     private static DatabaseHelper instance;
 
     private DatabaseHelper(final Context context) {
-        super(context, LegacyDatabase.DATABASE_NAME, null,
-                LegacyDatabase.DATABASE_VERSION);
+        super(context, Database.DATABASE_NAME, null,
+                Database.DATABASE_VERSION);
     }
 
     public static synchronized DatabaseHelper getHelper(Context context) {
@@ -45,6 +51,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
         db.execSQL(LegacyDatabase.TABLE_BANKS);
         db.execSQL(LegacyDatabase.TABLE_ACCOUNTS);
         db.execSQL(LegacyDatabase.TABLE_TRANSACTIONS);
+        db.execSQL(Database.TABLE_CONNECTION_PROPERTIES);
     }
 
     @Override
@@ -64,5 +71,65 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
             db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " ADD " +
                     LegacyDatabase.BANK_HIDE_ACCOUNTS + " integer;");
         }
+        if(oldVersion <= 11) {
+            try {
+                db.beginTransaction();
+                db.execSQL(Database.TABLE_CONNECTION_PROPERTIES);
+                migrateProperties(db);
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+        }
+    }
+
+    private void migrateProperties(final SQLiteDatabase db) {
+        String tempTable = LegacyDatabase.BANK_TABLE_NAME + "_temp";
+        db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " RENAME TO " + tempTable + ";");
+
+        // Drop username, password and extras fields from bank table
+        db.execSQL(LegacyDatabase.TABLE_BANKS);
+        db.execSQL("INSERT INTO " + LegacyDatabase.BANK_TABLE_NAME + " SELECT "
+            + LegacyDatabase.BANK_ID + ","
+            + LegacyDatabase.BANK_BALANCE + ","
+            + LegacyDatabase.BANK_TYPE + ","
+            + LegacyDatabase.BANK_CUSTOM_NAME + ","
+            + LegacyDatabase.BANK_UPDATED + ","
+            + LegacyDatabase.BANK_SORT_ORDER + ","
+            + LegacyDatabase.BANK_CURRENCY + ","
+            + LegacyDatabase.BANK_DISABLED + ","
+            + LegacyDatabase.BANK_HIDE_ACCOUNTS + " FROM " + tempTable);
+
+        // Add username, password and extras fields to properties table.
+        Cursor c = db.query(tempTable, null, null, null,null,null,null);
+        if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
+            while (!c.isLast() && !c.isAfterLast()) {
+                c.moveToNext();
+                long id = c.getLong(c.getColumnIndex(LegacyDatabase.BANK_ID));
+
+                ContentValues usernameProperty = new ContentValues();
+                usernameProperty.put(PROPERTY_CONNECTION_ID, id);
+                usernameProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.USERNAME);
+                usernameProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_USERNAME)));
+                db.insert(PROPERTY_TABLE_NAME, null, usernameProperty);
+
+                ContentValues passwordProperty = new ContentValues();
+                passwordProperty.put(PROPERTY_CONNECTION_ID, id);
+                passwordProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.PASSWORD);
+                passwordProperty.put(PROPERTY_VALUE, c.getString(c.getColumnIndex(LegacyDatabase.BANK_PASSWORD)));
+                db.insert(PROPERTY_TABLE_NAME, null, passwordProperty);
+
+                String extras = c.getString(c.getColumnIndex(LegacyDatabase.BANK_EXTRAS));
+                if(extras != null && !extras.isEmpty()) {
+                    ContentValues extrasProperty = new ContentValues();
+                    extrasProperty.put(PROPERTY_CONNECTION_ID, id);
+                    extrasProperty.put(PROPERTY_KEY, LegacyProviderConfiguration.EXTRAS);
+                    extrasProperty.put(PROPERTY_VALUE, extras);
+                    db.insert(PROPERTY_TABLE_NAME, null, extrasProperty);
+                }
+            }
+            c.close();
+        }
+        db.execSQL("DROP TABLE " + tempTable);
     }
 }
diff --git app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java
index 62e400a..650a84c 100644
--- app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java
+++ app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java
@@ -2,10 +2,6 @@ package com.liato.bankdroid.db;
 
 class LegacyDatabase {
 
-    static final String DATABASE_NAME = "data";
-
-    static final int DATABASE_VERSION = 11;
-
     static final String BANK_TABLE_NAME = "banks";
 
     static final String BANK_ID = "_id";
@@ -77,10 +73,6 @@ class LegacyDatabase {
             .append(" text not null, ")
             .append(BANK_TYPE)
             .append(" integer not null, ")
-            .append(BANK_USERNAME)
-            .append(" text not null, ")
-            .append(BANK_PASSWORD)
-            .append(" text not null, ")
             .append(BANK_CUSTOM_NAME)
             .append(" text, ")
             .append(BANK_UPDATED)
@@ -92,9 +84,7 @@ class LegacyDatabase {
             .append(BANK_DISABLED)
             .append(" integer, ")
             .append(BANK_HIDE_ACCOUNTS)
-            .append(" integer,")
-            .append(BANK_EXTRAS)
-            .append(" text);").toString();
+            .append(" integer);").toString();
 
     static final String TABLE_ACCOUNTS = new StringBuilder("create table ")
             .append(ACCOUNT_TABLE_NAME)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index be31940..fedeb0f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -40,6 +40,7 @@ import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -88,14 +89,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     protected Resources res;
 
-    private String username;
-
-    private String password;
-
     protected String customName;
 
-    private String extras;
-
     protected String currency = "SEK";
 
     protected ArrayList<Account> accounts = new ArrayList<Account>();
@@ -112,6 +107,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     protected boolean hideAccounts = false;
 
+    private Map<String, String> properties;
+
     public Bank(Context context) {
         this.context = context;
         this.res = this.context.getResources();
@@ -139,8 +136,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     public void update(String username, String password) throws BankException, LoginException,
             BankChoiceException, IOException {
-        this.username = username;
-        this.password = password;
+        setUsername(username);
+        setPassword(password);
         this.update();
     }
 
@@ -188,19 +185,21 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getPassword() {
+        String password = getProperty(LegacyProviderConfiguration.PASSWORD);
         return password == null ? "" : password;
     }
 
     public void setPassword(String password) {
-        this.password = password;
+        getProperties().put(LegacyProviderConfiguration.PASSWORD, password);
     }
 
     public String getUsername() {
+        String username = getProperty(LegacyProviderConfiguration.USERNAME);
         return username == null ? "" : username;
     }
 
     public void setUsername(String username) {
-        this.username = username;
+        getProperties().put(LegacyProviderConfiguration.USERNAME, username);
     }
 
     public BigDecimal getBalance() {
@@ -233,7 +232,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         if (customName != null && customName.length() > 0) {
             return customName;
         }
-        return username;
+        return getUsername();
     }
 
     public String getCustomName() {
@@ -245,28 +244,26 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getExtras() {
+        String extras = getProperty(LegacyProviderConfiguration.EXTRAS);
         return extras == null ? "" : extras;
     }
 
     public void setExtras(String extras) {
-        this.extras = extras;
-    }
+        getProperties().put(LegacyProviderConfiguration.EXTRAS, extras);
+      }
 
     public String getShortName() {
         return NAME_SHORT;
     }
 
-    public void setData(String username, String password, BigDecimal balance,
-            boolean disabled, long dbid, String currency, String customName, String extras,
+    public void setData(BigDecimal balance,
+            boolean disabled, long dbid, String currency, String customName,
             int hideAccounts) {
-        this.username = username;
-        this.password = password;
         this.balance = balance;
         this.disabled = disabled;
         this.dbid = dbid;
         this.currency = currency;
         this.customName = customName;
-        this.extras = extras;
         this.hideAccounts = hideAccounts == 1 ? true : false;
     }
 
@@ -338,6 +335,21 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return WEB_VIEW_ENABLED;
     }
 
+    public Map<String, String> getProperties() {
+        if(this.properties == null) {
+            this.properties = new HashMap<>();
+        }
+        return this.properties;
+    }
+
+    public String getProperty(String name) {
+        return getProperties().get(name);
+    }
+
+    public void setProperties(Map<String, String> properties) {
+        this.properties = properties;
+    }
+
     // Returns true if the current implementation of this bank is broken.
     public boolean isBroken() {
         return BROKEN;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
new file mode 100644
index 0000000..47d9195
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyProviderConfiguration.java
@@ -0,0 +1,9 @@
+package com.liato.bankdroid.banking;
+
+public interface LegacyProviderConfiguration {
+
+    String USERNAME = "legacy.username";
+    String PASSWORD = "legacy.password";
+    String EXTRAS = "legacy.extras";
+
+}

commit b8188acec657fe0404c74002d444afdbe8928186
Merge: 19fc258 62d5056
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Apr 25 18:59:11 2015 +0200

    Merge pull request #545 from liato/feature/butterknife
    
    Adds initial support for Butterknife

commit 62d5056f611cce5f952efa51209a413701c7a092
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Apr 25 13:53:17 2015 +0200

    Initial support for Butterknife

diff --git app/build.gradle app/build.gradle
index cbd10a3..f004c0d 100644
--- app/build.gradle
+++ app/build.gradle
@@ -45,6 +45,10 @@ android {
         targetCompatibility JavaVersion.VERSION_1_7
     }
 
+    lintOptions {
+        disable 'InvalidPackage'
+    }
+
     // Get signing keys for release
     gradle.taskGraph.whenReady { taskGraph ->
         if(taskGraph.hasTask(':app:assembleRelease')) {
@@ -80,6 +84,7 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-legacy')
+    compile 'com.jakewharton:butterknife:6.1.0'
     compile "com.android.support:appcompat-v7:22.0.+"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
diff --git app/proguard-rules.pro app/proguard-rules.pro
index 438bea8..f563262 100644
--- app/proguard-rules.pro
+++ app/proguard-rules.pro
@@ -23,3 +23,16 @@
 # to avoid problem on Samsung 4.2.2 devices with appcompat v21
 # see https://code.google.com/p/android/issues/detail?id=78377
 -keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}
+
+#Butterknife
+-keep class butterknife.** { *; }
+-dontwarn butterknife.internal.**
+-keep class **$$ViewInjector { *; }
+
+-keepclasseswithmembernames class * {
+    @butterknife.* <fields>;
+}
+
+-keepclasseswithmembernames class * {
+    @butterknife.* <methods>;
+}
diff --git app/src/main/java/com/liato/bankdroid/AboutActivity.java app/src/main/java/com/liato/bankdroid/AboutActivity.java
index e0a6c6c..203fda9 100644
--- app/src/main/java/com/liato/bankdroid/AboutActivity.java
+++ app/src/main/java/com/liato/bankdroid/AboutActivity.java
@@ -27,12 +27,19 @@ import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.widget.TextView;
 
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+
 public class AboutActivity extends LockableActivity {
 
+    @InjectView(R.id.txtVersion)
+    TextView mVersion;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.about);
+        ButterKnife.inject(this);
         PackageInfo pInfo;
         String version = "v1.x.x";
         try {
@@ -42,7 +49,7 @@ public class AboutActivity extends LockableActivity {
         } catch (final NameNotFoundException e) {
             e.printStackTrace();
         }
-        ((TextView) findViewById(R.id.txtVersion)).setText(
+        mVersion.setText(
                 getText(R.string.version).toString().replace("$version", version));
 
     }
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 9ff784e..8dbe918 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -58,9 +58,40 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+import butterknife.OnClick;
+
 public class BankEditActivity extends LockableActivity
         implements OnClickListener, OnItemSelectedListener {
 
+    @InjectView(R.id.spnBankeditBanklist)
+    Spinner mBankSpinner;
+
+    @InjectView(R.id.edtBankeditUsername)
+    EditText mUsernameField;
+
+    @InjectView(R.id.txtBankeditUsername)
+    TextView mUsernameLabel;
+
+    @InjectView(R.id.edtBankeditPassword)
+    EditText mPasswordField;
+
+    @InjectView(R.id.txtBankeditPassword)
+    TextView mPasswordLabel;
+
+    @InjectView(R.id.edtBankeditCustomName)
+    EditText mCustomNameField;
+
+    @InjectView(R.id.edtBankeditExtras)
+    EditText mExtrasField;
+
+    @InjectView(R.id.txtBankeditExtras)
+    TextView mExtrasLabel;
+
+    @InjectView(R.id.txtErrorDesc)
+    TextView mErrorDescription;
+
     private final static String TAG = "BankEditActivity";
 
     private Bank SELECTED_BANK;
@@ -71,17 +102,15 @@ public class BankEditActivity extends LockableActivity
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.bank);
+        ButterKnife.inject(this);
         this.getWindow()
                 .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
         ArrayList<Bank> items = BankFactory.listBanks(this);
         Collections.sort(items);
-        Spinner spnBanks = (Spinner) findViewById(R.id.spnBankeditBanklist);
-        BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, items);
-        spnBanks.setAdapter(adapter);
-        spnBanks.setOnItemSelectedListener(this);
 
-        findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
-        findViewById(R.id.btnSettingsOk).setOnClickListener(this);
+        BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, items);
+        mBankSpinner.setAdapter(adapter);
+        mBankSpinner.setOnItemSelectedListener(this);
 
         Bundle extras = getIntent().getExtras();
         if (extras != null) {
@@ -89,24 +118,19 @@ public class BankEditActivity extends LockableActivity
             if (BANKID != -1) {
                 Bank bank = BankFactory.bankFromDb(BANKID, this, false);
                 if (bank != null) {
-                    ((EditText) findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
-                    ((EditText) findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
-                    ((EditText) findViewById(R.id.edtBankeditCustomName))
-                            .setText(bank.getCustomName());
+                    mUsernameField.setText(bank.getUsername());
+                    mPasswordField.setText(bank.getPassword());
+                    mCustomNameField.setText(bank.getCustomName());
                     if (bank.getExtras() != null) {
-                        ((EditText) findViewById(R.id.edtBankeditExtras)).setText(bank.getExtras());
+                        mExtrasField.setText(bank.getExtras());
                     }
 
-                    TextView errorDesc = (TextView) findViewById(R.id.txtErrorDesc);
-                    if (bank.isDisabled()) {
-                        errorDesc.setVisibility(View.VISIBLE);
-                    } else {
-                        errorDesc.setVisibility(View.INVISIBLE);
-                    }
+                    mErrorDescription.setVisibility(bank.isDisabled() ? View.VISIBLE : View.INVISIBLE);
+
                     SELECTED_BANK = bank;
                     for (int i = 0; i < items.size(); i++) {
                         if (bank.getBanktypeId() == items.get(i).getBanktypeId()) {
-                            spnBanks.setSelection(i);
+                            mBankSpinner.setSelection(i);
                             break;
                         }
                     }
@@ -116,21 +140,22 @@ public class BankEditActivity extends LockableActivity
     }
 
     @Override
+    @OnClick({R.id.btnSettingsCancel, R.id.btnSettingsOk})
     public void onClick(View v) {
         if (v.getId() == R.id.btnSettingsCancel) {
             this.finish();
         } else if (v.getId() == R.id.btnSettingsOk) {
             SELECTED_BANK.setUsername(
-                    ((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString()
+                    mUsernameField.getText().toString()
                             .trim());
             SELECTED_BANK.setPassword(
-                    ((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString()
+                    mPasswordField.getText().toString()
                             .trim());
             SELECTED_BANK.setCustomName(
-                    ((EditText) findViewById(R.id.edtBankeditCustomName)).getText().toString()
+                    mCustomNameField.getText().toString()
                             .trim());
             SELECTED_BANK.setExtras(
-                    ((EditText) findViewById(R.id.edtBankeditExtras)).getText().toString().trim());
+                    mExtrasField.getText().toString().trim());
             SELECTED_BANK.setDbid(BANKID);
             new DataRetrieverTask(this, SELECTED_BANK).execute();
         }
@@ -140,52 +165,46 @@ public class BankEditActivity extends LockableActivity
     @Override
     public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
         SELECTED_BANK = (Bank) parentView.getItemAtPosition(pos);
-        EditText edtUsername = (EditText) findViewById(R.id.edtBankeditUsername);
-        EditText edtPassword = (EditText) findViewById(R.id.edtBankeditPassword);
-        EditText edtExtras = (EditText) findViewById(R.id.edtBankeditExtras);
-        TextView txtUsername = (TextView) findViewById(R.id.txtBankeditUsername);
-        TextView txtPassword = (TextView) findViewById(R.id.txtBankeditPassword);
-        TextView txtExtras = (TextView) findViewById(R.id.txtBankeditExtras);
-
-        edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
-        edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
-        txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
-
-        edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-        edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
-        edtPassword.setTypeface(Typeface.MONOSPACE);
-        txtPassword.setText(SELECTED_BANK.getInputTitlePassword());
-
-        edtExtras.setInputType(SELECTED_BANK.getInputTypeExtras());
+
+        mUsernameField.setInputType(SELECTED_BANK.getInputTypeUsername());
+        mUsernameField.setHint(SELECTED_BANK.getInputHintUsername());
+        mUsernameLabel.setText(SELECTED_BANK.getInputTitleUsername());
+
+        mPasswordField.setInputType(SELECTED_BANK.getInputTypePassword());
+        mPasswordField.setTransformationMethod(PasswordTransformationMethod.getInstance());
+        mPasswordField.setTypeface(Typeface.MONOSPACE);
+        mPasswordLabel.setText(SELECTED_BANK.getInputTitlePassword());
+
+        mExtrasField.setInputType(SELECTED_BANK.getInputTypeExtras());
         if ((SELECTED_BANK.getInputTypeExtras() & InputType.TYPE_TEXT_VARIATION_PASSWORD)
                 == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
-            edtExtras.setTransformationMethod(PasswordTransformationMethod.getInstance());
-            edtExtras.setTypeface(Typeface.MONOSPACE);
+            mExtrasField.setTransformationMethod(PasswordTransformationMethod.getInstance());
+            mExtrasField.setTypeface(Typeface.MONOSPACE);
         }
-        txtExtras.setText(SELECTED_BANK.getInputTitleExtras());
+        mExtrasLabel.setText(SELECTED_BANK.getInputTitleExtras());
 
         if (SELECTED_BANK.isInputUsernameHidden()) {
-            edtUsername.setVisibility(View.GONE);
-            txtUsername.setVisibility(View.GONE);
+            mUsernameField.setVisibility(View.GONE);
+            mUsernameLabel.setVisibility(View.GONE);
         } else {
-            edtUsername.setVisibility(View.VISIBLE);
-            txtUsername.setVisibility(View.VISIBLE);
+            mUsernameField.setVisibility(View.VISIBLE);
+            mUsernameLabel.setVisibility(View.VISIBLE);
         }
 
         if (SELECTED_BANK.isInputPasswordHidden()) {
-            edtPassword.setVisibility(View.GONE);
-            txtPassword.setVisibility(View.GONE);
+            mPasswordField.setVisibility(View.GONE);
+            mPasswordLabel.setVisibility(View.GONE);
         } else {
-            edtPassword.setVisibility(View.VISIBLE);
-            txtPassword.setVisibility(View.VISIBLE);
+            mPasswordField.setVisibility(View.VISIBLE);
+            mPasswordLabel.setVisibility(View.VISIBLE);
         }
 
         if (SELECTED_BANK.isInputExtrasHidden()) {
-            edtExtras.setVisibility(View.GONE);
-            txtExtras.setVisibility(View.GONE);
+            mExtrasField.setVisibility(View.GONE);
+            mExtrasLabel.setVisibility(View.GONE);
         } else {
-            edtExtras.setVisibility(View.VISIBLE);
-            txtExtras.setVisibility(View.VISIBLE);
+            mExtrasField.setVisibility(View.VISIBLE);
+            mExtrasLabel.setVisibility(View.VISIBLE);
         }
     }
 
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 7487741..8ffa910 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -52,8 +52,14 @@ import android.widget.TextView;
 
 import java.util.ArrayList;
 
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+
 public class MainActivity extends LockableActivity {
 
+    @InjectView(R.id.txtAccountsDesc)
+    TextView mAccountsDescription;
+
     private final static String TAG = "MainActivity";
 
     protected static boolean showHidden = false;
@@ -78,6 +84,8 @@ public class MainActivity extends LockableActivity {
         PairApplicationsActivity.initialSetupApiKey(this);
 
         setContentView(R.layout.main);
+        ButterKnife.inject(this);
+
         adapter = new AccountsAdapter(this, showHidden);
         final ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
         adapter.setGroups(banks);
@@ -145,15 +153,7 @@ public class MainActivity extends LockableActivity {
 
     public void refreshView() {
         final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
-        if (banks.size() > 0) {
-            findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-//            showTitleButton("refresh");
-            //findViewById(R.id.btnAccountsRefresh).setClickable(true);
-        } else {
-            findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
-//            hideTitleButton("refresh");
-            //findViewById(R.id.btnAccountsRefresh).setClickable(false);
-        }
+        mAccountsDescription.setVisibility(banks.isEmpty() ? View.VISIBLE : View.GONE);
 
         adapter.setShowHidden(showHidden);
         adapter.setGroups(banks);

commit 19fc258b296d449d9fd750f791d9591f0f852ab7
Merge: 385bd52 f29e718
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 23 21:37:16 2015 +0200

    Merge pull request #544 from liato/feature/refactor-banks
    
    Use getters for bank properties

commit f29e718dc574ee07031190610babf170b02faf7e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 22 22:52:31 2015 +0200

    Refactor field validations.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 585da4c..f46bc24 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -125,8 +125,7 @@ public abstract class AbsIkanoPartner extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 4a4ab26..96b45d2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -143,8 +143,7 @@ public class AkeliusInvest extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index ea8ae6a..ee79842 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -145,8 +145,7 @@ public class AkeliusSpar extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 719978f..3be6952 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -130,8 +130,7 @@ public class AmericanExpress extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 22ca766..cf00a9e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -100,7 +100,7 @@ public class AppeakPoker extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null) {
+        if (getUsername().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index cd9b860..b930846 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -115,8 +115,7 @@ public class BetterGlobe extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index ba4587b..5ba1723 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -127,8 +127,7 @@ public class Bioklubben extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index a56d6da..b9165e2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -97,7 +97,7 @@ public class BlekingeTrafiken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getUsername().length() == 0) {
+        if (getUsername().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 3eb8a55..0b1666f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -105,8 +105,7 @@ public class Bredband2VoIP extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index 2fdcfe0..577a2d6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -151,8 +151,7 @@ public class BrummerKF extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index 0b8d057..e83fc7a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -140,8 +140,7 @@ public class CSN extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index ce30ebd..1205120 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -55,7 +55,7 @@ public class Chalmrest extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getUsername().length() == 0) {
+        if (getUsername().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index 3ba0a52..1ece04d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -148,8 +148,7 @@ public class DanskeBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 42e2463..7e4241d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -137,8 +137,7 @@ public class DinersClub extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index b4cebf3..66a166c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -126,8 +126,7 @@ public class EasyCard extends Bank {
 
         super.update();
 
-        if (getUsername() == null || getPassword() == null || getUsername().length() != 9
-                || getPassword().length() == 0) {
+        if (getPassword().isEmpty() || getUsername().length() != 9) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index bd13b5c..c247a79 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -100,8 +100,7 @@ public class EspressoHouse extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index cea9bf9..380b8cb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -111,8 +111,7 @@ public class Everydaycard extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 1bf73ef..44d5ad7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -112,8 +112,7 @@ public class FirstCard extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index 4a0970a..9ba9212 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -158,8 +158,7 @@ public class ForexBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         /*
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 7f89663..fa831b1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -130,8 +130,7 @@ public class Handelsbanken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index f698378..c51674d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -131,8 +131,7 @@ public class Hemkop extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 23eb9e2..8fb36b4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -157,8 +157,7 @@ public class IkanoBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 8a40c3c..bde72f5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -106,8 +106,7 @@ public class Jojo extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index 98d5409..a27a8c0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -147,8 +147,7 @@ public class Marginalen extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 473bbe0..7fa2357 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -109,7 +109,7 @@ public class McDonalds extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getUsername().length() != 19) {
+        if (getUsername().length() != 19) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index bcd8a91..5147981 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -98,8 +98,7 @@ public class Meniga extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index 0411d76..817bb6a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -109,8 +109,7 @@ public class MinPension extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 5aafe2e..5b30f79 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -119,8 +119,7 @@ public abstract class MobilbankenBase extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index 43645af..6f306dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -141,8 +141,7 @@ public class NordeaDK extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 81944dd..9d0c10f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -126,8 +126,7 @@ public class Nordnet extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 6a88c50..8a5d97f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -117,8 +117,7 @@ public class Nordnetdirekt extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index eabb204..dcc343f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -168,8 +168,7 @@ public class OKQ8 extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         if (response == null) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index e1765bf..e3f2a1f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -112,8 +112,7 @@ public class Ostgotatrafiken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 8d0ced9..d58e3d6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -107,8 +107,7 @@ public class Osuuspankki extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 01cf099..15dec15 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -119,8 +119,7 @@ public class PayPal extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index 554f202..249773d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -118,8 +118,7 @@ public class Payson extends Bank {
     @Override
     public void update() throws BankChoiceException, BankException, LoginException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index 397920f..96df24c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -106,8 +106,7 @@ public class PlusGirot extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index be13d59..a233fb9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -96,8 +96,7 @@ public class ResursBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 189d66c..311bf85 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -122,8 +122,7 @@ public class SevenDay extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 7c99e9a..9032561 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -151,8 +151,7 @@ public class Skandiabanken extends Bank {
             BankChoiceException, IOException {
         super.update();
 
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 052083c..0bc81e0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -114,8 +114,7 @@ public class Steam extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 41bac2c..398ea29 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -116,8 +116,7 @@ public class SveaDirekt extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index dc16abc..e067df0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -105,8 +105,7 @@ public class SvenskaSpel extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index c7b4fb1..5e24c77 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -90,8 +90,7 @@ public class TestBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index cc3caca..ca41559 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -135,8 +135,7 @@ public class TicketRikskortet extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 2bd6a5b..b65a41f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -118,8 +118,7 @@ public class TrustBuddy extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 1d90f79..7012a16 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -124,8 +124,7 @@ public class Vasttrafik extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 93ee0c4..de78bc0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -180,8 +180,7 @@ public class Villabanken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 87d30c9..146d421 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -129,8 +129,7 @@ public class Volvofinans extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 8306df3..0119131 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -121,8 +121,7 @@ public class Zidisha extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 4827fb9..3521ae7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -195,7 +195,7 @@ public class Avanza extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(getUsername()) || TextUtils.isEmpty(getPassword())) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 32ab7d9..75fbe83 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -109,7 +109,7 @@ public class Bitcoin extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(getUsername())) {
+        if (getUsername().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_bitcoin_address).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 3f404a5..9efb4c3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -131,8 +131,7 @@ public class Coop extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index f996e7c..fde8c3a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -183,7 +183,7 @@ public class ICA extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(getUsername()) || TextUtils.isEmpty(getPassword())) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index cc7d29f..dc7a0c4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -120,8 +120,7 @@ public class ICABanken extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 841a2aa..f0e398d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -227,8 +227,7 @@ public class Lansforsakringar extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index dada087..d2b12d2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -288,8 +288,7 @@ public class Nordea extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 0bf4c9f..3d3ecbf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -81,7 +81,7 @@ public class Rikslunchen extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(getUsername())) {
+        if (getUsername().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         try {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index e9bb0af..d263d83 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -141,8 +141,7 @@ public class SEB extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index be3a5b7..7bcf933 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -167,8 +167,7 @@ public abstract class SEBKortBase extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index db75e84..f1cdc48 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -144,8 +144,7 @@ public abstract class AbstractSwedbank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
-                || getPassword().length() == 0) {
+        if (getUsername().isEmpty() || getPassword().isEmpty()) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();

commit 5968732df688c0ef73d6e1d0b45a87825b8d0704
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 22 22:30:21 2015 +0200

    Make sure an empty string is returned if fields are null

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 999f54e..be31940 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -188,7 +188,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getPassword() {
-        return password;
+        return password == null ? "" : password;
     }
 
     public void setPassword(String password) {
@@ -196,7 +196,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getUsername() {
-        return username;
+        return username == null ? "" : username;
     }
 
     public void setUsername(String username) {
@@ -245,7 +245,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getExtras() {
-        return this.extras;
+        return extras == null ? "" : extras;
     }
 
     public void setExtras(String extras) {

commit 831141335ebb3ba1858b86190c68c3b667bbaafd
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 22 21:46:57 2015 +0200

    Make some member fields private to ensure that the getters are used by sub classes.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 4350fc4..999f54e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -88,13 +88,13 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     protected Resources res;
 
-    protected String username;
+    private String username;
 
-    protected String password;
+    private String password;
 
     protected String customName;
 
-    protected String extras;
+    private String extras;
 
     protected String currency = "SEK";
 

commit 9e3b0117f55abd397b124c7446804cbd92867439
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 22 21:38:27 2015 +0200

    Use getters instead of super member variables.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index bc7a65c..585da4c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -101,8 +101,8 @@ public abstract class AbsIkanoPartner extends Bank {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewstate.val()));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventvalidation.val()));
-        postData.add(new BasicNameValuePair(userField.attr("name"), username));
-        postData.add(new BasicNameValuePair(passField.attr("name"), password));
+        postData.add(new BasicNameValuePair(userField.attr("name"), getUsername()));
+        postData.add(new BasicNameValuePair(passField.attr("name"), getPassword()));
         postData.add(new BasicNameValuePair(submitField.attr("name"), submitField.val()));
         return new LoginPackage(urlopen, postData, response,
                 "https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
@@ -125,8 +125,8 @@ public abstract class AbsIkanoPartner extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index db2d9d5..4a4ab26 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -115,8 +115,8 @@ public class AkeliusInvest extends Bank {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("action", "login"));
         postData.add(new BasicNameValuePair("logintoken", strLogintoken));
-        postData.add(new BasicNameValuePair("df_username", username));
-        postData.add(new BasicNameValuePair("df_password", password));
+        postData.add(new BasicNameValuePair("df_username", getUsername()));
+        postData.add(new BasicNameValuePair("df_password", getPassword()));
         postData.add(new BasicNameValuePair("Language", "SV"));
         postData.add(new BasicNameValuePair("IdleTime", "900"));
 
@@ -143,8 +143,8 @@ public class AkeliusInvest extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index b7231ed..ea8ae6a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -116,8 +116,8 @@ public class AkeliusSpar extends Bank {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("action", "login"));
         postData.add(new BasicNameValuePair("logintoken", strLogintoken));
-        postData.add(new BasicNameValuePair("df_username", username));
-        postData.add(new BasicNameValuePair("df_password", password));
+        postData.add(new BasicNameValuePair("df_username", getUsername()));
+        postData.add(new BasicNameValuePair("df_password", getPassword()));
         postData.add(new BasicNameValuePair("Language", "SV"));
         postData.add(new BasicNameValuePair("IdleTime", "900"));
 
@@ -145,8 +145,8 @@ public class AkeliusSpar extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index b9e84d3..719978f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -107,10 +107,10 @@ public class AmericanExpress extends Bank {
                 "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
         postData.add(new BasicNameValuePair("REMEMBERME", "on"));
         postData.add(new BasicNameValuePair("manage", "option1"));
-        postData.add(new BasicNameValuePair("UserID", username));
-        postData.add(new BasicNameValuePair("USERID", username));
-        postData.add(new BasicNameValuePair("Password", password));
-        postData.add(new BasicNameValuePair("PWD", password));
+        postData.add(new BasicNameValuePair("UserID", getUsername()));
+        postData.add(new BasicNameValuePair("USERID", getUsername()));
+        postData.add(new BasicNameValuePair("Password", getPassword()));
+        postData.add(new BasicNameValuePair("PWD", getPassword()));
 
         return new LoginPackage(urlopen, postData, response,
                 "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
@@ -130,8 +130,8 @@ public class AmericanExpress extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index b933506..22ca766 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -80,7 +80,7 @@ public class AppeakPoker extends Bank {
         urlopen = new Urllib(context);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         return new LoginPackage(urlopen, postData, "",
-                String.format("http://poker.appeak.se/playerInfo/?username=%s", username));
+                String.format("http://poker.appeak.se/playerInfo/?username=%s", getUsername()));
     }
 
     @Override
@@ -100,7 +100,7 @@ public class AppeakPoker extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null) {
+        if (getUsername() == null) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 44533df..cd9b860 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -98,8 +98,8 @@ public class BetterGlobe extends Bank {
         HashMap<String, String> headers = urlopen.getHeaders();
         headers.put("Referer", "http://betterglobe.com/login.aspx?lang=sv-SE");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("btnLogin", ""));
         return new LoginPackage(urlopen, postData, "",
                 "http://betterglobe.com/Login.aspx?rememberMe=False");
@@ -115,8 +115,8 @@ public class BetterGlobe extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index 9670523..ba4587b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -108,10 +108,10 @@ public class Bioklubben extends Bank {
         postData.add(new BasicNameValuePair("ctl00$toolkitscriptmanager",
                 "ctl00$UpdatePanel|ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
         postData.add(new BasicNameValuePair(
-                "ctl00$ContentPlaceHolder1$LoginUserControl$LoginNameTextBox", username));
+                "ctl00$ContentPlaceHolder1$LoginUserControl$LoginNameTextBox", getUsername()));
         postData.add(
                 new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$PasswordTextBox",
-                        password));
+                        getPassword()));
         return new LoginPackage(urlopen, postData, response, "http://bioklubben.sf.se/Start.aspx");
     }
 
@@ -127,8 +127,8 @@ public class Bioklubben extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index b1dad07..a56d6da 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -86,7 +86,7 @@ public class BlekingeTrafiken extends Bank {
         urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
         urlopen.addHeader("Accept", "application/json");
         HttpResponse httpResponse = urlopen.openAsHttpResponse(URL + "/webshop/card/balance/",
-                new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
+                new StringEntity("{\"cardnr\":\"" + getUsername() + "\"}"), true);
         if (httpResponse.getStatusLine().getStatusCode() != 200) {
             throw new BankException(res.getText(R.string.invalid_card_number).toString());
         }
@@ -97,7 +97,7 @@ public class BlekingeTrafiken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || username.length() == 0) {
+        if (getUsername() == null || getUsername().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index ece42a3..3eb8a55 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -81,8 +81,8 @@ public class Bredband2VoIP extends Bank {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_bredband2));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("cUsername", username));
-        postData.add(new BasicNameValuePair("cPassword", password));
+        postData.add(new BasicNameValuePair("cUsername", getUsername()));
+        postData.add(new BasicNameValuePair("cPassword", getPassword()));
         postData.add(new BasicNameValuePair("bIsCompany", "0"));
         postData.add(new BasicNameValuePair("submit", "Logga in"));
         response = urlopen.open(API_URL + "index/", postData, true);
@@ -105,8 +105,8 @@ public class Bredband2VoIP extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index 7932051..2fdcfe0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -122,8 +122,8 @@ public class BrummerKF extends Bank {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewstate));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventvalidation));
-        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtUsername", username));
-        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtPassword", password));
+        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtUsername", getUsername()));
+        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtPassword", getPassword()));
         postData.add(new BasicNameValuePair("ctl00$cphMainRegion$btnLogin", "Logga in"));
         postData.add(new BasicNameValuePair("ctl00$ctl08", "sv"));
         postData.add(
@@ -151,8 +151,8 @@ public class BrummerKF extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index e4f88c5..0b8d057 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -117,8 +117,8 @@ public class CSN extends Bank {
         postData.clear();
 
         postData.add(new BasicNameValuePair("metod", "validerapinkod"));
-        postData.add(new BasicNameValuePair("pnr", username));
-        postData.add(new BasicNameValuePair("pinkod", password));
+        postData.add(new BasicNameValuePair("pnr", getUsername()));
+        postData.add(new BasicNameValuePair("pinkod", getPassword()));
         return new LoginPackage(urlopen, postData, response,
                 "https://www.csn.se/bas/inloggning/Pinkod.do");
     }
@@ -140,8 +140,8 @@ public class CSN extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index b983208..ce30ebd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -55,11 +55,11 @@ public class Chalmrest extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || username.length() == 0) {
+        if (getUsername() == null || getUsername().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
-        String cardNr = username;
+        String cardNr = getUsername();
 
         HttpClient httpclient = new DefaultHttpClient();
         HttpGet httpget = new HttpGet(
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index da5f903..3ba0a52 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -129,8 +129,8 @@ public class DanskeBank extends Bank {
         postData.add(new BasicNameValuePair("hidStatusTid", sdf.format(new Date())));
         postData.add(new BasicNameValuePair("gsSikSystem", "KO"));
         postData.add(new BasicNameValuePair("gsLand", "SE"));
-        postData.add(new BasicNameValuePair("gsAftlnr", username));
-        postData.add(new BasicNameValuePair("gsLogon", password));
+        postData.add(new BasicNameValuePair("gsAftlnr", getUsername()));
+        postData.add(new BasicNameValuePair("gsLogon", getPassword()));
 
         return new LoginPackage(urlopen, postData, response, "https://mobil.danskebank.se/XI");
     }
@@ -148,8 +148,8 @@ public class DanskeBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 89a31f2..42e2463 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -117,8 +117,8 @@ public class DinersClub extends Bank {
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$UserName", username));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", password));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$UserName", getUsername()));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", getPassword()));
         postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
 
         return new LoginPackage(urlopen, postData, response,
@@ -137,8 +137,8 @@ public class DinersClub extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index b9bb0f7..b4cebf3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -97,10 +97,10 @@ public class EasyCard extends Bank {
 
         // Our data + button value
         postData.add(new BasicNameValuePair(
-                "ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", username));
+                "ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", getUsername()));
         postData.add(
                 new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$password",
-                        password));
+                        getPassword()));
         postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$ctl00",
                 "Logga in"));
 
@@ -126,8 +126,8 @@ public class EasyCard extends Bank {
 
         super.update();
 
-        if (username == null || password == null || username.length() != 9
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() != 9
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -140,7 +140,7 @@ public class EasyCard extends Bank {
             // Our data!
             String account_number = matcher.group(1).toString().trim(); // 123123123
 
-            if (!account_number.equalsIgnoreCase(this.username)) {
+            if (!account_number.equalsIgnoreCase(getUsername())) {
                 throw new BankException(res.getText(R.string.unable_to_login).toString());
             }
 
@@ -153,9 +153,9 @@ public class EasyCard extends Bank {
 
             // Construct accounts
             Account credit_spent = new Account("Saldo", credit_spent_amount,
-                    this.username + ":saldo", Account.CCARD);
+                    getUsername() + ":saldo", Account.CCARD);
             Account credit_left = new Account("Kredit", credit_left_amount,
-                    this.username + ":kredit", Account.OTHER);
+                    getUsername() + ":kredit", Account.OTHER);
 
             accounts.add(credit_spent);
             accounts.add(credit_left);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index 8b08872..bd13b5c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -75,10 +75,10 @@ public class EspressoHouse extends Bank {
                 "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$LoginButton"));
         postData.add(new BasicNameValuePair(
                 "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$UserName",
-                username));
+                getUsername()));
         postData.add(new BasicNameValuePair(
                 "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$Password",
-                password));
+                getPassword()));
         HttpResponse httpResponse = urlopen.openAsHttpResponse(
                 "http://www.espressohouse.com/coffee-card/logga-inladda/", postData, true);
         LoginPackage lp = new LoginPackage(urlopen, postData, null, API_URL);
@@ -100,8 +100,8 @@ public class EspressoHouse extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 9e2c7ec..cea9bf9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -93,8 +93,8 @@ public class Everydaycard extends Bank {
         urlopen = new Urllib(context);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("nextPage", "firstPage"));
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         return new LoginPackage(urlopen, postData, response, url);
     }
 
@@ -111,8 +111,8 @@ public class Everydaycard extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 0603275..1bf73ef 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -94,8 +94,8 @@ public class FirstCard extends Bank {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("op", "login"));
         postData.add(new BasicNameValuePair("errorpage", "login.jsp"));
-        postData.add(new BasicNameValuePair("pnr", username));
-        postData.add(new BasicNameValuePair("intpwd", password));
+        postData.add(new BasicNameValuePair("pnr", getUsername()));
+        postData.add(new BasicNameValuePair("intpwd", getPassword()));
         return new LoginPackage(urlopen, postData, null, "https://www.firstcard.se/login.jsp");
     }
 
@@ -112,8 +112,8 @@ public class FirstCard extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index 3e92776..4a0970a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -130,8 +130,8 @@ public class ForexBank extends Bank {
         // Assemble param table
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("p_tranid", tranId));
-        postData.add(new BasicNameValuePair("user_id", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("user_id", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("submitButton", "Logga in"));
         postData.add(new BasicNameValuePair("forcelayout", "touch"));
         postData.add(new BasicNameValuePair("fallbackQuery", fallbackQuery));
@@ -158,8 +158,8 @@ public class ForexBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         /*
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index a568dff..7f89663 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -111,8 +111,8 @@ public class Handelsbanken extends Bank {
         }
         String strLoginUrl = "https://m.handelsbanken.se/primary/_-" + matcher.group(1);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("pin", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("pin", getPassword()));
         postData.add(new BasicNameValuePair("execute", "true"));
         return new LoginPackage(urlopen, postData, response, strLoginUrl);
     }
@@ -130,8 +130,8 @@ public class Handelsbanken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index ffb80c6..f698378 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -112,8 +112,8 @@ public class Hemkop extends Bank {
         postData.add(new BasicNameValuePair("__SCROLLPOSITIONY", "266"));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
         postData.add(new BasicNameValuePair("ctl00$uiTopMenu$Search", ""));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$tbUsername", username));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$tbPassword", password));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$tbUsername", getUsername()));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$tbPassword", getPassword()));
         return new LoginPackage(urlopen, postData, response,
                 "https://www.hemkop.se/Mina-sidor/Logga-in/");
     }
@@ -131,8 +131,8 @@ public class Hemkop extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index aecca66..23eb9e2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -129,8 +129,8 @@ public class IkanoBank extends Bank {
         postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl02$lbLogin"));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ctl02$txtSocialSecurityNumber", username));
-        postData.add(new BasicNameValuePair("ctl02$txtPinCode", password));
+        postData.add(new BasicNameValuePair("ctl02$txtSocialSecurityNumber", getUsername()));
+        postData.add(new BasicNameValuePair("ctl02$txtPinCode", getPassword()));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
         return new LoginPackage(urlopen, postData, response,
                 "https://secure.ikanobank.se/engines/page.aspx?structid=1895");
@@ -157,8 +157,8 @@ public class IkanoBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 43c4d64..8a40c3c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -88,8 +88,8 @@ public class Jojo extends Bank {
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("GOTO", "/mobile/minakort.html"));
-        postData.add(new BasicNameValuePair("login", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("login", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("CUSTOMER_LOGIN", "LOGGA IN"));
         return new LoginPackage(urlopen, postData, response, URL + "/mobile/customer.html");
     }
@@ -106,8 +106,8 @@ public class Jojo extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index bfa47ac..98d5409 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -118,8 +118,8 @@ public class Marginalen extends Bank {
         postData.add(new BasicNameValuePair("commandorigin", "0.pin_logon_step1_view_handler"));
         postData.add(new BasicNameValuePair("guid", guid));
         postData.add(new BasicNameValuePair("hash", hash));
-        postData.add(new BasicNameValuePair("userId", username));
-        postData.add(new BasicNameValuePair("pin", password));
+        postData.add(new BasicNameValuePair("userId", getUsername()));
+        postData.add(new BasicNameValuePair("pin", getPassword()));
 
         return new LoginPackage(urlopen, postData, response, BASE_URL + "engine");
     }
@@ -147,8 +147,8 @@ public class Marginalen extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 0051b93..473bbe0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -90,7 +90,7 @@ public class McDonalds extends Bank {
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__Click", "0"));
-        postData.add(new BasicNameValuePair("CardNumber", username));
+        postData.add(new BasicNameValuePair("CardNumber", getUsername()));
 
         return new LoginPackage(urlopen, postData, response,
                 "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm&Seq=1");
@@ -109,7 +109,7 @@ public class McDonalds extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || username.length() != 19) {
+        if (getUsername() == null || getUsername().length() != 19) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index 9e7ddef..bcd8a91 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -77,8 +77,8 @@ public class Meniga extends Bank {
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.meniga.is/Mobile");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("email", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("email", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         return new LoginPackage(urlopen, postData, response, "https://www.meniga.is/Mobile");
     }
 
@@ -98,8 +98,8 @@ public class Meniga extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index 09d10c3..0411d76 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -77,8 +77,8 @@ public class MinPension extends Bank {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " token.");
         }
         postData.add(new BasicNameValuePair("__RequestVerificationToken", el.val()));
-        postData.add(new BasicNameValuePair("viewModel.Personnummer", username));
-        postData.add(new BasicNameValuePair("viewModel.Kod", password));
+        postData.add(new BasicNameValuePair("viewModel.Personnummer", getUsername()));
+        postData.add(new BasicNameValuePair("viewModel.Kod", getPassword()));
         LoginPackage lp = new LoginPackage(urlopen, postData, null,
                 "https://www.minpension.se/inloggning/personlig-kod");
         return lp;
@@ -109,8 +109,8 @@ public class MinPension extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index db2f10f..5aafe2e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -100,8 +100,8 @@ public abstract class MobilbankenBase extends Bank {
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("msisdn", msisdn));
-        postData.add(new BasicNameValuePair("user" + timestamp, username));
-        postData.add(new BasicNameValuePair("password" + timestamp, password));
+        postData.add(new BasicNameValuePair("user" + timestamp, getUsername()));
+        postData.add(new BasicNameValuePair("password" + timestamp, getPassword()));
         return new LoginPackage(urlopen, postData, response, postUrl);
     }
 
@@ -119,8 +119,8 @@ public abstract class MobilbankenBase extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index b7398d0..43645af 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -117,8 +117,8 @@ public class NordeaDK extends Bank {
         String strLoginUrl = "https://www.netbank.nordea.dk/mnetbank/servlet/Logon";
         this.referer = strLoginUrl;
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("user_id", username));
-        postData.add(new BasicNameValuePair("logon_code", password));
+        postData.add(new BasicNameValuePair("user_id", getUsername()));
+        postData.add(new BasicNameValuePair("logon_code", getPassword()));
         postData.add(new BasicNameValuePair("command", "1"));
         this.prefix = matcher.group(1);
         postData.add(new BasicNameValuePair("prefix", matcher.group(1)));
@@ -141,8 +141,8 @@ public class NordeaDK extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index a23781b..81944dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -106,8 +106,8 @@ public class Nordnet extends Bank {
         postData.add(new BasicNameValuePair("checksum", ""));
         postData.add(new BasicNameValuePair("referer", ""));
         postData.add(new BasicNameValuePair("encryption", "0"));
-        postData.add(new BasicNameValuePair(loginFieldName, username));
-        postData.add(new BasicNameValuePair(loginFieldPassword, password));
+        postData.add(new BasicNameValuePair(loginFieldName, getUsername()));
+        postData.add(new BasicNameValuePair(loginFieldPassword, getPassword()));
 
         return new LoginPackage(urlopen, postData, response,
                 "https://www.nordnet.se/mux/login/login.html");
@@ -126,8 +126,8 @@ public class Nordnet extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index e7a9948..6a88c50 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -96,9 +96,9 @@ public class Nordnetdirekt extends Bank {
         postData.add(new BasicNameValuePair("a4", "sv"));
         postData.add(new BasicNameValuePair("a3", "ADSE"));
         postData.add(new BasicNameValuePair("usa", "7"));
-        postData.add(new BasicNameValuePair("a1", username));
-        postData.add(new BasicNameValuePair("a2", password));
-        postData.add(new BasicNameValuePair("nyckel", extras));
+        postData.add(new BasicNameValuePair("a1", getUsername()));
+        postData.add(new BasicNameValuePair("a2", getPassword()));
+        postData.add(new BasicNameValuePair("nyckel", getExtras()));
         return new LoginPackage(urlopen, postData, response,
                 "https://www.nordnetdirekt.se/mux/inloggad/lib/login.html");
     }
@@ -117,8 +117,8 @@ public class Nordnetdirekt extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index b8174c7..eabb204 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -105,8 +105,8 @@ public class OKQ8 extends Bank {
         postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
         postData.add(new BasicNameValuePair("n_bank", ""));
         postData.add(new BasicNameValuePair("empty_pwd", ""));
-        postData.add(new BasicNameValuePair("user_id", username.toUpperCase()));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("user_id", getUsername().toUpperCase()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         return new LoginPackage(urlopen, postData, response,
                 "https://nettbank.edb.com/Logon/logon/step1");
     }
@@ -168,8 +168,8 @@ public class OKQ8 extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         if (response == null) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index ce3e44e..e1765bf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -92,8 +92,8 @@ public class Ostgotatrafiken extends Bank {
                 R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview));
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("Username", username));
-        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("Username", getUsername()));
+        postData.add(new BasicNameValuePair("Password", getPassword()));
         postData.add(new BasicNameValuePair("Login", "Logga in"));
 
         return new LoginPackage(urlopen, postData, response, URL);
@@ -112,8 +112,8 @@ public class Ostgotatrafiken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 1229ce2..8d0ced9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -87,8 +87,8 @@ public class Osuuspankki extends Bank {
         postData.add(new BasicNameValuePair("REQUEST_PREVIOUS_QUERYSTRING", ""));
         postData.add(new BasicNameValuePair("x", "24"));
         postData.add(new BasicNameValuePair("y", "5"));
-        postData.add(new BasicNameValuePair("USERNAME", username));
-        postData.add(new BasicNameValuePair("PWD", password));
+        postData.add(new BasicNameValuePair("USERNAME", getUsername()));
+        postData.add(new BasicNameValuePair("PWD", getPassword()));
 
         return new LoginPackage(urlopen, postData, response, "https://www.op.fi/op?kielikoodi=sv");
     }
@@ -107,8 +107,8 @@ public class Osuuspankki extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 2358cef..01cf099 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -99,8 +99,8 @@ public class PayPal extends Bank {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_paypal));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("email", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("email", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("ul-submit-cookied", "Logga in"));
         urlopen.addHeader("Origin",ORIGIN_URL);
         urlopen.addHeader("Referer", REFERER_URL);
@@ -119,8 +119,8 @@ public class PayPal extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index e9b6650..554f202 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -95,8 +95,8 @@ public class Payson extends Bank {
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__RequestVerificationToken", verificationToken));
-        postData.add(new BasicNameValuePair("Username", username));
-        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("Username", getUsername()));
+        postData.add(new BasicNameValuePair("Password", getPassword()));
         postData.add(new BasicNameValuePair("RedirectAfterLogin", ""));
         return new LoginPackage(urlopen, postData, response,
                 "https://www.payson.se/myaccount/account/SignIn/");
@@ -118,8 +118,8 @@ public class Payson extends Bank {
     @Override
     public void update() throws BankChoiceException, BankException, LoginException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index be949bc..397920f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -87,8 +87,8 @@ public class PlusGirot extends Bank {
         response = urlopen.open("https://kontoutdrag.plusgirot.se/ku/html/epostllg.htm");
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("KONTO", username));
-        postData.add(new BasicNameValuePair("PIN_KOD", password));
+        postData.add(new BasicNameValuePair("KONTO", getUsername()));
+        postData.add(new BasicNameValuePair("PIN_KOD", getPassword()));
         return new LoginPackage(urlopen, postData, response,
                 "https://kontoutdrag.plusgirot.se/ku/bgya006/init");
     }
@@ -106,8 +106,8 @@ public class PlusGirot extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index 3c863cb..be13d59 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -75,8 +75,8 @@ public class ResursBank extends Bank {
                 CertificateReader.getCertificates(context, R.raw.cert_resursbank));
         response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("kontonummer", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("kontonummer", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("page", "privat"));
         return new LoginPackage(urlopen, postData, response,
                 "https://secure.resurs.se/internetbank/login.jsp");
@@ -96,8 +96,8 @@ public class ResursBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 9f66217..189d66c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -101,8 +101,8 @@ public class SevenDay extends Bank {
         postData.add(new BasicNameValuePair("loginForm", "loginForm"));
         postData.add(new BasicNameValuePair("login", "login"));
         postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
-        postData.add(new BasicNameValuePair("ssn", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("ssn", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
 
         return new LoginPackage(urlopen, postData, response,
                 "https://www.sevenday.se/mina-sidor/mina-sidor.htm");
@@ -122,8 +122,8 @@ public class SevenDay extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index a08836c..7c99e9a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -109,8 +109,8 @@ public class Skandiabanken extends Bank {
 
         String loginUrl = getBaseUrlWithCustomerOwner() + "/login";
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
 
         try {
             String loginResponse = urlopen.open(loginUrl, postData);
@@ -151,8 +151,8 @@ public class Skandiabanken extends Bank {
             BankChoiceException, IOException {
         super.update();
 
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index a9d7ccf..052083c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -92,8 +92,8 @@ public class Steam extends Bank {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_steam));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("redir", "account"));
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         return new LoginPackage(urlopen, postData, null, "https://store.steampowered.com/login/");
     }
 
@@ -114,8 +114,8 @@ public class Steam extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index f0df829..41bac2c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -97,8 +97,8 @@ public class SveaDirekt extends Bank {
         String strLoginUrl = LOGIN_URL;
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("j_username", username));
-        postData.add(new BasicNameValuePair("j_password", password));
+        postData.add(new BasicNameValuePair("j_username", getUsername()));
+        postData.add(new BasicNameValuePair("j_password", getPassword()));
         return new LoginPackage(urlopen, postData, response, strLoginUrl);
     }
 
@@ -116,8 +116,8 @@ public class SveaDirekt extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 0f665a6..dc16abc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -92,7 +92,7 @@ public class SvenskaSpel extends Bank {
         LoginPackage lp = preLogin();
 
         StringEntity postdata = new StringEntity(
-                "{\"userName\":\"" + username + "\",\"password\":\"" + password + "\"}");
+                "{\"userName\":\"" + getUsername() + "\",\"password\":\"" + getPassword() + "\"}");
         HttpResponse httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), postdata, true);
 
         if (httpResponse.getStatusLine().getStatusCode() != 200) {
@@ -105,8 +105,8 @@ public class SvenskaSpel extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index fba7ebe..c7b4fb1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -90,8 +90,8 @@ public class TestBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index c6369f6..cc3caca 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -114,10 +114,10 @@ public class TicketRikskortet extends Bank {
                 "ctl00$CorporateHeaderArea$CorporateHeaderID$QuickSearch$SearchText", "Sök här"));
         postData.add(
                 new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$UserName",
-                        username));
+                        getUsername()));
         postData.add(
                 new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$Password",
-                        password));
+                        getPassword()));
         postData.add(new BasicNameValuePair(
                 "ctl00$StartpageArea$ApplicationArea$LoginControl$LoginButton", "Logga in"));
         return new LoginPackage(urlopen, postData, response, URL);
@@ -135,8 +135,8 @@ public class TicketRikskortet extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 41e39c8..2bd6a5b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -94,8 +94,8 @@ public class TrustBuddy extends Bank {
                 CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
         urlopen.setAllowCircularRedirects(true);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("logon", "Logga in"));
         return new LoginPackage(urlopen, postData, null, "https://trustbuddy.com/se/logga_in/");
     }
@@ -118,8 +118,8 @@ public class TrustBuddy extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index ae6e70d..1d90f79 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -96,10 +96,10 @@ public class Vasttrafik extends Bank {
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair(
                 "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxUserName",
-                username));
+                getUsername()));
         postData.add(new BasicNameValuePair(
                 "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxPassword",
-                password));
+                getPassword()));
         postData.add(new BasicNameValuePair(
                 "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$CheckBoxPersistent",
                 "on"));
@@ -124,8 +124,8 @@ public class Vasttrafik extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 9b17449..93ee0c4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -154,8 +154,8 @@ public class Villabanken extends Bank {
         postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "accountNumber"), username));
-        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "password"), password));
+        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "accountNumber"), getUsername()));
+        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "password"), getPassword()));
         postData.add(new BasicNameValuePair(ctl00, "Logga in"));
         postData.add(new BasicNameValuePair("__spDummyText1", ""));
         postData.add(new BasicNameValuePair("__spDummyText2", ""));
@@ -180,8 +180,8 @@ public class Villabanken extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index ba0453b..87d30c9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -100,8 +100,8 @@ public class Volvofinans extends Bank {
                 R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
         postData.add(new BasicNameValuePair("TARGET",
                 "https://inloggad.volvofinans.se/privat/inloggning/redirect.html"));
         postData.add(new BasicNameValuePair("REFERER",
@@ -129,8 +129,8 @@ public class Volvofinans extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index e44bd76..8306df3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -104,9 +104,9 @@ public class Zidisha extends Bank {
         String user_guess = mUserGuess.group(1);
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
-        postData.add(new BasicNameValuePair("textpassword", username));
+        postData.add(new BasicNameValuePair("username", getUsername()));
+        postData.add(new BasicNameValuePair("password", getPassword()));
+        postData.add(new BasicNameValuePair("textpassword", getUsername()));
         postData.add(new BasicNameValuePair("userlogin", ""));
         postData.add(new BasicNameValuePair("user_guess", user_guess));
         return new LoginPackage(urlopen, postData, response, "https://www.zidisha.org/process.php");
@@ -121,8 +121,8 @@ public class Zidisha extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index fa5389f..4827fb9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -75,8 +75,8 @@ public class Avanza extends Bank {
                 CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("Referer", URL + "/start");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("j_username", username));
-        postData.add(new BasicNameValuePair("j_password", password));
+        postData.add(new BasicNameValuePair("j_username", getUsername()));
+        postData.add(new BasicNameValuePair("j_password", getPassword()));
         postData.add(new BasicNameValuePair("url", URL + "/start"));
         String response = urlopen.open(URL + "/ab/handlelogin", postData);
         String homeUrl = "";
@@ -97,7 +97,7 @@ public class Avanza extends Bank {
                 CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
-                new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+                new String(getUsername() + ":" + getPassword()).getBytes(), Base64.NO_WRAP));
         balance = new BigDecimal(0);
 
         try {
@@ -195,7 +195,7 @@ public class Avanza extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
+        if (TextUtils.isEmpty(getUsername()) || TextUtils.isEmpty(getPassword())) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index f78cfbe..32ab7d9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -82,7 +82,7 @@ public class Bitcoin extends Bank {
         urlopen = new Urllib(context);
 
         try {
-            String response = urlopen.open(API_URL + username);
+            String response = urlopen.open(API_URL + getUsername());
             if (response == null || "".equals(response)) {
                 throw new LoginException(res.getText(
                         R.string.invalid_username_password).toString());
@@ -91,7 +91,7 @@ public class Bitcoin extends Bank {
             vObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
             vObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
             BlockchainResponse r = vObjectMapper.readValue(
-                    urlopen.open(API_URL + username), BlockchainResponse.class);
+                    urlopen.open(API_URL + getUsername()), BlockchainResponse.class);
             Account a = new Account("Bitcoin",
                     new BigDecimal(r.getFinalBalance()).divide(BigDecimal.valueOf(100000000)), "1");
             a.setCurrency("BTC");
@@ -109,7 +109,7 @@ public class Bitcoin extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(username)) {
+        if (TextUtils.isEmpty(getUsername())) {
             throw new LoginException(res.getText(
                     R.string.invalid_bitcoin_address).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 009720c..3f404a5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -107,8 +107,8 @@ public class Coop extends Bank {
         urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
         HttpResponse httpResponse = urlopen
                 .openAsHttpResponse("https://www.coop.se/Personliga-Baren/Logga-in/?method=Login",
-                        new StringEntity("{\"isBar\":\"true\",\"username\":\"" + username
-                                + "\",\"password\":\"" + password + "\"}"),
+                        new StringEntity("{\"isBar\":\"true\",\"username\":\"" + getUsername()
+                                + "\",\"password\":\"" + getPassword() + "\"}"),
                         true);
         urlopen.removeHeader("X-Requested-With");
         LoginPackage lp = new LoginPackage(urlopen, null, response,
@@ -131,8 +131,8 @@ public class Coop extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index 372e6c2..f996e7c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -89,7 +89,7 @@ public class ICA extends Bank {
         urlopen.addHeader("Accept", "application/json;charset=UTF-8");
         urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
-                new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+                new String(getUsername() + ":" + getPassword()).getBytes(), Base64.NO_WRAP));
 
         try {
             HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login",
@@ -183,7 +183,7 @@ public class ICA extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
+        if (TextUtils.isEmpty(getUsername()) || TextUtils.isEmpty(getPassword())) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index d09cd61..cc7d29f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -100,7 +100,7 @@ public class ICABanken extends Bank {
         urlopen.addHeader("ClientAppVersion", "777");
 
         String response = urlopen.open(String.format(
-                "%s/login/passwordlogin?customerId=%s&password=%s", API_URL, username, password));
+                "%s/login/passwordlogin?customerId=%s&password=%s", API_URL, getUsername(), getPassword()));
         if (response == null || "".equals(response)) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
@@ -120,8 +120,8 @@ public class ICABanken extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(
                     R.string.invalid_username_password).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 8a08bbb..841a2aa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -138,8 +138,8 @@ public class Lansforsakringar extends Bank {
         String loginToken = matcher.group(1);
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("login:userId", username));
-        postData.add(new BasicNameValuePair("login:pin", password));
+        postData.add(new BasicNameValuePair("login:userId", getUsername()));
+        postData.add(new BasicNameValuePair("login:pin", getPassword()));
         postData.add(new BasicNameValuePair("login", "login"));
         postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
         postData.add(
@@ -166,7 +166,7 @@ public class Lansforsakringar extends Bank {
         urlopen.addHeader("Ctoken", cr.getToken());
         try {
             LoginResponse lr = readJsonValue(API_BASEURL + "security/user",
-                    objectAsJson(new LoginRequest(username, password)), LoginResponse.class);
+                    objectAsJson(new LoginRequest(getUsername(), getPassword())), LoginResponse.class);
             urlopen.addHeader("Utoken", lr.getTicket());
         } catch (Exception e) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -227,8 +227,8 @@ public class Lansforsakringar extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 37eb265..dada087 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -267,8 +267,8 @@ public class Nordea extends Bank {
             postData.add(new BasicNameValuePair(name, value));
         }
         // Login information
-        postData.add(new BasicNameValuePair("userid", username));
-        postData.add(new BasicNameValuePair("pin", password));
+        postData.add(new BasicNameValuePair("userid", getUsername()));
+        postData.add(new BasicNameValuePair("pin", getPassword()));
         // Submit button is not contained within the form and thus cannot (should not) be found with the InputField matcher
         postData.add(new BasicNameValuePair("commonlogin$loginLight", "Logga in"));
         return new LoginPackage(urlopen, postData, this.lastResponse, LOGIN_URL);
@@ -288,8 +288,8 @@ public class Nordea extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index ff94126..0bf4c9f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -81,7 +81,7 @@ public class Rikslunchen extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (TextUtils.isEmpty(username)) {
+        if (TextUtils.isEmpty(getUsername())) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         try {
@@ -92,7 +92,7 @@ public class Rikslunchen extends Bank {
             urlopen.addHeader("Content-Type", "text/xml;charset=UTF-8");
             StringEntity body = new StringEntity(String.format(
                     "<v:Envelope xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:v=\"http://schemas.xmlsoap.org/soap/envelope/\"><v:Header /><v:Body><n0:getBalance id=\"o0\" c:root=\"1\" xmlns:n0=\"urn:PhoneService\"><cardNo i:type=\"d:string\">%s</cardNo></n0:getBalance></v:Body></v:Envelope>",
-                    username), "UTF-8");
+                    getUsername()), "UTF-8");
             InputStream is = urlopen.openStream("https://www.rikslunchen.se/rkchws/PhoneService",
                     body, true);
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index ae8d957..e9bb0af 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -109,8 +109,8 @@ public class SEB extends Bank {
         urlopen.setKeepAliveTimeout(5);
         //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("A1", username));
-        postData.add(new BasicNameValuePair("A2", password));
+        postData.add(new BasicNameValuePair("A1", getUsername()));
+        postData.add(new BasicNameValuePair("A2", getPassword()));
         postData.add(new BasicNameValuePair("A3", "4"));
         return new LoginPackage(urlopen, postData, response,
                 "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
@@ -123,8 +123,8 @@ public class SEB extends Bank {
                 CertificateReader.getCertificates(context, R.raw.cert_seb));
         urlopen.setFollowRedirects(false);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("A1", username));
-        postData.add(new BasicNameValuePair("A2", password));
+        postData.add(new BasicNameValuePair("A1", getUsername()));
+        postData.add(new BasicNameValuePair("A2", getPassword()));
         HttpResponse hr = urlopen.openAsHttpResponse(
                 "https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw",
                 postData, true);
@@ -141,8 +141,8 @@ public class SEB extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -152,7 +152,7 @@ public class SEB extends Bank {
 
         SEBRequest sessionRequest = new SEBRequest();
         Request r = new Request();
-        r.setUserCredentials(new UserCredentials(username, password));
+        r.setUserCredentials(new UserCredentials(getUsername(), getPassword()));
         ServiceInput serviceInput = new ServiceInput();
         serviceInput.setCondition("EQ");
         serviceInput.setVariableName("CUSTOMERTYPE");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 0f45e00..be3a5b7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -128,8 +128,8 @@ public abstract class SEBKortBase extends Bank {
         postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
         postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
         postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        postData.add(new BasicNameValuePair("UID", mProdgroup + username.toUpperCase()));
-        postData.add(new BasicNameValuePair("PASSWORD", password));
+        postData.add(new BasicNameValuePair("UID", mProdgroup + getUsername().toUpperCase()));
+        postData.add(new BasicNameValuePair("PASSWORD", getPassword()));
         postData.add(new BasicNameValuePair("mProdgroup", mProdgroup));
         postData.add(mParamsTarget);
         postData.add(mParamsErrorTarget);
@@ -167,8 +167,8 @@ public abstract class SEBKortBase extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 6e1ac0b..db75e84 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -99,7 +99,7 @@ public abstract class AbstractSwedbank extends Bank {
         try {
             LoginPackage lp = preLogin();
             httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(),
-                    new StringEntity(objectAsJson(new PersonalCodeRequest(username, password)),
+                    new StringEntity(objectAsJson(new PersonalCodeRequest(getUsername(), getPassword())),
                             HTTP.UTF_8), true);
             int responseCode = httpResponse.getStatusLine().getStatusCode();
             if (responseCode == 201) {
@@ -144,8 +144,8 @@ public abstract class AbstractSwedbank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0
-                || password.length() == 0) {
+        if (getUsername() == null || getPassword() == null || getUsername().length() == 0
+                || getPassword().length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();

commit 385bd52b6e026ab5f4e80b98fb45020f0b4ed356 (tag: v1.9.9.2)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 16 20:30:35 2015 +0200

    Creates release 1.9.9.2

diff --git CHANGELOG CHANGELOG
index 3ce8f7e..63c4f38 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,6 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-v1.9.9.2 (unreleased)
+v1.9.9.2 (2015-04-16)
 * Updates certificates for AmericanExpress, MinPension, Swedbank and Sparbankerna
 * Adapt to new URLs used by Ticket Rikskortet
 * Fixes application crash for Samsung devices running Android 4.2
diff --git app/build.gradle app/build.gradle
index 6a8f890..cbd10a3 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 211
-        versionName "1.9.9.1"
+        versionCode 212
+        versionName "1.9.9.2"
     }
 
     signingConfigs {

commit a2f3463896bdfcec6d656ed4350fb3ebc7aed165
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 16 20:29:07 2015 +0200

    Updates certificate for Swedbank

diff --git CHANGELOG CHANGELOG
index 03c8d52..3ce8f7e 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,7 +1,7 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 v1.9.9.2 (unreleased)
-* Updates certificates for AmericanExpress, MinPension
+* Updates certificates for AmericanExpress, MinPension, Swedbank and Sparbankerna
 * Adapt to new URLs used by Ticket Rikskortet
 * Fixes application crash for Samsung devices running Android 4.2
 
diff --git bankdroid-legacy/src/main/res/raw/cert_swedbank.pem bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
index 4097e2a..de1da63 100644
--- bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
+++ bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
@@ -1,32 +1,30 @@
 -----BEGIN CERTIFICATE-----

-EhN57wT5

+0UQR4Q6bOkPvbFXCMH5TXVONTkI33QMTEiUZ3hg=
 -----END CERTIFICATE-----
 auth.api.swedbank.se:443

commit e16aa05f6431312a9d4a79e51c3d8f70c7b4a9e3
Merge: 1a9228c e1099fc
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Apr 16 10:45:28 2015 +0200

    Merge pull request #542 from liato/feature/checkstyle-fixes
    
    Replaces tab characters with 4 spaces in whole project.

commit 1a9228c5d4989bfa57051b8784610021870d7f89
Merge: 0bf7929 00bda72
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Apr 16 10:44:41 2015 +0200

    Merge pull request #541 from liato/feature/540-appcompat-issue
    
    Fixes NoClassDefFoundException for Samsung devices running 4.2

commit e1099fc6536ff12c085fcad1249f94f5826e652d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Apr 12 22:07:09 2015 +0200

    Replaces tab characters with 4 spaces in whole project.

diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index 988ed85..07bfccf 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -53,9 +53,9 @@ public class LockableActivity extends ActionBarActivity {
 
     private boolean mHasLoaded = false;
 
-    //	private LinearLayout mTitlebarButtons;
+    //    private LinearLayout mTitlebarButtons;
     private LayoutInflater mInflater;
-//	private ProgressBar mProgressBar;
+//    private ProgressBar mProgressBar;
 
 //    private ImageView mHomeButton;
 //    private View mHomeButtonCont;
@@ -117,7 +117,7 @@ public class LockableActivity extends ActionBarActivity {
 //        child.setTag("item_"+tag);
 //        button.setOnClickListener(listener);
 //        mTitlebarButtons.addView(child);
-//	}
+//    }
 //
 //    protected void hideTitleButton(String tag) {
 //        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
@@ -188,15 +188,15 @@ public class LockableActivity extends ActionBarActivity {
         }
         /*
                 Save the current time If a lock pattern has been set
-		If this activity never loaded set the lock time to
-		10 seconds ago.
-		This is to prevent the following scenario:
-		    1. Activity Starts 
-		    2. Lock screen is displayed
+        If this activity never loaded set the lock time to
+        10 seconds ago.
+        This is to prevent the following scenario:
+            1. Activity Starts
+            2. Lock screen is displayed
             3. User presses the home button
             4. "lock time" is set in onPause to when the home button was pressed
             5. Activity is started again within 2 seconds and no lock screen is shown this time.
-	    */
+        */
         if (mHasLoaded) {
             writeLockTime();
         } else {
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 42d41a0..7487741 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -147,11 +147,11 @@ public class MainActivity extends LockableActivity {
         final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
         if (banks.size() > 0) {
             findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-//			showTitleButton("refresh");
+//            showTitleButton("refresh");
             //findViewById(R.id.btnAccountsRefresh).setClickable(true);
         } else {
             findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
-//			hideTitleButton("refresh");
+//            hideTitleButton("refresh");
             //findViewById(R.id.btnAccountsRefresh).setClickable(false);
         }
 
@@ -422,4 +422,4 @@ public class MainActivity extends LockableActivity {
         }
     }
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index 32af907..69f9268 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -65,7 +65,7 @@ public class PairApplicationsActivity extends LockableActivity {
     protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.pair_applications_layout);
-//		setHomeButtonEnabled(false);
+//        setHomeButtonEnabled(false);
 
         Bundle bundle = getIntent().getExtras();
 
diff --git app/src/main/java/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
index bf45758..bd8398a 100644
--- app/src/main/java/com/liato/bankdroid/SettingsActivity.java
+++ app/src/main/java/com/liato/bankdroid/SettingsActivity.java
@@ -200,4 +200,4 @@ public class SettingsActivity extends LockablePreferenceActivity
         return false;
     }
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/StartupReceiver.java app/src/main/java/com/liato/bankdroid/StartupReceiver.java
index 355d95c..b550441 100644
--- app/src/main/java/com/liato/bankdroid/StartupReceiver.java
+++ app/src/main/java/com/liato/bankdroid/StartupReceiver.java
@@ -77,4 +77,4 @@ public class StartupReceiver extends BroadcastReceiver {
             setAlarm(context);
         }
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/TimePreference.java app/src/main/java/com/liato/bankdroid/TimePreference.java
index 654ccd3..44586c5 100644
--- app/src/main/java/com/liato/bankdroid/TimePreference.java
+++ app/src/main/java/com/liato/bankdroid/TimePreference.java
@@ -69,4 +69,4 @@ public class TimePreference extends DialogPreference {
 
         lastValue = val;
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index 2e102b5..d2584f1 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -231,4 +231,4 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
 //            activity.setTitleButtonEnabled("forward", mWebView.canGoForward());
         }
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
index 52263ce..a4169f5 100644
--- app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -68,13 +68,13 @@ public class AccountsAdapter extends BaseAdapter {
         this.banks = banks;
                 /*for (Bank b : this.banks) {
                     ArrayList<Account> as = b.getAccounts();
-		    for (Account a : as) {
-		        if (a.isHidden() && !showHidden) {
-		            as.remove(a);
-		        }
-		            
-		    }
-		}*/
+            for (Account a : as) {
+                if (a.isHidden() && !showHidden) {
+                    as.remove(a);
+                }
+
+            }
+        }*/
     }
 
     public boolean isShowHidden() {
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
index 6e5578b..478d6f3 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
@@ -19,4 +19,4 @@ package com.liato.bankdroid.appwidget;
 
 public class BankdroidWidgetProvider_2x1 extends BankdroidWidgetProvider {
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/db/Crypto.java app/src/main/java/com/liato/bankdroid/db/Crypto.java
index a0bfb75..e87153c 100644
--- app/src/main/java/com/liato/bankdroid/db/Crypto.java
+++ app/src/main/java/com/liato/bankdroid/db/Crypto.java
@@ -13,14 +13,14 @@ public class Crypto {
     public final static String getKey() {
                 /*
                  * Manipulate the key before returning it.
-		 * 
-		 * ...
-		 * 
-		 * Code omitted.
-		 * 
-		 * ...
-		 * 
-		 */
+         *
+         * ...
+         *
+         * Code omitted.
+         *
+         * ...
+         *
+         */
 
         return KEY;
     }
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
index a9db8a0..af3be15 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
@@ -70,4 +70,4 @@ public final class PluginConstants {
 
     private PluginConstants() {
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
index 4ece0a1..d31170f 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -87,4 +87,4 @@ public class PluginReceiver extends BroadcastReceiver {
 
     }
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
index 181a7ca..2a1927c 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
@@ -108,4 +108,4 @@ public final class PluginUtils {
         int resourceId = getDynamicResourceId(context, resourceName, "string");
         return context.getString(resourceId);
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
index 8ad02eb..88e3650 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
@@ -129,4 +129,4 @@ public class AlphaPatternDrawable extends Drawable {
 
     }
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
index f445cfd..75613e7 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -90,11 +90,11 @@ public class ColorPickerDialog
 
         mNewColor.setColor(color);
 
-		/*
+        /*
                 if (mListener != null) {
-			mListener.onColorChanged(color);
-		}
-		*/
+            mListener.onColorChanged(color);
+        }
+        */
 
     }
 
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
index 5a2d72d..d393f94 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
@@ -168,4 +168,4 @@ public class ColorPickerPanelView extends View {
         invalidate();
     }
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
index 9ba4365..66cc01a 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -251,4 +251,4 @@ public class ColorPickerPreference
         mAlphaSliderEnabled = enable;
     }
 
-}
\ No newline at end of file
+}
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
index 87b32b1..66a7c4d 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -889,11 +889,11 @@ public class ColorPickerView extends View {
         if (mShowAlphaPanel != visible) {
             mShowAlphaPanel = visible;
 
-			/*
+            /*
                          * Reset all shader to force a recreation.
-			 * Otherwise they will not look right after
-			 * the size of the view has changed.
-			 */
+             * Otherwise they will not look right after
+             * the size of the view has changed.
+             */
             mValShader = null;
             mSatShader = null;
             mHueShader = null;
@@ -952,4 +952,4 @@ public class ColorPickerView extends View {
 
         public void onColorChanged(int color);
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
index 8fdaeb4..2c2d817 100644
--- app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
+++ app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -102,4 +102,4 @@ public class SimpleCrypto {
         sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 9c1c784..db2d9d5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -156,18 +156,18 @@ public class AkeliusInvest extends Bank {
         while (matcher.find()) {
             /*
              * Capture groups:
-             * GROUP                ICA					AKELIUSINVEST
-             * 1: ID                0000000000			Kontonamn
-             * 2: Name              ICA KONTO			KontoID
-             * 3: Disponibelt       00.000,00			Kontonummer
-             * 4: Saldo             1.655,71			Valuta
-             * 5: 										Tillgängligt belopp
-             * 6: 										Saldo
+             * GROUP                ICA                    AKELIUSINVEST
+             * 1: ID                0000000000            Kontonamn
+             * 2: Name              ICA KONTO            KontoID
+             * 3: Disponibelt       00.000,00            Kontonummer
+             * 4: Saldo             1.655,71            Valuta
+             * 5:                                         Tillgängligt belopp
+             * 6:                                         Saldo
              */
-//			Försök att lösa problemet med för långa, icke radbrytande kontonamn:
-//				if (matcher.group(1).length() > 24)  {
-//					matcher.group(1).replaceFirst("(", "(\n");
-//				}
+//            Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//                if (matcher.group(1).length() > 24)  {
+//                    matcher.group(1).replaceFirst("(", "(\n");
+//                }
 
             mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());
             accounts.add(new Account(
@@ -202,11 +202,11 @@ public class AkeliusInvest extends Bank {
                 .open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="
                         + accountId);
         matcher = reTransactions.matcher(response);
-                /* 				ICA-banken	Akelius Invest
-		 * Beskrivning	1			2
-		 * Datum		2			1
-		 * Belopp		3			3
-		 */
+                /*                 ICA-banken    Akelius Invest
+         * Beskrivning    1            2
+         * Datum        2            1
+         * Belopp        3            3
+         */
 
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index c8a84fe..b7231ed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -158,18 +158,18 @@ public class AkeliusSpar extends Bank {
         while (matcher.find()) {
             /*
              * Capture groups:
-             * GROUP                ICA					AKELIUSINVEST
-             * 1: ID                0000000000			Kontonamn
-             * 2: Name              ICA KONTO			KontoID
-             * 3: Disponibelt       00.000,00			Kontonummer
-             * 4: Saldo             1.655,71			Valuta
-             * 5: 										Tillgängligt belopp
-             * 6: 										Saldo
+             * GROUP                ICA                    AKELIUSINVEST
+             * 1: ID                0000000000            Kontonamn
+             * 2: Name              ICA KONTO            KontoID
+             * 3: Disponibelt       00.000,00            Kontonummer
+             * 4: Saldo             1.655,71            Valuta
+             * 5:                                         Tillgängligt belopp
+             * 6:                                         Saldo
              */
-//			Försök att lösa problemet med för långa, icke radbrytande kontonamn:
-//				if (matcher.group(1).length() > 24)  {
-//					matcher.group(1).replaceFirst("(", "(\n");
-//				}
+//            Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//                if (matcher.group(1).length() > 24)  {
+//                    matcher.group(1).replaceFirst("(", "(\n");
+//                }
 
             mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());
             accounts.add(new Account(
@@ -205,11 +205,11 @@ public class AkeliusSpar extends Bank {
                 .open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="
                         + accountId);
         matcher = reTransactions.matcher(response);
-                /* 				ICA-banken	Akelius Invest
-		 * Beskrivning	1			2
-		 * Datum		2			1
-		 * Belopp		3			3
-		 */
+                /*                 ICA-banken    Akelius Invest
+         * Beskrivning    1            2
+         * Datum        2            1
+         * Belopp        3            3
+         */
 
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index f34b1af..89a31f2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -189,7 +189,7 @@ public class DinersClub extends Bank {
         String response = null;
         Matcher matcher;
 
-		/* We're going to look at all the pages until we find one that has transactions on it */
+        /* We're going to look at all the pages until we find one that has transactions on it */
         response = urlopen.open(
                 String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
         matcher = reTransactions.matcher(response);
@@ -197,13 +197,13 @@ public class DinersClub extends Bank {
 
         while (matcher.find()) {
                         /*
-			 * Capture groups:
-			 * GROUP				EXAMPLE DATA
-			 * 1: Trans. date		2010-10-06
-			 * 2: Specifications	Skyways Express Ab
-			 * 3: Foreign amount	30,30 EUR
-			 * 4: Amount			2.462,00 kr
-			 */
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Trans. date        2010-10-06
+             * 2: Specifications    Skyways Express Ab
+             * 3: Foreign amount    30,30 EUR
+             * 4: Amount            2.462,00 kr
+             */
 
             transactions.add(new Transaction(matcher.group(1), matcher.group(2),
                     Helpers.parseBalance(matcher.group(4))));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 80a4b75..0603275 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -121,14 +121,14 @@ public class FirstCard extends Bank {
         response = urlopen.open("https://www.firstcard.se/mkol/index.jsp");
         Matcher matcher = reAccounts.matcher(response);
         while (matcher.find()) {
-                        /*
-			 * Capture groups:
-			 * GROUP				EXAMPLE DATA
-			 * 1: id				kdKPq4ghlcy9wpXymSzzS46wWQcS_0OT
-			 * 2: account number	1111 3333 7777 9999
-			 * 3: amount 			9 824,08
-			 *
-			 */
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: id                kdKPq4ghlcy9wpXymSzzS46wWQcS_0OT
+             * 2: account number    1111 3333 7777 9999
+             * 3: amount            9 824,08
+             *
+             */
             accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
                     Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
             balance = balance.add(Helpers.parseBalance(matcher.group(3)));
@@ -151,16 +151,16 @@ public class FirstCard extends Bank {
         Matcher matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
-			/*
-			 * Capture groups:
-			 * GROUP						EXAMPLE DATA
-			 * 1: date						101006
-			 * 2: specification				GOOGLE *RealArcade
-			 * 3: currency					USD
-			 * 4: amount					3,49
-			 * 5: amount in local currency	24,08
-			 *
-			 */
+            /*
+             * Capture groups:
+             * GROUP                        EXAMPLE DATA
+             * 1: date                      101006
+             * 2: specification             GOOGLE *RealArcade
+             * 3: currency                  USD
+             * 4: amount                    3,49
+             * 5: amount in local currency  24,08
+             *
+             */
             String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
             strDate = "20" + strDate.charAt(0) + strDate.charAt(1) + "-" + strDate.charAt(2)
                     + strDate.charAt(3) + "-" + strDate.charAt(4) + strDate.charAt(5);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index d36685f..ffb80c6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -197,23 +197,23 @@ public class Hemkop extends Bank {
         try {
             response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
             Document d = Jsoup.parse(response);
-        	Elements es = d.select(".transactions tbody tr");
+            Elements es = d.select(".transactions tbody tr");
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
             for (Element e : es) {
                 Transaction t = new Transaction(e.child(1).ownText().trim(),
-                					e.child(0).ownText().trim(),
+                                    e.child(0).ownText().trim(),
                         Helpers.parseBalance(e.child(3).ownText()));
                 if (!TextUtils.isEmpty(e.child(2).ownText())) {
                     t.setCurrency(Helpers.parseCurrency(e.child(2).ownText().trim(), "SEK"));
                 }
                 transactions.add(t);
-        	}
+            }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-        	e.printStackTrace();
+            e.printStackTrace();
             Log.e(TAG, e.getMessage() != null ? e.getMessage() : "");
         } catch (IOException e) {
-        	e.printStackTrace();
+            e.printStackTrace();
             Log.e(TAG,  e.getMessage() != null ? e.getMessage() : "");
         }
         finally {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index a1e1da2..bfa47ac 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -186,13 +186,13 @@ public class Marginalen extends Bank {
         matcher = reTransactions.matcher(response);
         while (matcher.find()) {
                 /*
-        	 * Capture groups:
-        	 * GROUP                    EXAMPLE DATA
-        	 * 1: Date                  2011-04-06
-        	 * 2: Specification         Pressbyran
-        	 * 3: Amount                -20
-        	 *
-        	 */
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Date                  2011-04-06
+             * 2: Specification         Pressbyran
+             * 3: Amount                -20
+             *
+             */
             transactions.add(new Transaction(matcher.group(1).trim(),
                     Html.fromHtml(matcher.group(2)).toString().trim(),
                     Helpers.parseBalance(matcher.group(3))));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index e86a6b8..b7398d0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -157,13 +157,13 @@ public class NordeaDK extends Bank {
         matcher.reset();
         while (matcher.find()) {
                         /*
-			 * Capture groups:
-			 * GROUP 		EXAMPLE DATA
-			 * 1: Link		https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
-			 * 2: ID 		0
-			 * 3: Name 		Check-in-konto
-			 * 4: Amount	1.234,56
-			 */
+             * Capture groups:
+             * GROUP         EXAMPLE DATA
+             * 1: Link        https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
+             * 2: ID         0
+             * 3: Name         Check-in-konto
+             * 4: Amount    1.234,56
+             */
             String name = Html.fromHtml(matcher.group(3)).toString().trim();
             String id = matcher.group(2).toString().trim();
             BigDecimal amount = Helpers.parseBalance(matcher.group(4));
@@ -223,13 +223,13 @@ public class NordeaDK extends Bank {
         }
 
         matcher = reTransactions.matcher(response);
-		/*
-		 * Capture groups:
-		 * GROUP 	EXAMPLE 	DATA
-		 * 1: 		Date 		29.07
-		 * 2: 		Transaction	Bgs Check-in-konto
-		 * 3: 		Amount 		906.56
-		 */
+        /*
+         * Capture groups:
+         * GROUP     EXAMPLE     DATA
+         * 1:         Date         29.07
+         * 2:         Transaction    Bgs Check-in-konto
+         * 3:         Amount         906.56
+         */
 
         while (matcher.find()) {
             String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index d6bd9a8..b8174c7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -122,14 +122,14 @@ public class OKQ8 extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
-			/*
-			 * After login ok we end up at an intermediate login page with a submit
-			 * form that contains information that must be passed to the next page:
-			 * <input type="hidden" name="so" value="xxx"/>
-			 * <input type="hidden" name="last_logon_time" value="xxx"/>
-			 * <input type="hidden" name="failed_logon_attempts" value="xxx"/>
-			 * <input type="hidden" name="login_service_url" value="xxx"/>
-			 */
+            /*
+             * After login ok we end up at an intermediate login page with a submit
+             * form that contains information that must be passed to the next page:
+             * <input type="hidden" name="so" value="xxx"/>
+             * <input type="hidden" name="last_logon_time" value="xxx"/>
+             * <input type="hidden" name="failed_logon_attempts" value="xxx"/>
+             * <input type="hidden" name="login_service_url" value="xxx"/>
+             */
         matcher = reLoginRedir.matcher(response);
         postData.clear();
         if (!matcher.find()) {
@@ -175,27 +175,27 @@ public class OKQ8 extends Bank {
         if (response == null) {
             urlopen = login();
         }
-		/*
-		 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
-		 * The balance is the first value (of three) that are matched by reBalance expression.
-		 */
+        /*
+         * The start page contains the balance of the account ("Kvar att utnytta") so read it.
+         * The balance is the first value (of three) that are matched by reBalance expression.
+         */
         Matcher matcher = reBalance.matcher(response);
         if (matcher.find()) {
             accounts.add(
                     new Account("Kvar att utnyttja", Helpers.parseBalance(matcher.group(1)), "1"));
             balance = balance.add(Helpers.parseBalance(matcher.group(1)));
         }
-		/*
-		 * Find the next value that is "Saldo". Add a new account but don't add to the balance.
-		 */
+        /*
+         * Find the next value that is "Saldo". Add a new account but don't add to the balance.
+         */
         if (matcher.find()) {
             accounts.add(new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "2"));
             accounts.add(
                     new Account("Saldo", Helpers.parseBalance(matcher.group(1)).negate(), "4"));
         }
-		/*
-		 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.
-		 */
+        /*
+         * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.
+         */
         if (matcher.find()) {
             accounts.add(new Account("Köpgräns", Helpers.parseBalance(matcher.group(1)), "3"));
         }
@@ -210,12 +210,12 @@ public class OKQ8 extends Bank {
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
-			/*
-			 * Capture group 1 = date
-			 * Capture group 2 = text
-			 * Capture group 3 = amount
-			 * Negate the amount since buys are reported as positive.
-			 */
+            /*
+             * Capture group 1 = date
+             * Capture group 2 = text
+             * Capture group 3 = amount
+             * Negate the amount since buys are reported as positive.
+             */
             transactions.add(new Transaction(matcher.group(1).trim(),
                     Html.fromHtml(matcher.group(2)).toString().trim(),
                     Helpers.parseBalance(matcher.group(3)).negate()));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 688056c..a9d7ccf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -137,15 +137,15 @@ public class Steam extends Bank {
             matcher = reTransactions.matcher(response);
             while (matcher.find()) {
                     /*
-	             * Capture groups:
-	             * GROUP                EXAMPLE DATA
-	             * 1: Date              18 Oct 2007
-	             * 2: Amount            0,99&#8364;
-	             * 3: Event             Purchase
-	             * 4: Item              Team Fortress 2&nbsp;
-	             * 5: Sub item          Mann Co. Supply Crate Key
-	             * 
-	             */
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Date              18 Oct 2007
+                 * 2: Amount            0,99&#8364;
+                 * 3: Event             Purchase
+                 * 4: Item              Team Fortress 2&nbsp;
+                 * 5: Sub item          Mann Co. Supply Crate Key
+                 *
+                 */
                 SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
                 SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
                 Date transactionDate;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 6321814..0f665a6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -114,11 +114,11 @@ public class SvenskaSpel extends Bank {
         Matcher matcher = reBalance.matcher(response);
         if (matcher.find()) {
                         /*
-			 * Capture groups:
-			 * GROUP                    EXAMPLE DATA
-			 * 1: balance               845
-			 *
-			 */
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: balance               845
+             *
+             */
             Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "1");
             balance = Helpers.parseBalance(matcher.group(1));
             balance = balance.add(Helpers.parseBalance(matcher.group(1)));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index ff3b0ed..e44bd76 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -133,11 +133,11 @@ public class Zidisha extends Bank {
 
         while (matcher.find()) {
                         /*
-			 * 1: Funds uploaded
-			 * 2: Available for withdrawal
-			 * 3: Lent by me
-			 * 4: Total Impact
-			 */
+             * 1: Funds uploaded
+             * 2: Available for withdrawal
+             * 3: Lent by me
+             * 4: Total Impact
+             */
             Account insattningar = new Account("Insättningar",
                     Helpers.parseBalance(matcher.group(1)), "insattningar");
             Account tillgangligt = new Account("Tillgängligt",
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
index 68ecf0a..114b003 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
@@ -171,4 +171,4 @@ public class Account implements Serializable {
         return mPositionAggregations;
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
index 35a0be0..19ac97f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
@@ -27,4 +27,4 @@ public class AccountOverview implements Serializable {
         return mAccounts;
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
index 5c943a3..5bb5cbe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
@@ -104,4 +104,4 @@ public class Account {
         this.transactions = transactions;
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
index 3d90c33..460dcd5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
@@ -37,4 +37,4 @@ public class AccountsRequest {
         }
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
index 494312a..c12b46a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
@@ -125,4 +125,4 @@ public class Account {
         mBalance = b;
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
index fd9132e..e61bfa0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
@@ -19,4 +19,4 @@ public class AccountsResponse {
         mAccounts = a;
     }
 
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
index 36dc047..cbef72f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
@@ -5,18 +5,18 @@ import org.simpleframework.xml.Root;
 
 /*
 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
-	<soap:Body>
-		<ns2:getBalanceResponse xmlns:ns2="urn:PhoneService">
-			<return>
-				<amount>1101.14</amount>
-				<lastTopUpDate>2014-01-01</lastTopUpDate>
-			</return>
-		</ns2:getBalanceResponse>
-		<soap:Fault>
-			<faultcode>soap:Server</faultcode>
-			<faultstring>card for 48565643 cannot be found!</faultstring>
-		</soap:Fault>
-	</soap:Body>
+    <soap:Body>
+        <ns2:getBalanceResponse xmlns:ns2="urn:PhoneService">
+            <return>
+                <amount>1101.14</amount>
+                <lastTopUpDate>2014-01-01</lastTopUpDate>
+            </return>
+        </ns2:getBalanceResponse>
+        <soap:Fault>
+            <faultcode>soap:Server</faultcode>
+            <faultstring>card for 48565643 cannot be found!</faultstring>
+        </soap:Fault>
+    </soap:Body>
 </soap:Envelope>
  */
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index 3e824e1..0d3dd84 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -39,7 +39,7 @@ import java.math.BigDecimal;
  *
  * <pre>
  * final Uri uri = Uri.parse(&quot;content://&quot; + AUTHORITY + &quot;/&quot; + TRANSACTIONS_CAT
- * 		+ &quot;/&quot; + API_KEY + apiKey);
+ *         + &quot;/&quot; + API_KEY + apiKey);
  * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION, ACCOUNT_SELECTION_FILTER, new
  * String[] { currentAccountId }, null);
  * startManagingCursor(cur);

commit 00bda7263e243f6b3345c57412d9e7207e59b03b
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Apr 11 00:46:10 2015 +0200

    Fixes NoClassDefFoundException for Samsung devices running 4.2

diff --git CHANGELOG CHANGELOG
index 07ddaad..03c8d52 100644
--- CHANGELOG
+++ CHANGELOG
@@ -3,6 +3,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 v1.9.9.2 (unreleased)
 * Updates certificates for AmericanExpress, MinPension
 * Adapt to new URLs used by Ticket Rikskortet
+* Fixes application crash for Samsung devices running Android 4.2
 
 v1.9.9.1 (2015-04-09)
 * Fixes application crash for Jojo accounts.
diff --git app/proguard-rules.pro app/proguard-rules.pro
index dbad36b..438bea8 100644
--- app/proguard-rules.pro
+++ app/proguard-rules.pro
@@ -18,3 +18,8 @@
 
 -keep class com.crashlytics.** { *; }
 -dontwarn com.crashlytics.**
+
+# Allow obfuscation of android.support.v7.internal.view.menu.**
+# to avoid problem on Samsung 4.2.2 devices with appcompat v21
+# see https://code.google.com/p/android/issues/detail?id=78377
+-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}

commit 0bf7929962ebedddbd5d4f17ed53377042d2a900
Merge: 52a44d0 07c8ff3
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 10 23:06:44 2015 +0200

    Merge pull request #539 from robho/remove_unused_certificate
    
    Removes unused certificate for Everydaycard

commit 52a44d01a0c035cbe8963a61130693fb3c394cc2
Merge: 2cc9151 139e7a5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 10 23:05:37 2015 +0200

    Merge pull request #538 from robho/fix_rikskortet
    
    Adapt to new URLs for Ticket Rikskortet

commit 139e7a57bedac9112af60dcd6b63f8c73e5d4e52
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Fri Apr 10 21:10:00 2015 +0200

    Adapt to new URLs for Ticket Rikskortet

diff --git CHANGELOG CHANGELOG
index 5f523f1..07ddaad 100644
--- CHANGELOG
+++ CHANGELOG
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
 
 v1.9.9.2 (unreleased)
 * Updates certificates for AmericanExpress, MinPension
+* Adapt to new URLs used by Ticket Rikskortet
 
 v1.9.9.1 (2015-04-09)
 * Fixes application crash for Jojo accounts.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 30279eb..c6369f6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -48,7 +48,11 @@ public class TicketRikskortet extends Bank {
 
     private static final String NAME_SHORT = "rikskortet";
 
-    private static final String URL = "https://www.edenred.se/sv/System/Logga-in/";
+    private static final String URL = "https://www.edenred.se/rikskuponger/mina-sidor/logga-in/";
+
+    private static final String URL_OVERVIEW = "https://www.edenred.se/rikskuponger/mina-sidor/employee/start/";
+
+    private static final String URL_TRANSACTIONS = "https://www.edenred.se/rikskuponger/mina-sidor/employee/start/transaktioner/";
 
     private static final int BANKTYPE_ID = Bank.RIKSKORTET;
 
@@ -86,7 +90,7 @@ public class TicketRikskortet extends Bank {
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
-        response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
+        response = urlopen.open(URL);
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(
@@ -116,8 +120,7 @@ public class TicketRikskortet extends Bank {
                         password));
         postData.add(new BasicNameValuePair(
                 "ctl00$StartpageArea$ApplicationArea$LoginControl$LoginButton", "Logga in"));
-        return new LoginPackage(urlopen, postData, response,
-                "https://www.edenred.se/sv/System/Logga-in/");
+        return new LoginPackage(urlopen, postData, response, URL);
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
@@ -137,9 +140,8 @@ public class TicketRikskortet extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        if (!"https://www.edenred.se/sv/Apps/Employee/Start/".equalsIgnoreCase(
-                urlopen.getCurrentURI())) {
-            response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/");
+        if (!urlopen.getCurrentURI().equalsIgnoreCase(URL_OVERVIEW)) {
+            response = urlopen.open(URL_OVERVIEW);
         }
 
         Matcher matcher = reBalance.matcher(response);
@@ -166,8 +168,7 @@ public class TicketRikskortet extends Bank {
         super.updateTransactions(account, urlopen);
 
         Matcher matcher;
-        String response = urlopen.open(
-                "https://www.edenred.se/sv/Apps/Employee/Start/Transaktioner/");
+        String response = urlopen.open(URL_TRANSACTIONS);
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 

commit 07c8ff340184d8a498c1f50ad985b57de8b1e16b
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Fri Apr 10 22:18:05 2015 +0200

    Everydaycard certificate is unused -> remove
    
    Bankdroid stopped using https for Everydaycard years ago (2012-09-20, in
    c8662e20583910bec177666aacf45ba574f1395d). So, remove unused certificate and
    old, broken code that was left behind (although disabled).

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 10a9369..9e2c7ec 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -39,11 +39,8 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
-//import com.liato.bankdroid.banking.Transaction;
-
 public class Everydaycard extends Bank {
 
     private static final String TAG = "Everydaycard";
@@ -68,8 +65,6 @@ public class Everydaycard extends Bank {
             "Aktuell bonus \\(sek\\)</td>\\s*<td>.*</td>\\s*<td>([^<]+)<",
             Pattern.CASE_INSENSITIVE);
 
-    //	private Pattern reAccountTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-//	private Pattern reBonusTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private String response = null;
 
     public Everydaycard(Context context) {
@@ -94,14 +89,8 @@ public class Everydaycard extends Bank {
         return preLoginInternal("http://valuta.g2solutions.se/mobil/web/logonSubmit.do");
     }
 
-//    private LoginPackage preLoginNonMobile() throws BankException,
-//            ClientProtocolException, IOException {
-//    	return preLoginInternal("https://valuta.g2solutions.se/valuta/web/logonSubmit.do");
-//    }
-
     private LoginPackage preLoginInternal(String url) throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
+        urlopen = new Urllib(context);
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("nextPage", "firstPage"));
         postData.add(new BasicNameValuePair("username", username));
@@ -111,7 +100,6 @@ public class Everydaycard extends Bank {
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
-        //LoginPackage lp = preLoginNonMobile();
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
         if (response.contains("Felaktigt Login")) {
@@ -149,48 +137,4 @@ public class Everydaycard extends Bank {
         }
         super.updateComplete();
     }
-
-//	@Override
-//    public void updateAllTransactions() throws LoginException, BankException {
-//		if (urlopen == null) {
-//			urlopen = login();
-//        }
-//		try {
-//			response = urlopen.open("https://valuta.g2solutions.se/valuta/web/manageCustomer.do?action=account");
-//			for (Account account: accounts) {
-//				Matcher matcher;
-//				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-//            
-//				switch (account.getType()) {
-//				case Account.CCARD:
-//					matcher = reAccountTransactions.matcher(response);
-//					while (matcher.find()) {
-//						transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate()));
-//					}
-//					break;
-//				// Bonus account
-//				case Account.OTHER:
-//					matcher = reBonusTransactions.matcher(response);
-//					while (matcher.find()) {
-//						if (!matcher.group(4).equals("0,00")) {
-//							transactions.add(new Transaction(matcher.group(1), matcher.group(2) + " (-" + matcher.group(3) + ")", Helpers.parseBalance(matcher.group(4))));
-//						}
-//					}
-//					break;
-//				default:
-//					return;
-//				}
-//
-//				account.setTransactions(transactions);
-//			}
-//		} catch (ClientProtocolException e) {
-//			throw new BankException(e.getMessage());
-//		} catch (IOException e) {
-//			throw new BankException(e.getMessage());
-//		} finally {
-//			if (urlopen != null) {
-//				urlopen.close();
-//			}
-//        }
-//	}
 }
diff --git bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
deleted file mode 100644
index be37da2..0000000
--- bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
-valuta.g2solutions.se:443

commit 2cc91515f6ff71d74c8e7d1ac8bb6ef38f96f3e2
Merge: edf6df2 4f063fb
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 10 22:16:11 2015 +0200

    Merge pull request #536 from liato/feature/certificates
    
    Updates certificates

commit edf6df2d8de3ef5448c1472ef689f51ab74fdb82
Merge: c73d437 ddfee57
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 10 22:12:03 2015 +0200

    Merge pull request #537 from robho/fix_typos
    
    Fix typos

commit 4f063fbd010dfbab9cc3cd28461782bad8badb08
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 10 21:14:46 2015 +0200

    Updates certificates

diff --git CHANGELOG CHANGELOG
index b048f74..5f523f1 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v1.9.9.2 (unreleased)
+* Updates certificates for AmericanExpress, MinPension
+
 v1.9.9.1 (2015-04-09)
 * Fixes application crash for Jojo accounts.
 * Removes support for DinersClub due to BankId requirement.
@@ -18,6 +21,7 @@ v1.9.9.0 (2015-04-02)
 * Fixes issue with PayPal (now even supporting WWW login and transactions).
 * Updates certificates for IkanoPartners
 * Removes support for Sparbanken Öresund due to BankId requirement.
+
 v1.9.8.0 (2015-02-27)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
 * Adds support for EspressoHouse (thanks to fredrike)
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index faa567a..e274d30 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,38 +1,41 @@
 -----BEGIN CERTIFICATE-----

-P6OBQ0XaFaAWHO6xJ5ACxo2KX1ygAqvX2JEp0HqipyNBTlLau75BXw==

+OWXrJnKvRfrsnl+zaEhCOM0oYsPVF4Np7Yw1Yw==
 -----END CERTIFICATE-----
 www.americanexpress.com:443
diff --git bankdroid-legacy/src/main/res/raw/cert_minpension.pem bankdroid-legacy/src/main/res/raw/cert_minpension.pem
index 04543bb..a9db360 100644
--- bankdroid-legacy/src/main/res/raw/cert_minpension.pem
+++ bankdroid-legacy/src/main/res/raw/cert_minpension.pem
@@ -1,25 +1,29 @@
 -----BEGIN CERTIFICATE-----

-iz43

+Sg4ppKz/AHPCyN4SCh4pB4fVlr3XtldcQ2d1TTrN
 -----END CERTIFICATE-----
 www.minpension.se:443

commit ddfee57530b40511b9b8c1d1d3df4e440dc27dbc
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Fri Apr 10 21:06:13 2015 +0200

    Fix typos

diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 97f7f43..5bd1925 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -100,7 +100,7 @@
 	<string name="liveview_help_title">Vad är LiveView?</string>
 	<string name="liveview_help_summary">Läs mer om LiveView på Sony Ericssons webbsida</string>
 	<string name="share_data_title">Dela ut data</string>
-	<string name="share_data_enable_title">Aktivera utdelninga av data</string>
+	<string name="share_data_enable_title">Aktivera utdelning av data</string>
 	<string name="share_data_enable_summary">Medge andra installerade applikationer åtkomst till kontoutdrag</string>
 	<string name="api_key_title">API-nyckel</string>
 	<string name="api_key_summary">Använd denna nyckel för för att komma åt kontoutdrag från andra applikationer</string>
diff --git app/src/main/res/xml/settings.xml app/src/main/res/xml/settings.xml
index cd156b0..9e58638 100644
--- app/src/main/res/xml/settings.xml
+++ app/src/main/res/xml/settings.xml
@@ -255,7 +255,7 @@
 					android:key="debug_refreshrate_in_seconds"
 					android:defaultValue="false"
 					android:title="Update freq. in sec."
-					android:summary="Update frequenzy is given in seconds instead of minutes"
+					android:summary="Update frequency is given in seconds instead of minutes"
 					android:dependency="debug_mode" />
                 <CheckBoxPreference
                     android:key="debug_only_testbank"
@@ -282,4 +282,4 @@
 			</PreferenceScreen>
 		</PreferenceScreen>
 	</PreferenceCategory>
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>

commit c73d43762dc8589ca6fe83eb48fbff04ed3a82b1 (tag: v1.9.9.1)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 9 21:11:15 2015 +0200

    Creates release 1.9.9.1

diff --git CHANGELOG CHANGELOG
index 4ed321c..b048f74 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,6 +1,6 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
-v1.9.9.1 (unreleased)
+v1.9.9.1 (2015-04-09)
 * Fixes application crash for Jojo accounts.
 * Removes support for DinersClub due to BankId requirement.
 * Fixes login issues with some PayPal accounts.
diff --git app/build.gradle app/build.gradle
index 37b8a48..6a8f890 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 210
-        versionName "1.9.9.0"
+        versionCode 211
+        versionName "1.9.9.1"
     }
 
     signingConfigs {

commit 805e6115c6b76bd451436a7178d0a195159802da
Merge: 49da267 890ca42
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 9 13:09:16 2015 +0200

    Merge pull request #535 from liato/feature/paypal
    
    Fixes login issues with some PayPal accounts.

commit 890ca42e71b7c25429458a31ab7c21476e7f51cb
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Apr 9 12:01:20 2015 +0200

    Fixes login issues with some PayPal accounts.

diff --git CHANGELOG CHANGELOG
index 99a8167..4ed321c 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,8 +1,9 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 v1.9.9.1 (unreleased)
-* Fix application crash for Jojo accounts.
-* Removes support for DinersClub due to BankId requirement
+* Fixes application crash for Jojo accounts.
+* Removes support for DinersClub due to BankId requirement.
+* Fixes login issues with some PayPal accounts.
 
 v1.9.9.0 (2015-04-02)
 * Adds support for minpension.se.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index b7a6a03..2358cef 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -108,9 +108,11 @@ public class PayPal extends Bank {
         if (response.contains("Some information you entered isn't right.")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
+        /* TODO find a reliable way to verify that the user has logged in successfully.
         if (!response.contains("cgi-bin/webscr?cmd=_logout\" class=\"btn btn-small btn-secondary logout\">")) {
             throw new BankException("Error logging in to PayPal");
         }
+        */
         return urlopen;
     }
 

commit 49da26701e979f5623d5e24f682cc5148cf847c0
Merge: 26da790 a482d2e
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Apr 6 07:02:09 2015 +0200

    Merge pull request #533 from liato/feature/db-refactoring
    
    Refactor database creation

commit a482d2e7bb1a99a66a6a62d5471fcb99181aaf7d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Apr 5 09:34:21 2015 +0200

    Refactor database creation.

diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 1a54860..b1143e8 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -38,10 +38,6 @@ public class DBAdapter {
 
     static final String TAG = "DBAdapter";
 
-    static final String DATABASE_NAME = "data";
-
-    static final int DATABASE_VERSION = 11;
-
     private DatabaseHelper mDbHelper;
 
     private SQLiteDatabase mDb;
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index 1e23d09..5f67276 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -29,8 +29,8 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
     private static DatabaseHelper instance;
 
     private DatabaseHelper(final Context context) {
-        super(context, DBAdapter.DATABASE_NAME, null,
-                DBAdapter.DATABASE_VERSION);
+        super(context, LegacyDatabase.DATABASE_NAME, null,
+                LegacyDatabase.DATABASE_VERSION);
     }
 
     public static synchronized DatabaseHelper getHelper(Context context) {
@@ -42,33 +42,9 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
 
     @Override
     public void onCreate(final SQLiteDatabase db) {
-        db.execSQL("create table banks (_id integer primary key autoincrement, "
-                + "balance text not null, "
-                + "banktype integer not null, "
-                + "username text not null, "
-                + "password text not null, "
-                + "custname text, "
-                + "updated text, "
-                + "sortorder real, "
-                + "currency text, "
-                + "disabled integer, "
-                + "hideAccounts integer,"
-                + "extras text);");
-        db.execSQL("create table accounts (bankid integer not null, "
-                + "id text not null, "
-                + "balance text not null, "
-                + "acctype integer not null, "
-                + "hidden integer not null, "
-                + "notify integer not null, "
-                + "currency text, "
-                + "name text not null, "
-                + "aliasfor text);");
-        db.execSQL("create table transactions (_id integer primary key autoincrement, "
-                + "transdate text not null, "
-                + "btransaction text not null, "
-                + "amount text not null, "
-                + "currency text, "
-                + "account text not null);");
+        db.execSQL(LegacyDatabase.TABLE_BANKS);
+        db.execSQL(LegacyDatabase.TABLE_ACCOUNTS);
+        db.execSQL(LegacyDatabase.TABLE_TRANSACTIONS);
     }
 
     @Override
@@ -79,11 +55,14 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
         // Version <= 1.7.2 
         if (oldVersion <= 9) {
             // Add an "extras" field to the bank and and "alias for" field to the account.
-            db.execSQL("ALTER TABLE banks ADD extras text;");
-            db.execSQL("ALTER TABLE accounts ADD aliasfor text;");
+            db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " ADD " +
+                    LegacyDatabase.BANK_EXTRAS + " text;");
+            db.execSQL("ALTER TABLE " + LegacyDatabase.ACCOUNT_TABLE_NAME + " ADD " +
+                    LegacyDatabase.ACCOUNT_ALIAS_FOR + " text;");
         }
         if (oldVersion <= 10) {
-            db.execSQL("ALTER TABLE banks ADD hideAccounts interger;");
+            db.execSQL("ALTER TABLE " + LegacyDatabase.BANK_TABLE_NAME + " ADD " +
+                    LegacyDatabase.BANK_HIDE_ACCOUNTS + " integer;");
         }
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java
new file mode 100644
index 0000000..62e400a
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/db/LegacyDatabase.java
@@ -0,0 +1,139 @@
+package com.liato.bankdroid.db;
+
+class LegacyDatabase {
+
+    static final String DATABASE_NAME = "data";
+
+    static final int DATABASE_VERSION = 11;
+
+    static final String BANK_TABLE_NAME = "banks";
+
+    static final String BANK_ID = "_id";
+
+    static final String BANK_BALANCE = "balance";
+
+    static final String BANK_TYPE = "banktype";
+
+    static final String BANK_USERNAME = "username";
+
+    static final String BANK_PASSWORD = "password";
+
+    static final String BANK_CUSTOM_NAME = "custname";
+
+    static final String BANK_UPDATED = "updated";
+
+    static final String BANK_SORT_ORDER = "sortorder";
+
+    static final String BANK_CURRENCY = "currency";
+
+    static final String BANK_DISABLED = "disabled";
+
+    static final String BANK_HIDE_ACCOUNTS = "hideAccounts";
+
+    static final String BANK_EXTRAS = "extras";
+
+
+    static final String ACCOUNT_TABLE_NAME = "accounts";
+
+    static final String ACCOUNT_BANK_ID = "bankid";
+
+    static final String ACCOUNT_ID = "id";
+
+    static final String ACCOUNT_BALANCE = "balance";
+
+    static final String ACCOUNT_CURRENCY = "currency";
+
+    static final String ACCOUNT_TYPE = "acctype";
+
+    static final String ACCOUNT_NAME = "name";
+
+    static final String ACCOUNT_HIDDEN = "hidden";
+
+    static final String ACCOUNT_NOTIFY = "notify";
+
+    static final String ACCOUNT_ALIAS_FOR = "aliasfor";
+
+
+    static final String TRANSACTION_TABLE_NAME = "transactions";
+
+    static final String TRANSACTION_ID = "_id";
+
+    static final String TRANSACTION_DATE = "transdate";
+
+    static final String TRANSACTION_DESCRIPTION = "btransaction";
+
+    static final String TRANSACTION_AMOUNT = "amount";
+
+    static final String TRANSACTION_CURRENCY = "currency";
+
+    static final String TRANSACTION_ACCOUNT_ID = "account";
+
+    static final String TABLE_BANKS = new StringBuilder("create table ")
+            .append(BANK_TABLE_NAME)
+            .append(" (")
+            .append(BANK_ID)
+            .append(" integer primary key autoincrement, ")
+            .append(BANK_BALANCE)
+            .append(" text not null, ")
+            .append(BANK_TYPE)
+            .append(" integer not null, ")
+            .append(BANK_USERNAME)
+            .append(" text not null, ")
+            .append(BANK_PASSWORD)
+            .append(" text not null, ")
+            .append(BANK_CUSTOM_NAME)
+            .append(" text, ")
+            .append(BANK_UPDATED)
+            .append(" text, ")
+            .append(BANK_SORT_ORDER)
+            .append(" real, ")
+            .append(BANK_CURRENCY)
+            .append(" text, ")
+            .append(BANK_DISABLED)
+            .append(" integer, ")
+            .append(BANK_HIDE_ACCOUNTS)
+            .append(" integer,")
+            .append(BANK_EXTRAS)
+            .append(" text);").toString();
+
+    static final String TABLE_ACCOUNTS = new StringBuilder("create table ")
+            .append(ACCOUNT_TABLE_NAME)
+            .append(" (")
+            .append(ACCOUNT_BANK_ID)
+            .append(" integer not null, ")
+            .append(ACCOUNT_ID)
+            .append(" text not null, ")
+            .append(ACCOUNT_BALANCE)
+            .append(" text not null, ")
+            .append(ACCOUNT_TYPE)
+            .append(" integer not null, ")
+            .append(ACCOUNT_HIDDEN)
+            .append(" integer not null, ")
+            .append(ACCOUNT_NOTIFY)
+            .append(" integer not null, ")
+            .append(ACCOUNT_CURRENCY)
+            .append(" text, ")
+            .append(ACCOUNT_NAME)
+            .append(" text not null, ")
+            .append(ACCOUNT_ALIAS_FOR)
+            .append(" text);").toString();
+
+    static final String TABLE_TRANSACTIONS = new StringBuilder("create table ")
+            .append(TRANSACTION_TABLE_NAME)
+            .append(" (")
+            .append(TRANSACTION_ID)
+            .append(" integer primary key autoincrement, ")
+            .append(TRANSACTION_DATE)
+            .append(" text not null, ")
+            .append(TRANSACTION_DESCRIPTION)
+            .append(" text not null, ")
+            .append(TRANSACTION_AMOUNT)
+            .append(" text not null, ")
+            .append(TRANSACTION_CURRENCY)
+            .append(" text, ")
+            .append(TRANSACTION_ACCOUNT_ID)
+            .append(" text not null);").toString();
+
+    private LegacyDatabase() {
+    }
+}

commit 26da79063fd97d69500e87cf4537a30fea41733c
Merge: 08bfe8d 2f48db1
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Apr 4 16:41:16 2015 +0200

    Merge pull request #532 from liato/feature/exception-handling
    
    Improves Exception handling

commit 08bfe8dec76a35cebf9df6e0ff89880c4ef10a17
Merge: ed4b6cc a5b07ed
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Apr 4 16:40:20 2015 +0200

    Merge pull request #531 from liato/feature/remove-dinersclub
    
    Removes Dinersclub because they now require BankId or SMS

commit a5b07edae51ad70d00982c7524588b76affeb89e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Apr 4 11:31:06 2015 +0200

    Removes DinersClub

diff --git CHANGELOG CHANGELOG
index 470cb87..99a8167 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,8 @@
-v1.9.9.1 (2015-04-03)
+Please view this file on the master branch, on stable branches it's out of date.
+
+v1.9.9.1 (unreleased)
 * Fix application crash for Jojo accounts.
+* Removes support for DinersClub due to BankId requirement
 
 v1.9.9.0 (2015-04-02)
 * Adds support for minpension.se.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 9b247a9..77f5c0b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -14,7 +14,6 @@ import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.DanskeBank;
-import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.EspressoHouse;
 import com.liato.bankdroid.banking.banks.Everydaycard;
@@ -124,8 +123,8 @@ public class LegacyBankFactory {
                 return new Jojo(context);
             // case IBankTypes.STEAM:
             //    return new Steam(context);
-            case IBankTypes.DINERSCLUB:
-                return new DinersClub(context);
+            // case IBankTypes.DINERSCLUB:
+            //    return new DinersClub(context);
             case IBankTypes.IKANOBANK:
                 return new IkanoBank(context);
             //  case IBankTypes.SASEUROBONUSMASTERCARD:
@@ -283,7 +282,7 @@ public class LegacyBankFactory {
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
         // banks.add(new Steam(context));
-        banks.add(new DinersClub(context));
+        // banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
         // banks.add(new EurobonusMastercard(context));
         banks.add(new Rikslunchen(context));

commit 2f48db166d5f0765a6b087c3707ee0fe12d55e3d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Apr 4 11:02:36 2015 +0200

    Improves Exception handling

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index adc88c0..8a08bbb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -16,8 +16,10 @@
 
 package com.liato.bankdroid.banking.banks.lansforsakringar;
 
+import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
@@ -147,7 +149,7 @@ public class Lansforsakringar extends Bank {
         return new LoginPackage(weblogin, postData, response, weblogin.getCurrentURI());
     }
 
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
@@ -173,22 +175,24 @@ public class Lansforsakringar extends Bank {
     }
 
 
-    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException, IOException {
         try {
             return mObjectMapper.readValue(is, valueType);
-        } catch (Exception e) {
+        } catch (JsonParseException | JsonMappingException e) {
             throw new BankException(e.getMessage(), e);
+        } finally {
+            try {
+                is.close();
+            } catch(IOException e) {
+                // Ignore
+            }
         }
+
     }
 
     private <T> T readJsonValue(String url, String postData, Class<T> valueType)
-            throws BankException {
-        try {
-            return readJsonValue(urlopen.openStream(url, postData, false), valueType);
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage(), e);
-        }
+            throws BankException, IOException {
+        return readJsonValue(urlopen.openStream(url, postData, false), valueType);
     }
 
     public String objectAsJson(Object value) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 148edc8..6e1ac0b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -1,6 +1,8 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
+import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import com.liato.bankdroid.banking.Account;
@@ -333,10 +335,10 @@ public abstract class AbstractSwedbank extends Bank {
         return API_BASE + resource + '?' + dsid;
     }
 
-    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException, IOException {
         try {
             return mObjectMapper.readValue(is, valueType);
-        } catch (Exception e) {
+        } catch(JsonParseException | JsonMappingException e) {
             throw new BankException(e.getMessage(), e);
         } finally {
             try {

commit ed4b6cca8cdd0dbb4c30f42fc947ea204ceb5c71
Merge: 4d74a74 007d861
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Apr 4 05:26:36 2015 +0200

    Merge pull request #530 from liato/feature/certificates
    
    Updates certificate for SveaDirekt

commit 4d74a745084976c69f22113b2b075afff9f10301
Merge: b0110a2 e9c6d03
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Apr 4 05:24:53 2015 +0200

    Merge pull request #529 from liato/feature/jojo-fix
    
    Adds null check for pagination existens.

commit 007d86150746a4cfd0835f9722d13e8935b5dc0c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 3 14:20:45 2015 +0200

    Updates certificate for SveaDirekt

diff --git bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
index f2821b9..cedc057 100644
--- bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
+++ bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
@@ -1,32 +1,31 @@
 -----BEGIN CERTIFICATE-----

+/B5LM6Txr5Y=
 -----END CERTIFICATE-----
 services.sveadirekt.se:443

commit e9c6d03f74f69b2c2b6b7b5f8a8e28fe13f170db
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Apr 3 13:57:46 2015 +0200

    Adds null check for pagination existens.
    
    Fixes #528

diff --git CHANGELOG CHANGELOG
index ba611cb..470cb87 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,3 +1,6 @@
+v1.9.9.1 (2015-04-03)
+* Fix application crash for Jojo accounts.
+
 v1.9.9.0 (2015-04-02)
 * Adds support for minpension.se.
 * Adds option to disable auto updates while roaming.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index fc0d358..43c4d64 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -184,7 +184,7 @@ public class Jojo extends Bank {
 
         private String parseNextUrl() {
             Element elem = mDocument.select("div.pageselector_pagenr a").last();
-            if (elem.select("span.pageselect_prevnext_selected").isEmpty()) {
+            if (elem == null || elem.select("span.pageselect_prevnext_selected").isEmpty()) {
                 return null;
             }
             return elem.attr("href");

commit b0110a226e5b103446e277a390bbbf2e6affdc88 (tag: v1.9.9.0)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 2 22:45:51 2015 +0200

    Create release 1.9.9.0

diff --git CHANGELOG CHANGELOG
index 3fa8878..ba611cb 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,4 +1,4 @@
-v1.9.9.0 (2015-04-01)
+v1.9.9.0 (2015-04-02)
 * Adds support for minpension.se.
 * Adds option to disable auto updates while roaming.
 * Removes Skandiabanken due to their new BankId requirement.
diff --git app/build.gradle app/build.gradle
index 4191413..37b8a48 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 209
-        versionName "1.9.9.0-RC2"
+        versionCode 210
+        versionName "1.9.9.0"
     }
 
     signingConfigs {

commit 9b80855e63bc7c837190c43eaff4906458e86bb8
Merge: 6cf7ca3 2605e22
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Apr 2 19:25:55 2015 +0200

    Merge pull request #527 from liato/feature/disable-sparbanken-oresund
    
    Removes Sparbanken Öresund due to BankId requirement.

commit 2605e227a6cd18a843b310e4910680503707cd20
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 2 15:47:04 2015 +0200

    Removes Sparbanken Öresund due to BankId requirement.

diff --git CHANGELOG CHANGELOG
index 0900a64..3fa8878 100644
--- CHANGELOG
+++ CHANGELOG
@@ -10,6 +10,7 @@ v1.9.9.0 (2015-04-01)
 * Fixes LockPattern crashes for Samsung Galaxy devices.
 * Fixes issue with PayPal (now even supporting WWW login and transactions).
 * Updates certificates for IkanoPartners
+* Removes support for Sparbanken Öresund due to BankId requirement.
 v1.9.8.0 (2015-02-27)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
 * Adds support for EspressoHouse (thanks to fredrike)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index d64a4b0..9b247a9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -43,7 +43,6 @@ import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skoda;
-import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
@@ -189,8 +188,8 @@ public class LegacyBankFactory {
                 return new IKEA(context);
             case IBankTypes.SPARBANKEN_SYD:
                 return new SparbankenSyd(context);
-            case IBankTypes.SPARBANKEN_ORESUND:
-                return new SparbankenOresund(context);
+            // case IBankTypes.SPARBANKEN_ORESUND:
+            //    return new SparbankenOresund(context);
             case IBankTypes.NORDNETDIREKT:
                 return new Nordnetdirekt(context);
             // case IBankTypes.SKANDIABANKEN:

commit 6cf7ca35608a28950f7d43af4776e0722474145d
Merge: b58a82c 5e43c43
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Apr 2 11:04:09 2015 +0200

    Merge pull request #524 from liato/feature/paypal
    
    Updated isLoggedIn check for PayPal

commit 5e43c4355a6aab97c2df7ea924b5b3a7e34d5efa
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Apr 2 10:00:28 2015 +0200

    Updated isLoggedIn check for PayPal

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 0bde0b5..b7a6a03 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -108,7 +108,7 @@ public class PayPal extends Bank {
         if (response.contains("Some information you entered isn't right.")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-        if (!response.contains("<title>PayPal: Summary</title>")) {
+        if (!response.contains("cgi-bin/webscr?cmd=_logout\" class=\"btn btn-small btn-secondary logout\">")) {
             throw new BankException("Error logging in to PayPal");
         }
         return urlopen;

commit b58a82cb009596fe2800238eac72cafb87f2ee25 (tag: v1.9.9.0-RC2)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 1 22:05:23 2015 +0200

    Creates release 1.9.9.0-RC2

diff --git CHANGELOG CHANGELOG
index 407694b..0900a64 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,4 +1,4 @@
-v1.9.9.0 (2015-03-21)
+v1.9.9.0 (2015-04-01)
 * Adds support for minpension.se.
 * Adds option to disable auto updates while roaming.
 * Removes Skandiabanken due to their new BankId requirement.
@@ -9,6 +9,7 @@ v1.9.9.0 (2015-03-21)
 * Fixes Payson balance. NOTE: Transactions not supported yet (thanks to robho).
 * Fixes LockPattern crashes for Samsung Galaxy devices.
 * Fixes issue with PayPal (now even supporting WWW login and transactions).
+* Updates certificates for IkanoPartners
 v1.9.8.0 (2015-02-27)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
 * Adds support for EspressoHouse (thanks to fredrike)
diff --git app/build.gradle app/build.gradle
index f416efb..4191413 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 208
-        versionName "1.9.9.0-RC1"
+        versionCode 209
+        versionName "1.9.9.0-RC2"
     }
 
     signingConfigs {

commit dc9430c9f94c222756918e2cbd457b9ba6939f7a
Merge: d781f90 eadea11
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Apr 1 22:00:51 2015 +0200

    Merge pull request #523 from liato/goober-patch-1
    
    Update README.rst

commit eadea112aa4f01d4eba11b6450d19a441d303bd5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 1 21:53:27 2015 +0200

    Update README.rst
    
    Move Gitter badge to top

diff --git README.rst README.rst
index 0bcc475..6f0d790 100644
--- README.rst
+++ README.rst
@@ -1,10 +1,13 @@
 .. image:: https://travis-ci.org/liato/android-bankdroid.svg?branch=master
     :target: https://travis-ci.org/liato/android-bankdroid
 
+.. image:: https://badges.gitter.im/Join%20Chat.svg
+    :alt: Join the chat at https://gitter.im/liato/android-bankdroid
+    :target: https://gitter.im/liato/android-bankdroid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
+
 Bankdroid
 =========
 
-
 Bankdroid is an Android app for Swedish banks, payment cards and similar services. Key features include:
 
 * Automatic updates of your balance and transactions
@@ -37,10 +40,6 @@ Bankdroid is written for Android Studio 0.8.2 and Gradle 1.12. Here's how to get
 running on your computer:
 
 1. Make sure you have `Android Studio 0.8.2 or later <https://developer.android.com/sdk/installing/studio.html>`_
-
-.. image:: https://badges.gitter.im/Join%20Chat.svg
-   :alt: Join the chat at https://gitter.im/liato/android-bankdroid
-   :target: https://gitter.im/liato/android-bankdroid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
 2. `Clone <https://help.github.com/articles/which-remote-url-should-i-use>`_ the project (if you want to contribute you should `fork <https://help.github.com/articles/fork-a-repo>`_ the project first and then clone your fork)
 3. Open the project's settings.gradle file in Android Studio and select "Use default gradle wrapper (recommended)"
 4. Select "Make project" from the Build menu

commit d781f9099ad469c11b1920683e58cd65b1055a8a
Merge: 61dedf7 1dec6cc
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Apr 1 21:50:32 2015 +0200

    Merge pull request #522 from liato/feature/disable-swedbank-corporate-and-youth
    
    Disable corporate and youth profiles for Swedbank and Sparbankerna.

commit 1dec6cc639f9de9283cdb711312e8f75d6b96e2e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 1 21:38:30 2015 +0200

    Disable corporate and youth profiles for Swedbank and Sparbankerna.

diff --git CHANGELOG CHANGELOG
index bf58d6f..407694b 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,5 +1,4 @@
 v1.9.9.0 (2015-03-21)
-* Adds support for Swedbank/Sparbankerna Corporate and Youth profiles.
 * Adds support for minpension.se.
 * Adds option to disable auto updates while roaming.
 * Removes Skandiabanken due to their new BankId requirement.
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index e98332d..d64a4b0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -247,14 +247,14 @@ public class LegacyBankFactory {
                 return new EspressoHouse(context);
             case IBankTypes.MINPENSION:
                 return new MinPension(context);
-            case IBankTypes.SPARBANKERNA_CORPORATE:
-                return new SparbankernaCorporate(context);
-            case IBankTypes.SPARBANKERNA_YOUTH:
-                return new SparbankernaYouth(context);
-            case IBankTypes.SWEDBANK_CORPORATE:
-                return new SwedbankCorporate(context);
-            case IBankTypes.SWEDBANK_YOUTH:
-                return new SwedbankYouth(context);
+            // case IBankTypes.SPARBANKERNA_CORPORATE:
+            //    return new SparbankernaCorporate(context);
+            // case IBankTypes.SPARBANKERNA_YOUTH:
+            //    return new SparbankernaYouth(context);
+            // case IBankTypes.SWEDBANK_CORPORATE:
+            //    return new SwedbankCorporate(context);
+            // case IBankTypes.SWEDBANK_YOUTH:
+            //    return new SwedbankYouth(context);
             default:
                 throw new BankException("BankType id not found.");
         }
@@ -343,10 +343,10 @@ public class LegacyBankFactory {
         banks.add(new Bredband2VoIP(context));
         banks.add(new EspressoHouse(context));
         banks.add(new MinPension(context));
-        banks.add(new SparbankernaCorporate(context));
-        banks.add(new SparbankernaYouth(context));
-        banks.add(new SwedbankCorporate(context));
-        banks.add(new SwedbankYouth(context));
+        // banks.add(new SparbankernaCorporate(context));
+        // banks.add(new SparbankernaYouth(context));
+        // banks.add(new SwedbankCorporate(context));
+        // banks.add(new SwedbankYouth(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {

commit 61dedf7aec590d1294a3f36efb20ec3ee03bf10d
Merge: bd04248 13355d8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 1 21:34:20 2015 +0200

    Merge pull request #520 from liato/feature/paypal
    
    Fixes issue with PayPal (now even supporting WWW login and transactions).

commit bd0424838513fa54d800f996eb3a8c84d31b95eb
Merge: 465aa26 2409d4e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 1 21:34:00 2015 +0200

    Merge pull request #519 from liato/feature/urllib-retries
    
    Adds 5 connection attempts to Urllib

commit 13355d8382ade9232e6356bda4887f01c6433ff8
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Apr 1 10:41:57 2015 +0200

    Fixes issue with PayPal (closing #512 #483)

diff --git CHANGELOG CHANGELOG
index eb82633..bf58d6f 100644
--- CHANGELOG
+++ CHANGELOG
@@ -9,6 +9,7 @@ v1.9.9.0 (2015-03-21)
 * Fixes transaction issues for EspressoHouse.
 * Fixes Payson balance. NOTE: Transactions not supported yet (thanks to robho).
 * Fixes LockPattern crashes for Samsung Galaxy devices.
+* Fixes issue with PayPal (now even supporting WWW login and transactions).
 v1.9.8.0 (2015-02-27)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
 * Adds support for EspressoHouse (thanks to fredrike)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 7ed55db..0bde0b5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -16,9 +16,13 @@
 
 package com.liato.bankdroid.banking.banks;
 
+import android.content.Context;
+import android.text.InputType;
+
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -27,52 +31,36 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.message.BasicNameValuePair;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.text.TextUtils;
-
 import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PayPal extends Bank {
-
     private static final String TAG = "PayPal";
-
     private static final String NAME = "PayPal";
-
     private static final String NAME_SHORT = "paypal";
-
-    private static final String URL = "https://www.paypal.com/";
+    private static final String ORIGIN_URL =  "https://www.paypal.com";
+    private static final String REFERER_URL ="https://www.paypal.com/se/webapps/mpp/home";
+    private static final String OVERVIEW_URL = "https://www.paypal.com/myaccount/home";
+    private static final String LOGIN_URL = "https://www.paypal.com/signin/intent/";
+    private static final String BALANCE_URL = "https://www.paypal.com/myaccount/wallet/balance";
 
     private static final int BANKTYPE_ID = IBankTypes.PAYPAL;
-
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
             | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-
     private static final boolean STATIC_BALANCE = true;
-
-    private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reBalance = Pattern.compile(
-            "PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>",
-            Pattern.CASE_INSENSITIVE);
-
-    private Pattern reAccounts = Pattern.compile(
-            "row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>",
-            Pattern.CASE_INSENSITIVE);
-
     private String response = null;
 
     public PayPal(Context context) {
@@ -95,53 +83,33 @@ public class PayPal extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context,
-                CertificateReader.getCertificates(context, R.raw.cert_paypal));
-        urlopen.setUserAgent(
-                "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
-        //Get cookies and url to post to
-        response = urlopen.open("https://www.paypal.com/en");
-        Document d = Jsoup.parse(response);
-        Element e = d.select("form[name=login_form]").first();
-
-        String strPostUrl;
-        if (e != null && !TextUtils.isEmpty(e.attr("action"))) {
-            strPostUrl = e.attr("action").trim();
-        } else {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " post url.");
+        try {
+            urlopen = login();
+            LoginPackage lp = new LoginPackage(urlopen, null,
+                    response, OVERVIEW_URL);
+            lp.setIsLoggedIn(true);
+            return lp;
+        } catch (LoginException e) {
+            return null;
         }
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("login_email", username));
-        postData.add(new BasicNameValuePair("login_password", password));
-        postData.add(new BasicNameValuePair("target_page", "0"));
-        postData.add(new BasicNameValuePair("submit.x", "Log In"));
-        postData.add(new BasicNameValuePair("form_charset", "UTF-8"));
-        postData.add(new BasicNameValuePair("browser_name", "undefined"));
-        postData.add(new BasicNameValuePair("browser_version", "undefined"));
-        postData.add(new BasicNameValuePair("operating_system", "Windows"));
-        postData.add(new BasicNameValuePair("bp_mid",
-                "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
-        postData.add(new BasicNameValuePair("bp_ks1",
-                "v=1;l=16;Di0:2663Di1:48Ui0:15Ui1:81Di2:176Di3:48Ui2:32Ui3:96Di4:384Ui4:48Di5:352Ui5:48Di6:128Ui6:80Di7:112Ui7:48Di8:113Ui8:79Di9:125Ui9:51Di10:98Ui10:72Di11:227Ui11:51Di12:80Ui12:80Di13:128Ui13:64Di14:48Ui14:80Di15:416Ui15:80"));
-        postData.add(new BasicNameValuePair("bp_ks2", ""));
-        postData.add(new BasicNameValuePair("bp_ks3", ""));
-        postData.add(new BasicNameValuePair("flow_name",
-                "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
-        postData.add(new BasicNameValuePair("fso",
-                "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
-        return new LoginPackage(urlopen, postData, response, strPostUrl);
     }
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
-        LoginPackage lp = preLogin();
-        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("If you still can't log in") || response.contains(
-                "both your email address and password")) {
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_paypal));
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("email", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("ul-submit-cookied", "Logga in"));
+        urlopen.addHeader("Origin",ORIGIN_URL);
+        urlopen.addHeader("Referer", REFERER_URL);
+        response = urlopen.open(LOGIN_URL, postData, true);
+        if (response.contains("Some information you entered isn't right.")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-        if (response.contains("your last action could not be completed")) {
-            throw new BankException("Error: PPL92");
+        if (!response.contains("<title>PayPal: Summary</title>")) {
+            throw new BankException("Error logging in to PayPal");
         }
         return urlopen;
     }
@@ -155,47 +123,66 @@ public class PayPal extends Bank {
         }
         urlopen = login();
 
-        response = urlopen.open(
-                "https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access=" + ((int) (
-                        System.currentTimeMillis() / 1000L)));
-        Matcher matcher = reAccounts.matcher(response);
-        int accId = 1;
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: name              SEK (Primary)
-             * 2: amount            554.70
-             * 3: currency          SEK
-             *
-             */
-            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(2)), "" + accId);
-            account.setCurrency(matcher.group(3).trim());
-            accounts.add(account);
-            accId++;
-        }
-        matcher = reBalance.matcher(response);
-        if (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: balance           554.70
-             * 2: currency          SEK
-             *
-             */
-            balance = Helpers.parseBalance(matcher.group(1));
-            currency = matcher.group(2).trim();
-            if (accounts.isEmpty()) {
-                // Probably a premier account.
-                Account account = new Account(currency, balance, "1");
-                account.setCurrency(currency);
-                accounts.add(account);
+        /* Start by parsing the data in "response" (containing transactions) */
+        List<Transaction> transactions = new ArrayList<>();
+        Document trans = Jsoup.parse(response);
+        try {
+            for (Element e : trans.select(".transactionItem .row")) {
+                String date = e.select(".dateParts").first().text(); //"Mar 17 2015"
+                date = new SimpleDateFormat("yyyy-MM-dd").format(
+                        new SimpleDateFormat("MMM dd yyyy").parse(date));
+                String description = e.select(".transactionDescription").first().text(); //"Unovation Inc."
+                String type = e.select(".transactionType").first().text(); //"Recurring Payment "
+                String amount = e.select(".transactionAmount").first().text(); //"-negative $3.00 USD"
+                Transaction t = new Transaction(date,
+                        description + "\n— " + type, Helpers.parseBalance(amount));
+                t.setCurrency(amount.substring(amount.length() - 3));
+                transactions.add(t);
             }
+        } catch (ParseException | NullPointerException e) {
+            //Ignore parsing errors of transactions (for now).
+            //TODO handle parsing errors gracefully.
         }
 
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        try {
+            //Set bank balance from first page balance.
+            String bal = trans.select(".balanceNumeral.nemo_balanceNumeral .h2").text();
+            this.balance = Helpers.parseBalance(bal);
+            this.setCurrency(bal.substring(bal.length() - 3));
+
+            //Get all currencies and create separate accounts for each.
+            response = urlopen.open(BALANCE_URL);
+            Document doc = Jsoup.parse(response);
+            Element wallet = doc.getElementById("wallet");
+            bal = wallet.attr("data-balance").replace("&quot;", "\"");
+            JSONObject acc = new JSONObject(bal);
+            this.balance = Helpers.parseBalance(
+                    acc.getJSONObject("totalAvailable").getString("unformattedAmount"));
+            this.setCurrency(acc.getString("primaryCurrency"));
+
+            JSONArray accArr = acc.getJSONArray("balanceDetails");
+            for (int i = 0; i < accArr.length(); i++) {
+                try {
+                    JSONObject a = accArr.getJSONObject(i);
+                    String accountName = a.getString("currency");
+                    String displayName = accountName;
+                    if (accountName.equals(this.getCurrency()))
+                        displayName = accountName + " (Primary)";
+                    Double amount = a.getJSONObject("available")
+                            .getDouble("unformattedAmount");
+                    Account account = new Account(displayName,
+                            Helpers.parseBalance(amount.toString()),
+                            accountName,
+                            Account.REGULAR,
+                            accountName);
+                    account.setTransactions(transactions);
+                    accounts.add(account);
+                } catch (JSONException e) {
+                    //Ignore if we can't add a new account..
+                }
+            }
+        } catch (JSONException e) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString(), e);
         }
         super.updateComplete();
     }

commit 2409d4e5ee9d893ed18449e344ff6ddc59e8eb82
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Apr 1 21:04:53 2015 +0200

    Adds 5 connection attempts to Urllib

diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 3ee068d..e336da1 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -26,6 +26,7 @@ import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.NameValuePair;
+import org.apache.http.NoHttpResponseException;
 import org.apache.http.ProtocolException;
 import org.apache.http.client.AuthenticationHandler;
 import org.apache.http.client.ClientProtocolException;
@@ -86,6 +87,8 @@ import java.util.List;
 
 public class Urllib {
 
+    private static int MAX_RETRIES = 5;
+
     public static String DEFAULT_USER_AGENT
             = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
 
@@ -226,6 +229,24 @@ public class Urllib {
             request.addHeader(headerKeys[i], headerVals[i]);
         }
 
+        HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
+
+            public boolean retryRequest(IOException exception, int executionCount,
+                                        HttpContext context) {
+                // retry a max of 5 times
+                if (executionCount >= MAX_RETRIES) {
+                    return false;
+                }
+                if (exception instanceof NoHttpResponseException) {
+                    return true;
+                } else if (exception instanceof ClientProtocolException) {
+                    return true;
+                }
+                return false;
+            }
+        };
+        httpclient.setHttpRequestRetryHandler(retryHandler);
+
         response = httpclient.execute(request, mHttpContext);
 
         //HttpUriRequest currentReq = (HttpUriRequest)mHttpContext.getAttribute(ExecutionContext.HTTP_REQUEST);

commit 465aa267c43df9967ba2a70e2e1336b39e30ce71
Merge: d9144d8 6c58d60
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Apr 1 17:36:09 2015 +0200

    Merge pull request #521 from liato/feature/cert_ikanopartner
    
    Update certificate for Ikanopartner

commit d9144d8d6980585c7e6aa3349d539167bc3149ad
Merge: 3310661 f151542
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Apr 1 10:45:49 2015 +0200

    Merge pull request #518 from gitter-badger/gitter-badge
    
    Add a Gitter chat badge to README.rst

commit 6c58d608531784895f4de0e989c3484b34ad7aba
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Apr 1 10:44:20 2015 +0200

    Update certificate for Ikanopartner

diff --git bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
index e6fb824..c8a43bb 100644
--- bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
@@ -1,34 +1,50 @@
 -----BEGIN CERTIFICATE-----

-npgXOrhX

+X2rz9QRCM2gbnOM+w8D12w==
 -----END CERTIFICATE-----
 partner.ikanobank.se:443

commit f1515424663e8af5dd1e8c91f680033d8b04835c
Author: The Gitter Badger <badger@gitter.im>
Date:   Tue Mar 31 07:49:58 2015 +0000

    Added Gitter badge

diff --git README.rst README.rst
index 0be1f02..0bcc475 100644
--- README.rst
+++ README.rst
@@ -37,6 +37,10 @@ Bankdroid is written for Android Studio 0.8.2 and Gradle 1.12. Here's how to get
 running on your computer:
 
 1. Make sure you have `Android Studio 0.8.2 or later <https://developer.android.com/sdk/installing/studio.html>`_
+
+.. image:: https://badges.gitter.im/Join%20Chat.svg
+   :alt: Join the chat at https://gitter.im/liato/android-bankdroid
+   :target: https://gitter.im/liato/android-bankdroid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
 2. `Clone <https://help.github.com/articles/which-remote-url-should-i-use>`_ the project (if you want to contribute you should `fork <https://help.github.com/articles/fork-a-repo>`_ the project first and then clone your fork)
 3. Open the project's settings.gradle file in Android Studio and select "Use default gradle wrapper (recommended)"
 4. Select "Make project" from the Build menu

commit 33106613452bd2f7b196a732ea389b91dac1334a
Merge: 0b545f6 db6df87
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Mar 30 18:29:31 2015 +0200

    Merge pull request #517 from liato/feature/add-license-file
    
    Create LICENSE

commit db6df87597cf6e1685b54487046237a33fccd356
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Mar 28 11:53:10 2015 +0100

    Update LICENSE

diff --git LICENSE LICENSE
index 5c304d1..09703d5 100644
--- LICENSE
+++ LICENSE
@@ -1,201 +1,13 @@
-Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
+Copyright 2015 liato
 
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
 
-   1. Definitions.
+   http://www.apache.org/licenses/LICENSE-2.0
 
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

commit 835aafaa9d773922e2e2518cfec153d1b95ce3d6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Mar 28 11:43:22 2015 +0100

    Create LICENSE

diff --git LICENSE LICENSE
new file mode 100644
index 0000000..5c304d1
--- /dev/null
+++ LICENSE
@@ -0,0 +1,201 @@
+Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

commit 0b545f6fcca7218efdeb6e40389e8a5a28096def
Merge: d9dbaa5 49ab1f5
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Mar 25 13:24:25 2015 +0100

    Merge pull request #514 from liato/feature/fix-exception-handling
    
    Fixes IOException handling.

commit 49ab1f5fbd0b6c550985e6aa19577f91b65dfece
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 25 13:06:35 2015 +0100

    Ignore refund for Coop if it does not exists or is zero.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index a357123..009720c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -217,10 +217,14 @@ public class Coop extends Bank {
         response = urlopen
                 .open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
         dResponse = Jsoup.parse(response);
-        Account a = new Account("Återbäring",
-                Helpers.parseBalance(dResponse.select(".Heading--coopNew").text()),
-                "refound", Account.OTHER, "SEK");
-        accounts.add(a);
+        Elements refound = dResponse.select(".Heading--coopNew");
+        if (refound.hasText()) {
+            BigDecimal balance = Helpers.parseBalance(refound.text());
+            if (balance.compareTo(BigDecimal.ZERO) >= 0) {
+                Account a = new Account("Återbäring", balance, "refound", Account.OTHER, "SEK");
+                accounts.add(a);
+            }
+        }
 
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 2efc154d5617b5c9ad05eac2488a546cdda56efb
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Mar 24 01:10:24 2015 +0100

    Fixes IOException handling.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index c1dcee5..ece42a3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -110,22 +110,19 @@ public class Bredband2VoIP extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            response = urlopen.open(API_URL + "services/");
-            Matcher mSaldoUrl = reSaldoUrl.matcher(response);
-            while (mSaldoUrl.find()) {
-                String account = mSaldoUrl.group(1);
-                String r = urlopen.open(
-                        API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
-                Matcher mSaldo = reSaldo.matcher(r);
-                if (mSaldo.find()) {
-                    accounts.add(new Account(account,
-                            Helpers.parseBalance(mSaldo.group(1)),
-                            account));
-                }
+
+        response = urlopen.open(API_URL + "services/");
+        Matcher mSaldoUrl = reSaldoUrl.matcher(response);
+        while (mSaldoUrl.find()) {
+            String account = mSaldoUrl.group(1);
+            String r = urlopen.open(
+                    API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
+            Matcher mSaldo = reSaldo.matcher(r);
+            if (mSaldo.find()) {
+                accounts.add(new Account(account,
+                        Helpers.parseBalance(mSaldo.group(1)),
+                        account));
             }
-        } catch (Exception e) {
-            throw new BankException(e.getMessage(), e);
         }
         super.updateComplete();
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 701c22c..b983208 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -59,52 +59,49 @@ public class Chalmrest extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
-        try {
-            String cardNr = username;
-
-            HttpClient httpclient = new DefaultHttpClient();
-            HttpGet httpget = new HttpGet(
-                    "http://kortladdning.chalmerskonferens.se/bgw.aspx?type=getCardAndArticles&card="
-                            + cardNr);
-            HttpResponse response = httpclient.execute(httpget);
-            HttpEntity entity = response.getEntity();
-            if (entity == null) {
-                throw new BankException("Couldn't connect!");
-            }
-
-            String s1 = EntityUtils.toString(entity);
-            Pattern pattern = Pattern.compile(
-                    "<ExtendedInfo Name=\"Kortvarde\" Type=\"System.Double\" >(.*?)</ExtendedInfo>");
-            Matcher matcher = pattern.matcher(s1);
-
-            if (!matcher.find()) {
-                throw new BankException("Couldn't parse value!");
-            }
-
-            String value = matcher.group(1);
-
-            StringBuilder sb = new StringBuilder();
-            int last = 0;
-            Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
-            while (match.find()) {
-                sb.append(value.substring(last, match.start()));
-                int i = Integer.parseInt(match.group(1), 16);
-                sb.append((char) i);
-                last = match.end();
-            }
-            sb.append(value.substring(last));
-            value = sb.toString().replace(',', '.');
-
-            matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
-            if (!matcher.find()) {
-                throw new BankException("Coldn't parse name!");
-            }
-            String name = matcher.group(1);
-
-            accounts.add(new Account(name, BigDecimal.valueOf(Double.parseDouble(value)), "1"));
-        } catch (Exception e) {
-            throw new BankException(e.getMessage(), e);
+        String cardNr = username;
+
+        HttpClient httpclient = new DefaultHttpClient();
+        HttpGet httpget = new HttpGet(
+                "http://kortladdning.chalmerskonferens.se/bgw.aspx?type=getCardAndArticles&card="
+                        + cardNr);
+        HttpResponse response = httpclient.execute(httpget);
+        HttpEntity entity = response.getEntity();
+        if (entity == null) {
+            throw new BankException("Couldn't connect!");
         }
+
+        String s1 = EntityUtils.toString(entity);
+        Pattern pattern = Pattern.compile(
+                "<ExtendedInfo Name=\"Kortvarde\" Type=\"System.Double\" >(.*?)</ExtendedInfo>");
+        Matcher matcher = pattern.matcher(s1);
+
+        if (!matcher.find()) {
+            throw new BankException("Couldn't parse value!");
+        }
+
+        String value = matcher.group(1);
+
+        StringBuilder sb = new StringBuilder();
+        int last = 0;
+        Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
+        while (match.find()) {
+            sb.append(value.substring(last, match.start()));
+            int i = Integer.parseInt(match.group(1), 16);
+            sb.append((char) i);
+            last = match.end();
+        }
+        sb.append(value.substring(last));
+        value = sb.toString().replace(',', '.');
+
+        matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
+        if (!matcher.find()) {
+            throw new BankException("Coldn't parse name!");
+        }
+        String name = matcher.group(1);
+
+        accounts.add(new Account(name, BigDecimal.valueOf(Double.parseDouble(value)), "1"));
+
         super.updateComplete();
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index e1c537c..fa5389f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -92,7 +92,7 @@ public class Avanza extends Bank {
         return lp;
     }
 
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context,
                 CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
@@ -187,8 +187,6 @@ public class Avanza extends Bank {
             }
         } catch (JsonParseException e) {
             throw new BankException(e.getMessage(), e);
-        } catch (Exception e) {
-            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index b9fab52..a357123 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -214,17 +214,13 @@ public class Coop extends Bank {
             }
         }
 
-        try {
-            response = urlopen
-                    .open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
-            dResponse = Jsoup.parse(response);
-            Account a = new Account("Återbäring",
-                    Helpers.parseBalance(dResponse.select(".Heading--coopNew").text()),
-                    "refound", Account.OTHER, "SEK");
-            accounts.add(a);
-        } catch (Exception e) {
-            throw new BankException(e.getMessage(), e);
-        }
+        response = urlopen
+                .open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
+        dResponse = Jsoup.parse(response);
+        Account a = new Account("Återbäring",
+                Helpers.parseBalance(dResponse.select(".Heading--coopNew").text()),
+                "refound", Account.OTHER, "SEK");
+        accounts.add(a);
 
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -243,38 +239,35 @@ public class Coop extends Bank {
 
     @Override
     public void updateTransactions(Account account, Urllib urlopen)
-            throws LoginException, BankException {
+            throws LoginException, BankException, IOException {
         AccountType at = getAccuntType(account.getId());
         TransactionParams tp = mTransactionParams.get(at);
         if (at == null || tp == null || !tp.isValid() || !isFirstAccountForType(account.getId())) {
             return;
         }
-        try {
-            String data = URLEncoder.encode(String
-                    .format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}",
-                            tp.getMinDate(), tp.getMaxDate()), "utf-8");
-            String url = String
-                    .format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s",
-                            tp.getPageGuid(), data, System.currentTimeMillis());
-            WebTransactionHistoryResponse transactionsResponse = getObjectmapper()
-                    .readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
-            if (transactionsResponse != null && transactionsResponse.getModel() != null) {
-                List<Transaction> transactions = new ArrayList<>();
-                account.setTransactions(transactions);
-                for (Result r : transactionsResponse.getModel().getResults()) {
-                    StringBuilder title = new StringBuilder(
-                            !TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
-                    if (!TextUtils.isEmpty(r.getCardholder())) {
-                        title.append(" (").append(r.getCardholder()).append(")");
-                    }
-                    if (r.getDate() != null) {
-                        transactions.add(new Transaction(formatDate(r.getDate()), title.toString(),
-                                BigDecimal.valueOf(r.getSum())));
-                    }
+
+        String data = URLEncoder.encode(String
+                .format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}",
+                        tp.getMinDate(), tp.getMaxDate()), "utf-8");
+        String url = String
+                .format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s",
+                        tp.getPageGuid(), data, System.currentTimeMillis());
+        WebTransactionHistoryResponse transactionsResponse = getObjectmapper()
+                .readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
+        if (transactionsResponse != null && transactionsResponse.getModel() != null) {
+            List<Transaction> transactions = new ArrayList<>();
+            account.setTransactions(transactions);
+            for (Result r : transactionsResponse.getModel().getResults()) {
+                StringBuilder title = new StringBuilder(
+                        !TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
+                if (!TextUtils.isEmpty(r.getCardholder())) {
+                    title.append(" (").append(r.getCardholder()).append(")");
+                }
+                if (r.getDate() != null) {
+                    transactions.add(new Transaction(formatDate(r.getDate()), title.toString(),
+                            BigDecimal.valueOf(r.getSum())));
                 }
             }
-        } catch (Exception e) {
-            e.printStackTrace();
         }
     }
 

commit d9dbaa535bdecb9b32f6bb97b3f230daed05c17f
Merge: 7d74e9e 41929e0
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 24 14:01:27 2015 +0100

    Merge pull request #515 from liato/feature/paypal-ertificate
    
    Update certificate for Paypal

commit 7d74e9ed05add0e660d779094c7a7ddab5207e7c
Merge: f9fb01a 2cae736
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 24 14:00:51 2015 +0100

    Merge pull request #516 from liato/feature/jojo-multiple-cards
    
    Adds support for paginated list of Jojo cards.

commit 2cae7361cc6a240de5f6ea69b7c234c0bebd0a15
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Mar 24 12:59:16 2015 +0100

    Adds support for paginated list of Jojo cards.
    
    Fixes #510

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 926bfca..fc0d358 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -38,7 +38,9 @@ import android.text.InputType;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.NoSuchElementException;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -110,16 +112,14 @@ public class Jojo extends Bank {
         }
         urlopen = login();
 
-        Document d = Jsoup.parse(response);
-        Elements cards = d.select(".my_cards_allinfo table tbody");
-        if (!cards.isEmpty()) {
-            for (Element card : cards) {
-                String cardNumber = card.select("tr:first-child td").text().trim();
-                BigDecimal saldo = getSaldo(cardNumber);
-                String name = card.select("tr:nth-child(2) td").text().trim();
-                String displayName = NAME_NOT_SET.equals(name) ? cardNumber : name;
-                accounts.add(new Account(displayName, saldo, cardNumber));
-                balance = balance.add(saldo);
+        Iterator<Account> it = new AccountIterator(response);
+        while (it.hasNext()) {
+            try {
+                Account account = it.next();
+                accounts.add(account);
+                balance.add(account.getBalance());
+            } catch (NoSuchElementException e) {
+                throw new BankException(res.getText(R.string.server_error_try_again).toString(), e);
             }
         }
 
@@ -147,4 +147,70 @@ public class Jojo extends Bank {
         }
         return BigDecimal.ZERO;
     }
+
+    private class AccountIterator implements Iterator<Account> {
+
+        private Document mDocument;
+
+        private Iterator<Element> mCards;
+
+        private String mNextUrl;
+
+        public AccountIterator(String response) {
+            setDocument(response);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return mCards.hasNext() || mNextUrl != null;
+        }
+
+        @Override
+        public Account next() {
+            if (!mCards.hasNext()) {
+                fetchNextPage();
+            }
+            return toAccount(mCards.next());
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("Remove not supported");
+        }
+
+        private Elements parseCardElements() {
+            return mDocument.select(".my_cards_allinfo table tbody");
+        }
+
+        private String parseNextUrl() {
+            Element elem = mDocument.select("div.pageselector_pagenr a").last();
+            if (elem.select("span.pageselect_prevnext_selected").isEmpty()) {
+                return null;
+            }
+            return elem.attr("href");
+        }
+
+        private void fetchNextPage() {
+            try {
+                String response = urlopen.open(URL + mNextUrl);
+                setDocument(response);
+            } catch (IOException e) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        private void setDocument(String response) {
+            mDocument = Jsoup.parse(response);
+            mCards = parseCardElements().iterator();
+            mNextUrl = parseNextUrl();
+        }
+
+        private Account toAccount(Element card) {
+            String cardNumber = card.select("tr:first-child td").text().trim();
+            BigDecimal saldo = getSaldo(cardNumber);
+            String name = card.select("tr:nth-child(2) td").text().trim();
+            String displayName = NAME_NOT_SET.equals(name) ? cardNumber : name;
+            return new Account(displayName, saldo, cardNumber);
+        }
+    }
 }

commit 41929e0b92e929fee29219173a646cef242d9d64
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Mar 24 11:24:56 2015 +0100

    Update certificate for Paypal

diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
index 3704c0c..044eb09 100644
--- bankdroid-legacy/src/main/res/raw/cert_paypal.pem
+++ bankdroid-legacy/src/main/res/raw/cert_paypal.pem
@@ -1,36 +1,40 @@
 -----BEGIN CERTIFICATE-----

-XPfzzQCJDYWaonDa

+n64=
 -----END CERTIFICATE-----
 www.paypal.com:443

commit f9fb01a6c850ba776eb27304040204d2f3a7a48b
Merge: 301efdf 1bc8611
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 22 19:39:22 2015 +0100

    Merge pull request #511 from liato/feature/rikskortet-remove-exceptions
    
    Remove catching of IOException for Rikskortet

commit 1bc86118e2856a76ea8632866cd2de1b44f64ce3
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 22 19:29:24 2015 +0100

    Remove catching of IOException in Bank class

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index c58dd43..30279eb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -25,7 +25,6 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
@@ -140,13 +139,7 @@ public class TicketRikskortet extends Bank {
         urlopen = login();
         if (!"https://www.edenred.se/sv/Apps/Employee/Start/".equalsIgnoreCase(
                 urlopen.getCurrentURI())) {
-            try {
-                response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/");
-            } catch (ClientProtocolException e) {
-                throw new BankException(e.getMessage(), e);
-            } catch (IOException e) {
-                throw new BankException(e.getMessage(), e);
-            }
+            response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/");
         }
 
         Matcher matcher = reBalance.matcher(response);

commit 301efdfff7885bf3895f8e32940d15fe1aca7db3 (tag: v1.9.9.0-RC1)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Mar 21 09:50:05 2015 +0100

    Creates release 1.9.9.0-RC1

diff --git CHANGELOG CHANGELOG
index 85e30a0..eb82633 100644
--- CHANGELOG
+++ CHANGELOG
@@ -1,3 +1,14 @@
+v1.9.9.0 (2015-03-21)
+* Adds support for Swedbank/Sparbankerna Corporate and Youth profiles.
+* Adds support for minpension.se.
+* Adds option to disable auto updates while roaming.
+* Removes Skandiabanken due to their new BankId requirement.
+* Fixes issue with Nordnet (thanks to jonasgroth).
+* Fixes crash when account is not available from widget.
+* Fixes transactions for Forex Bank (thanks to jonasgroth).
+* Fixes transaction issues for EspressoHouse.
+* Fixes Payson balance. NOTE: Transactions not supported yet (thanks to robho).
+* Fixes LockPattern crashes for Samsung Galaxy devices.
 v1.9.8.0 (2015-02-27)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
 * Adds support for EspressoHouse (thanks to fredrike)
diff --git app/build.gradle app/build.gradle
index da2e810..f416efb 100644
--- app/build.gradle
+++ app/build.gradle
@@ -27,8 +27,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 22
-        versionCode 202
-        versionName "1.9.8.0"
+        versionCode 208
+        versionName "1.9.9.0-RC1"
     }
 
     signingConfigs {

commit 691f3697ff58b79c7326649f9e63dba2d32d3faa
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Mar 21 09:33:39 2015 +0100

    Update certificate for Östgötatrafiken

diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
index 191f412..5207955 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
@@ -1,35 +1,32 @@
 -----BEGIN CERTIFICATE-----

-MCe7Jchh43bGAvJhOzi706Enkio=

+YQuw4+jd
 -----END CERTIFICATE-----
 webtick.ostgotatrafiken.se:443

commit f8020bb5d7c8c16caa7d9bc1f92df86c854d68d1
Merge: 5caad40 acb2782
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 17 15:35:42 2015 +0100

    Merge pull request #509 from liato/feature/lint
    
    Initial lint configuration.

commit 5caad40a1e0932e023645fce6da19672fadf7f2e
Merge: d88bfd5 6677069
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 17 15:35:34 2015 +0100

    Merge pull request #507 from liato/feature/pmd
    
    Adds PMD checks.

commit 6677069c110bb474d43331d301e955f7cd1b5834
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 16 21:46:24 2015 +0100

    Adds PMD checks.

diff --git config/quality/pmd/pmd-ruleset.xml config/quality/pmd/pmd-ruleset.xml
new file mode 100644
index 0000000..cf02c4c
--- /dev/null
+++ config/quality/pmd/pmd-ruleset.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Android Application Rules"
+    xmlns="http://pmd.sf.net/ruleset/1.0.0"
+    xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
+    xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
+
+    <description>Custom ruleset for Android application</description>
+
+    <exclude-pattern>.*/R.java</exclude-pattern>
+    <exclude-pattern>.*/gen/.*</exclude-pattern>
+
+    <rule ref="rulesets/java/android.xml">
+        <!-- Config.LOGD deprecated in API level 4 !-->
+        <exclude name="ProtectLogD" />
+        <!-- Config.LOGV deprecated in API level 4 !-->
+        <exclude name="ProtectLogV" />
+    </rule>
+    <rule ref="rulesets/java/clone.xml" />
+    <rule ref="rulesets/java/finalizers.xml" />
+    <rule ref="rulesets/java/imports.xml" />
+    <rule ref="rulesets/java/logging-java.xml" />
+    <rule ref="rulesets/java/braces.xml" />
+    <rule ref="rulesets/java/strings.xml" />
+    <rule ref="rulesets/java/basic.xml" />
+    <rule ref="rulesets/java/naming.xml">
+        <exclude name="AbstractNaming" />
+        <exclude name="LongVariable" />
+        <exclude name="LongMethodName" />
+        <exclude name="ShortMethodName" />
+        <exclude name="ShortVariable" />
+        <exclude name="VariableNamingConventions" />
+    </rule>
+</ruleset>
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 5506ef5..49a6144 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -1,8 +1,9 @@
 apply plugin: 'checkstyle'
 apply plugin: 'findbugs'
+apply plugin: 'pmd'
 
 // Add checkstyle, findbugs and lint to the check task.
-check.dependsOn 'checkstyle', 'lint', 'findbugs'
+check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'lint'
 
 task checkstyle(type: Checkstyle) {
     configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
@@ -48,3 +49,24 @@ task findbugs(type: FindBugs) {
 
     classpath = files()
 }
+
+task pmd(type: Pmd) {
+    ruleSetFiles = files("${project.rootDir}/config/quality/pmd/pmd-ruleset.xml")
+    ignoreFailures = true // TODO Set to false when project has been cleaned.
+    ruleSets = []
+
+    source 'src'
+    include '**/*.java'
+    exclude '**/generated/**'
+
+    reports {
+        xml.enabled = false
+        html.enabled = true
+        xml {
+            destination "$project.buildDir/reports/pmd/pmd.xml"
+        }
+        html {
+            destination "$project.buildDir/reports/pmd/pmd.html"
+        }
+    }
+}

commit acb27825f49e203fb292c6638ff2ad12e178a301
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 16 22:14:47 2015 +0100

    Initial lint configuration.

diff --git config/quality/lint/lint.xml config/quality/lint/lint.xml
new file mode 100644
index 0000000..293d793
--- /dev/null
+++ config/quality/lint/lint.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+    <issue id="AdapterViewChildren" severity="ignore" />
+    <issue id="AllowBackup" severity="ignore" />
+    <issue id="AlwaysShowAction" severity="ignore" />
+    <issue id="ButtonCase" severity="ignore" />
+    <issue id="ButtonOrder" severity="ignore" />
+    <issue id="ButtonStyle" severity="ignore" />
+    <issue id="CommitPrefEdits" severity="ignore" />
+    <issue id="CommitTransaction" severity="ignore" />
+    <issue id="ContentDescription" severity="ignore" />
+    <issue id="CutPasteId" severity="ignore" />
+    <issue id="DalvikOverride" severity="ignore" />
+    <issue id="DefaultLocale" severity="ignore" />
+    <issue id="Deprecated" severity="ignore" />
+    <issue id="DeviceAdmin" severity="ignore" />
+    <issue id="DisableBaselineAlignment" severity="ignore" />
+    <issue id="DrawAllocation" severity="ignore" />
+    <issue id="DuplicateActivity" severity="ignore" />
+    <issue id="DuplicateDefinition" severity="ignore" />
+    <issue id="DuplicateIds" severity="ignore" />
+    <issue id="DuplicateIncludedIds" severity="ignore" />
+    <issue id="DuplicateUsesFeature" severity="ignore" />
+    <issue id="EnforceUTF8" severity="ignore" />
+    <issue id="ExportedContentProvider" severity="ignore" />
+    <issue id="ExportedReceiver" severity="ignore" />
+    <issue id="ExportedService" severity="ignore" />
+    <issue id="ExtraText" severity="ignore" />
+    <issue id="ExtraTranslation" severity="ignore" />
+    <issue id="FloatMath" severity="ignore" />
+    <issue id="GifUsage" severity="ignore" />
+    <issue id="GradleOverrides" severity="ignore" />
+    <issue id="GrantAllUris" severity="ignore" />
+    <issue id="GridLayout" severity="ignore" />
+    <issue id="HandlerLeak" severity="ignore" />
+    <issue id="HardcodedDebugMode" severity="ignore" />
+    <issue id="HardcodedText" severity="ignore" />
+    <issue id="IconColors" severity="ignore" />
+    <issue id="IconDensities" severity="error" />
+    <issue id="IconDipSize" severity="error" />
+    <issue id="IconDuplicates" severity="ignore" />
+    <issue id="IconDuplicatesConfig" severity="ignore" />
+    <issue id="IconExtension" severity="ignore" />
+    <issue id="IconLauncherShape" severity="ignore" />
+    <issue id="IconLocation" severity="ignore" />
+    <issue id="IconMissingDensityFolder" severity="ignore" />
+    <issue id="IconMixedNinePatch" severity="ignore" />
+    <issue id="IconNoDpi" severity="ignore" />
+    <issue id="IconXmlAndPng" severity="ignore" />
+    <issue id="IllegalResourceRef" severity="ignore" />
+    <issue id="InOrMmUsage" severity="ignore" />
+    <issue id="InconsistentArrays" severity="ignore" />
+    <issue id="InconsistentLayout" severity="ignore" />
+    <issue id="InefficientWeight" severity="ignore" />
+    <issue id="InlinedApi" severity="ignore" />
+    <issue id="InnerclassSeparator" severity="ignore" />
+    <issue id="Instantiatable" severity="ignore" />
+    <issue id="InvalidId" severity="ignore" />
+    <issue id="InvalidPackage" severity="ignore" />
+    <issue id="JavascriptInterface" severity="ignore" />
+    <issue id="LabelFor" severity="ignore" />
+    <issue id="LibraryCustomView" severity="ignore" />
+    <issue id="LocalSuppress" severity="ignore" />
+    <issue id="MangledCRLF" severity="ignore" />
+    <issue id="ManifestOrder" severity="ignore" />
+    <issue id="ManifestTypo" severity="ignore" />
+    <issue id="MenuTitle" severity="ignore" />
+    <issue id="MergeRootFrame" severity="ignore" />
+    <issue id="MissingApplicationIcon" severity="ignore" />
+    <issue id="MissingId" severity="ignore" />
+    <issue id="MissingPrefix" severity="ignore" />
+    <issue id="MissingQuantity" severity="ignore" />
+    <issue id="MissingRegistered" severity="ignore" />
+    <issue id="MissingSuperCall" severity="ignore" />
+    <issue id="MissingTranslation" severity="ignore" />
+    <issue id="MissingVersion" severity="ignore" />
+    <issue id="MockLocation" severity="ignore" />
+    <issue id="MultipleUsesSdk" severity="ignore" />
+    <issue id="NamespaceTypo" severity="ignore" />
+    <issue id="NestedScrolling" severity="ignore" />
+    <issue id="NestedWeights" severity="ignore" />
+    <issue id="NewApi" severity="ignore" />
+    <issue id="NotSibling" severity="ignore" />
+    <issue id="ObsoleteLayoutParam" severity="ignore" />
+    <issue id="OldTargetApi" severity="ignore" />
+    <issue id="OnClick" severity="ignore" />
+    <issue id="Orientation" severity="ignore" />
+    <issue id="Overdraw" severity="ignore" />
+    <issue id="Override" severity="ignore" />
+    <issue id="PackagedPrivateKey" severity="ignore" />
+    <issue id="ParcelCreator" severity="ignore" />
+    <issue id="PrivateResource" severity="ignore" />
+    <issue id="Proguard" severity="ignore" />
+    <issue id="ProguardSplit" severity="ignore" />
+    <issue id="ProtectedPermissions" severity="ignore" />
+    <issue id="PxUsage" severity="ignore" />
+    <issue id="Recycle" severity="ignore" />
+    <issue id="Registered" severity="ignore" />
+    <issue id="RequiredSize" severity="ignore" />
+    <issue id="ResAuto" severity="ignore" />
+    <issue id="ResourceAsColor" severity="ignore" />
+    <issue id="ScrollViewCount" severity="ignore" />
+    <issue id="ScrollViewSize" severity="ignore" />
+    <issue id="SdCardPath" severity="ignore" />
+    <issue id="SecureRandom" severity="ignore" />
+    <issue id="ServiceCast" severity="ignore" />
+    <issue id="SetJavaScriptEnabled" severity="ignore" />
+    <issue id="ShowToast" severity="ignore" />
+    <issue id="SimpleDateFormat" severity="ignore" />
+    <issue id="SmallSp" severity="ignore" />
+    <issue id="SpUsage" severity="ignore" />
+    <issue id="StateListReachable" severity="ignore" />
+    <issue id="StringFormatCount" severity="ignore" />
+    <issue id="StringFormatInvalid" severity="ignore" />
+    <issue id="StringFormatMatches" severity="ignore" />
+    <issue id="StyleCycle" severity="ignore" />
+    <issue id="Suspicious0dp" severity="ignore" />
+    <issue id="SuspiciousImport" severity="ignore" />
+    <issue id="TextFields" severity="ignore" />
+    <issue id="TextViewEdits" severity="ignore" />
+    <issue id="TooDeepLayout" severity="ignore" />
+    <issue id="TooManyViews" severity="ignore" />
+    <issue id="TrulyRandom" severity="ignore" />
+    <issue id="TypographyDashes" severity="ignore" />
+    <issue id="TypographyEllipsis" severity="ignore" />
+    <issue id="TypographyFractions" severity="ignore" />
+    <issue id="TypographyOther" severity="ignore" />
+    <issue id="Typos" severity="ignore" />
+    <issue id="UniquePermission" severity="ignore" />
+    <issue id="UnknownId" severity="ignore" />
+    <issue id="UnknownIdInLayout" severity="ignore" />
+    <issue id="UnlocalizedSms" severity="ignore" />
+    <issue id="UnusedNamespace" severity="ignore" />
+    <issue id="UnusedQuantity" severity="ignore" />
+    <issue id="UnusedResources" severity="ignore" />
+    <issue id="UseCheckPermission" severity="ignore" />
+    <issue id="UseCompoundDrawables" severity="ignore" />
+    <issue id="UseSparseArrays" severity="ignore" />
+    <issue id="UseValueOf" severity="ignore" />
+    <issue id="UselessLeaf" severity="ignore" />
+    <issue id="UselessParent" severity="ignore" />
+    <issue id="UsesMinSdkAttributes" severity="ignore" />
+    <issue id="ValidFragment" severity="ignore" />
+    <issue id="ViewConstructor" severity="ignore" />
+    <issue id="ViewTag" severity="ignore" />
+    <issue id="Wakelock" severity="ignore" />
+    <issue id="WorldReadableFiles" severity="ignore" />
+    <issue id="WorldWriteableFiles" severity="ignore" />
+    <issue id="WrongCall" severity="ignore" />
+    <issue id="WrongCase" severity="ignore" />
+    <issue id="WrongFolder" severity="ignore" />
+    <issue id="WrongManifestParent" severity="ignore" />
+    <issue id="WrongViewCast" severity="ignore" />
+</lint>
diff --git config/quality/quality.gradle config/quality/quality.gradle
index 5506ef5..af048b3 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -21,6 +21,11 @@ checkstyle {
 android {
     lintOptions {
         abortOnError false // TODO Set to true when project has been cleaned.
+        lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
+
+        htmlReport true
+        // optional path to report (default will be lint-results.html in the builddir)
+        htmlOutput file("$project.buildDir/reports/lint/lint.html")
     }
 }
 

commit d88bfd50920de3fce8602695fa9d9cfa6f851837
Merge: 22b2e1f 486c082
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 17 15:13:24 2015 +0100

    Merge pull request #508 from liato/feature/findbugs-fix
    
    Fixes findbugs scan issue.

commit 486c082bda8cf7738ff016bef00378567d9771ef
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 16 22:03:36 2015 +0100

    Fixes findbugs scan issue.
    
    Now findbugs will scan all sub modules and not only the app module.

diff --git config/quality/quality.gradle config/quality/quality.gradle
index 5506ef5..6061040 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -29,7 +29,7 @@ task findbugs(type: FindBugs) {
     effort = "max"
     reportLevel = "high"
     excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")
-    classes = files("${project.rootDir}/app/build/intermediates/classes")
+    classes = files("$project.buildDir/intermediates/classes")
 
     source 'src'
     include '**/*.java'

commit 22b2e1fa72591341a4516fe48d08a396bc693647
Merge: a5660bd 20393e4
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Mar 16 15:56:01 2015 +0100

    Merge pull request #506 from liato/feature/findbugs
    
    Adds initial support for findbugs checks

commit 20393e45f599151ea1e6976b4e95f42fdf1774d7
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 16 14:02:39 2015 +0100

    Adds initial support for findbugs checks

diff --git .travis.yml .travis.yml
index 3f1cc66..b0adc4b 100644
--- .travis.yml
+++ .travis.yml
@@ -10,7 +10,7 @@ android:
     - extra-android-m2repository
     - android-22
 
-script: ./gradlew check
+script: ./gradlew assembleDebug check
 
 notifications:
   email: false
diff --git config/quality/findbugs/findbugs-filter.xml config/quality/findbugs/findbugs-filter.xml
new file mode 100644
index 0000000..8b00090
--- /dev/null
+++ config/quality/findbugs/findbugs-filter.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<FindBugsFilter>
+    <!-- http://stackoverflow.com/questions/7568579/eclipsefindbugs-exclude-filter-files-doesnt-work -->
+    <Match>
+        <Class name="~.*\.R\$.*"/>
+    </Match>
+    <Match>
+        <Class name="~.*\.Manifest\$.*"/>
+    </Match>
+    <!-- All bugs in test classes, except for JUnit-specific bugs -->
+    <Match>
+        <Class name="~.*\.*Test" />
+        <Not>
+            <Bug code="IJU" />
+        </Not>
+    </Match>
+</FindBugsFilter>
diff --git config/quality/quality.gradle config/quality/quality.gradle
index e6a9c47..5506ef5 100644
--- config/quality/quality.gradle
+++ config/quality/quality.gradle
@@ -1,7 +1,8 @@
 apply plugin: 'checkstyle'
+apply plugin: 'findbugs'
 
-// Add checkstyle and lint to the check task.
-check.dependsOn 'checkstyle', 'lint'
+// Add checkstyle, findbugs and lint to the check task.
+check.dependsOn 'checkstyle', 'lint', 'findbugs'
 
 task checkstyle(type: Checkstyle) {
     configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
@@ -22,3 +23,28 @@ android {
         abortOnError false // TODO Set to true when project has been cleaned.
     }
 }
+
+task findbugs(type: FindBugs) {
+    ignoreFailures = true // TODO Set to false when project has been cleaned.
+    effort = "max"
+    reportLevel = "high"
+    excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")
+    classes = files("${project.rootDir}/app/build/intermediates/classes")
+
+    source 'src'
+    include '**/*.java'
+    exclude '**/generated/**'
+
+    reports {
+        xml.enabled = false
+        html.enabled = true
+        xml {
+            destination "$project.buildDir/reports/findbugs/findbugs.xml"
+        }
+        html {
+            destination "$project.buildDir/reports/findbugs/findbugs.html"
+        }
+    }
+
+    classpath = files()
+}

commit a5660bd5e7255a1c97545a0af60e13b2f5baae36
Merge: 9d074a1 096d565
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 15 18:01:33 2015 +0100

    Merge pull request #504 from liato/feature/format-codebase
    
    Reformat codebase to conform to the newly added codingstyle.

commit 9d074a15c4e4212eb02f2d80cd5c33c25696b2df
Merge: cfdad6e 675b000
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 15 15:34:39 2015 +0100

    Merge pull request #505 from liato/feature/tuning-checkstyle
    
    Tuning checkstyle.

commit 675b000b1ff2a9a87908cda06f07fb2954974c2d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 15 12:11:15 2015 +0100

    Tuning checkstyle.
    
    Disabled checks: MethodLength, EmptyBlock, MagicNumber, MissingSwitchStatement
    Added content:// to ignorePattern for LineLength

diff --git config/quality/checkstyle/checkstyle.xml config/quality/checkstyle/checkstyle.xml
index 0fc6033..fa1b9cd 100644
--- config/quality/checkstyle/checkstyle.xml
+++ config/quality/checkstyle/checkstyle.xml
@@ -40,7 +40,7 @@
         <module name="IllegalImport" />
         <module name="RedundantImport" />
         <module name="UnusedImports" />
-        <module name="MethodLength" />
+       <!-- <module name="MethodLength" /> -->
         <module name="ParameterNumber" />
         <module name="EmptyForIteratorPad" />
         <module name="MethodParamPad" />
@@ -58,7 +58,7 @@
         <module name="ModifierOrder" />
         <module name="RedundantModifier" />
         <module name="AvoidNestedBlocks" />
-        <module name="EmptyBlock" />
+        <!--<module name="EmptyBlock" />-->
         <module name="LeftCurly" />
         <module name="NeedBraces" />
         <module name="RightCurly" />
@@ -66,8 +66,8 @@
         <module name="EqualsHashCode" />
         <module name="IllegalInstantiation" />
         <module name="InnerAssignment" />
-        <module name="MagicNumber" />
-        <module name="MissingSwitchDefault" />
+        <!-- <module name="MagicNumber" /> -->
+        <!--<module name="MissingSwitchDefault" />-->
         <module name="SimplifyBooleanExpression" />
         <module name="SimplifyBooleanReturn" />
         <module name="FinalClass" />
@@ -76,12 +76,12 @@
         <module name="ArrayTypeStyle" />
 
         <module name="UpperEll" />
-        <module name="MethodLength">
+      <!--  <module name="MethodLength">
             <property name="max" value="40" />
-        </module>
+        </module> -->
         <module name="LineLength">
             <property name="max" value="100" />
-             <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
+             <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://|content://"/>
         </module>
         <module name="InnerTypeLast" />
     </module>

commit 096d565e3d1ab004bec53cfed2b08d6eab000b3e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 15 11:54:50 2015 +0100

    Reformat codebase to conform to the newly added codingstyle.
    
    NOTE: The commit only includes the run of Ctrl + Alt + L (Reformat code) from AndroidStudio on the java folders
    with Optimize imports, Rearrange entries and Include subdirectories checked.

diff --git app/src/main/java/com/ast/util/CookieParser.java app/src/main/java/com/ast/util/CookieParser.java
index ebd6418..a8b33fb 100644
--- app/src/main/java/com/ast/util/CookieParser.java
+++ app/src/main/java/com/ast/util/CookieParser.java
@@ -26,32 +26,22 @@ package com.ast.util;
 public class CookieParser {
 
     /**
-     * Abstract representation of an HTTP cookie.
-     */
-    public static class Cookie {
-
-        public String host;
-        public String value; // cookie string without the leading intro: "Set-Cookie: "
-        public String expires;
-        public String path;
-        public String domain;
-        public String sessionId;
-        public boolean secure;
-    }
-
-    /**
-     * Parses the given <tt>setCookieString</tt> from an HTTP response and creates a {@link Cookie} from it.
+     * Parses the given <tt>setCookieString</tt> from an HTTP response and creates a {@link Cookie}
+     * from it.
      * The {@link Cookie} can be used by clients to send cookie on subsequent requests.
      *
-     * @param host <code>String</code> cookie host
+     * @param host            <code>String</code> cookie host
      * @param setCookieString <code>String</code> complete cookie string
      * @return a {@link Cookie} that was created from the given <tt>setCookieString</tt>
      */
     public static Cookie parse(String host, String setCookieString) {
 
-        if (host == null) throw new IllegalArgumentException("Parameter \"host\" must not be null");
-        if (setCookieString == null)
+        if (host == null) {
+            throw new IllegalArgumentException("Parameter \"host\" must not be null");
+        }
+        if (setCookieString == null) {
             throw new IllegalArgumentException("Parameter \"setCookieString\" must not be null");
+        }
 
         Cookie result = new Cookie();
 
@@ -59,7 +49,7 @@ public class CookieParser {
         String[] fields = setCookieString.split(";\\s*");
         result.host = host;
 
-        // ignore leading cookie intro 
+        // ignore leading cookie intro
         result.value = fields[0].startsWith("Set-Cookie: ") ? fields[0].substring(12) : fields[0];
         if (result.value.startsWith("JSESSIONID=")) {
             result.sessionId = result.value.substring(11);
@@ -83,4 +73,24 @@ public class CookieParser {
         return result;
     }
 
+    /**
+     * Abstract representation of an HTTP cookie.
+     */
+    public static class Cookie {
+
+        public String host;
+
+        public String value; // cookie string without the leading intro: "Set-Cookie: "
+
+        public String expires;
+
+        public String path;
+
+        public String domain;
+
+        public String sessionId;
+
+        public boolean secure;
+    }
+
 }
diff --git app/src/main/java/com/liato/bankdroid/AboutActivity.java app/src/main/java/com/liato/bankdroid/AboutActivity.java
index 7f7c72e..e0a6c6c 100644
--- app/src/main/java/com/liato/bankdroid/AboutActivity.java
+++ app/src/main/java/com/liato/bankdroid/AboutActivity.java
@@ -36,12 +36,14 @@ public class AboutActivity extends LockableActivity {
         PackageInfo pInfo;
         String version = "v1.x.x";
         try {
-            pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
+            pInfo = getPackageManager().getPackageInfo(getPackageName(),
+                    PackageManager.GET_META_DATA);
             version = pInfo.versionName;
         } catch (final NameNotFoundException e) {
             e.printStackTrace();
         }
-        ((TextView) findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));
+        ((TextView) findViewById(R.id.txtVersion)).setText(
+                getText(R.string.version).toString().replace("$version", version));
 
     }
 
diff --git app/src/main/java/com/liato/bankdroid/ActivityHelper.java app/src/main/java/com/liato/bankdroid/ActivityHelper.java
index 6aa0815..2fea3c1 100644
--- app/src/main/java/com/liato/bankdroid/ActivityHelper.java
+++ app/src/main/java/com/liato/bankdroid/ActivityHelper.java
@@ -8,15 +8,15 @@ import android.content.ContextWrapper;
 public class ActivityHelper {
 
     public static void dismissDialog(Dialog dialog) {
-        if(dialog.isShowing()) { //check if dialog is showing.
+        if (dialog.isShowing()) { //check if dialog is showing.
 
             //get the Context object that was used to great the dialog
             Context context = ((ContextWrapper) dialog.getContext()).getBaseContext();
 
             //if the Context used here was an activity AND it hasn't been finished
             //then dismiss it
-            if(context instanceof Activity) {
-                if(!((Activity)context).isFinishing()) {
+            if (context instanceof Activity) {
+                if (!((Activity) context).isFinishing()) {
                     dialog.dismiss();
                 }
             } else { //if the Context used wasnt an Activity, then dismiss it too
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index adcdd22..9ff784e 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -16,10 +16,17 @@
 
 package com.liato.bankdroid;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankChoice;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.NetworkUtils;
 
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
@@ -46,282 +53,294 @@ import android.widget.ImageView;
 import android.widget.Spinner;
 import android.widget.TextView;
 
-import com.crashlytics.android.Crashlytics;
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankChoice;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.utils.NetworkUtils;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class BankEditActivity extends LockableActivity
+        implements OnClickListener, OnItemSelectedListener {
+
+    private final static String TAG = "BankEditActivity";
+
+    private Bank SELECTED_BANK;
+
+    private long BANKID = -1;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.bank);
+        this.getWindow()
+                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
+        ArrayList<Bank> items = BankFactory.listBanks(this);
+        Collections.sort(items);
+        Spinner spnBanks = (Spinner) findViewById(R.id.spnBankeditBanklist);
+        BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, items);
+        spnBanks.setAdapter(adapter);
+        spnBanks.setOnItemSelectedListener(this);
 
-public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
-	private final static String TAG = "BankEditActivity";
-	private Bank SELECTED_BANK;
-	private long BANKID = -1;
-
-	@Override
-	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.bank);
-		this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 
-		ArrayList<Bank> items = BankFactory.listBanks(this);
-		Collections.sort(items);
-		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);
-		BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, items);
-		spnBanks.setAdapter(adapter);
-		spnBanks.setOnItemSelectedListener(this);
-
-		findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
-		findViewById(R.id.btnSettingsOk).setOnClickListener(this);
-
-		Bundle extras = getIntent().getExtras(); 
-		if (extras != null) {
-			BANKID = extras.getLong("id", -1);
-			if (BANKID != -1) {
-				Bank bank = BankFactory.bankFromDb(BANKID, this, false);
-				if (bank != null) {
-					((EditText)findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
-                    ((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
-                    ((EditText)findViewById(R.id.edtBankeditCustomName)).setText(bank.getCustomName());
+        findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
+        findViewById(R.id.btnSettingsOk).setOnClickListener(this);
+
+        Bundle extras = getIntent().getExtras();
+        if (extras != null) {
+            BANKID = extras.getLong("id", -1);
+            if (BANKID != -1) {
+                Bank bank = BankFactory.bankFromDb(BANKID, this, false);
+                if (bank != null) {
+                    ((EditText) findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
+                    ((EditText) findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
+                    ((EditText) findViewById(R.id.edtBankeditCustomName))
+                            .setText(bank.getCustomName());
                     if (bank.getExtras() != null) {
-                        ((EditText)findViewById(R.id.edtBankeditExtras)).setText(bank.getExtras());
+                        ((EditText) findViewById(R.id.edtBankeditExtras)).setText(bank.getExtras());
+                    }
+
+                    TextView errorDesc = (TextView) findViewById(R.id.txtErrorDesc);
+                    if (bank.isDisabled()) {
+                        errorDesc.setVisibility(View.VISIBLE);
+                    } else {
+                        errorDesc.setVisibility(View.INVISIBLE);
                     }
-                    
-					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
-					if (bank.isDisabled()) {
-						errorDesc.setVisibility(View.VISIBLE);
-					}
-					else {
-						errorDesc.setVisibility(View.INVISIBLE);
-					}
-					SELECTED_BANK = bank;
-					for (int i = 0; i < items.size(); i++) {
-						if (bank.getBanktypeId() == items.get(i).getBanktypeId()) {
-							spnBanks.setSelection(i);
-							break;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	@Override
-	public void onClick(View v) {
-		if (v.getId() == R.id.btnSettingsCancel) {
-			this.finish();
-		}
-		else if (v.getId() == R.id.btnSettingsOk){
-			SELECTED_BANK.setUsername(((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim());
-            SELECTED_BANK.setPassword(((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
-            SELECTED_BANK.setCustomName(((EditText) findViewById(R.id.edtBankeditCustomName)).getText().toString().trim());
-            SELECTED_BANK.setExtras(((EditText) findViewById(R.id.edtBankeditExtras)).getText().toString().trim());
-			SELECTED_BANK.setDbid(BANKID);
-			new DataRetrieverTask(this, SELECTED_BANK).execute();
-		}
-
-	}
-
-	@Override
-	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
-		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
-        EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
-        EditText edtExtras = (EditText)findViewById(R.id.edtBankeditExtras);
-        TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
-        TextView txtPassword = (TextView)findViewById(R.id.txtBankeditPassword);
-        TextView txtExtras = (TextView)findViewById(R.id.txtBankeditExtras);
-        
-		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
-		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
+                    SELECTED_BANK = bank;
+                    for (int i = 0; i < items.size(); i++) {
+                        if (bank.getBanktypeId() == items.get(i).getBanktypeId()) {
+                            spnBanks.setSelection(i);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.btnSettingsCancel) {
+            this.finish();
+        } else if (v.getId() == R.id.btnSettingsOk) {
+            SELECTED_BANK.setUsername(
+                    ((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString()
+                            .trim());
+            SELECTED_BANK.setPassword(
+                    ((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString()
+                            .trim());
+            SELECTED_BANK.setCustomName(
+                    ((EditText) findViewById(R.id.edtBankeditCustomName)).getText().toString()
+                            .trim());
+            SELECTED_BANK.setExtras(
+                    ((EditText) findViewById(R.id.edtBankeditExtras)).getText().toString().trim());
+            SELECTED_BANK.setDbid(BANKID);
+            new DataRetrieverTask(this, SELECTED_BANK).execute();
+        }
+
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
+        SELECTED_BANK = (Bank) parentView.getItemAtPosition(pos);
+        EditText edtUsername = (EditText) findViewById(R.id.edtBankeditUsername);
+        EditText edtPassword = (EditText) findViewById(R.id.edtBankeditPassword);
+        EditText edtExtras = (EditText) findViewById(R.id.edtBankeditExtras);
+        TextView txtUsername = (TextView) findViewById(R.id.txtBankeditUsername);
+        TextView txtPassword = (TextView) findViewById(R.id.txtBankeditPassword);
+        TextView txtExtras = (TextView) findViewById(R.id.txtBankeditExtras);
+
+        edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
+        edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
         txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
 
         edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
-		edtPassword.setTypeface(Typeface.MONOSPACE);
+        edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+        edtPassword.setTypeface(Typeface.MONOSPACE);
         txtPassword.setText(SELECTED_BANK.getInputTitlePassword());
 
         edtExtras.setInputType(SELECTED_BANK.getInputTypeExtras());
-        if ((SELECTED_BANK.getInputTypeExtras() & InputType.TYPE_TEXT_VARIATION_PASSWORD) == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
+        if ((SELECTED_BANK.getInputTypeExtras() & InputType.TYPE_TEXT_VARIATION_PASSWORD)
+                == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
             edtExtras.setTransformationMethod(PasswordTransformationMethod.getInstance());
             edtExtras.setTypeface(Typeface.MONOSPACE);
         }
         txtExtras.setText(SELECTED_BANK.getInputTitleExtras());
-		
+
         if (SELECTED_BANK.isInputUsernameHidden()) {
             edtUsername.setVisibility(View.GONE);
             txtUsername.setVisibility(View.GONE);
-        }
-        else {
+        } else {
             edtUsername.setVisibility(View.VISIBLE);
             txtUsername.setVisibility(View.VISIBLE);
         }
-        
+
         if (SELECTED_BANK.isInputPasswordHidden()) {
             edtPassword.setVisibility(View.GONE);
             txtPassword.setVisibility(View.GONE);
-        }
-        else {
+        } else {
             edtPassword.setVisibility(View.VISIBLE);
             txtPassword.setVisibility(View.VISIBLE);
         }
-        
+
         if (SELECTED_BANK.isInputExtrasHidden()) {
             edtExtras.setVisibility(View.GONE);
             txtExtras.setVisibility(View.GONE);
-        }
-        else {
+        } else {
             edtExtras.setVisibility(View.VISIBLE);
             txtExtras.setVisibility(View.VISIBLE);
-        }          
-	}
-
-	@Override
-	public void onNothingSelected(AdapterView<?> arg) {
-	}
-
-	private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
-		private LayoutInflater inflater;
-
-		@Override
-		public View getView(int position, View convertView, ViewGroup parent) {
-			if (convertView == null) {
-				convertView = inflater.inflate(R.layout.bank_spinner_item, parent, false);
-			}
-            ((TextView)convertView.findViewById(R.id.txtBank)).setText(((Bank)getItem(position)).getName());
-            ((ImageView)convertView.findViewById(R.id.imgBank)).setImageResource(((Bank)getItem(position)).getImageResource());
-			return convertView;			
-		}
-
-		public BankSpinnerAdapter(Context context, List<T> items) {
-		    super(context, R.layout.bank_spinner_item, R.id.txtBank, items);
-			inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-		}
-
-		@Override
-		public View getDropDownView(int position, View convertView,
-				ViewGroup parent) {
-			if (convertView == null) {
-				convertView = inflater.inflate(R.layout.bank_spinner_dropdown_item, parent, false);
-			}
-            ((TextView)convertView.findViewById(R.id.txtBank)).setText(((Bank)getItem(position)).getName());
-            ((ImageView)convertView.findViewById(R.id.imgBank)).setImageResource(((Bank)getItem(position)).getImageResource());
-			return convertView;
-		}
-
-
-	}
-	private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
-		private final ProgressDialog dialog = new ProgressDialog(BankEditActivity.this);
-		private Exception exc = null;
-		private Bank bank;
-		private BankEditActivity context;
-		private Resources res;
-
-		public DataRetrieverTask(BankEditActivity context, Bank bank) {
-			this.context = context;
-			this.res = context.getResources();
-			this.bank = bank;
-		}
-		protected void onPreExecute() {
-			this.dialog.setMessage(res.getText(R.string.logging_in));
-			this.dialog.show();
-		}
-
-		protected Void doInBackground(final String... args) {
-			try {
-				bank.update();
-				bank.updateAllTransactions();
-				bank.closeConnection();
-				DBAdapter.save(bank, context);
-
-				// Transactions updated.
-				final SharedPreferences prefs = PreferenceManager
-						.getDefaultSharedPreferences(getBaseContext());
-				if (prefs.getBoolean("content_provider_enabled", false)) {
-					final ArrayList<Account> accounts = bank.getAccounts();
-					for (final Account account : accounts) {
-						AutoRefreshService.broadcastTransactionUpdate(
-								getBaseContext(), bank.getDbId(),
-								account.getId());
-					}
-				}
-			} catch (BankException e) {
-				this.exc = e;
+        }
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> arg) {
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+    }
+
+    private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
+
+        private LayoutInflater inflater;
+
+        public BankSpinnerAdapter(Context context, List<T> items) {
+            super(context, R.layout.bank_spinner_item, R.id.txtBank, items);
+            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = inflater.inflate(R.layout.bank_spinner_item, parent, false);
+            }
+            ((TextView) convertView.findViewById(R.id.txtBank))
+                    .setText(((Bank) getItem(position)).getName());
+            ((ImageView) convertView.findViewById(R.id.imgBank))
+                    .setImageResource(((Bank) getItem(position)).getImageResource());
+            return convertView;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView,
+                ViewGroup parent) {
+            if (convertView == null) {
+                convertView = inflater.inflate(R.layout.bank_spinner_dropdown_item, parent, false);
+            }
+            ((TextView) convertView.findViewById(R.id.txtBank))
+                    .setText(((Bank) getItem(position)).getName());
+            ((ImageView) convertView.findViewById(R.id.imgBank))
+                    .setImageResource(((Bank) getItem(position)).getImageResource());
+            return convertView;
+        }
+
+
+    }
+
+    private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
+
+        private final ProgressDialog dialog = new ProgressDialog(BankEditActivity.this);
+
+        private Exception exc = null;
+
+        private Bank bank;
+
+        private BankEditActivity context;
+
+        private Resources res;
+
+        public DataRetrieverTask(BankEditActivity context, Bank bank) {
+            this.context = context;
+            this.res = context.getResources();
+            this.bank = bank;
+        }
+
+        protected void onPreExecute() {
+            this.dialog.setMessage(res.getText(R.string.logging_in));
+            this.dialog.show();
+        }
+
+        protected Void doInBackground(final String... args) {
+            try {
+                bank.update();
+                bank.updateAllTransactions();
+                bank.closeConnection();
+                DBAdapter.save(bank, context);
+
+                // Transactions updated.
+                final SharedPreferences prefs = PreferenceManager
+                        .getDefaultSharedPreferences(getBaseContext());
+                if (prefs.getBoolean("content_provider_enabled", false)) {
+                    final ArrayList<Account> accounts = bank.getAccounts();
+                    for (final Account account : accounts) {
+                        AutoRefreshService.broadcastTransactionUpdate(
+                                getBaseContext(), bank.getDbId(),
+                                account.getId());
+                    }
+                }
+            } catch (BankException e) {
+                this.exc = e;
                 Crashlytics.logException(e);
-			} catch (LoginException e) {
-				this.exc = e;
-			}
-            catch (BankChoiceException e) {
+            } catch (LoginException e) {
+                this.exc = e;
+            } catch (BankChoiceException e) {
                 this.exc = e;
             } catch (IOException e) {
                 this.exc = e;
-                if(NetworkUtils.isInternetAvailable()) {
+                if (NetworkUtils.isInternetAvailable()) {
                     Crashlytics.logException(e);
                 }
             }
-			return null;
-		}
+            return null;
+        }
 
-		protected void onPostExecute(final Void unused) {
-			AutoRefreshService.sendWidgetRefresh(context);
+        protected void onPostExecute(final Void unused) {
+            AutoRefreshService.sendWidgetRefresh(context);
             ActivityHelper.dismissDialog(this.dialog);
-			if (this.exc != null) {
-				AlertDialog.Builder builder = new AlertDialog.Builder(context);
-				if (this.exc instanceof BankChoiceException) {
-				    final BankChoiceException e = (BankChoiceException)exc;
-	                final String[] items = new String[e.getBanks().size()];
-	                int i = 0;
-	                for (BankChoice b : e.getBanks()) {
-	                    items[i] = b.getName();
-	                    i++;
-	                }
-	                builder.setTitle(R.string.select_a_bank);
-	                builder.setItems(items, new DialogInterface.OnClickListener() {
-	                    public void onClick(DialogInterface dialog, int item) {
-	                        SELECTED_BANK.setExtras(e.getBanks().get(item).getId());
-	                        new DataRetrieverTask(context, SELECTED_BANK).execute();
-	                    }
-	                });
-				}
-				else {
+            if (this.exc != null) {
+                AlertDialog.Builder builder = new AlertDialog.Builder(context);
+                if (this.exc instanceof BankChoiceException) {
+                    final BankChoiceException e = (BankChoiceException) exc;
+                    final String[] items = new String[e.getBanks().size()];
+                    int i = 0;
+                    for (BankChoice b : e.getBanks()) {
+                        items[i] = b.getName();
+                        i++;
+                    }
+                    builder.setTitle(R.string.select_a_bank);
+                    builder.setItems(items, new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int item) {
+                            SELECTED_BANK.setExtras(e.getBanks().get(item).getId());
+                            new DataRetrieverTask(context, SELECTED_BANK).execute();
+                        }
+                    });
+                } else {
                     exc.printStackTrace();
-                    builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
-    				.setIcon(android.R.drawable.ic_dialog_alert)
-    				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-    					public void onClick(DialogInterface dialog, int id) {
-    						dialog.cancel();
-    					}
-    				});
-				}
-				AlertDialog alert = builder.create();
-                if(!context.isFinishing()) {
+                    builder.setMessage(this.exc.getMessage())
+                            .setTitle(res.getText(R.string.could_not_create_account))
+                            .setIcon(android.R.drawable.ic_dialog_alert)
+                            .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int id) {
+                                    dialog.cancel();
+                                }
+                            });
+                }
+                AlertDialog alert = builder.create();
+                if (!context.isFinishing()) {
                     alert.show();
                 }
-			}
-			else {
-				context.finish();
-			}
-		}
-	}
-
-	@Override
-	protected void onResume() {
-		super.onResume();
-	}
-
-	@Override
-	protected void onPause() {
-		super.onPause();
-	}
-
-	@Override
-	protected void onSaveInstanceState(Bundle outState) {
-		super.onSaveInstanceState(outState);
-	}
-	
+            } else {
+                context.finish();
+            }
+        }
+    }
+
 }
diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index 6ab6fae..5dbf2f0 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -1,12 +1,12 @@
 package com.liato.bankdroid;
 
-import android.app.Application;
-import android.widget.Toast;
-
 import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
 
+import android.app.Application;
+import android.widget.Toast;
+
 import java.util.List;
 import java.util.Locale;
 
@@ -15,6 +15,7 @@ import io.fabric.sdk.android.Fabric;
 public class BankdroidApplication extends Application {
 
     public static final String LOG_KEY_LOCALE = "locale";
+
     public static final String LOG_KEY_BANKS = "banks";
 
     private String message = "";
@@ -35,7 +36,8 @@ public class BankdroidApplication extends Application {
                 bankStringBuilder.append(bank.getName())
                         .append(",");
             }
-            Crashlytics.setString(LOG_KEY_BANKS, bankStringBuilder.substring(0, bankStringBuilder.length() - 1));
+            Crashlytics.setString(LOG_KEY_BANKS,
+                    bankStringBuilder.substring(0, bankStringBuilder.length() - 1));
         }
     }
 
diff --git app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
index 9335936..3ba1a09 100644
--- app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
+++ app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
@@ -15,186 +15,186 @@ import android.widget.PopupWindow;
 
 /**
  * This class does most of the work of wrapping the {@link PopupWindow} so it's simpler to use.
- * 
+ *
  * @author qberticus
- * 
  */
 public class BetterPopupWindow {
-	protected final View anchor;
-	private final PopupWindow window;
-	private View root;
-	private Drawable background = null;
-	private final WindowManager windowManager;
-
-	/**
-	 * Create a BetterPopupWindow
-	 * 
-	 * @param anchor
-	 *            the view that the BetterPopupWindow will be displaying 'from'
-	 */
-	public BetterPopupWindow(View anchor) {
-		this.anchor = anchor;
-		this.window = new PopupWindow(anchor.getContext());
-
-		// when a touch even happens outside of the window
-		// make the window go away
-		this.window.setTouchInterceptor(new OnTouchListener() {
-			@Override
-			public boolean onTouch(View v, MotionEvent event) {
-				if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-					BetterPopupWindow.this.window.dismiss();
-					return true;
-				}
-				return false;
-			}
-		});
-
-		this.windowManager = (WindowManager) this.anchor.getContext().getSystemService(Context.WINDOW_SERVICE);
-		onCreate();
-	}
-
-	/**
-	 * Anything you want to have happen when created. Probably should create a view and setup the event listeners on
-	 * child views.
-	 */
-	protected void onCreate() {}
-
-	/**
-	 * In case there is stuff to do right before displaying.
-	 */
-	protected void onShow() {}
-
-	private void preShow() {
-		if(this.root == null) {
-			throw new IllegalStateException("setContentView was not called with a view to display.");
-		}
-		onShow();
-
-		if(this.background == null) {
-			this.window.setBackgroundDrawable(new BitmapDrawable());
-		} else {
-			this.window.setBackgroundDrawable(this.background);
-		}
-
-		// if using PopupWindow#setBackgroundDrawable this is the only values of the width and hight that make it work
-		// otherwise you need to set the background of the root viewgroup
-		// and set the popupwindow background to an empty BitmapDrawable
-		this.window.setWidth(WindowManager.LayoutParams.FILL_PARENT);
-		this.window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
-		this.window.setTouchable(true);
-		this.window.setFocusable(true);
-		this.window.setOutsideTouchable(true);
-
-		this.window.setContentView(this.root);
-	}
-
-	public void setBackgroundDrawable(Drawable background) {
-		this.background = background;
-	}
-
-	/**
-	 * Sets the content view. Probably should be called from {@link onCreate}
-	 * 
-	 * @param root
-	 *            the view the popup will display
-	 */
-	public void setContentView(View root) {
-		this.root = root;
-		this.window.setContentView(root);
-	}
-
-	/**
-	 * Will inflate and set the view from a resource id
-	 * 
-	 * @param layoutResID
-	 */
-	public void setContentView(int layoutResID) {
-		LayoutInflater inflator =
-				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-		this.setContentView(inflator.inflate(layoutResID, null));
-	}
-
-	/**
-	 * If you want to do anything when {@link dismiss} is called
-	 * 
-	 * @param listener
-	 */
-	public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
-		this.window.setOnDismissListener(listener);
-	}
-
-	/**
-	 * Displays like a popdown menu from the anchor view
-	 */
-	public void showLikePopDownMenu() {
-		this.showLikePopDownMenu(0, 0);
-	}
-
-	/**
-	 * Displays like a popdown menu from the anchor view.
-	 * 
-	 * @param xOffset
-	 *            offset in X direction
-	 * @param yOffset
-	 *            offset in Y direction
-	 */
-	public void showLikePopDownMenu(int xOffset, int yOffset) {
-		this.preShow();
-
-		this.window.setAnimationStyle(R.style.Animations_PopDownMenu);
-
-		this.window.showAsDropDown(this.anchor, xOffset, yOffset);
-	}
-
-	/**
-	 * Displays like a QuickAction from the anchor view.
-	 */
-	public void showLikeQuickAction() {
-		this.showLikeQuickAction(0, 0);
-	}
-
-	/**
-	 * Displays like a QuickAction from the anchor view.
-	 * 
-	 * @param xOffset
-	 *            offset in the X direction
-	 * @param yOffset
-	 *            offset in the Y direction
-	 */
-	public void showLikeQuickAction(int xOffset, int yOffset) {
-		this.preShow();
-
-		this.window.setAnimationStyle(R.style.Animations_GrowFromBottom);
-
-		int[] location = new int[2];
-		this.anchor.getLocationOnScreen(location);
-
-		Rect anchorRect =
-				new Rect(location[0], location[1], location[0] + this.anchor.getWidth(), location[1]
-					+ this.anchor.getHeight());
-
-		this.root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-
-		int rootWidth = this.root.getMeasuredWidth();
-		int rootHeight = this.root.getMeasuredHeight();
-
-		int screenWidth = this.windowManager.getDefaultDisplay().getWidth();
-		int screenHeight = this.windowManager.getDefaultDisplay().getHeight();
-
-		int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
-		int yPos = anchorRect.top - rootHeight + yOffset;
-
-		// display on bottom
-		if(rootHeight > anchorRect.top) {
-			yPos = anchorRect.bottom - yOffset;
-			this.window.setAnimationStyle(R.style.Animations_GrowFromTop);
-			this.root.findViewById(R.id.layPopupCont).setBackgroundResource(R.drawable.popup_bg_up);
-		}
-
-		this.window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos);
-	}
-
-	public void dismiss() {
-		this.window.dismiss();
-	}
+
+    protected final View anchor;
+
+    private final PopupWindow window;
+
+    private final WindowManager windowManager;
+
+    private View root;
+
+    private Drawable background = null;
+
+    /**
+     * Create a BetterPopupWindow
+     *
+     * @param anchor the view that the BetterPopupWindow will be displaying 'from'
+     */
+    public BetterPopupWindow(View anchor) {
+        this.anchor = anchor;
+        this.window = new PopupWindow(anchor.getContext());
+
+        // when a touch even happens outside of the window
+        // make the window go away
+        this.window.setTouchInterceptor(new OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+                    BetterPopupWindow.this.window.dismiss();
+                    return true;
+                }
+                return false;
+            }
+        });
+
+        this.windowManager = (WindowManager) this.anchor.getContext()
+                .getSystemService(Context.WINDOW_SERVICE);
+        onCreate();
+    }
+
+    /**
+     * Anything you want to have happen when created. Probably should create a view and setup the
+     * event listeners on
+     * child views.
+     */
+    protected void onCreate() {
+    }
+
+    /**
+     * In case there is stuff to do right before displaying.
+     */
+    protected void onShow() {
+    }
+
+    private void preShow() {
+        if (this.root == null) {
+            throw new IllegalStateException(
+                    "setContentView was not called with a view to display.");
+        }
+        onShow();
+
+        if (this.background == null) {
+            this.window.setBackgroundDrawable(new BitmapDrawable());
+        } else {
+            this.window.setBackgroundDrawable(this.background);
+        }
+
+        // if using PopupWindow#setBackgroundDrawable this is the only values of the width and hight that make it work
+        // otherwise you need to set the background of the root viewgroup
+        // and set the popupwindow background to an empty BitmapDrawable
+        this.window.setWidth(WindowManager.LayoutParams.FILL_PARENT);
+        this.window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
+        this.window.setTouchable(true);
+        this.window.setFocusable(true);
+        this.window.setOutsideTouchable(true);
+
+        this.window.setContentView(this.root);
+    }
+
+    public void setBackgroundDrawable(Drawable background) {
+        this.background = background;
+    }
+
+    /**
+     * Sets the content view. Probably should be called from {@link onCreate}
+     *
+     * @param root the view the popup will display
+     */
+    public void setContentView(View root) {
+        this.root = root;
+        this.window.setContentView(root);
+    }
+
+    /**
+     * Will inflate and set the view from a resource id
+     */
+    public void setContentView(int layoutResID) {
+        LayoutInflater inflator =
+                (LayoutInflater) this.anchor.getContext()
+                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        this.setContentView(inflator.inflate(layoutResID, null));
+    }
+
+    /**
+     * If you want to do anything when {@link dismiss} is called
+     */
+    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
+        this.window.setOnDismissListener(listener);
+    }
+
+    /**
+     * Displays like a popdown menu from the anchor view
+     */
+    public void showLikePopDownMenu() {
+        this.showLikePopDownMenu(0, 0);
+    }
+
+    /**
+     * Displays like a popdown menu from the anchor view.
+     *
+     * @param xOffset offset in X direction
+     * @param yOffset offset in Y direction
+     */
+    public void showLikePopDownMenu(int xOffset, int yOffset) {
+        this.preShow();
+
+        this.window.setAnimationStyle(R.style.Animations_PopDownMenu);
+
+        this.window.showAsDropDown(this.anchor, xOffset, yOffset);
+    }
+
+    /**
+     * Displays like a QuickAction from the anchor view.
+     */
+    public void showLikeQuickAction() {
+        this.showLikeQuickAction(0, 0);
+    }
+
+    /**
+     * Displays like a QuickAction from the anchor view.
+     *
+     * @param xOffset offset in the X direction
+     * @param yOffset offset in the Y direction
+     */
+    public void showLikeQuickAction(int xOffset, int yOffset) {
+        this.preShow();
+
+        this.window.setAnimationStyle(R.style.Animations_GrowFromBottom);
+
+        int[] location = new int[2];
+        this.anchor.getLocationOnScreen(location);
+
+        Rect anchorRect =
+                new Rect(location[0], location[1], location[0] + this.anchor.getWidth(), location[1]
+                        + this.anchor.getHeight());
+
+        this.root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+        int rootWidth = this.root.getMeasuredWidth();
+        int rootHeight = this.root.getMeasuredHeight();
+
+        int screenWidth = this.windowManager.getDefaultDisplay().getWidth();
+        int screenHeight = this.windowManager.getDefaultDisplay().getHeight();
+
+        int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
+        int yPos = anchorRect.top - rootHeight + yOffset;
+
+        // display on bottom
+        if (rootHeight > anchorRect.top) {
+            yPos = anchorRect.bottom - yOffset;
+            this.window.setAnimationStyle(R.style.Animations_GrowFromTop);
+            this.root.findViewById(R.id.layPopupCont).setBackgroundResource(R.drawable.popup_bg_up);
+        }
+
+        this.window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos);
+    }
+
+    public void dismiss() {
+        this.window.dismiss();
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index b0a9aea..b891631 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -16,18 +16,6 @@
 
 package com.liato.bankdroid;
 
-import java.io.IOException;
-import java.util.ArrayList;
-
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
 import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
@@ -39,130 +27,149 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.utils.NetworkUtils;
 
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
+
     private final static String TAG = "DataRetrieverTask";
-	private final ProgressDialog dialog;
-	private ArrayList<String> errors;
-	private final MainActivity parent;
-	private int bankcount;
-	private final Resources res;
-	private long bankId = -1;
-
-	public DataRetrieverTask(final MainActivity parent) {
-		this.parent = parent;
-		this.res = parent.getResources();
-		this.dialog = new ProgressDialog(parent);
-	}
-
-	public DataRetrieverTask(final MainActivity parent, final long bankId) {
-		this(parent);
-		this.bankId = bankId;
-	}
-
-	@Override
-	protected void onPreExecute() {
-		this.dialog.setMessage(res.getText(R.string.updating_account_balance)
-				+ "\n ");
-		this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-		this.dialog.setCancelable(false);
-		this.dialog.show();
-	}
-
-	@Override
-	protected Void doInBackground(final String... args) {
-		errors = new ArrayList<String>();
-		ArrayList<Bank> banks;
-		if (bankId != -1) {
-			banks = new ArrayList<Bank>();
-			banks.add(BankFactory.bankFromDb(bankId, parent, true));
-		} else {
-			banks = BankFactory.banksFromDb(parent, true);
-		}
-		bankcount = banks.size();
-		this.dialog.setMax(bankcount);
-		int i = 0;
-		for (final Bank bank : banks) {
-			publishProgress(new String[] { new Integer(i).toString(),
-					bank.getName() + " (" + bank.getUsername() + ")" });
-			if (bank.isDisabled()) {
-				continue;
-			}
-			try {
-				bank.update();
-				bank.updateAllTransactions();
-				bank.closeConnection();
-				DBAdapter.save(bank, parent);
-				i++;
-			} catch (final BankException e) {
-				this.errors.add(bank.getName() + " (" + bank.getUsername()
-						+ ")");
+
+    private final ProgressDialog dialog;
+
+    private final MainActivity parent;
+
+    private final Resources res;
+
+    private ArrayList<String> errors;
+
+    private int bankcount;
+
+    private long bankId = -1;
+
+    public DataRetrieverTask(final MainActivity parent) {
+        this.parent = parent;
+        this.res = parent.getResources();
+        this.dialog = new ProgressDialog(parent);
+    }
+
+    public DataRetrieverTask(final MainActivity parent, final long bankId) {
+        this(parent);
+        this.bankId = bankId;
+    }
+
+    @Override
+    protected void onPreExecute() {
+        this.dialog.setMessage(res.getText(R.string.updating_account_balance)
+                + "\n ");
+        this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+        this.dialog.setCancelable(false);
+        this.dialog.show();
+    }
+
+    @Override
+    protected Void doInBackground(final String... args) {
+        errors = new ArrayList<String>();
+        ArrayList<Bank> banks;
+        if (bankId != -1) {
+            banks = new ArrayList<Bank>();
+            banks.add(BankFactory.bankFromDb(bankId, parent, true));
+        } else {
+            banks = BankFactory.banksFromDb(parent, true);
+        }
+        bankcount = banks.size();
+        this.dialog.setMax(bankcount);
+        int i = 0;
+        for (final Bank bank : banks) {
+            publishProgress(new String[]{new Integer(i).toString(),
+                    bank.getName() + " (" + bank.getUsername() + ")"});
+            if (bank.isDisabled()) {
+                continue;
+            }
+            try {
+                bank.update();
+                bank.updateAllTransactions();
+                bank.closeConnection();
+                DBAdapter.save(bank, parent);
+                i++;
+            } catch (final BankException e) {
+                this.errors.add(bank.getName() + " (" + bank.getUsername()
+                        + ")");
 
                 Crashlytics.logException(e);
-			} catch (final LoginException e) {
-				this.errors.add(bank.getName() + " (" + bank.getUsername()
-						+ ")");
-				DBAdapter.disable(bank, parent);
-			} catch (BankChoiceException e) {
+            } catch (final LoginException e) {
+                this.errors.add(bank.getName() + " (" + bank.getUsername()
+                        + ")");
+                DBAdapter.disable(bank, parent);
+            } catch (BankChoiceException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
                 Log.e(TAG, "BankChoiceError: " + e.getMessage());
-            } catch(IOException e) {
+            } catch (IOException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
-                if(NetworkUtils.isInternetAvailable()) {
+                if (NetworkUtils.isInternetAvailable()) {
                     Crashlytics.logException(e);
                 }
             }
 
-			final SharedPreferences prefs = PreferenceManager
-					.getDefaultSharedPreferences(parent);
-			if (prefs.getBoolean("content_provider_enabled", false)) {
-				final ArrayList<Account> accounts = bank.getAccounts();
-				for (final Account account : accounts) {
-					AutoRefreshService.broadcastTransactionUpdate(parent,
-							bank.getDbId(), account.getId());
-				}
-			}
-		}
-		publishProgress(new String[] { new Integer(i).toString(), "" });
-		return null;
-	}
-
-	@Override
-	protected void onProgressUpdate(final String... args) {
-		this.dialog.setProgress(new Integer(args[0]));
-		this.dialog.setMessage(res.getText(R.string.updating_account_balance)
-				+ "\n" + args[1]);
-	}
-
-	@Override
-	protected void onPostExecute(final Void unused) {
-		parent.refreshView();
-		AutoRefreshService.sendWidgetRefresh(parent);
-		ActivityHelper.dismissDialog(this.dialog);
-
-		if ((this.errors != null) && !this.errors.isEmpty()) {
-			final StringBuilder errormsg = new StringBuilder();
-			errormsg.append(res.getText(R.string.accounts_were_not_updated)
-					+ ":\n");
-			for (final String err : errors) {
-				errormsg.append(err);
-				errormsg.append("\n");
-			}
-			final AlertDialog.Builder builder = new AlertDialog.Builder(parent);
-			builder.setMessage(errormsg.toString())
-					.setTitle(res.getText(R.string.errors_when_updating))
-					.setIcon(android.R.drawable.ic_dialog_alert)
-					.setNeutralButton("Ok",
-							new DialogInterface.OnClickListener() {
-								public void onClick(
-										final DialogInterface dialog,
-										final int id) {
-									dialog.cancel();
-								}
-							});
-			final AlertDialog alert = builder.create();
-			alert.show();
-		}
-	}
+            final SharedPreferences prefs = PreferenceManager
+                    .getDefaultSharedPreferences(parent);
+            if (prefs.getBoolean("content_provider_enabled", false)) {
+                final ArrayList<Account> accounts = bank.getAccounts();
+                for (final Account account : accounts) {
+                    AutoRefreshService.broadcastTransactionUpdate(parent,
+                            bank.getDbId(), account.getId());
+                }
+            }
+        }
+        publishProgress(new String[]{new Integer(i).toString(), ""});
+        return null;
+    }
+
+    @Override
+    protected void onProgressUpdate(final String... args) {
+        this.dialog.setProgress(new Integer(args[0]));
+        this.dialog.setMessage(res.getText(R.string.updating_account_balance)
+                + "\n" + args[1]);
+    }
+
+    @Override
+    protected void onPostExecute(final Void unused) {
+        parent.refreshView();
+        AutoRefreshService.sendWidgetRefresh(parent);
+        ActivityHelper.dismissDialog(this.dialog);
+
+        if ((this.errors != null) && !this.errors.isEmpty()) {
+            final StringBuilder errormsg = new StringBuilder();
+            errormsg.append(res.getText(R.string.accounts_were_not_updated)
+                    + ":\n");
+            for (final String err : errors) {
+                errormsg.append(err);
+                errormsg.append("\n");
+            }
+            final AlertDialog.Builder builder = new AlertDialog.Builder(parent);
+            builder.setMessage(errormsg.toString())
+                    .setTitle(res.getText(R.string.errors_when_updating))
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setNeutralButton("Ok",
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(
+                                        final DialogInterface dialog,
+                                        final int id) {
+                                    dialog.cancel();
+                                }
+                            });
+            final AlertDialog alert = builder.create();
+            alert.show();
+        }
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index 3e3a98b..988ed85 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -16,6 +16,9 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
@@ -36,38 +39,43 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 
-import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
-import com.liato.bankdroid.lockpattern.LockPatternUtils;
-
 public class LockableActivity extends ActionBarActivity {
+
     private static int PATTERNLOCK_UNLOCK = 42;
-	private SharedPreferences mPrefs;
-	private Editor mEditor;
-	private LockPatternUtils mLockPatternUtils;
-	private boolean mHasLoaded = false;
-	protected boolean mSkipLockOnce = false;
-	
-//	private LinearLayout mTitlebarButtons;
-	private LayoutInflater mInflater;
+
+    protected boolean mSkipLockOnce = false;
+
+    private SharedPreferences mPrefs;
+
+    private Editor mEditor;
+
+    private LockPatternUtils mLockPatternUtils;
+
+    private boolean mHasLoaded = false;
+
+    //	private LinearLayout mTitlebarButtons;
+    private LayoutInflater mInflater;
 //	private ProgressBar mProgressBar;
-	
+
 //    private ImageView mHomeButton;
 //    private View mHomeButtonCont;
 
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-		mLockPatternUtils = new LockPatternUtils(this);
-        mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
-        mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+        mLockPatternUtils = new LockPatternUtils(this);
+        mLockPatternUtils
+                .setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
+        mLockPatternUtils.setTactileFeedbackEnabled(
+                mPrefs.getBoolean("patternlock_tactile_feedback", false));
 //        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
         }
     }
-	
-	@Override
+
+    @Override
     public void setContentView(int layoutResID) {
         super.setContentView(layoutResID);
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
@@ -170,14 +178,16 @@ public class LockableActivity extends ActionBarActivity {
 //        });
 //        mProgressBar.startAnimation(animation);
 //    }
-    
+
     @Override
-	protected void onPause() {
-		super.onPause();
-		// Don't do anything if no lock pattern is set
-		if (!mLockPatternUtils.isLockPatternEnabled()) return;
+    protected void onPause() {
+        super.onPause();
+        // Don't do anything if no lock pattern is set
+        if (!mLockPatternUtils.isLockPatternEnabled()) {
+            return;
+        }
         /*
-		Save the current time If a lock pattern has been set
+                Save the current time If a lock pattern has been set
 		If this activity never loaded set the lock time to
 		10 seconds ago.
 		This is to prevent the following scenario:
@@ -186,73 +196,71 @@ public class LockableActivity extends ActionBarActivity {
             3. User presses the home button
             4. "lock time" is set in onPause to when the home button was pressed
             5. Activity is started again within 2 seconds and no lock screen is shown this time.
-	    */ 
-		if (mHasLoaded) {
-		    writeLockTime();
-		} else {
-		    writeLockTime(SystemClock.elapsedRealtime()-10000);
-		}
-	}
-
-	@Override
-	protected void onResume() {
-		super.onResume();
+	    */
+        if (mHasLoaded) {
+            writeLockTime();
+        } else {
+            writeLockTime(SystemClock.elapsedRealtime() - 10000);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
         // Don't do anything if no lock pattern is set
-		if (!mLockPatternUtils.isLockPatternEnabled()) {
-		    return;
-		}
-		if (mSkipLockOnce) {
-		    mSkipLockOnce = false;
-		    return;
-		}
-		// If a lock pattern is set we need to check the time for when the last
-		// activity was open. If it's been more than two seconds the user
-		// will have to enter the lock pattern to continue.
-		long currentTime = SystemClock.elapsedRealtime();
-		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
-		long timedif = Math.abs(currentTime - lockedAt);
-		if (timedif > 2000) {
-            mHasLoaded = false;         
-		    launchPatternLock();
-		}
-		else {
-		    mHasLoaded = true;		    
-		}
-	}
-
-	private void launchPatternLock() {
+        if (!mLockPatternUtils.isLockPatternEnabled()) {
+            return;
+        }
+        if (mSkipLockOnce) {
+            mSkipLockOnce = false;
+            return;
+        }
+        // If a lock pattern is set we need to check the time for when the last
+        // activity was open. If it's been more than two seconds the user
+        // will have to enter the lock pattern to continue.
+        long currentTime = SystemClock.elapsedRealtime();
+        long lockedAt = mPrefs.getLong("locked_at", currentTime - 10000);
+        long timedif = Math.abs(currentTime - lockedAt);
+        if (timedif > 2000) {
+            mHasLoaded = false;
+            launchPatternLock();
+        } else {
+            mHasLoaded = true;
+        }
+    }
+
+    private void launchPatternLock() {
         Intent intent = new Intent(this, ConfirmLockPattern.class);
         intent.putExtra(ConfirmLockPattern.HEADER_TEXT, getText(R.string.patternlock_header));
-        startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
-	}
-	
-	private void writeLockTime() {
+        startActivityForResult(intent, PATTERNLOCK_UNLOCK);
+    }
+
+    private void writeLockTime() {
         writeLockTime(SystemClock.elapsedRealtime());
-	}
+    }
 
     private void writeLockTime(long time) {
         mEditor = mPrefs.edit();
         mEditor.putLong("locked_at", time);
-        mEditor.commit();       
+        mEditor.commit();
     }
-	
+
     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         if (requestCode == PATTERNLOCK_UNLOCK) {
             if (resultCode == RESULT_OK) {
                 writeLockTime();
-            }
-            else {
+            } else {
                 launchPatternLock();
             }
         }
-    }   	
-    
+    }
+
     protected void skipLockOnce() {
         mSkipLockOnce = true;
     }
-    
-    
+
+
     @Override
     public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) {
         View decorview = getWindow().getDecorView();
@@ -265,13 +273,14 @@ public class LockableActivity extends ActionBarActivity {
         final int dw = outBitmap.getWidth();
         final int dh = outBitmap.getHeight();
 
-        Bitmap bluredBitmap = Bitmap.createBitmap(outBitmap.getWidth(), outBitmap.getHeight(), outBitmap.getConfig());
+        Bitmap bluredBitmap = Bitmap
+                .createBitmap(outBitmap.getWidth(), outBitmap.getHeight(), outBitmap.getConfig());
         Canvas c = new Canvas(bluredBitmap);
-        
+
         c.save();
-        c.scale(((float)dw)/vw, ((float)dh)/vh);
+        c.scale(((float) dw) / vw, ((float) dh) / vh);
         decorview.draw(c);
-        c.restore();        
+        c.restore();
 
         canvas.drawBitmap(pixelate(bluredBitmap, 5), 0, 0, null);
         Bitmap lockbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lock);
@@ -280,12 +289,13 @@ public class LockableActivity extends ActionBarActivity {
         p.setAntiAlias(true);
         p.setDither(true);
         p.setFilterBitmap(true);
-        
-        canvas.drawBitmap(lockbitmap, null, new RectF(dw*0.25f,dh*0.25f,dw*0.75f,dh*0.75f), p);
-        
+
+        canvas.drawBitmap(lockbitmap, null,
+                new RectF(dw * 0.25f, dh * 0.25f, dw * 0.75f, dh * 0.75f), p);
+
         return true;
     }
-    
+
     private Bitmap pixelate(Bitmap bitmap, int size) {
         Bitmap bm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
         Canvas c = new Canvas(bm);
@@ -293,11 +303,11 @@ public class LockableActivity extends ActionBarActivity {
         p.setStyle(Style.FILL);
         int w = bm.getWidth();
         int h = bm.getHeight();
-        
-        int[] pixels = new int[w*h];
+
+        int[] pixels = new int[w * h];
         bitmap.getPixels(pixels, 0, w, 0, 0, w, h);
-        for (int i = 0; i < h; i = i+size) {
-            for (int j = 0; j < w; j = j+size) {
+        for (int i = 0; i < h; i = i + size) {
+            for (int j = 0; j < w; j = j + size) {
                 int a = 0;
                 int r = 0;
                 int g = 0;
@@ -305,7 +315,7 @@ public class LockableActivity extends ActionBarActivity {
                 int pc = 0;
                 for (int k = 0; k < size; k++) {
                     for (int l = 0; l < size; l++) {
-                        int pxp = (i+k)*w+j+l;
+                        int pxp = (i + k) * w + j + l;
                         if (pxp < pixels.length) {
                             int pixel = pixels[pxp];
                             a += Color.alpha(pixel);
@@ -321,7 +331,7 @@ public class LockableActivity extends ActionBarActivity {
                 g /= pc;
                 b /= pc;
                 p.setColor(Color.argb(a, r, g, b));
-                c.drawRect(j, i, j+size, i+size, p);
+                c.drawRect(j, i, j + size, i + size, p);
             }
         }
         return bm;
@@ -330,5 +340,5 @@ public class LockableActivity extends ActionBarActivity {
     public boolean shouldShowActionBar() {
         return true;
     }
-    
+
 }
diff --git app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
index 89392e6..87a459d 100644
--- app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -27,34 +27,41 @@ import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceManager;
-import android.util.Log;
-import android.view.Window;
 import android.view.WindowManager;
 
 public class LockablePreferenceActivity extends PreferenceActivity {
+
     private static int PATTERNLOCK_UNLOCK = 42;
-	private SharedPreferences mPrefs;
-	private Editor mEditor;
-	private LockPatternUtils mLockPatternUtils;
+
+    private SharedPreferences mPrefs;
+
+    private Editor mEditor;
+
+    private LockPatternUtils mLockPatternUtils;
+
     private boolean mHasLoaded = false;
 
-	@Override
-	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-		mLockPatternUtils = new LockPatternUtils(this);
-        mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
-        mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+        mLockPatternUtils = new LockPatternUtils(this);
+        mLockPatternUtils
+                .setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
+        mLockPatternUtils.setTactileFeedbackEnabled(
+                mPrefs.getBoolean("patternlock_tactile_feedback", false));
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
         }
-	}
+    }
 
-	@Override
-	protected void onPause() {
-		super.onPause();
-		// Don't do anything if no lock pattern is set
-		if (!mLockPatternUtils.isLockPatternEnabled()) return;
+    @Override
+    protected void onPause() {
+        super.onPause();
+        // Don't do anything if no lock pattern is set
+        if (!mLockPatternUtils.isLockPatternEnabled()) {
+            return;
+        }
         /*
         Save the current time If a lock pattern has been set
         If this activity never loaded set the lock time to
@@ -65,41 +72,40 @@ public class LockablePreferenceActivity extends PreferenceActivity {
             3. User presses the home button
             4. "lock time" is set in onPause to when the home button was pressed
             5. Activity is started again within 2 seconds and no lock screen is shown this time.
-        */ 
+        */
         if (mHasLoaded) {
             writeLockTime();
         } else {
-            writeLockTime(SystemClock.elapsedRealtime()-10000);
+            writeLockTime(SystemClock.elapsedRealtime() - 10000);
         }
     }
 
-	@Override
-	protected void onResume() {
-		super.onResume();
+    @Override
+    protected void onResume() {
+        super.onResume();
         // Don't do anything if lock pattern is not set
-		if (!mLockPatternUtils.isLockPatternEnabled() || !isLockEnabled()) {
-		    return;
-		}
-		// If a lock pattern is set we need to check the time for when the last
-		// activity was open. If it's been more than two seconds the user
-		// will have to enter the lock pattern to continue.
-		long currentTime = SystemClock.elapsedRealtime();
-		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
-		long timedif = Math.abs(currentTime - lockedAt);
-		if (timedif > 2000) {
-		    launchPatternLock();
-		}
-        else {
-            mHasLoaded = true;          
+        if (!mLockPatternUtils.isLockPatternEnabled() || !isLockEnabled()) {
+            return;
+        }
+        // If a lock pattern is set we need to check the time for when the last
+        // activity was open. If it's been more than two seconds the user
+        // will have to enter the lock pattern to continue.
+        long currentTime = SystemClock.elapsedRealtime();
+        long lockedAt = mPrefs.getLong("locked_at", currentTime - 10000);
+        long timedif = Math.abs(currentTime - lockedAt);
+        if (timedif > 2000) {
+            launchPatternLock();
+        } else {
+            mHasLoaded = true;
         }
-	}
+    }
 
-	private void launchPatternLock() {
+    private void launchPatternLock() {
         Intent intent = new Intent(this, ConfirmLockPattern.class);
         intent.putExtra(ConfirmLockPattern.HEADER_TEXT, getText(R.string.patternlock_header));
-        startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
-	}
-	
+        startActivityForResult(intent, PATTERNLOCK_UNLOCK);
+    }
+
     private void writeLockTime() {
         writeLockTime(SystemClock.elapsedRealtime());
     }
@@ -107,27 +113,26 @@ public class LockablePreferenceActivity extends PreferenceActivity {
     private void writeLockTime(long time) {
         mEditor = mPrefs.edit();
         mEditor.putLong("locked_at", time);
-        mEditor.commit();       
+        mEditor.commit();
+    }
+
+    protected boolean isLockEnabled() {
+        return mPrefs.getBoolean("lock_enabled", true);
     }
 
-	protected void setLockEnabled(boolean enabled) {
+    protected void setLockEnabled(boolean enabled) {
         mEditor = mPrefs.edit();
         mEditor.putBoolean("lock_enabled", enabled);
-        mEditor.commit();        
-	}
+        mEditor.commit();
+    }
 
-    protected boolean isLockEnabled() {
-        return mPrefs.getBoolean("lock_enabled", true);       
-    }	
-    
     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
         if (requestCode == PATTERNLOCK_UNLOCK) {
             if (resultCode == RESULT_OK) {
                 writeLockTime();
-            }
-            else {
+            } else {
                 launchPatternLock();
             }
         }
@@ -137,6 +142,6 @@ public class LockablePreferenceActivity extends PreferenceActivity {
     protected void onStop() {
         super.onStop();
         setLockEnabled(true);
-    }   	
-    
+    }
+
 }
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 919bd86..42d41a0 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -16,7 +16,12 @@
 
 package com.liato.bankdroid;
 
-import java.util.ArrayList;
+import com.liato.bankdroid.adapters.AccountsAdapter;
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.db.DBAdapter;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -45,369 +50,376 @@ import android.widget.Button;
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.liato.bankdroid.adapters.AccountsAdapter;
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.db.DBAdapter;
+import java.util.ArrayList;
 
 public class MainActivity extends LockableActivity {
-	private final static String TAG = "MainActivity";
-	protected AccountsAdapter adapter = null;
-	private static Bank selected_bank = null;
-	private static Account selected_account = null;
-	protected static boolean showHidden = false;
-
-	@Override
-	public void onCreate(final Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-
-		PairApplicationsActivity.initialSetupApiKey(this);
-		
-		setContentView(R.layout.main);
-		adapter = new AccountsAdapter(this, showHidden);
-		final ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
-		adapter.setGroups(banks);
-		final ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-		lv.setAdapter(adapter);
-		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
-			public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
-				if (adapter.getItem(position) instanceof Account) {
-					selected_account = (Account)adapter.getItem(position);
-					final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
-					pmenu.showLikeQuickAction(0, 12);
-					return true;
-				} else if (adapter.getItem(position) instanceof Bank) {
-					selected_bank = (Bank) adapter.getItem(position);
-					selected_bank.toggleHideAccounts();
-					DBAdapter.save(selected_bank, MainActivity.this);
-					refreshView();
-					return true;
-				}
-				return false;
-			}
-		});
-		lv.setOnItemClickListener(new OnItemClickListener() {
-			public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
-				if (adapter.getItem(position) instanceof Bank) {
-					selected_bank = (Bank) adapter.getItem(position);
-					final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
-					pmenu.showLikeQuickAction(0, 12);
-				}
-				else {
-					final Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
-					final Account account = (Account) adapter.getItem(position);
-					intent.putExtra("account", account.getId());
-					intent.putExtra("bank", account.getBankDbId());
-					MainActivity.this.startActivity(intent);
-				}
-			}
-		});
-
-		final Bundle extras = getIntent().getExtras();
-		// Clicking on widgets opens the transactions history through MainActivity so that
-		// the user can back out to the main window.
-		if (AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS.equals(getIntent().getAction())) {
-	        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		    if (prefs.getBoolean("widget_opens_transactions", true)) {
-		        skipLockOnce();
-    			final Intent intent = new Intent(this, TransactionsActivity.class);
-    			intent.putExtra("account", extras.getString("account"));
-    			intent.putExtra("bank", extras.getLong("bank"));
-    			startActivity(intent);
-		    }
-		}
+
+    private final static String TAG = "MainActivity";
+
+    protected static boolean showHidden = false;
+
+    private static Bank selected_bank = null;
+
+    private static Account selected_account = null;
+
+    private final BroadcastReceiver receiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(final Context context, final Intent intent) {
+            refreshView();
+        }
+    };
+
+    protected AccountsAdapter adapter = null;
+
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        PairApplicationsActivity.initialSetupApiKey(this);
+
+        setContentView(R.layout.main);
+        adapter = new AccountsAdapter(this, showHidden);
+        final ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
+        adapter.setGroups(banks);
+        final ListView lv = (ListView) findViewById(R.id.lstAccountsList);
+        lv.setAdapter(adapter);
+        lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+            public boolean onItemLongClick(final AdapterView<?> parent, final View view,
+                    final int position, final long id) {
+                if (adapter.getItem(position) instanceof Account) {
+                    selected_account = (Account) adapter.getItem(position);
+                    final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
+                    pmenu.showLikeQuickAction(0, 12);
+                    return true;
+                } else if (adapter.getItem(position) instanceof Bank) {
+                    selected_bank = (Bank) adapter.getItem(position);
+                    selected_bank.toggleHideAccounts();
+                    DBAdapter.save(selected_bank, MainActivity.this);
+                    refreshView();
+                    return true;
+                }
+                return false;
+            }
+        });
+        lv.setOnItemClickListener(new OnItemClickListener() {
+            public void onItemClick(final AdapterView<?> parent, final View view,
+                    final int position, final long id) {
+                if (adapter.getItem(position) instanceof Bank) {
+                    selected_bank = (Bank) adapter.getItem(position);
+                    final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
+                    pmenu.showLikeQuickAction(0, 12);
+                } else {
+                    final Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
+                    final Account account = (Account) adapter.getItem(position);
+                    intent.putExtra("account", account.getId());
+                    intent.putExtra("bank", account.getBankDbId());
+                    MainActivity.this.startActivity(intent);
+                }
+            }
+        });
+
+        final Bundle extras = getIntent().getExtras();
+        // Clicking on widgets opens the transactions history through MainActivity so that
+        // the user can back out to the main window.
+        if (AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS.equals(getIntent().getAction())) {
+            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+            if (prefs.getBoolean("widget_opens_transactions", true)) {
+                skipLockOnce();
+                final Intent intent = new Intent(this, TransactionsActivity.class);
+                intent.putExtra("account", extras.getString("account"));
+                intent.putExtra("bank", extras.getLong("bank"));
+                startActivity(intent);
+            }
+        }
         ((BankdroidApplication) getApplication()).showAndDeleteApplicationMessage();
-	}
-
-	
-
-	@Override
-	public void onResume() {
-		super.onResume();
-		// Receive refresh Intent from AutoRefreshService and refresh the main view if changes
-		// have been detected.
-		registerReceiver(receiver, new IntentFilter(AutoRefreshService.BROADCAST_MAIN_REFRESH));
-		refreshView();
-	}
-
-	private final BroadcastReceiver receiver=new BroadcastReceiver() {
-		@Override
-		public void onReceive(final Context context, final Intent intent) {
-			refreshView();
-		}
-	};
-
-	public void refreshView() {
-		final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
-		if (banks.size() > 0) {
-			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // Receive refresh Intent from AutoRefreshService and refresh the main view if changes
+        // have been detected.
+        registerReceiver(receiver, new IntentFilter(AutoRefreshService.BROADCAST_MAIN_REFRESH));
+        refreshView();
+    }
+
+    public void refreshView() {
+        final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
+        if (banks.size() > 0) {
+            findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
 //			showTitleButton("refresh");
-			//findViewById(R.id.btnAccountsRefresh).setClickable(true);
-		}
-		else {
-			findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
+            //findViewById(R.id.btnAccountsRefresh).setClickable(true);
+        } else {
+            findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
 //			hideTitleButton("refresh");
-			//findViewById(R.id.btnAccountsRefresh).setClickable(false);
-		}
-
-		adapter.setShowHidden(showHidden);
-		adapter.setGroups(banks);
-		adapter.notifyDataSetChanged();
-	}
-
-	@Override
-	public boolean onCreateOptionsMenu(final Menu menu) {
-		super.onCreateOptionsMenu(menu);
-		final MenuInflater inflater = new MenuInflater(this);
-		inflater.inflate(R.menu.main, menu);
-		return true;
-	}
-
-
-	@Override
-	protected Dialog onCreateDialog(final int id) {
-		super.onCreateDialog(id);
-		final Dialog dialog = new Dialog(this);
-		dialog.setContentView(R.layout.about);
-		dialog.setTitle(getString(R.string.about));
-		PackageInfo pInfo;
-		String version = "v1.x.x";
-		try {
-			pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
-			version = pInfo.versionName;
-		} catch (final NameNotFoundException e) {
-			e.printStackTrace();
-		}
-		((TextView)dialog.findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));
-		return dialog;
-	}
-
-	@Override
-	public boolean onOptionsItemSelected (final MenuItem item){
-		Intent intent;
-		switch (item.getItemId()) {
-		case R.id.action_toggle_hidden:
-			showHidden = !showHidden;
-            item.setTitle(showHidden ? R.string.menu_hide_hidden : R.string.menu_show_hidden);
-			refreshView();
-			return true;
-		case R.id.action_settings:
-			intent = new Intent(this, SettingsActivity.class);
-			this.startActivity(intent);
-			//Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
-			return true;
-        case R.id.action_about:
-            intent = new Intent(this, AboutActivity.class);
-            startActivity(intent);
-            return true;
-        case R.id.action_refresh:
-            new DataRetrieverTask(MainActivity.this).execute();
-            return true;
-        case R.id.action_add:
-            final Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
-            startActivity(intentAccount);
-            return true;
+            //findViewById(R.id.btnAccountsRefresh).setClickable(false);
+        }
+
+        adapter.setShowHidden(showHidden);
+        adapter.setGroups(banks);
+        adapter.notifyDataSetChanged();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        final MenuInflater inflater = new MenuInflater(this);
+        inflater.inflate(R.menu.main, menu);
+        return true;
+    }
+
+
+    @Override
+    protected Dialog onCreateDialog(final int id) {
+        super.onCreateDialog(id);
+        final Dialog dialog = new Dialog(this);
+        dialog.setContentView(R.layout.about);
+        dialog.setTitle(getString(R.string.about));
+        PackageInfo pInfo;
+        String version = "v1.x.x";
+        try {
+            pInfo = getPackageManager()
+                    .getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
+            version = pInfo.versionName;
+        } catch (final NameNotFoundException e) {
+            e.printStackTrace();
+        }
+        ((TextView) dialog.findViewById(R.id.txtVersion))
+                .setText(getText(R.string.version).toString().replace("$version", version));
+        return dialog;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem item) {
+        Intent intent;
+        switch (item.getItemId()) {
+            case R.id.action_toggle_hidden:
+                showHidden = !showHidden;
+                item.setTitle(showHidden ? R.string.menu_hide_hidden : R.string.menu_show_hidden);
+                refreshView();
+                return true;
+            case R.id.action_settings:
+                intent = new Intent(this, SettingsActivity.class);
+                this.startActivity(intent);
+                //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
+                return true;
+            case R.id.action_about:
+                intent = new Intent(this, AboutActivity.class);
+                startActivity(intent);
+                return true;
+            case R.id.action_refresh:
+                new DataRetrieverTask(MainActivity.this).execute();
+                return true;
+            case R.id.action_add:
+                final Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
+                startActivity(intentAccount);
+                return true;
 
         }
-		return false;
-	}
-
-	@Override
-	public void onDestroy() {
-		super.onDestroy();
-		unregisterReceiver(receiver);
-	}
-
-	/**
-	 * Extends {@link BetterPopupWindow}
-	 * <p>
-	 * Overrides onCreate to create the view and register the button listeners
-	 * 
-	 * @author qbert
-	 * 
-	 */
-	private static class PopupMenuBank extends BetterPopupWindow implements OnClickListener {
-		MainActivity parent = null;
-		public PopupMenuBank(final View anchor, final MainActivity parent) {
-			super(anchor);
-			this.parent = parent;
-		}
-
-		@Override
-		protected void onCreate() {
-			// inflate layout
-			final LayoutInflater inflater =
-				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-			final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
+        return false;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(receiver);
+    }
+
+    /**
+     * Extends {@link BetterPopupWindow}
+     * <p>
+     * Overrides onCreate to create the view and register the button listeners
+     *
+     * @author qbert
+     */
+    private static class PopupMenuBank extends BetterPopupWindow implements OnClickListener {
+
+        MainActivity parent = null;
+
+        public PopupMenuBank(final View anchor, final MainActivity parent) {
+            super(anchor);
+            this.parent = parent;
+        }
+
+        @Override
+        protected void onCreate() {
+            // inflate layout
+            final LayoutInflater inflater =
+                    (LayoutInflater) this.anchor.getContext()
+                            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
-            final Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
+            final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
             final Button btnWWW = (Button) root.findViewById(R.id.btnWWW);
             if (selected_bank.getHideAccounts()) {
                 btnHide.setVisibility(View.GONE);
                 btnUnhide.setVisibility(View.VISIBLE);
                 btnUnhide.setOnClickListener(this);
-            }
-            else {
+            } else {
                 btnHide.setVisibility(View.VISIBLE);
                 btnUnhide.setVisibility(View.GONE);
                 btnHide.setOnClickListener(this);
             }
-            if(selected_bank.isWebViewEnabled()) {
+            if (selected_bank.isWebViewEnabled()) {
                 btnWWW.setOnClickListener(this);
             } else {
                 btnWWW.setVisibility(View.GONE);
             }
-			root.findViewById(R.id.btnRefresh).setOnClickListener(this);
-			root.findViewById(R.id.btnEdit).setOnClickListener(this);
-			root.findViewById(R.id.btnRemove).setOnClickListener(this);
-
-
-			this.setContentView(root);
-		}
-
-		@Override
-		public void onClick(final View v) {
-			final Context context = this.anchor.getContext();
-			final int id = v.getId();
-			switch (id) {
-			case R.id.btnHide:
-			case R.id.btnUnhide:
-				this.dismiss();
-				selected_bank.toggleHideAccounts();
-				DBAdapter.save(selected_bank, context);
-				parent.refreshView();
-				return;
-			case R.id.btnWWW:
-				if (selected_bank != null && selected_bank.isWebViewEnabled()) {
-					//Uri uri = Uri.parse(selected_bank.getURL());
-					//Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-					final Intent intent = new Intent(context, WebViewActivity.class);
-					intent.putExtra("bankid", selected_bank.getDbId());
-					context.startActivity(intent);
-				}
-				this.dismiss();
-				return;
-			case R.id.btnEdit:
-				final Intent intent = new Intent(context, BankEditActivity.class);
-				intent.putExtra("id", selected_bank.getDbId());
-				context.startActivity(intent);
-				this.dismiss();
-				return;
-			case R.id.btnRefresh:
-				this.dismiss();
-				new DataRetrieverTask(parent, selected_bank.getDbId()).execute();
-				return;
-			case R.id.btnRemove:
-				this.dismiss();
-				final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-				//builder.setMessage(getText(R.string.passwords_mismatch)).setTitle(getText(R.string.passwords_mismatch_title))
-				builder.setMessage(context.getText(R.string.remove_bank_msg)).setTitle(context.getText(R.string.remove_bank_title))
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setPositiveButton(context.getText(R.string.yes), new DialogInterface.OnClickListener() {
-					public void onClick(final DialogInterface dialog, final int id) {
-						final DBAdapter db = new DBAdapter(context);
-						db.deleteBank(selected_bank.getDbId());
-						dialog.cancel();
-						parent.refreshView();
-					}
-				})
-				.setNegativeButton(context.getText(R.string.no), new DialogInterface.OnClickListener() {
-					public void onClick(final DialogInterface dialog, final int id) {
-						dialog.cancel();
-					}
-				});
-				final AlertDialog alert = builder.create();
-				alert.show();
-				return;
-			}
-
-		}
-	}
-
-
-	/**
-	 * Extends {@link BetterPopupWindow}
-	 * <p>
-	 * Overrides onCreate to create the view and register the button listeners
-	 * 
-	 * @author qbert
-	 * 
-	 */
-	private static class PopupMenuAccount extends BetterPopupWindow implements OnClickListener {
-		MainActivity parent = null;
-		public PopupMenuAccount(final View anchor, final MainActivity parent) {
-			super(anchor);
-			this.parent = parent;
-		}
-
-		@Override
-		protected void onCreate() {
-			final LayoutInflater inflater =
-				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-			final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, null);
-			final Button btnHide = (Button) root.findViewById(R.id.btnHide);
-			final Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
-			final Button btnDisableNotifications = (Button)root.findViewById(R.id.btnDisableNotifications);
-			final Button btnEnableNotifications = (Button)root.findViewById(R.id.btnEnableNotifications);
-			if (selected_account.isHidden()) {
-				btnHide.setVisibility(View.GONE);
-				btnUnhide.setVisibility(View.VISIBLE);
-				btnUnhide.setOnClickListener(this);
-			}
-			else {
-				btnHide.setVisibility(View.VISIBLE);
-				btnUnhide.setVisibility(View.GONE);
-				btnHide.setOnClickListener(this);
-			}
-			if (selected_account.isNotify()) {
-				btnDisableNotifications.setVisibility(View.VISIBLE);
-				btnDisableNotifications.setOnClickListener(this);
-				btnEnableNotifications.setVisibility(View.GONE);
-			}
-			else {
-				btnDisableNotifications.setVisibility(View.GONE);
-				btnEnableNotifications.setOnClickListener(this);
-				btnEnableNotifications.setVisibility(View.VISIBLE);
-			}
-			this.setContentView(root);
-		}
-
-		@Override
-		public void onClick(final View v) {
-			final int id = v.getId();
-			switch (id) {
-			case R.id.btnHide:
-				this.dismiss();
-				selected_account.setHidden(true);
-				DBAdapter.save(selected_account.getBank(), parent);
-				parent.refreshView();
-				return;
-			case R.id.btnUnhide:
-				this.dismiss();
-				selected_account.setHidden(false);
-				DBAdapter.save(selected_account.getBank(), parent);
-				parent.refreshView();
-				return;
-			case R.id.btnEnableNotifications:
-				this.dismiss();
-				selected_account.setNotify(true);
-				DBAdapter.save(selected_account.getBank(), parent);
-				parent.refreshView();
-				return;
-			case R.id.btnDisableNotifications:
-				this.dismiss();
-				selected_account.setNotify(false);
-				DBAdapter.save(selected_account.getBank(), parent);
-				parent.refreshView();
-				return;
-
-			}
-
-		}
-	}
+            root.findViewById(R.id.btnRefresh).setOnClickListener(this);
+            root.findViewById(R.id.btnEdit).setOnClickListener(this);
+            root.findViewById(R.id.btnRemove).setOnClickListener(this);
+
+            this.setContentView(root);
+        }
+
+        @Override
+        public void onClick(final View v) {
+            final Context context = this.anchor.getContext();
+            final int id = v.getId();
+            switch (id) {
+                case R.id.btnHide:
+                case R.id.btnUnhide:
+                    this.dismiss();
+                    selected_bank.toggleHideAccounts();
+                    DBAdapter.save(selected_bank, context);
+                    parent.refreshView();
+                    return;
+                case R.id.btnWWW:
+                    if (selected_bank != null && selected_bank.isWebViewEnabled()) {
+                        //Uri uri = Uri.parse(selected_bank.getURL());
+                        //Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                        final Intent intent = new Intent(context, WebViewActivity.class);
+                        intent.putExtra("bankid", selected_bank.getDbId());
+                        context.startActivity(intent);
+                    }
+                    this.dismiss();
+                    return;
+                case R.id.btnEdit:
+                    final Intent intent = new Intent(context, BankEditActivity.class);
+                    intent.putExtra("id", selected_bank.getDbId());
+                    context.startActivity(intent);
+                    this.dismiss();
+                    return;
+                case R.id.btnRefresh:
+                    this.dismiss();
+                    new DataRetrieverTask(parent, selected_bank.getDbId()).execute();
+                    return;
+                case R.id.btnRemove:
+                    this.dismiss();
+                    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+                    //builder.setMessage(getText(R.string.passwords_mismatch)).setTitle(getText(R.string.passwords_mismatch_title))
+                    builder.setMessage(context.getText(R.string.remove_bank_msg))
+                            .setTitle(context.getText(R.string.remove_bank_title))
+                            .setIcon(android.R.drawable.ic_dialog_alert)
+                            .setPositiveButton(context.getText(R.string.yes),
+                                    new DialogInterface.OnClickListener() {
+                                        public void onClick(final DialogInterface dialog,
+                                                final int id) {
+                                            final DBAdapter db = new DBAdapter(context);
+                                            db.deleteBank(selected_bank.getDbId());
+                                            dialog.cancel();
+                                            parent.refreshView();
+                                        }
+                                    })
+                            .setNegativeButton(context.getText(R.string.no),
+                                    new DialogInterface.OnClickListener() {
+                                        public void onClick(final DialogInterface dialog,
+                                                final int id) {
+                                            dialog.cancel();
+                                        }
+                                    });
+                    final AlertDialog alert = builder.create();
+                    alert.show();
+                    return;
+            }
+
+        }
+    }
+
+
+    /**
+     * Extends {@link BetterPopupWindow}
+     * <p>
+     * Overrides onCreate to create the view and register the button listeners
+     *
+     * @author qbert
+     */
+    private static class PopupMenuAccount extends BetterPopupWindow implements OnClickListener {
+
+        MainActivity parent = null;
+
+        public PopupMenuAccount(final View anchor, final MainActivity parent) {
+            super(anchor);
+            this.parent = parent;
+        }
+
+        @Override
+        protected void onCreate() {
+            final LayoutInflater inflater =
+                    (LayoutInflater) this.anchor.getContext()
+                            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, null);
+            final Button btnHide = (Button) root.findViewById(R.id.btnHide);
+            final Button btnUnhide = (Button) root.findViewById(R.id.btnUnhide);
+            final Button btnDisableNotifications = (Button) root
+                    .findViewById(R.id.btnDisableNotifications);
+            final Button btnEnableNotifications = (Button) root
+                    .findViewById(R.id.btnEnableNotifications);
+            if (selected_account.isHidden()) {
+                btnHide.setVisibility(View.GONE);
+                btnUnhide.setVisibility(View.VISIBLE);
+                btnUnhide.setOnClickListener(this);
+            } else {
+                btnHide.setVisibility(View.VISIBLE);
+                btnUnhide.setVisibility(View.GONE);
+                btnHide.setOnClickListener(this);
+            }
+            if (selected_account.isNotify()) {
+                btnDisableNotifications.setVisibility(View.VISIBLE);
+                btnDisableNotifications.setOnClickListener(this);
+                btnEnableNotifications.setVisibility(View.GONE);
+            } else {
+                btnDisableNotifications.setVisibility(View.GONE);
+                btnEnableNotifications.setOnClickListener(this);
+                btnEnableNotifications.setVisibility(View.VISIBLE);
+            }
+            this.setContentView(root);
+        }
+
+        @Override
+        public void onClick(final View v) {
+            final int id = v.getId();
+            switch (id) {
+                case R.id.btnHide:
+                    this.dismiss();
+                    selected_account.setHidden(true);
+                    DBAdapter.save(selected_account.getBank(), parent);
+                    parent.refreshView();
+                    return;
+                case R.id.btnUnhide:
+                    this.dismiss();
+                    selected_account.setHidden(false);
+                    DBAdapter.save(selected_account.getBank(), parent);
+                    parent.refreshView();
+                    return;
+                case R.id.btnEnableNotifications:
+                    this.dismiss();
+                    selected_account.setNotify(true);
+                    DBAdapter.save(selected_account.getBank(), parent);
+                    parent.refreshView();
+                    return;
+                case R.id.btnDisableNotifications:
+                    this.dismiss();
+                    selected_account.setNotify(false);
+                    DBAdapter.save(selected_account.getBank(), parent);
+                    parent.refreshView();
+                    return;
+
+            }
+
+        }
+    }
 
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index e97cc73..32af907 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -6,7 +6,7 @@
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,6 +15,9 @@
  */
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.provider.BankTransactionsProvider;
+import com.liato.bankdroid.provider.IBankTransactionsProvider;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -29,113 +32,110 @@ import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.liato.bankdroid.provider.BankTransactionsProvider;
-import com.liato.bankdroid.provider.IBankTransactionsProvider;
-
 /**
  * @author Magnus Andersson
  * @since 8 jun 2011
  */
 public class PairApplicationsActivity extends LockableActivity {
 
-	/**
-	 * 
-	 */
-	private static final String TAG = "Pair Application";
-	private static final String PAIR_APP_NAME = "com.liato.bankdroid.PAIR_APP_NAME";
-
-	/** {@inheritDoc} */
-	@Override
-	protected void onCreate(final Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.pair_applications_layout);
+    /**
+     *
+     */
+    private static final String TAG = "Pair Application";
+
+    private static final String PAIR_APP_NAME = "com.liato.bankdroid.PAIR_APP_NAME";
+
+    public static void initialSetupApiKey(Context ctx) {
+        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+        final String apiKey = prefs.getString("content_provider_api_key", "");
+        if (apiKey.equals("")) {
+            final SharedPreferences.Editor editor = prefs.edit();
+
+            // Create a random HEX String
+            final String genKey = Long.toHexString(Double.doubleToLongBits(Math.random()));
+
+            // Commit to preferences
+            editor.putString("content_provider_api_key", genKey.toUpperCase());
+            editor.commit();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pair_applications_layout);
 //		setHomeButtonEnabled(false);
-		
-		Bundle bundle = getIntent().getExtras();
-
-		if(bundle.containsKey(PAIR_APP_NAME)) {
-			String appName = bundle.getString(PAIR_APP_NAME);
-
-			ImageView img = (ImageView) findViewById(R.id.imageView1);
-			String logoUri = "drawable/applogo_"+appName.toLowerCase();
-
-			// Dynamically load logo
-			int imageResource = getResources().getIdentifier(logoUri, null, getPackageName());
-
-			try {
-				Drawable d = getResources().getDrawable(imageResource);
-				img.setImageDrawable(d);
-				img.requestLayout();
-			} catch (NotFoundException e) {
-				Log.e(TAG, "Could not find the requested image using uri " + logoUri);
-				e.printStackTrace();
-			}
-			// Change application name
-			TextView appNameView = (TextView) findViewById(R.id.app_name);
-			appNameView.setText(appName);
-		} else {
-			Log.w(TAG, "Unknown application");
-		}
-
-
-	}
-
-	@Override
-	public boolean onKeyDown(int keyCode, KeyEvent event) {
-		//Handle the back button
-		if (keyCode == KeyEvent.KEYCODE_BACK) {
-			setResult(RESULT_CANCELED);
-			finish();
-			return true;
-		}
-
-		return super.onKeyDown(keyCode, event);
-	} 
-
-	public void cancelPairing(final View v) {
-		setResult(RESULT_CANCELED);
-		finish();
-	}
-
-	public void confirmPairing(final View v) {
-		Intent intent = this.getIntent();
-
-		Context ctx = getBaseContext();
-
-		// Make sure sharing is enabled
-		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx);
-		Editor editor = pref.edit();
-		editor.putBoolean("content_provider_enabled", true);
-		editor.commit();
-        String apiKey;
 
-        try{
-		    apiKey = BankTransactionsProvider.getApiKey(ctx);
+        Bundle bundle = getIntent().getExtras();
+
+        if (bundle.containsKey(PAIR_APP_NAME)) {
+            String appName = bundle.getString(PAIR_APP_NAME);
+
+            ImageView img = (ImageView) findViewById(R.id.imageView1);
+            String logoUri = "drawable/applogo_" + appName.toLowerCase();
+
+            // Dynamically load logo
+            int imageResource = getResources().getIdentifier(logoUri, null, getPackageName());
+
+            try {
+                Drawable d = getResources().getDrawable(imageResource);
+                img.setImageDrawable(d);
+                img.requestLayout();
+            } catch (NotFoundException e) {
+                Log.e(TAG, "Could not find the requested image using uri " + logoUri);
+                e.printStackTrace();
+            }
+            // Change application name
+            TextView appNameView = (TextView) findViewById(R.id.app_name);
+            appNameView.setText(appName);
+        } else {
+            Log.w(TAG, "Unknown application");
         }
-        catch (IllegalArgumentException e){
-            //Initialize API key if it is not set
-            initialSetupApiKey(ctx);
-            apiKey = BankTransactionsProvider.getApiKey(ctx);
+
+
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        //Handle the back button
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            setResult(RESULT_CANCELED);
+            finish();
+            return true;
         }
 
-		intent.putExtra(IBankTransactionsProvider.API_KEY,apiKey);
-		setResult(RESULT_OK, intent);
+        return super.onKeyDown(keyCode, event);
+    }
+
+    public void cancelPairing(final View v) {
+        setResult(RESULT_CANCELED);
+        finish();
+    }
+
+    public void confirmPairing(final View v) {
+        Intent intent = this.getIntent();
 
-		finish();
-	}
+        Context ctx = getBaseContext();
 
-	public static void initialSetupApiKey(Context ctx) {
-		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
-		final String apiKey = prefs.getString("content_provider_api_key", "");
-		if(apiKey.equals("")) {
-			final SharedPreferences.Editor editor = prefs.edit();
+        // Make sure sharing is enabled
+        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx);
+        Editor editor = pref.edit();
+        editor.putBoolean("content_provider_enabled", true);
+        editor.commit();
+        String apiKey;
+
+        try {
+            apiKey = BankTransactionsProvider.getApiKey(ctx);
+        } catch (IllegalArgumentException e) {
+            //Initialize API key if it is not set
+            initialSetupApiKey(ctx);
+            apiKey = BankTransactionsProvider.getApiKey(ctx);
+        }
 
-			// Create a random HEX String
-			final String genKey = Long.toHexString(Double.doubleToLongBits(Math.random()));
+        intent.putExtra(IBankTransactionsProvider.API_KEY, apiKey);
+        setResult(RESULT_OK, intent);
 
-			// Commit to preferences
-			editor.putString("content_provider_api_key", genKey.toUpperCase());
-			editor.commit();
-		}
-	}
+        finish();
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
index 4eaeaee..bf45758 100644
--- app/src/main/java/com/liato/bankdroid/SettingsActivity.java
+++ app/src/main/java/com/liato/bankdroid/SettingsActivity.java
@@ -16,6 +16,15 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.nordea.Nordea;
+import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
+import com.liato.bankdroid.lockpattern.ChooseLockPattern;
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
@@ -27,98 +36,94 @@ import android.preference.PreferenceScreen;
 import android.util.Log;
 import android.widget.Toast;
 
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
-import com.liato.bankdroid.banking.banks.nordea.Nordea;
-import com.liato.bankdroid.lockpattern.ChooseLockPattern;
-import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
-import com.liato.bankdroid.lockpattern.LockPatternUtils;
-
 import java.math.BigDecimal;
 
-public class SettingsActivity extends LockablePreferenceActivity implements OnPreferenceClickListener, OnPreferenceChangeListener {
-	private final static String TAG = "SettingsActivity";
-	private final static int DISABLE_LOCKPATTERN = 1;
-	private final static int ENABLE_LOCKPATTERN = 2;
-	private final static int CHANGE_LOCKPATTERN = 3;
-	private LockPatternUtils mLockPatternUtils;
-
-	/** Called when the activity is first created. */
-	@Override
-	public void onCreate(final Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		mLockPatternUtils = new LockPatternUtils(this);
-		addPreferencesFromResource(R.xml.settings);
-		getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
-		(findPreference("patternlock_change")).setOnPreferenceClickListener(this);
-		(findPreference("remotenotifier_help")).setOnPreferenceClickListener(this);
-		(findPreference("openwatch_help")).setOnPreferenceClickListener(this);
-		(findPreference("liveview_help")).setOnPreferenceClickListener(this);
-		(findPreference("account_types_screen")).setOnPreferenceClickListener(this);
-		(findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
-		(findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
-		(findPreference("liveview_screen")).setOnPreferenceClickListener(this);
+public class SettingsActivity extends LockablePreferenceActivity
+        implements OnPreferenceClickListener, OnPreferenceChangeListener {
+
+    private final static String TAG = "SettingsActivity";
+
+    private final static int DISABLE_LOCKPATTERN = 1;
+
+    private final static int ENABLE_LOCKPATTERN = 2;
+
+    private final static int CHANGE_LOCKPATTERN = 3;
+
+    private LockPatternUtils mLockPatternUtils;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mLockPatternUtils = new LockPatternUtils(this);
+        addPreferencesFromResource(R.xml.settings);
+        getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
+        (findPreference("patternlock_change")).setOnPreferenceClickListener(this);
+        (findPreference("remotenotifier_help")).setOnPreferenceClickListener(this);
+        (findPreference("openwatch_help")).setOnPreferenceClickListener(this);
+        (findPreference("liveview_help")).setOnPreferenceClickListener(this);
+        (findPreference("account_types_screen")).setOnPreferenceClickListener(this);
+        (findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
+        (findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
+        (findPreference("liveview_screen")).setOnPreferenceClickListener(this);
         (findPreference("notification_sound")).setOnPreferenceClickListener(this);
         (findPreference("test_notification")).setOnPreferenceClickListener(this);
         (findPreference("notify_min_delta")).setOnPreferenceChangeListener(this);
-		final CheckBoxPreference patternLock = ((CheckBoxPreference)findPreference("patternlock_enabled"));
-		patternLock.setOnPreferenceClickListener(this);
-		// Check the pattern lock check box if the lock pattern is enabled
-		patternLock.setChecked(mLockPatternUtils.isLockPatternEnabled());
-	}
-
-	@Override
-	public boolean onPreferenceClick(final Preference pref) {
-		final String prefKey = pref.getKey();
-		if ("account_types_screen".equals(prefKey) ||
-				"remotenotifier_screen".equals(prefKey) ||
-				"openwatch_screen".equals(prefKey) ||
-				"liveview_screen".equals(prefKey)) {
-			((PreferenceScreen)pref).getDialog().getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
-			return false;
-		}
-
-		if ("notification_sound".equals(prefKey)) {
-			return false;
-		}
-		
-		if ("patternlock_enabled".equals(prefKey)) {
-			this.setLockEnabled(false);
-			if (mLockPatternUtils.isLockPatternEnabled()) {
-				// The user is trying to disable the lock pattern,
-				// only disable if the user knows the pattern.
-				startActivityForResult(new Intent(this, ConfirmLockPattern.class), DISABLE_LOCKPATTERN);
-				return true;
-			}
-			else {
-				// No lock pattern has been set yet, let the user choose a new one.
-				startActivityForResult(new Intent(this, ChooseLockPattern.class), ENABLE_LOCKPATTERN);
-				return true;
-			}
-		}
-		else if ("patternlock_change".equals(prefKey)) {
-			this.setLockEnabled(false);
-			startActivityForResult(new Intent(this, ChooseLockPattern.class), CHANGE_LOCKPATTERN);
-			return true;
-		}
-		else if ("remotenotifier_help".equals(prefKey)) {
-			startActivity(new Intent(Intent.ACTION_VIEW,
-					Uri.parse("http://code.google.com/p/android-notifier/")));
-			return true;
-		}
-		else if ("openwatch_help".equals(prefKey)) {
-			startActivity(new Intent(Intent.ACTION_VIEW,
-					Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));
-			return true;
-		}
-		else if ("liveview_help".equals(prefKey)) {
-			startActivity(new Intent(Intent.ACTION_VIEW,
-					Uri.parse("http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay")));
-			return true;
-		}
-		else if ("test_notification".equals(prefKey)) {
+        final CheckBoxPreference patternLock = ((CheckBoxPreference) findPreference(
+                "patternlock_enabled"));
+        patternLock.setOnPreferenceClickListener(this);
+        // Check the pattern lock check box if the lock pattern is enabled
+        patternLock.setChecked(mLockPatternUtils.isLockPatternEnabled());
+    }
+
+    @Override
+    public boolean onPreferenceClick(final Preference pref) {
+        final String prefKey = pref.getKey();
+        if ("account_types_screen".equals(prefKey) ||
+                "remotenotifier_screen".equals(prefKey) ||
+                "openwatch_screen".equals(prefKey) ||
+                "liveview_screen".equals(prefKey)) {
+            ((PreferenceScreen) pref).getDialog().getWindow()
+                    .setBackgroundDrawableResource(R.drawable.background_repeat);
+            return false;
+        }
+
+        if ("notification_sound".equals(prefKey)) {
+            return false;
+        }
+
+        if ("patternlock_enabled".equals(prefKey)) {
+            this.setLockEnabled(false);
+            if (mLockPatternUtils.isLockPatternEnabled()) {
+                // The user is trying to disable the lock pattern,
+                // only disable if the user knows the pattern.
+                startActivityForResult(new Intent(this, ConfirmLockPattern.class),
+                        DISABLE_LOCKPATTERN);
+                return true;
+            } else {
+                // No lock pattern has been set yet, let the user choose a new one.
+                startActivityForResult(new Intent(this, ChooseLockPattern.class),
+                        ENABLE_LOCKPATTERN);
+                return true;
+            }
+        } else if ("patternlock_change".equals(prefKey)) {
+            this.setLockEnabled(false);
+            startActivityForResult(new Intent(this, ChooseLockPattern.class), CHANGE_LOCKPATTERN);
+            return true;
+        } else if ("remotenotifier_help".equals(prefKey)) {
+            startActivity(new Intent(Intent.ACTION_VIEW,
+                    Uri.parse("http://code.google.com/p/android-notifier/")));
+            return true;
+        } else if ("openwatch_help".equals(prefKey)) {
+            startActivity(new Intent(Intent.ACTION_VIEW,
+                    Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));
+            return true;
+        } else if ("liveview_help".equals(prefKey)) {
+            startActivity(new Intent(Intent.ACTION_VIEW,
+                    Uri.parse(
+                            "http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay")));
+            return true;
+        } else if ("test_notification".equals(prefKey)) {
             Log.d(TAG, "Sending test notification.");
             Account account1 = new Account("Personkonto", new BigDecimal(8351.00), "22");
             Bank bank1 = new Swedbank(this);
@@ -130,49 +135,47 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
             bank2.setDbid(22);
             bank2.setCustomName("800416-0002");
 
-            AutoRefreshService.showNotification(bank1, account1, new BigDecimal(-143.50), this);      
-            AutoRefreshService.showNotification(bank2, account2, new BigDecimal(-123.50), this);      
-		    return true;
-		}
-		return false;
-	}
-
-	@Override
-	protected void onActivityResult(final int requestCode, final int resultCode,
-			final Intent data) {
-		super.onActivityResult(requestCode, resultCode, data);
-		if (requestCode == DISABLE_LOCKPATTERN) {
-			if (resultCode == RESULT_OK) {
-				mLockPatternUtils.setLockPatternEnabled(false);
-				mLockPatternUtils.saveLockPattern(null);
-				((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(false);
-			}
-			else {
-				Log.d(TAG, "User was unable to disable pattern lock.");
-			}
-		}
-		else if (requestCode == ENABLE_LOCKPATTERN) {
-			// User attempted to enable the pattern lock, toggle the checkbox.
-			((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(mLockPatternUtils.isLockPatternEnabled());
-		}
-		else if (requestCode == CHANGE_LOCKPATTERN) {
-			// Don't do anything special
-		}
-	}
-
-	@Override
-	protected void onResume() {
-		super.onResume();
-		this.setLockEnabled(true);
-	}
-
-	@Override
-	protected void onPause() {
-		super.onPause();
-		StartupReceiver.setAlarm(this);
-		// Blur/unblur the widget balance
-		AutoRefreshService.sendWidgetRefresh(this);
-	}
+            AutoRefreshService.showNotification(bank1, account1, new BigDecimal(-143.50), this);
+            AutoRefreshService.showNotification(bank2, account2, new BigDecimal(-123.50), this);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected void onActivityResult(final int requestCode, final int resultCode,
+            final Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (requestCode == DISABLE_LOCKPATTERN) {
+            if (resultCode == RESULT_OK) {
+                mLockPatternUtils.setLockPatternEnabled(false);
+                mLockPatternUtils.saveLockPattern(null);
+                ((CheckBoxPreference) findPreference("patternlock_enabled")).setChecked(false);
+            } else {
+                Log.d(TAG, "User was unable to disable pattern lock.");
+            }
+        } else if (requestCode == ENABLE_LOCKPATTERN) {
+            // User attempted to enable the pattern lock, toggle the checkbox.
+            ((CheckBoxPreference) findPreference("patternlock_enabled"))
+                    .setChecked(mLockPatternUtils.isLockPatternEnabled());
+        } else if (requestCode == CHANGE_LOCKPATTERN) {
+            // Don't do anything special
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        this.setLockEnabled(true);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        StartupReceiver.setAlarm(this);
+        // Blur/unblur the widget balance
+        AutoRefreshService.sendWidgetRefresh(this);
+    }
 
     @Override
     public boolean onPreferenceChange(Preference pref, Object newValue) {
@@ -181,16 +184,16 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
             Integer val;
             try {
                 val = Integer.valueOf((String) newValue);
-            }
-            catch (NumberFormatException e) {
+            } catch (NumberFormatException e) {
                 val = null;
             }
-            
+
             if (val != null && val >= 0) {
                 return true;
-            }
-            else {
-                Toast.makeText(pref.getContext(), String.format(pref.getContext().getString(R.string.invalid_integer), newValue), Toast.LENGTH_LONG).show();
+            } else {
+                Toast.makeText(pref.getContext(),
+                        String.format(pref.getContext().getString(R.string.invalid_integer),
+                                newValue), Toast.LENGTH_LONG).show();
             }
             return false;
         }
diff --git app/src/main/java/com/liato/bankdroid/StartupReceiver.java app/src/main/java/com/liato/bankdroid/StartupReceiver.java
index 710ca31..355d95c 100644
--- app/src/main/java/com/liato/bankdroid/StartupReceiver.java
+++ app/src/main/java/com/liato/bankdroid/StartupReceiver.java
@@ -20,58 +20,61 @@ import com.liato.bankdroid.appwidget.AutoRefreshService;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
-import android.appwidget.AppWidgetManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.net.ConnectivityManager;
-import android.net.Uri;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
-import android.util.Log;
 
-public class StartupReceiver extends BroadcastReceiver{
+public class StartupReceiver extends BroadcastReceiver {
+
     private final static String TAG = "StartupReceiver";
-	@Override
-	public void onReceive(Context context, Intent intent) {
-		//Set alarms for auto updates on boot, package update, package replace and package new
-		if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
-	        updateNow(context);
-		}
-        else {
-            setAlarm(context);
-        }
-	}
-	
-	public static void setAlarm(Context context) {
-		PendingIntent alarmSender;
-		alarmSender = PendingIntent.getService(context, 0, new Intent(context, AutoRefreshService.class), PendingIntent.FLAG_UPDATE_CURRENT);
-		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+    public static void setAlarm(Context context) {
+        PendingIntent alarmSender;
+        alarmSender = PendingIntent
+                .getService(context, 0, new Intent(context, AutoRefreshService.class),
+                        PendingIntent.FLAG_UPDATE_CURRENT);
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         boolean autoUpdatesEnabled = prefs.getBoolean("autoupdates_enabled", true);
-        Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0")); 
-        AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+        Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0"));
+        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         if (!autoUpdatesEnabled) {
-        	am.cancel(alarmSender);
-        }
-        else {
-	        long firstTime = SystemClock.elapsedRealtime();
-	        int secondsInMinute = 60;
-	        if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_refreshrate_in_seconds", false)) {
-	            secondsInMinute = 1;
-	        }
-	        am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*secondsInMinute*1000, refreshRate*secondsInMinute*1000, alarmSender);
+            am.cancel(alarmSender);
+        } else {
+            long firstTime = SystemClock.elapsedRealtime();
+            int secondsInMinute = 60;
+            if (prefs.getBoolean("debug_mode", false) && prefs
+                    .getBoolean("debug_refreshrate_in_seconds", false)) {
+                secondsInMinute = 1;
+            }
+            am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    firstTime + refreshRate * secondsInMinute * 1000,
+                    refreshRate * secondsInMinute * 1000, alarmSender);
         }
-	
-	}
-	
-	public static void updateNow(Context context) {
+
+    }
+
+    public static void updateNow(Context context) {
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         boolean autoUpdatesEnabled = prefs.getBoolean("autoupdates_enabled", true);
         long lastUpdate = prefs.getLong("autoupdates_last_update", 0);
-        Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0")); 
-        if (autoUpdatesEnabled && System.currentTimeMillis() - lastUpdate > refreshRate*60*1000) {
+        Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0"));
+        if (autoUpdatesEnabled
+                && System.currentTimeMillis() - lastUpdate > refreshRate * 60 * 1000) {
             context.startService(new Intent(context, AutoRefreshService.class));
         }
-	}
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        //Set alarms for auto updates on boot, package update, package replace and package new
+        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+            updateNow(context);
+        } else {
+            setAlarm(context);
+        }
+    }
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/TimePreference.java app/src/main/java/com/liato/bankdroid/TimePreference.java
index eebc58b..654ccd3 100644
--- app/src/main/java/com/liato/bankdroid/TimePreference.java
+++ app/src/main/java/com/liato/bankdroid/TimePreference.java
@@ -9,60 +9,64 @@ import android.view.View;
 import android.widget.TimePicker;
 
 public class TimePreference extends DialogPreference {
-	private int lastValue = 0;
-	private TimePicker picker = null;
-
-	public TimePreference(Context ctxt, AttributeSet attrs) {
-		super(ctxt, attrs);
-
-		setPositiveButtonText("Set");
-		setNegativeButtonText("Cancel");
-	}
-
-	@Override
-	protected View onCreateDialogView() {
-		picker = new TimePicker(getContext());
-		picker.setIs24HourView(true);
-		return picker;
-	}
-
-	@Override
-	protected void onBindDialogView(View v) {
-		super.onBindDialogView(v);
-
-		picker.setCurrentHour(lastValue / 60);
-		picker.setCurrentMinute(lastValue % 60);
-	}
-
-	@Override
-	protected void onDialogClosed(boolean positiveResult) {
-		super.onDialogClosed(positiveResult);
-
-		if (positiveResult) {
-			lastValue = picker.getCurrentHour() * 60 + picker.getCurrentMinute(); 
-
-			if (callChangeListener(lastValue))
-				persistInt(lastValue);
-		}
-	}
-
-	@Override
-	protected Object onGetDefaultValue(TypedArray a, int index) {
-		return (a.getInt(index, 0));
-	}
-
-	@Override
-	protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
-		int val = 0;
-		
-		if (restoreValue) {
-			val = getPersistedInt(val);
-		} else {
-			try{
-				val = Integer.parseInt(defaultValue.toString());
-			} catch (NumberFormatException e) { }
-		}
-		
-		lastValue = val;
-	}
+
+    private int lastValue = 0;
+
+    private TimePicker picker = null;
+
+    public TimePreference(Context ctxt, AttributeSet attrs) {
+        super(ctxt, attrs);
+
+        setPositiveButtonText("Set");
+        setNegativeButtonText("Cancel");
+    }
+
+    @Override
+    protected View onCreateDialogView() {
+        picker = new TimePicker(getContext());
+        picker.setIs24HourView(true);
+        return picker;
+    }
+
+    @Override
+    protected void onBindDialogView(View v) {
+        super.onBindDialogView(v);
+
+        picker.setCurrentHour(lastValue / 60);
+        picker.setCurrentMinute(lastValue % 60);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (positiveResult) {
+            lastValue = picker.getCurrentHour() * 60 + picker.getCurrentMinute();
+
+            if (callChangeListener(lastValue)) {
+                persistInt(lastValue);
+            }
+        }
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray a, int index) {
+        return (a.getInt(index, 0));
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        int val = 0;
+
+        if (restoreValue) {
+            val = getPersistedInt(val);
+        } else {
+            try {
+                val = Integer.parseInt(defaultValue.toString());
+            } catch (NumberFormatException e) {
+            }
+        }
+
+        lastValue = val;
+    }
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
index 60b4353..1e0290b 100644
--- app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
+++ app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
@@ -16,6 +16,11 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.Transaction;
+
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
@@ -27,16 +32,12 @@ import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.Transaction;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
 public class TransactionsActivity extends LockableActivity {
+
     final static String TAG = "TransactionActivity";
 
     @Override
@@ -46,12 +47,14 @@ public class TransactionsActivity extends LockableActivity {
         setContentView(R.layout.transactions);
         Bundle extras = getIntent().getExtras();
         Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
-        if(bank == null) {
+        if (bank == null) {
             redirectToMain(getString(R.string.error_bank_not_found));
             return;
         }
-        Account account = BankFactory.accountFromDb(this, extras.getLong("bank") + "_" + extras.getString("account"), true);
-        if(account == null) {
+        Account account = BankFactory
+                .accountFromDb(this, extras.getLong("bank") + "_" + extras.getString("account"),
+                        true);
+        if (account == null) {
             redirectToMain(getString(R.string.error_account_not_found));
             return;
         }
@@ -62,7 +65,8 @@ public class TransactionsActivity extends LockableActivity {
         ImageView icon = (ImageView) findViewById(R.id.imgListitemAccountsGroup);
         viewBankName.setText(bank.getDisplayName());
         viewAccountName.setText(account.getName());
-        viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        viewAccountBalance
+                .setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
         icon.setImageResource(bank.getImageResource());
         List<Transaction> transactions = account.getTransactions();
 
@@ -86,8 +90,17 @@ public class TransactionsActivity extends LockableActivity {
         super.onResume();
     }
 
+    private void redirectToMain(String errorMessage) {
+        final Intent intent = new Intent(this, MainActivity.class);
+        ((BankdroidApplication) getApplicationContext())
+                .setApplicationMessage(getString(R.string.error_bank_not_found));
+        startActivity(intent);
+    }
+
     private class TransactionsAdapter extends BaseAdapter {
+
         private LayoutInflater inflater;
+
         private ArrayList<Object> items = new ArrayList<Object>();
 
         public TransactionsAdapter(List<Transaction> transactions) {
@@ -106,16 +119,21 @@ public class TransactionsActivity extends LockableActivity {
             }
         }
 
-        public View newTransactionView(Transaction transaction, ViewGroup parent, View convertView) {
+        public View newTransactionView(Transaction transaction, ViewGroup parent,
+                View convertView) {
             if (convertView == null) {
                 convertView = inflater.inflate(R.layout.transaction_item, parent, false);
             }
-            ((TextView) convertView.findViewById(R.id.txtTransaction)).setText(transaction.getTransaction());
-            ((TextView) convertView.findViewById(R.id.txtAmount)).setText(Helpers.formatBalance(transaction.getAmount(), transaction.getCurrency()));
+            ((TextView) convertView.findViewById(R.id.txtTransaction))
+                    .setText(transaction.getTransaction());
+            ((TextView) convertView.findViewById(R.id.txtAmount)).setText(
+                    Helpers.formatBalance(transaction.getAmount(), transaction.getCurrency()));
             if (transaction.getAmount().signum() == 1) {
-                ((ImageView) convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_positive);
+                ((ImageView) convertView.findViewById(R.id.imgColor))
+                        .setBackgroundResource(R.drawable.transaction_positive);
             } else {
-                ((ImageView) convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_negative);
+                ((ImageView) convertView.findViewById(R.id.imgColor))
+                        .setBackgroundResource(R.drawable.transaction_negative);
             }
             return convertView;
         }
@@ -183,10 +201,4 @@ public class TransactionsActivity extends LockableActivity {
 
     }
 
-    private void redirectToMain(String errorMessage) {
-        final Intent intent = new Intent(this, MainActivity.class);
-        ((BankdroidApplication) getApplicationContext()).setApplicationMessage(getString(R.string.error_bank_not_found));
-        startActivity(intent);
-    }
-
 }
diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index 3874b5e..2e102b5 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -16,6 +16,14 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Bank.SessionPackage;
+import com.liato.bankdroid.banking.BankFactory;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.client.CookieStore;
+import org.apache.http.cookie.Cookie;
+
 import android.content.res.Resources.NotFoundException;
 import android.os.Bundle;
 import android.os.Handler;
@@ -30,14 +38,6 @@ import android.webkit.WebChromeClient;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Bank.SessionPackage;
-import com.liato.bankdroid.banking.BankFactory;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.client.CookieStore;
-import org.apache.http.cookie.Cookie;
-
 import java.io.IOException;
 
 import eu.nullbyte.android.urllib.Urllib;
@@ -45,13 +45,18 @@ import eu.nullbyte.android.urllib.Urllib;
 import static android.graphics.Color.WHITE;
 
 public class WebViewActivity extends LockableActivity implements OnClickListener {
+
     private final static String TAG = "WebViewActivity";
+
     private static WebView mWebView;
-    private boolean mFirstPageLoaded = false;
+
     private final LockableActivity activity = this;
+
+    private boolean mFirstPageLoaded = false;
+
     private Handler mMainThreadhandler = new Handler(Looper.getMainLooper());
 
-    
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -65,13 +70,13 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
 //        this.setTitleButtonEnabled("refresh", false);
 
         final CookieSyncManager csm = CookieSyncManager.createInstance(this);
-        mWebView = (WebView)findViewById(R.id.wvBank);
+        mWebView = (WebView) findViewById(R.id.wvBank);
         mWebView.setBackgroundColor(0);
         mWebView.getSettings().setJavaScriptEnabled(true);
-        mWebView.getSettings().setBuiltInZoomControls(true); 
+        mWebView.getSettings().setBuiltInZoomControls(true);
         mWebView.getSettings().setUserAgentString(Urllib.DEFAULT_USER_AGENT);
         mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
-        
+
         mWebView.setWebChromeClient(new WebChromeClient() {
             public void onProgressChanged(WebView view, int progress) {
 //                activity.setProgressBar(progress);
@@ -80,36 +85,36 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                     Runnable runnable = new Runnable() {
                         public void run() {
 //                            activity.hideProgressBar();
-                            if (mFirstPageLoaded) mWebView.setBackgroundColor(WHITE);
+                            if (mFirstPageLoaded) {
+                                mWebView.setBackgroundColor(WHITE);
+                            }
                         }
                     };
                     // Let the progress bar hit 100% before we hide it.
                     handler.postDelayed(runnable, 100);
-                    
-                }
-                else if (mFirstPageLoaded) {
+
+                } else if (mFirstPageLoaded) {
 //                    activity.showProgressBar();
                 }
             }
-          });
+        });
         mWebView.setWebViewClient(new BankWebViewClient());
         String preloader = "Error...";
         try {
             preloader = IOUtils.toString(getResources().openRawResource(R.raw.loading));
             preloader = String.format(preloader,
-                                    "", // Javascript function
-                                    "" // HTML
-                                    );
-        }
-        catch (NotFoundException e) {
+                    "", // Javascript function
+                    "" // HTML
+            );
+        } catch (NotFoundException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
-        }
-        catch (IOException e) {
+        } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
-        mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", preloader, "text/html", "utf-8", null);
+        mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", preloader, "text/html", "utf-8",
+                null);
         Bundle extras = getIntent().getExtras();
         final long bankId = extras.getLong("bankid", -1);
         //final long bankId = -1;
@@ -117,7 +122,8 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
             Runnable generateLoginPage = new Runnable() {
                 public void run() {
                     Bank bank = BankFactory.bankFromDb(bankId, WebViewActivity.this, false);
-                    final SessionPackage loginPackage = bank.getSessionPackage(WebViewActivity.this);
+                    final SessionPackage loginPackage = bank
+                            .getSessionPackage(WebViewActivity.this);
                     final CookieStore cookieStore = loginPackage.getCookiestore();
                     mMainThreadhandler.post(new Runnable() {
                         @Override
@@ -129,19 +135,21 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                                 for (Cookie cookie : cookieStore.getCookies()) {
                                     cookieString = String.format("%s=%s;%spath=%s; domain=%s;",
                                             cookie.getName(), cookie.getValue(),
-                                            cookie.getExpiryDate() == null ? "" : "expires="+cookie.getExpiryDate()+"; ",
+                                            cookie.getExpiryDate() == null ? ""
+                                                    : "expires=" + cookie.getExpiryDate() + "; ",
                                             cookie.getPath() == null ? "/" : cookie.getPath(),
                                             cookie.getDomain());
                                     cookieManager.setCookie(cookie.getDomain(), cookieString);
                                 }
                                 csm.sync();
                             }
-                            mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", loginPackage.getHtml(), "text/html", "utf-8", null);
+                            mWebView.loadDataWithBaseURL("what://is/this/i/dont/even",
+                                    loginPackage.getHtml(), "text/html", "utf-8", null);
                         }
                     });
                 }
-              };
-              new Thread(generateLoginPage).start();
+            };
+            new Thread(generateLoginPage).start();
         }
     }
 
@@ -149,13 +157,39 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         super.onResume();
     }
 
+    //Handle the back key
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (mWebView != null) {
+            if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
+                mWebView.goBack();
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public void onClick(View v) {
+        String tag = (String) v.getTag();
+        if ("refresh".equals(tag)) {
+            mWebView.reload();
+        } else if ("back".equals(tag)) {
+            mWebView.goBack();
+        } else if ("forward".equals(tag)) {
+            mWebView.goForward();
+        }
+    }
+
     // Make sure clicked links are loaded in our webview.
     private class BankWebViewClient extends WebViewClient {
 
         @Override
         public void onLoadResource(WebView view, String url) {
             super.onLoadResource(view, url);
-            if (mFirstPageLoaded) handleHistoryChange();
+            if (mFirstPageLoaded) {
+                handleHistoryChange();
+            }
         }
 
 
@@ -164,8 +198,10 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
             super.onPageFinished(view, url);
             if (!mFirstPageLoaded) {
                 //This is the generated POST page.
-                if (url.startsWith("what:")) return;
-                
+                if (url.startsWith("what:")) {
+                    return;
+                }
+
                 //This is the first real page.
                 //Remove the generated page from history.
                 mWebView.clearHistory();
@@ -174,7 +210,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                 return;
             }
         }
-        
+
 
         @Override
         public void onFormResubmission(WebView view, Message dontResend,
@@ -189,36 +225,10 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
             view.loadUrl(url);
             return true;
         }
-        
+
         public void handleHistoryChange() {
 //            activity.setTitleButtonEnabled("back", mWebView.canGoBack());
 //            activity.setTitleButtonEnabled("forward", mWebView.canGoForward());
         }
-    }	
-
-    //Handle the back key
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (mWebView != null) {
-            if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
-                mWebView.goBack();
-                return true;
-            }
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public void onClick(View v) {
-        String tag = (String)v.getTag();
-        if ("refresh".equals(tag)) {
-            mWebView.reload();
-        }
-        else if ("back".equals(tag)) {
-            mWebView.goBack();
-        }
-        else if ("forward".equals(tag)) {
-            mWebView.goForward();
-        }
     }
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
index 1e18ad5..52263ce 100644
--- app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -16,7 +16,10 @@
 
 package com.liato.bankdroid.adapters;
 
-import java.util.ArrayList;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
 
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -29,37 +32,42 @@ import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
+import java.util.ArrayList;
 
 public class AccountsAdapter extends BaseAdapter {
-	public final static int VIEWTYPE_BANK = 0;
+
+    public final static int VIEWTYPE_BANK = 0;
+
     public final static int VIEWTYPE_ACCOUNT = 1;
+
     public final static int VIEWTYPE_EMPTY = 2;
-	private ArrayList<Bank> banks;
-	private Context context;
-	private LayoutInflater inflater;
-	private boolean showHidden;
-	SharedPreferences prefs;
+
+    SharedPreferences prefs;
+
+    private ArrayList<Bank> banks;
+
+    private Context context;
+
+    private LayoutInflater inflater;
+
+    private boolean showHidden;
 
     public AccountsAdapter(Context context, boolean showHidden) {
-		this.context = context;
-		this.banks = new ArrayList<Bank>();
-		inflater = LayoutInflater.from(this.context);
-		this.showHidden = showHidden;
-		prefs = PreferenceManager.getDefaultSharedPreferences(context);
-	}
-
-	public void addGroup(Bank bank) {
-		banks.add(bank);
-	}
-
-	public void setGroups(ArrayList<Bank> banks) {
-		this.banks = banks;
-		/*for (Bank b : this.banks) {
-		    ArrayList<Account> as = b.getAccounts(); 
+        this.context = context;
+        this.banks = new ArrayList<Bank>();
+        inflater = LayoutInflater.from(this.context);
+        this.showHidden = showHidden;
+        prefs = PreferenceManager.getDefaultSharedPreferences(context);
+    }
+
+    public void addGroup(Bank bank) {
+        banks.add(bank);
+    }
+
+    public void setGroups(ArrayList<Bank> banks) {
+        this.banks = banks;
+                /*for (Bank b : this.banks) {
+                    ArrayList<Account> as = b.getAccounts();
 		    for (Account a : as) {
 		        if (a.isHidden() && !showHidden) {
 		            as.remove(a);
@@ -67,7 +75,7 @@ public class AccountsAdapter extends BaseAdapter {
 		            
 		    }
 		}*/
-	}
+    }
 
     public boolean isShowHidden() {
         return showHidden;
@@ -77,142 +85,146 @@ public class AccountsAdapter extends BaseAdapter {
         this.showHidden = showHidden;
     }
 
-	public View newBankView(Bank bank, ViewGroup parent, View convertView) {
-		if (convertView == null) {
-			convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
-		}
+    public View newBankView(Bank bank, ViewGroup parent, View convertView) {
+        if (convertView == null) {
+            convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
+        }
 
-		ImageView icon = (ImageView)convertView.findViewById(R.id.imgListitemAccountsGroup);
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(bank.getDisplayName());
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(bank.getName());
+        ImageView icon = (ImageView) convertView.findViewById(R.id.imgListitemAccountsGroup);
+        ((TextView) convertView.findViewById(R.id.txtListitemAccountsGroupAccountname))
+                .setText(bank.getDisplayName());
+        ((TextView) convertView.findViewById(R.id.txtListitemAccountsGroupBankname))
+                .setText(bank.getName());
         ((TextView) convertView
                 .findViewById(R.id.txtListitemAccountsGroupTotal))
                 .setText(Helpers.formatBalance(bank.getBalance(),
                         bank.getCurrency(),
-                        prefs.getBoolean("round_balance", false) || !bank.getDisplayDecimals(), bank.getDecimalFormatter()));
-		icon.setImageResource(bank.getImageResource());
-		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
-		if (bank.isDisabled()) {
-			warning.setVisibility(View.VISIBLE);
-		}
-		else {
-			warning.setVisibility(View.INVISIBLE);
-		}
-		return convertView;
-	}
-
-	public View newAccountView(Account account, ViewGroup parent, View convertView) {
+                        prefs.getBoolean("round_balance", false) || !bank.getDisplayDecimals(),
+                        bank.getDecimalFormatter()));
+        icon.setImageResource(bank.getImageResource());
+        ImageView warning = (ImageView) convertView.findViewById(R.id.imgWarning);
+        if (bank.isDisabled()) {
+            warning.setVisibility(View.VISIBLE);
+        } else {
+            warning.setVisibility(View.INVISIBLE);
+        }
+        return convertView;
+    }
+
+    public View newAccountView(Account account, ViewGroup parent, View convertView) {
         if ((account.isHidden() && !showHidden) || account.getBank().getHideAccounts()) {
-            return convertView == null ? inflater.inflate(R.layout.empty, parent, false) : convertView;
+            return convertView == null ? inflater.inflate(R.layout.empty, parent, false)
+                    : convertView;
+        }
+        if (convertView == null) {
+            convertView = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
         }
-		if (convertView == null) {
-			convertView = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
-		}
-		convertView.findViewById(R.id.divider).setBackgroundColor(Color.argb(30, 255, 255, 255));
-		TextView txtAccountName = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemAccountname));
-        TextView txtBalance = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance));
-		txtAccountName.setText(account.getName());
-		txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        convertView.findViewById(R.id.divider).setBackgroundColor(Color.argb(30, 255, 255, 255));
+        TextView txtAccountName = ((TextView) convertView
+                .findViewById(R.id.txtListitemAccountsItemAccountname));
+        TextView txtBalance = ((TextView) convertView
+                .findViewById(R.id.txtListitemAccountsItemBalance));
+        txtAccountName.setText(account.getName());
+        txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
         txtBalance
                 .setText(Helpers.formatBalance(account.getBalance(),
                         account.getCurrency(),
-                        prefs.getBoolean("round_balance", false) || !account.getBank().getDisplayDecimals(),
+                        prefs.getBoolean("round_balance", false) || !account.getBank()
+                                .getDisplayDecimals(),
                         account.getBank().getDecimalFormatter()));
-		if (account.isHidden()) {
+        if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
             txtBalance.setTextColor(Color.argb(255, 191, 191, 191));
-		}
-		else {
+        } else {
             txtAccountName.setTextColor(Color.WHITE);
             txtBalance.setTextColor(Color.WHITE);
-		}
-		return convertView;
-	}
-
-	@Override
-	public int getCount() {
-		int c = 0;
-		for(Bank g : banks) {
-			if (g.getHideAccounts())
-				c++;
- 			else
-				c += g.getAccounts().size()+1;
-		}
-		return c;
-	}
-
-	@Override
-	public Object getItem(int position) {
-		if (banks.size() == 0) {
-			return null;
-		}
-		if (position == 0) {
-			return banks.get(0);
-		}
-
-		int i = 0;
-		for (Bank g : banks) {
-			if (position == i) {
-				return g;
-			}
-			else if (g.getHideAccounts()) {
-				i++;
-				continue;
-			}
-			else if (position <= (g.getAccounts().size()+i)) {
-				return g.getAccounts().get(position-i-1);
-			}
-			i += g.getAccounts().size()+1;
-		}
-
-		return(null);
-	}
-
-	@Override
-	public long getItemId(int position) {
-		return position;
-	}
-
-	@Override
-	public View getView(int position, View convertView, ViewGroup parent) {
-		Object item = getItem(position);
-		if (item == null) {
-			return null;
-		}
-		if (item instanceof Bank) {
-			return newBankView((Bank)item, parent, convertView);
-		}
-		else if (item instanceof Account) {
-			return newAccountView((Account)item, parent, convertView);
-		}
-		return null;
-	}
-
-	public boolean isEnabled(int position) {
-	    if (getItemViewType(position) == VIEWTYPE_EMPTY) return false;
-	    return true;
-	}
-
-
-	@Override
-	public int getViewTypeCount () {
-		return 3;
-	}
-
-	@Override
-	public int getItemViewType(int position) {
-		Object item = getItem(position);
-		if (item instanceof Bank) {
-			return VIEWTYPE_BANK;
-		}
-		else {
-		    if ((((Account)item).isHidden() && !showHidden) ||
+        }
+        return convertView;
+    }
+
+    @Override
+    public int getCount() {
+        int c = 0;
+        for (Bank g : banks) {
+            if (g.getHideAccounts()) {
+                c++;
+            } else {
+                c += g.getAccounts().size() + 1;
+            }
+        }
+        return c;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        if (banks.size() == 0) {
+            return null;
+        }
+        if (position == 0) {
+            return banks.get(0);
+        }
+
+        int i = 0;
+        for (Bank g : banks) {
+            if (position == i) {
+                return g;
+            } else if (g.getHideAccounts()) {
+                i++;
+                continue;
+            } else if (position <= (g.getAccounts().size() + i)) {
+                return g.getAccounts().get(position - i - 1);
+            }
+            i += g.getAccounts().size() + 1;
+        }
+
+        return (null);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        Object item = getItem(position);
+        if (item == null) {
+            return null;
+        }
+        if (item instanceof Bank) {
+            return newBankView((Bank) item, parent, convertView);
+        } else if (item instanceof Account) {
+            return newAccountView((Account) item, parent, convertView);
+        }
+        return null;
+    }
+
+    public boolean isEnabled(int position) {
+        if (getItemViewType(position) == VIEWTYPE_EMPTY) {
+            return false;
+        }
+        return true;
+    }
+
+
+    @Override
+    public int getViewTypeCount() {
+        return 3;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        Object item = getItem(position);
+        if (item instanceof Bank) {
+            return VIEWTYPE_BANK;
+        } else {
+            if ((((Account) item).isHidden() && !showHidden) ||
                     ((Account) item).getBank().getHideAccounts()) {
-		        return VIEWTYPE_EMPTY;
-		    }
-		}
-		return VIEWTYPE_ACCOUNT;
-	}
+                return VIEWTYPE_EMPTY;
+            }
+        }
+        return VIEWTYPE_ACCOUNT;
+    }
 }
 
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index a66bfc7..d04a3db 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -16,10 +16,18 @@
 
 package com.liato.bankdroid.appwidget;
 
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
+import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.liveview.LiveViewService;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -40,34 +48,150 @@ import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
-import com.crashlytics.android.Crashlytics;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.MainActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.liveview.LiveViewService;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
 
 public class AutoRefreshService extends Service {
-	private final static String TAG = "AutoRefreshService";
-	public final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
-	public final static String BROADCAST_MAIN_REFRESH = "com.liato.bankdroid.MAIN_REFRESH";
-	public final static String BROADCAST_REMOTE_NOTIFIER = "org.damazio.notifier.service.UserReceiver.USER_MESSAGE";
-	public final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
-	public final static String BROADCAST_OPENWATCH_VIBRATE = "com.smartmadsoft.openwatch.action.VIBRATE";
-	public final static String ACTION_MAIN_SHOW_TRANSACTIONS = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
-	public final static String BROADCAST_TRANSACTIONS_UPDATED = "com.liato.bankdroid.action.TRANSACTIONS";
-
-	@Override
-	public void onCreate() {
-
-	}
-	
+
+    public final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
+
+    public final static String BROADCAST_MAIN_REFRESH = "com.liato.bankdroid.MAIN_REFRESH";
+
+    public final static String BROADCAST_REMOTE_NOTIFIER
+            = "org.damazio.notifier.service.UserReceiver.USER_MESSAGE";
+
+    public final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
+
+    public final static String BROADCAST_OPENWATCH_VIBRATE
+            = "com.smartmadsoft.openwatch.action.VIBRATE";
+
+    public final static String ACTION_MAIN_SHOW_TRANSACTIONS
+            = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
+
+    public final static String BROADCAST_TRANSACTIONS_UPDATED
+            = "com.liato.bankdroid.action.TRANSACTIONS";
+
+    private final static String TAG = "AutoRefreshService";
+
+    public static void showNotification(final Bank bank, final Account account,
+            final BigDecimal diff, Context context) {
+
+        final SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(context);
+        if (!prefs.getBoolean("notify_on_change", true)) {
+            return;
+        }
+
+        String text = String.format("%s: %s%s", account.getName(),
+                ((diff.compareTo(new BigDecimal(0)) == 1) ? "+" : ""),
+                Helpers.formatBalance(diff, account.getCurrency()));
+        if (!prefs.getBoolean("notify_delta_only", false)) {
+            text = String.format("%s (%s)", text,
+                    Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        }
+
+        final NotificationManager notificationManager = (NotificationManager) context
+                .getSystemService(NOTIFICATION_SERVICE);
+        final Notification notification = new Notification(bank.getImageResource(), text,
+                System.currentTimeMillis());
+        // Remove notification from statusbar when clicked
+        notification.flags |= Notification.FLAG_AUTO_CANCEL;
+
+        // http://www.freesound.org/samplesViewSingle.php?id=75235
+        // http://www.freesound.org/samplesViewSingle.php?id=91924
+        if (prefs.getString("notification_sound", null) != null) {
+            notification.sound = Uri.parse(prefs.getString(
+                    "notification_sound", null));
+        }
+        if (prefs.getBoolean("notify_with_vibration", true)) {
+            final long[] vib = {0, 90, 130, 80, 350, 190, 20, 380};
+            notification.vibrate = vib;
+            // notification.defaults |= Notification.DEFAULT_VIBRATE;
+        }
+
+        if (prefs.getBoolean("notify_with_led", true)) {
+            notification.ledARGB = prefs.getInt("notify_with_led_color",
+                    context.getResources().getColor(R.color.default_led_color));
+            notification.flags |= Notification.FLAG_SHOW_LIGHTS;
+            notification.ledOnMS = 700;
+            notification.ledOffMS = 200;
+        }
+
+        final PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
+                new Intent(context, MainActivity.class), 0);
+
+        notification.setLatestEventInfo(context, bank.getDisplayName(), text, contentIntent);
+
+        String numNotifications = prefs.getString("num_notifications", "total");
+        int notificationId = (int) (numNotifications.equals("total") ? 0
+                : numNotifications.equals("bank") ? bank.getDbId()
+                        : numNotifications.equals("account") ? account.getId().hashCode()
+                                : SystemClock.elapsedRealtime());
+        notificationManager.notify(notificationId, notification);
+
+        // Broadcast to Remote Notifier if enabled
+        // http://code.google.com/p/android-notifier/
+        if (prefs.getBoolean("notify_remotenotifier", false)) {
+            final Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
+            i.putExtra("title", String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
+            i.putExtra("description", text);
+            context.sendBroadcast(i);
+        }
+
+        // Broadcast to OpenWatch if enabled
+        // http://forum.xda-developers.com/showthread.php?t=554551
+        if (prefs.getBoolean("notify_openwatch", false)) {
+            Intent i;
+            if (prefs.getBoolean("notify_openwatch_vibrate", false)) {
+                i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
+            } else {
+                i = new Intent(BROADCAST_OPENWATCH_TEXT);
+            }
+            i.putExtra("line1", String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
+            i.putExtra("line2", text);
+            context.sendBroadcast(i);
+        }
+
+        // Broadcast to LiveView if enabled
+        // http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay
+        if (prefs.getBoolean("notify_liveview", false)) {
+            final Intent i = new Intent(context, LiveViewService.class);
+            i.putExtra(LiveViewService.INTENT_EXTRA_ANNOUNCE, true);
+            i.putExtra(LiveViewService.INTENT_EXTRA_TITLE,
+                    String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
+            i.putExtra(LiveViewService.INTENT_EXTRA_TEXT, text);
+            context.startService(i);
+        }
+
+    }
+
+    public static void broadcastTransactionUpdate(final Context context,
+            final long bankId, final String accountId) {
+        final Intent i = new Intent(BROADCAST_TRANSACTIONS_UPDATED);
+        i.putExtra("accountId", Long.toString(bankId) + "_" + accountId);
+        context.sendBroadcast(i);
+    }
+
+    public static void sendWidgetRefresh(final Context context) {
+        // Send intent to BankdroidWidgetProvider
+        final Intent updateIntent = new Intent(BROADCAST_WIDGET_REFRESH);
+        final PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
+                0, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+        try {
+            pendingIntent.send();
+        } catch (final CanceledException e) {
+            // TODO Auto-generated catch block
+            Log.e("", e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void onCreate() {
+
+    }
+
     @Override
     public void onStart(Intent intent, int startId) {
         handleStart(intent, startId);
@@ -78,17 +202,16 @@ public class AutoRefreshService extends Service {
         handleStart(intent, startId);
         return START_NOT_STICKY;
     }
-    
+
     private void handleStart(Intent intent, int startId) {
         ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
         NetworkInfo ni = cm.getActiveNetworkInfo();
         if (ni != null &&
                 ni.isConnected() &&
                 shouldUpdateOnRoaming(ni)) {
-            if (InsideUpdatePeriod()){
+            if (InsideUpdatePeriod()) {
                 new DataRetrieverTask().execute();
-            }
-            else{
+            } else {
                 Log.v(TAG, "Skipping update due to not in update period.");
                 stopSelf();
             }
@@ -105,290 +228,191 @@ public class AutoRefreshService extends Service {
     }
 
     private boolean InsideUpdatePeriod() {
-		final SharedPreferences prefs = PreferenceManager
-			.getDefaultSharedPreferences(this);
-		
-		int start = prefs.getInt("refresh_start_minutes", 0);
-		int stop = prefs.getInt("refresh_stop_minutes", 0);
-		
-		// If start is bigger than stop we always update. It should perhaps 
-		// be possible to set start to 17:00 and stop to 07:00 and have to 
-		// updates working from 17 to 07 around midnight
-		if (start >= stop)
-			return true;
-		
+        final SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(this);
+
+        int start = prefs.getInt("refresh_start_minutes", 0);
+        int stop = prefs.getInt("refresh_stop_minutes", 0);
+
+        // If start is bigger than stop we always update. It should perhaps
+        // be possible to set start to 17:00 and stop to 07:00 and have to
+        // updates working from 17 to 07 around midnight
+        if (start >= stop) {
+            return true;
+        }
+
         Date now = new Date();
-		int minutesSinceMidnight = now.getHours() * 60 + now.getMinutes();
-		return minutesSinceMidnight > start && minutesSinceMidnight < stop;
-	}
+        int minutesSinceMidnight = now.getHours() * 60 + now.getMinutes();
+        return minutesSinceMidnight > start && minutesSinceMidnight < stop;
+    }
+
+    @Override
+    public void onDestroy() {
+    }
 
-	@Override
-	public void onDestroy() {
-	}
+    @Override
+    public IBinder onBind(final Intent intent) {
+        return null;
+    }
 
-	@Override
-	public IBinder onBind(final Intent intent) {
-		return null;
-	}
+    private class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
-    public static void showNotification(final Bank bank, final Account account,
-            final BigDecimal diff, Context context) {
-        
-		final SharedPreferences prefs = PreferenceManager
-				.getDefaultSharedPreferences(context);
-		if (!prefs.getBoolean("notify_on_change", true)) {
-			return;
-		}
-        
-        String text = String.format("%s: %s%s", account.getName(), ((diff.compareTo(new BigDecimal(0)) == 1) ? "+": ""), Helpers.formatBalance(diff, account.getCurrency()));
-        if (!prefs.getBoolean("notify_delta_only", false)) {
-            text = String.format("%s (%s)", text, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
-        }
+        SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(AutoRefreshService.this);
 
-        final NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
-		final Notification notification = new Notification(bank.getImageResource(), text,
-				System.currentTimeMillis());
-		// Remove notification from statusbar when clicked
-		notification.flags |= Notification.FLAG_AUTO_CANCEL;
-
-		// http://www.freesound.org/samplesViewSingle.php?id=75235
-		// http://www.freesound.org/samplesViewSingle.php?id=91924
-		if (prefs.getString("notification_sound", null) != null) {
-			notification.sound = Uri.parse(prefs.getString(
-					"notification_sound", null));
-		}
-		if (prefs.getBoolean("notify_with_vibration", true)) {
-			final long[] vib = { 0, 90, 130, 80, 350, 190, 20, 380 };
-			notification.vibrate = vib;
-			// notification.defaults |= Notification.DEFAULT_VIBRATE;
-		}
+        private ArrayList<String> errors;
 
-        if (prefs.getBoolean("notify_with_led", true)) {
-            notification.ledARGB = prefs.getInt("notify_with_led_color", context.getResources().getColor(R.color.default_led_color));
-            notification.flags |= Notification.FLAG_SHOW_LIGHTS;
-            notification.ledOnMS = 700; 
-            notification.ledOffMS = 200; 
+        private Resources res;
+
+        public DataRetrieverTask() {
         }
-		
-		final PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
-				new Intent(context, MainActivity.class), 0);
-
-		notification.setLatestEventInfo(context, bank.getDisplayName(), text, contentIntent);
-
-		String numNotifications = prefs.getString("num_notifications", "total");
-		int notificationId = (int) (numNotifications.equals("total") ? 0 : numNotifications.equals("bank") ? bank.getDbId() : numNotifications.equals("account") ? account.getId().hashCode() : SystemClock.elapsedRealtime());
-		notificationManager.notify(notificationId, notification);
-
-		// Broadcast to Remote Notifier if enabled
-		// http://code.google.com/p/android-notifier/
-		if (prefs.getBoolean("notify_remotenotifier", false)) {
-			final Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
-			i.putExtra("title", String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
-			i.putExtra("description", text);
-			context.sendBroadcast(i);
-		}
-
-		// Broadcast to OpenWatch if enabled
-		// http://forum.xda-developers.com/showthread.php?t=554551
-		if (prefs.getBoolean("notify_openwatch", false)) {
-			Intent i;
-			if (prefs.getBoolean("notify_openwatch_vibrate", false)) {
-				i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
-			} else {
-				i = new Intent(BROADCAST_OPENWATCH_TEXT);
-			}
-			i.putExtra("line1", String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
-			i.putExtra("line2", text);
-			context.sendBroadcast(i);
-		}
-		
-		// Broadcast to LiveView if enabled
-		// http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay
-		if (prefs.getBoolean("notify_liveview", false)) {
-			final Intent i = new Intent(context, LiveViewService.class);
-			i.putExtra(LiveViewService.INTENT_EXTRA_ANNOUNCE, true);
-			i.putExtra(LiveViewService.INTENT_EXTRA_TITLE, String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
-			i.putExtra(LiveViewService.INTENT_EXTRA_TEXT, text);
-			context.startService(i);
-		}
-
-	}
-
-	private class DataRetrieverTask extends AsyncTask<String, String, Void> {
-		SharedPreferences prefs = PreferenceManager
-				.getDefaultSharedPreferences(AutoRefreshService.this);
-		private ArrayList<String> errors;
-		private Resources res;
-
-		public DataRetrieverTask() {
-		}
-
-		@Override
-		protected void onPreExecute() {
-		}
-
-		@Override
-		protected Void doInBackground(final String... args) {
-			errors = new ArrayList<String>();
-			Boolean refreshWidgets = false;
-			final ArrayList<Bank> banks = BankFactory.banksFromDb(
-					AutoRefreshService.this, true);
-			if (banks.isEmpty()) {
-				return null;
-			}
-			final DBAdapter db = new DBAdapter(AutoRefreshService.this);
-			BigDecimal currentBalance;
-			BigDecimal diff;
-			BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0"));
-			
-			final HashMap<String, Account> accounts = new HashMap<String, Account>();
-
-			for (final Bank bank : banks) {
-				if (prefs.getBoolean("debug_mode", false)
-						&& prefs.getBoolean("debug_only_testbank", false)) {
-					Log.d(TAG,
-							"Debug::Only_Testbank is ON. Skipping update for "
-									+ bank.getName());
-					continue;
-				}
-				if (bank.isDisabled()) {
-					continue;
-				}
-				try {
-					currentBalance = bank.getBalance();
-					accounts.clear();
-					for (final Account account : bank.getAccounts()) {
-						accounts.put(account.getId(), account);
-					}
-					bank.update();
-					diff = currentBalance.subtract(bank.getBalance());
-					if (diff.compareTo(new BigDecimal(0)) != 0  && diff.abs().compareTo(minDelta) != -1) {
-						Account oldAccount;
-						for (final Account account : bank.getAccounts()) {
-							oldAccount = accounts.get(account.getId());
-							if (oldAccount != null) {
-								if (account.getBalance().compareTo(
-										oldAccount.getBalance()) != 0) {
-									boolean notify = false;
-									switch (account.getType()) {
-									case Account.REGULAR:
-										notify = prefs.getBoolean(
-												"notify_for_deposit", true);
-										break;
-									case Account.FUNDS:
-										notify = prefs.getBoolean(
-												"notify_for_funds", false);
-										break;
-									case Account.LOANS:
-										notify = prefs.getBoolean(
-												"notify_for_loans", false);
-										break;
-									case Account.CCARD:
-										notify = prefs.getBoolean(
-												"notify_for_ccards", true);
-										break;
-									case Account.OTHER:
-										notify = prefs.getBoolean(
-												"notify_for_other", false);
-										break;
-									}
-									if (account.isHidden()
-											|| !account.isNotify()) {
-										notify = false;
-									}
-									if (notify) {
-										diff = account.getBalance().subtract(
-												oldAccount.getBalance());
-										showNotification(bank, account, diff, AutoRefreshService.this);
-									}
-
-									refreshWidgets = true;
-								}
-							}
-						}
-						if (prefs.getBoolean(
-								"autoupdates_transactions_enabled", true)) {
-							bank.updateAllTransactions();
-						}
-					}
-					bank.closeConnection();
-					db.updateBank(bank);
-
-					// Send update for all accounts since we're overwriting the
-					// database transaction history
-					if (prefs.getBoolean("content_provider_enabled", false)) {
-						for (final Account account : bank.getAccounts()) {
-							broadcastTransactionUpdate(getBaseContext(),
-									bank.getDbId(), account.getId());
-						}
-					}
-				} catch (final BankException e) {
-					// Refresh widgets if an update fails
-					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
-							+ "'; BankException: " + e.getMessage());
 
-                    Crashlytics.logException(e);
-				} catch (final LoginException e) {
-					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
-							+ "'; LoginException: " + e.getMessage());
-					refreshWidgets = true;
-					db.disableBank(bank.getDbId());
-				}
-                catch (BankChoiceException e) {
+        @Override
+        protected void onPreExecute() {
+        }
+
+        @Override
+        protected Void doInBackground(final String... args) {
+            errors = new ArrayList<String>();
+            Boolean refreshWidgets = false;
+            final ArrayList<Bank> banks = BankFactory.banksFromDb(
+                    AutoRefreshService.this, true);
+            if (banks.isEmpty()) {
+                return null;
+            }
+            final DBAdapter db = new DBAdapter(AutoRefreshService.this);
+            BigDecimal currentBalance;
+            BigDecimal diff;
+            BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0"));
+
+            final HashMap<String, Account> accounts = new HashMap<String, Account>();
+
+            for (final Bank bank : banks) {
+                if (prefs.getBoolean("debug_mode", false)
+                        && prefs.getBoolean("debug_only_testbank", false)) {
+                    Log.d(TAG,
+                            "Debug::Only_Testbank is ON. Skipping update for "
+                                    + bank.getName());
+                    continue;
+                }
+                if (bank.isDisabled()) {
+                    continue;
                 }
-                catch (Exception e) {
+                try {
+                    currentBalance = bank.getBalance();
+                    accounts.clear();
+                    for (final Account account : bank.getAccounts()) {
+                        accounts.put(account.getId(), account);
+                    }
+                    bank.update();
+                    diff = currentBalance.subtract(bank.getBalance());
+                    if (diff.compareTo(new BigDecimal(0)) != 0
+                            && diff.abs().compareTo(minDelta) != -1) {
+                        Account oldAccount;
+                        for (final Account account : bank.getAccounts()) {
+                            oldAccount = accounts.get(account.getId());
+                            if (oldAccount != null) {
+                                if (account.getBalance().compareTo(
+                                        oldAccount.getBalance()) != 0) {
+                                    boolean notify = false;
+                                    switch (account.getType()) {
+                                        case Account.REGULAR:
+                                            notify = prefs.getBoolean(
+                                                    "notify_for_deposit", true);
+                                            break;
+                                        case Account.FUNDS:
+                                            notify = prefs.getBoolean(
+                                                    "notify_for_funds", false);
+                                            break;
+                                        case Account.LOANS:
+                                            notify = prefs.getBoolean(
+                                                    "notify_for_loans", false);
+                                            break;
+                                        case Account.CCARD:
+                                            notify = prefs.getBoolean(
+                                                    "notify_for_ccards", true);
+                                            break;
+                                        case Account.OTHER:
+                                            notify = prefs.getBoolean(
+                                                    "notify_for_other", false);
+                                            break;
+                                    }
+                                    if (account.isHidden()
+                                            || !account.isNotify()) {
+                                        notify = false;
+                                    }
+                                    if (notify) {
+                                        diff = account.getBalance().subtract(
+                                                oldAccount.getBalance());
+                                        showNotification(bank, account, diff,
+                                                AutoRefreshService.this);
+                                    }
+
+                                    refreshWidgets = true;
+                                }
+                            }
+                        }
+                        if (prefs.getBoolean(
+                                "autoupdates_transactions_enabled", true)) {
+                            bank.updateAllTransactions();
+                        }
+                    }
+                    bank.closeConnection();
+                    db.updateBank(bank);
+
+                    // Send update for all accounts since we're overwriting the
+                    // database transaction history
+                    if (prefs.getBoolean("content_provider_enabled", false)) {
+                        for (final Account account : bank.getAccounts()) {
+                            broadcastTransactionUpdate(getBaseContext(),
+                                    bank.getDbId(), account.getId());
+                        }
+                    }
+                } catch (final BankException e) {
+                    // Refresh widgets if an update fails
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
+                            + "'; BankException: " + e.getMessage());
+
+                    Crashlytics.logException(e);
+                } catch (final LoginException e) {
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
+                            + "'; LoginException: " + e.getMessage());
+                    refreshWidgets = true;
+                    db.disableBank(bank.getDbId());
+                } catch (BankChoiceException e) {
+                } catch (Exception e) {
                     Log.e(TAG, "Error while updating bank '" + bank.getDbId()
                             + "'; Exception: " + e.getMessage());
                 }
-			}
-
-			if (refreshWidgets) {
-				final Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
-				sendBroadcast(updateIntent);
-				sendWidgetRefresh(AutoRefreshService.this);
-			}
-			return null;
-		}
-
-		@Override
-		protected void onProgressUpdate(final String... args) {
-		}
-
-		@Override
-		protected void onPostExecute(final Void unused) {
-			if ((this.errors != null) && !this.errors.isEmpty()) {
-				final StringBuilder errormsg = new StringBuilder();
-				errormsg.append(res.getText(R.string.accounts_were_not_updated)
-						+ ":\n");
-				for (final String err : errors) {
-					errormsg.append(err);
-					errormsg.append("\n");
-				}
-			}
-			Editor edit = prefs.edit();
-			edit.putLong("autoupdates_last_update", System.currentTimeMillis());
-			edit.commit();
-			AutoRefreshService.this.stopSelf();
-		}
-	}
-
-	public static void broadcastTransactionUpdate(final Context context,
-			final long bankId, final String accountId) {
-		final Intent i = new Intent(BROADCAST_TRANSACTIONS_UPDATED);
-		i.putExtra("accountId", Long.toString(bankId) + "_" + accountId);
-		context.sendBroadcast(i);
-	}
-
-	public static void sendWidgetRefresh(final Context context) {
-		// Send intent to BankdroidWidgetProvider
-		final Intent updateIntent = new Intent(BROADCAST_WIDGET_REFRESH);
-		final PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
-				0, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-		try {
-			pendingIntent.send();
-		} catch (final CanceledException e) {
-			// TODO Auto-generated catch block
-			Log.e("", e.getMessage(), e);
-		}
-	}
+            }
+
+            if (refreshWidgets) {
+                final Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
+                sendBroadcast(updateIntent);
+                sendWidgetRefresh(AutoRefreshService.this);
+            }
+            return null;
+        }
+
+        @Override
+        protected void onProgressUpdate(final String... args) {
+        }
+
+        @Override
+        protected void onPostExecute(final Void unused) {
+            if ((this.errors != null) && !this.errors.isEmpty()) {
+                final StringBuilder errormsg = new StringBuilder();
+                errormsg.append(res.getText(R.string.accounts_were_not_updated)
+                        + ":\n");
+                for (final String err : errors) {
+                    errormsg.append(err);
+                    errormsg.append("\n");
+                }
+            }
+            Editor edit = prefs.edit();
+            edit.putLong("autoupdates_last_update", System.currentTimeMillis());
+            edit.commit();
+            AutoRefreshService.this.stopSelf();
+        }
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 118e305..2e6ec71 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -16,6 +16,19 @@
 
 package com.liato.bankdroid.appwidget;
 
+import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.NetworkUtils;
+
 import android.app.PendingIntent;
 import android.app.Service;
 import android.appwidget.AppWidgetManager;
@@ -34,43 +47,37 @@ import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
-import com.crashlytics.android.Crashlytics;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.MainActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.utils.NetworkUtils;
-
 import java.io.IOException;
 
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
-	private final static String TAG = "BankdroidWidgetProvider";
+
+    private final static String TAG = "BankdroidWidgetProvider";
+
     private final static String ACTION_WIDGET_BLUR = "com.liato.bankdroid.action.WIDGET_BLUR";
+
     private final static String ACTION_WIDGET_UNBLUR = "com.liato.bankdroid.action.WIDGET_UNBLUR";
-	
-	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId, Account account) {
-		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, account);
-		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
-	}
-
-	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId) {
-		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
-		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
-	}
-	
+
+    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId, Account account) {
+        RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, account);
+        if (views != null) {
+            appWidgetManager.updateAppWidget(appWidgetId, views);
+        }
+    }
+
+    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId) {
+        RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+        if (views != null) {
+            appWidgetManager.updateAppWidget(appWidgetId, views);
+        }
+    }
+
     static void unblurAppWidget(Context context, AppWidgetManager appWidgetManager,
             int appWidgetId) {
-        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);  
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
         Editor e = prefs.edit();
-        e.putBoolean("widget_unblurred_"+appWidgetId, true);
+        e.putBoolean("widget_unblurred_" + appWidgetId, true);
         e.commit();
 
         RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
@@ -81,13 +88,13 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
             views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE);
             appWidgetManager.updateAppWidget(appWidgetId, views);
         }
-    }	
+    }
 
     static void blurAppWidget(Context context, AppWidgetManager appWidgetManager,
             int appWidgetId) {
-        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);  
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
         Editor e = prefs.edit();
-        e.remove("widget_unblurred_"+appWidgetId);
+        e.remove("widget_unblurred_" + appWidgetId);
         e.commit();
         RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
         if (views != null) {
@@ -97,178 +104,185 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
             views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE);
             appWidgetManager.updateAppWidget(appWidgetId, views);
         }
-    }   
+    }
+
 
-    
     static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId) {
-		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
-		long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
-		if (accountId == null) {
-			Log.w("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
-			return disableAppWidget(context, appWidgetManager,
-					appWidgetId);
-		}
-		Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false);
-		if (account == null) {
-			Log.w("BankdroidWidgetProvider", "Account not found in db: "+accountId);
-			return disableAppWidget(context, appWidgetManager,
-					appWidgetId);
-			
-		}
-
-		Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false);
-		if (bank == null) {
-			Log.w("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
-			return disableAppWidget(context, appWidgetManager,
-					appWidgetId);
-			
-		}
-		
-		account.setBank(bank);
-		return buildAppWidget(context, appWidgetManager,
-				appWidgetId, account);
-	}	
-
-
-
-	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId, Account account) {
-		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
-		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
-        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
+            int appWidgetId) {
+        String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
+        long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
+        if (accountId == null) {
+            Log.w("BankdroidWidgetProvider", "Widget not found. ID: " + appWidgetId);
+            return disableAppWidget(context, appWidgetManager,
+                    appWidgetId);
+        }
+        Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false);
+        if (account == null) {
+            Log.w("BankdroidWidgetProvider", "Account not found in db: " + accountId);
+            return disableAppWidget(context, appWidgetManager,
+                    appWidgetId);
+
+        }
+
+        Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false);
+        if (bank == null) {
+            Log.w("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
+            return disableAppWidget(context, appWidgetManager,
+                    appWidgetId);
+
+        }
+
+        account.setBank(bank);
+        return buildAppWidget(context, appWidgetManager,
+                appWidgetId, account);
+    }
+
+
+    static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId, Account account) {
+        AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
+        int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
         SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
-		if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) {
-			if (providerInfo.initialLayout == R.layout.widget_large) {
-				layoutId = R.layout.widget_large_transparent;
-			} else {
-				layoutId = R.layout.widget_transparent;
-			}
-		}
-		Bank bank = account.getBank();
-		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
+        if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo
+                != null)) {
+            if (providerInfo.initialLayout == R.layout.widget_large) {
+                layoutId = R.layout.widget_large_transparent;
+            } else {
+                layoutId = R.layout.widget_transparent;
+            }
+        }
+        Bank bank = account.getBank();
+        RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
         views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
-        views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false), bank.getDecimalFormatter()));
-		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
-		if (bank.isDisabled()) {
-			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
-		}
-		else {
-			views.setViewVisibility(R.id.frmWarning, View.INVISIBLE);
-		}
-		Intent intent = new Intent(context, MainActivity.class);
-		PendingIntent pendingIntent;
-
-		//intent = new Intent(context, AccountsActivity.class);
-		pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-		views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent);
-		
-		intent = new Intent(context, WidgetService.class);
-		intent.setAction(AutoRefreshService.BROADCAST_WIDGET_REFRESH);
-		intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-		intent.setData(Uri.parse("rofl://copter/"+appWidgetId+"/"+System.currentTimeMillis()));
-		pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
-		views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent);
-		views.setOnClickPendingIntent(R.id.hitBox, pendingIntent);
-		
+        views.setTextViewText(R.id.txtWidgetAccountbalance,
+                Helpers.formatBalance(account.getBalance(), account.getCurrency(),
+                        defprefs.getBoolean("round_widget_balance", false),
+                        bank.getDecimalFormatter()));
+        views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
+        if (bank.isDisabled()) {
+            views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
+        } else {
+            views.setViewVisibility(R.id.frmWarning, View.INVISIBLE);
+        }
+        Intent intent = new Intent(context, MainActivity.class);
+        PendingIntent pendingIntent;
+
+        //intent = new Intent(context, AccountsActivity.class);
+        pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+        views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent);
+
+        intent = new Intent(context, WidgetService.class);
+        intent.setAction(AutoRefreshService.BROADCAST_WIDGET_REFRESH);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+        intent.setData(
+                Uri.parse("rofl://copter/" + appWidgetId + "/" + System.currentTimeMillis()));
+        pendingIntent = PendingIntent
+                .getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+        views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent);
+        views.setOnClickPendingIntent(R.id.hitBox, pendingIntent);
+
         intent = new Intent(context, WidgetService.class);
         intent.setAction(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR);
         intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-        intent.setData(Uri.parse("rofl://copter/widgetunblur/"+appWidgetId+"/"+System.currentTimeMillis()));
-        pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+        intent.setData(Uri.parse(
+                "rofl://copter/widgetunblur/" + appWidgetId + "/" + System.currentTimeMillis()));
+        pendingIntent = PendingIntent
+                .getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
         views.setOnClickPendingIntent(R.id.imgBalanceblur, pendingIntent);
-        
-        if (defprefs.getBoolean("widget_blur_balance", false) && !prefs.getBoolean("widget_unblurred_" + appWidgetId, false)) {
+
+        if (defprefs.getBoolean("widget_blur_balance", false) && !prefs
+                .getBoolean("widget_unblurred_" + appWidgetId, false)) {
             views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE);
             views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE);
             views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
-        }
-        else {
+        } else {
             views.setViewVisibility(R.id.imgBalanceblur, View.GONE);
             views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.GONE);
             views.setViewVisibility(R.id.txtWidgetAccountbalance, View.VISIBLE);
-            views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE);            
+            views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE);
 
             intent = new Intent(context, MainActivity.class);
             intent.setAction(AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS);
-            intent.setData(Uri.parse("rofl://copter/showtransactions/"+appWidgetId+"/"+System.currentTimeMillis()));
+            intent.setData(Uri.parse("rofl://copter/showtransactions/" + appWidgetId + "/" + System
+                    .currentTimeMillis()));
             intent.putExtra("bank", bank.getDbId());
             intent.putExtra("account", account.getId());
             pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
             views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
-            views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);        
+            views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
         }
 
-		return views;
-	}
-	
-
-	static RemoteViews disableAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId) {
-		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
-		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
-        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
-		if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) {
-			if (providerInfo.initialLayout == R.layout.widget_large) {
-				layoutId=R.layout.widget_large_transparent;
-			} else {
-				layoutId=R.layout.widget_transparent;
-			}
-		}		
-		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
-		views.setTextViewText(R.id.txtWidgetAccountname, "");
-		views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR");
-		views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
-		views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
-
-		Intent intent = new Intent(context, MainActivity.class);
-		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
-		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
-
-		return views;
-	}	
-	
-	
-	
-	public void onReceive(Context context, Intent intent) {
-		// v1.5 fix that doesn't call onDelete Action
-		final String action = intent.getAction();
-		if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
-			final int appWidgetId = intent.getExtras().getInt( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
-			if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
-				this.onDeleted(context, new int[] { appWidgetId });
-			}
-		}
-		else {
-			super.onReceive(context, intent);
-		}
-
-
-		if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH) || action.equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
-			AppWidgetManager appWM = AppWidgetManager.getInstance(context);
-			int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent());
-			final int N = appWidgetIds.length;
-			for (int i = 0; i < N; i++) {
-				int appWidgetId = appWidgetIds[i];
-				updateAppWidget(context, appWM, appWidgetId);
-			}
-		}
-	}	
-
-	@Override
-	public void onDeleted(Context context, int[] appWidgetIds) {
-		super.onDeleted(context, appWidgetIds);
-		final int N = appWidgetIds.length;
-		for (int i = 0; i < N; i++) {
-			WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]);
-		}
-	}
-
-	public static class WidgetService extends Service {
+        return views;
+    }
+
+
+    static RemoteViews disableAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId) {
+        AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
+        int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
+        if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo
+                != null)) {
+            if (providerInfo.initialLayout == R.layout.widget_large) {
+                layoutId = R.layout.widget_large_transparent;
+            } else {
+                layoutId = R.layout.widget_transparent;
+            }
+        }
+        RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
+        views.setTextViewText(R.id.txtWidgetAccountname, "");
+        views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR");
+        views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
+        views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
+
+        Intent intent = new Intent(context, MainActivity.class);
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+        views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
+        views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
+
+        return views;
+    }
+
+
+    public void onReceive(Context context, Intent intent) {
+        // v1.5 fix that doesn't call onDelete Action
+        final String action = intent.getAction();
+        if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
+            final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                    AppWidgetManager.INVALID_APPWIDGET_ID);
+            if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                this.onDeleted(context, new int[]{appWidgetId});
+            }
+        } else {
+            super.onReceive(context, intent);
+        }
+
+        if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH) || action
+                .equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
+            AppWidgetManager appWM = AppWidgetManager.getInstance(context);
+            int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent());
+            final int N = appWidgetIds.length;
+            for (int i = 0; i < N; i++) {
+                int appWidgetId = appWidgetIds[i];
+                updateAppWidget(context, appWM, appWidgetId);
+            }
+        }
+    }
+
+    @Override
+    public void onDeleted(Context context, int[] appWidgetIds) {
+        super.onDeleted(context, appWidgetIds);
+        final int N = appWidgetIds.length;
+        for (int i = 0; i < N; i++) {
+            WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]);
+        }
+    }
+
+    public static class WidgetService extends Service {
 
         @Override
         public void onStart(Intent intent, int startId) {
@@ -282,19 +296,24 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         }
 
         public void handleStart(Intent intent, int startId) {
-            if (intent == null) return;
+            if (intent == null) {
+                return;
+            }
             int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
             Context context = getApplicationContext();
             String action = intent.getAction();
-            if (action == null) return;
-            if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) {
-                new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId).execute();
+            if (action == null) {
+                return;
             }
-            else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR)) {
+            if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) {
+                new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId)
+                        .execute();
+            } else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR)) {
                 unblurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId);
 
                 Handler blurHandler = new Handler();
                 class BlurRunnable implements Runnable {
+
                     private int mAppWidgetId;
 
                     public BlurRunnable(int appWidgetId) {
@@ -309,100 +328,105 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
                 }
 
-
                 SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
-                Integer unblurTimeout = 1000*Integer.parseInt(defprefs.getString("widget_blur_balance_timeout", "5"));
+                Integer unblurTimeout = 1000 * Integer
+                        .parseInt(defprefs.getString("widget_blur_balance_timeout", "5"));
                 blurHandler.postDelayed(new BlurRunnable(appWidgetId), unblurTimeout);
-            }
-            else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_BLUR)) {
+            } else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_BLUR)) {
                 blurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId);
             }
         }
 
-		@Override
-		public IBinder onBind(Intent arg0) {
-			// TODO Auto-generated method stub
-			return null;
-		}
-
-		protected class WidgetUpdateTask extends AsyncTask<Void, Void, Void> {
-			@Override
-			protected void onPreExecute() {
-				super.onPreExecute();
-				RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
-				if (views != null) {
-					views.setViewVisibility(R.id.frmProgress, View.VISIBLE);
-					appWidgetManager.updateAppWidget(appWidgetId, views);
-				}
-			}
-
-			private Context context;
-			private AppWidgetManager appWidgetManager;
-			private int appWidgetId;
-			private SharedPreferences prefs;
-
-			public WidgetUpdateTask(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
-				this.context = context;
-				this.appWidgetManager = appWidgetManager;
-				this.appWidgetId = appWidgetId;
-				this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
-			}
-
-			@Override
-			protected Void doInBackground(Void... params) {
-				String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
-				if (accountId == null) {
-					Log.w("WidgetService", "Widget not found in db: "+appWidgetId);
-					return null;
-				}
-				long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
-				Bank bank = BankFactory.bankFromDb(new Long(bankId), context, true);
-				if (bank == null) {
-					return null;
-				}
-
-				try {
-					if (!bank.isDisabled()) {
-						bank.update();
-						if (prefs.getBoolean("widget_updates_transactions", false)) {
-						    bank.updateAllTransactions();
-						}
-						bank.closeConnection();
-						DBAdapter.save(bank, context);
-					}
-
-				} 
-				catch (BankException e) {
-    				Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
-                    Crashlytics.logException(e);
-				} catch (LoginException e) {
-					Log.e("", "Disabling bank: "+bank.getDbId());
-					DBAdapter.disable(bank,context);
-				}
-                catch (BankChoiceException e) {
-                    Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+        @Override
+        public IBinder onBind(Intent arg0) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        protected class WidgetUpdateTask extends AsyncTask<Void, Void, Void> {
+
+            private Context context;
+
+            private AppWidgetManager appWidgetManager;
+
+            private int appWidgetId;
+
+            private SharedPreferences prefs;
+
+            public WidgetUpdateTask(Context context, AppWidgetManager appWidgetManager,
+                    int appWidgetId) {
+                this.context = context;
+                this.appWidgetManager = appWidgetManager;
+                this.appWidgetId = appWidgetId;
+                this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
+            }
+
+            @Override
+            protected void onPreExecute() {
+                super.onPreExecute();
+                RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+                if (views != null) {
+                    views.setViewVisibility(R.id.frmProgress, View.VISIBLE);
+                    appWidgetManager.updateAppWidget(appWidgetId, views);
                 }
-                catch(IOException e) {
-                    Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
-                    if(NetworkUtils.isInternetAvailable()) {
+            }
+
+            @Override
+            protected Void doInBackground(Void... params) {
+                String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
+                if (accountId == null) {
+                    Log.w("WidgetService", "Widget not found in db: " + appWidgetId);
+                    return null;
+                }
+                long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
+                Bank bank = BankFactory.bankFromDb(new Long(bankId), context, true);
+                if (bank == null) {
+                    return null;
+                }
+
+                try {
+                    if (!bank.isDisabled()) {
+                        bank.update();
+                        if (prefs.getBoolean("widget_updates_transactions", false)) {
+                            bank.updateAllTransactions();
+                        }
+                        bank.closeConnection();
+                        DBAdapter.save(bank, context);
+                    }
+
+                } catch (BankException e) {
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId() + "'; " + e
+                            .getMessage());
+                    Crashlytics.logException(e);
+                } catch (LoginException e) {
+                    Log.e("", "Disabling bank: " + bank.getDbId());
+                    DBAdapter.disable(bank, context);
+                } catch (BankChoiceException e) {
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId() + "'; " + e
+                            .getMessage());
+                } catch (IOException e) {
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId() + "'; " + e
+                            .getMessage());
+                    if (NetworkUtils.isInternetAvailable()) {
                         Crashlytics.logException(e);
                     }
                 }
-				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
-				return null;
-			}
-			@Override
-			protected void onPostExecute(Void result) {
-				super.onPostExecute(result);
-				RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
-				if (views != null) {
-					views.setViewVisibility(R.id.frmProgress, View.INVISIBLE);
-					appWidgetManager.updateAppWidget(appWidgetId, views);
-				}
-				WidgetService.this.stopSelf();
-			}
-
-			
-		}
-	}
+                BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
+                return null;
+            }
+
+            @Override
+            protected void onPostExecute(Void result) {
+                super.onPostExecute(result);
+                RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+                if (views != null) {
+                    views.setViewVisibility(R.id.frmProgress, View.INVISIBLE);
+                    appWidgetManager.updateAppWidget(appWidgetId, views);
+                }
+                WidgetService.this.stopSelf();
+            }
+
+
+        }
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
index 84794bf..6e5578b 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
@@ -18,4 +18,5 @@ package com.liato.bankdroid.appwidget;
 
 
 public class BankdroidWidgetProvider_2x1 extends BankdroidWidgetProvider {
+
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
index b6c480c..663421f 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
@@ -17,6 +17,6 @@
 package com.liato.bankdroid.appwidget;
 
 
-
 public class BankdroidWidgetProvider_4x1 extends BankdroidWidgetProvider {
+
 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
index 092bdee..973e62d 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
@@ -16,6 +16,13 @@
 
 package com.liato.bankdroid.appwidget;
 
+import com.liato.bankdroid.LockableActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.adapters.AccountsAdapter;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
@@ -27,59 +34,87 @@ import android.widget.AdapterView.OnItemClickListener;
 import android.widget.CheckBox;
 import android.widget.ListView;
 
-import com.liato.bankdroid.LockableActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.adapters.AccountsAdapter;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-
 import java.util.ArrayList;
 
 public class WidgetConfigureActivity extends LockableActivity {
+
     private static final String WIDGET_PREFIX = "widget_";
-	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
-	private static final int LOGIN_ID = 1;
-	private AccountsAdapter adapter;
-	
-	public WidgetConfigureActivity() {
-		super();
-		
-	}
-
-	@Override
-	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-	}	
-	
-	public void onResume() {
-		super.onResume();
+
+    private static final int LOGIN_ID = 1;
+
+    int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+    private AccountsAdapter adapter;
+
+    public WidgetConfigureActivity() {
+        super();
+
+    }
+
+    public static void setAccountBankId(Context context, int appWidgetId, String accountId,
+            long bankId) {
+        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+        prefs.putString(WIDGET_PREFIX + appWidgetId, accountId);
+        prefs.putLong(WIDGET_PREFIX + appWidgetId + "_bankid", bankId);
+        prefs.commit();
+    }
+
+    public static String getAccountId(Context context, int appWidgetId) {
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
+        return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
+    }
+
+    public static long getBankId(Context context, int appWidgetId) {
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
+        return prefs.getLong(WIDGET_PREFIX + appWidgetId + "_bankid", -1);
+    }
+
+    public static void delAccountId(Context context, int appWidgetId) {
+        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+        prefs.remove(WIDGET_PREFIX + appWidgetId);
+        prefs.remove(WIDGET_PREFIX + appWidgetId + "_bankid");
+        prefs.commit();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    public void onResume() {
+        super.onResume();
 
         setContentView(R.layout.main);
         this.setTitle(this.getString(R.string.choose_an_account));
         setResult(RESULT_CANCELED);
-        ((View)findViewById(R.id.layMainMenu)).setVisibility(View.GONE);
+        ((View) findViewById(R.id.layMainMenu)).setVisibility(View.GONE);
 
         Intent intent = getIntent();
         Bundle extras = intent.getExtras();
         if (extras != null) {
-            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
+                    AppWidgetManager.INVALID_APPWIDGET_ID);
         }
         if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
             finish();
-        }       
+        }
 
-        ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+        ListView lv = (ListView) findViewById(R.id.lstAccountsList);
         lv.setOnItemClickListener(new OnItemClickListener() {
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                if (adapter.getItemViewType(position) != AccountsAdapter.VIEWTYPE_ACCOUNT) return;
+                if (adapter.getItemViewType(position) != AccountsAdapter.VIEWTYPE_ACCOUNT) {
+                    return;
+                }
                 final Context context = WidgetConfigureActivity.this;
-                Account account = (Account)parent.getItemAtPosition(position);
+                Account account = (Account) parent.getItemAtPosition(position);
                 Bank bank = account.getBank();
-                WidgetConfigureActivity.setAccountBankId(context, mAppWidgetId, account.getId(), bank.getDbId());
-                SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-                prefs.putBoolean("transperant_background" + mAppWidgetId, ((CheckBox)findViewById(R.id.chkTransperantBackground)).isChecked());
-                prefs.commit();             
+                WidgetConfigureActivity
+                        .setAccountBankId(context, mAppWidgetId, account.getId(), bank.getDbId());
+                SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0)
+                        .edit();
+                prefs.putBoolean("transperant_background" + mAppWidgetId,
+                        ((CheckBox) findViewById(R.id.chkTransperantBackground)).isChecked());
+                prefs.commit();
                 // Push widget update to surface with newly set prefix
                 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                 BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
@@ -91,47 +126,22 @@ public class WidgetConfigureActivity extends LockableActivity {
                 finish();
             }
         });
-        
+
         refreshView();
     }
-	
-	public static void setAccountBankId(Context context, int appWidgetId, String accountId, long bankId) {
-        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-        prefs.putString(WIDGET_PREFIX + appWidgetId, accountId);
-        prefs.putLong(WIDGET_PREFIX + appWidgetId + "_bankid", bankId);
-        prefs.commit();
-	}
 
-    public static String getAccountId(Context context, int appWidgetId) {
-        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
-        return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
-    }
+    private void refreshView() {
+        ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
 
-    public static long getBankId(Context context, int appWidgetId) {
-        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
-        return prefs.getLong(WIDGET_PREFIX + appWidgetId + "_bankid", -1);
+        if (banks.size() > 0) {
+            findViewById(R.id.chkTransperantBackground).setVisibility(View.VISIBLE);
+            findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
+            ListView lv = (ListView) findViewById(R.id.lstAccountsList);
+            adapter = new AccountsAdapter(this, false);
+            adapter.setGroups(banks);
+            lv.setAdapter(adapter);
+        }
     }
-	
-	public static void delAccountId(Context context, int appWidgetId) {
-        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-        prefs.remove(WIDGET_PREFIX + appWidgetId);
-        prefs.remove(WIDGET_PREFIX + appWidgetId + "_bankid");
-        prefs.commit();
-	}
-	
-	
-	private void refreshView() {
-		ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
-
-		if (banks.size() > 0) {
-			findViewById(R.id.chkTransperantBackground).setVisibility(View.VISIBLE);
-			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-			adapter = new AccountsAdapter(this, false);
-			adapter.setGroups(banks);
-			lv.setAdapter(adapter);
-		}
-	}
 
 
     @Override
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index e576c3f..1d851ea 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -16,175 +16,176 @@
 
 package com.liato.bankdroid.banking;
 
-import android.content.Context;
-import android.database.Cursor;
-
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 
+import android.content.Context;
+import android.database.Cursor;
+
 import java.math.BigDecimal;
 import java.util.ArrayList;
 
 public class BankFactory {
 
-	public static Bank fromBanktypeId(int id, Context context) throws BankException {
-		return LegacyBankFactory.fromBanktypeId(id, context);
-	}
+    public static Bank fromBanktypeId(int id, Context context) throws BankException {
+        return LegacyBankFactory.fromBanktypeId(id, context);
+    }
 
 
-	public static ArrayList<Bank> listBanks(Context context) {
+    public static ArrayList<Bank> listBanks(Context context) {
         return LegacyBankFactory.listBanks(context);
-	}
-
-	public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
-		Bank bank = null;
-		DBAdapter db = new DBAdapter(context);
-		Cursor c = db.getBank(id);
-
-		if (c != null && c.getCount() > 0) {
-			try {
-				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				String password = "";
-				try {
-					password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
-				} catch (Exception e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-
-				bank.setData(c.getString(c.getColumnIndex("username")),
-							 password,
-							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-							 (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-							 c.getLong(c.getColumnIndex("_id")),
-							 c.getString(c.getColumnIndex("currency")),
-							 c.getString(c.getColumnIndex("custname")),
-							 c.getString(c.getColumnIndex("extras")),
-                             c.getInt(c.getColumnIndex("hideAccounts")));
-				if (loadAccounts) {
-					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
-				}
-			} catch (BankException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			finally {
-				c.close();
-			}
-		}
-		return bank;
-	}
-
-	public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
-		ArrayList<Bank> banks = new ArrayList<Bank>();
-		DBAdapter db = new DBAdapter(context);
-		Cursor c = db.fetchBanks();
-		if (c == null || c.getCount() == 0) {
-			return banks;
-		}
-		while (!c.isLast() && !c.isAfterLast()) {
-			c.moveToNext();
-			try {
-				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-
-	            String password = "";
+    }
+
+    public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
+        Bank bank = null;
+        DBAdapter db = new DBAdapter(context);
+        Cursor c = db.getBank(id);
+
+        if (c != null && c.getCount() > 0) {
+            try {
+                bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+                String password = "";
+                try {
+                    password = SimpleCrypto
+                            .decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
+                } catch (Exception e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+
+                bank.setData(c.getString(c.getColumnIndex("username")),
+                        password,
+                        new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                        (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+                        c.getLong(c.getColumnIndex("_id")),
+                        c.getString(c.getColumnIndex("currency")),
+                        c.getString(c.getColumnIndex("custname")),
+                        c.getString(c.getColumnIndex("extras")),
+                        c.getInt(c.getColumnIndex("hideAccounts")));
+                if (loadAccounts) {
+                    bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+                }
+            } catch (BankException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } finally {
+                c.close();
+            }
+        }
+        return bank;
+    }
+
+    public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
+        ArrayList<Bank> banks = new ArrayList<Bank>();
+        DBAdapter db = new DBAdapter(context);
+        Cursor c = db.fetchBanks();
+        if (c == null || c.getCount() == 0) {
+            return banks;
+        }
+        while (!c.isLast() && !c.isAfterLast()) {
+            c.moveToNext();
+            try {
+                Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+
+                String password = "";
                 try {
-                    password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
+                    password = SimpleCrypto
+                            .decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
                 } catch (Exception e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 bank.setData(c.getString(c.getColumnIndex("username")),
-				             password,
-				             new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-				             (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-				             c.getLong(c.getColumnIndex("_id")),
-				             c.getString(c.getColumnIndex("currency")),
-				             c.getString(c.getColumnIndex("custname")),
-                             c.getString(c.getColumnIndex("extras")),
-                             c.getInt(c.getColumnIndex("hideAccounts")));
-				if (loadAccounts) {
-					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
-				}
-				banks.add(bank);
-			} catch (BankException e) {
-				//e.printStackTrace();
-			}
-		}
-		c.close();
-		return banks;
-	}
-
-	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
-		DBAdapter db = new DBAdapter(context);
-		Cursor c = db.getAccount(accountId);
-
-		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
-			return null;
-		}
-
-		Account account = new Account(c.getString(c.getColumnIndex("name")),
-                                      new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                      c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                                      c.getLong(c.getColumnIndex("bankid")),
-                                      c.getInt(c.getColumnIndex("acctype")));
+                        password,
+                        new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                        (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+                        c.getLong(c.getColumnIndex("_id")),
+                        c.getString(c.getColumnIndex("currency")),
+                        c.getString(c.getColumnIndex("custname")),
+                        c.getString(c.getColumnIndex("extras")),
+                        c.getInt(c.getColumnIndex("hideAccounts")));
+                if (loadAccounts) {
+                    bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+                }
+                banks.add(bank);
+            } catch (BankException e) {
+                //e.printStackTrace();
+            }
+        }
+        c.close();
+        return banks;
+    }
+
+    public static Account accountFromDb(Context context, String accountId,
+            boolean loadTransactions) {
+        DBAdapter db = new DBAdapter(context);
+        Cursor c = db.getAccount(accountId);
+
+        if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
+            return null;
+        }
+
+        Account account = new Account(c.getString(c.getColumnIndex("name")),
+                new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                c.getString(c.getColumnIndex("id")).split("_", 2)[1],
+                c.getLong(c.getColumnIndex("bankid")),
+                c.getInt(c.getColumnIndex("acctype")));
         account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
         account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
         account.setCurrency(c.getString(c.getColumnIndex("currency")));
         account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
-		c.close();
-		if (loadTransactions) {
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			String fromAccount = accountId;
-			if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
-			    fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
-			}
-			c = db.fetchTransactions(fromAccount);
-			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
-				while (!c.isLast() && !c.isAfterLast()) {
-					c.moveToNext();
-					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")),
-                                     c.getString(c.getColumnIndex("btransaction")),
-                                     new BigDecimal(c.getString(c.getColumnIndex("amount"))),
-                                     c.getString(c.getColumnIndex("currency"))));
-				}
-				c.close();
-			}
-			account.setTransactions(transactions);
-		}
-		return account;
-	}
-
-	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
-		ArrayList<Account> accounts = new ArrayList<Account>();
-		DBAdapter db = new DBAdapter(context);
-		Cursor c = db.fetchAccounts(bankId);
-		if (c == null || c.getCount() == 0) {
-			return accounts;
-		}
-		while (!c.isLast() && !c.isAfterLast()) {
-			c.moveToNext();
-			try {
-    			Account account = new Account(c.getString(c.getColumnIndex("name")),
-                                              new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                              c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                                              c.getLong(c.getColumnIndex("bankid")),
-                                              c.getInt(c.getColumnIndex("acctype")));
-    	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
+        c.close();
+        if (loadTransactions) {
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            String fromAccount = accountId;
+            if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
+                fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
+            }
+            c = db.fetchTransactions(fromAccount);
+            if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
+                while (!c.isLast() && !c.isAfterLast()) {
+                    c.moveToNext();
+                    transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")),
+                            c.getString(c.getColumnIndex("btransaction")),
+                            new BigDecimal(c.getString(c.getColumnIndex("amount"))),
+                            c.getString(c.getColumnIndex("currency"))));
+                }
+                c.close();
+            }
+            account.setTransactions(transactions);
+        }
+        return account;
+    }
+
+    public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
+        ArrayList<Account> accounts = new ArrayList<Account>();
+        DBAdapter db = new DBAdapter(context);
+        Cursor c = db.fetchAccounts(bankId);
+        if (c == null || c.getCount() == 0) {
+            return accounts;
+        }
+        while (!c.isLast() && !c.isAfterLast()) {
+            c.moveToNext();
+            try {
+                Account account = new Account(c.getString(c.getColumnIndex("name")),
+                        new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                        c.getString(c.getColumnIndex("id")).split("_", 2)[1],
+                        c.getLong(c.getColumnIndex("bankid")),
+                        c.getInt(c.getColumnIndex("acctype")));
+                account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
+                account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
                 account.setCurrency(c.getString(c.getColumnIndex("currency")));
                 account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
-    			accounts.add(account);
-			}
-			catch (ArrayIndexOutOfBoundsException e) {
-			    // Attempted to load an account without and ID, probably an old Avanza account.
-			}
-		}
-		c.close();
-		return accounts;
-	}
+                accounts.add(account);
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // Attempted to load an account without and ID, probably an old Avanza account.
+            }
+        }
+        c.close();
+        return accounts;
+    }
 
 }
diff --git app/src/main/java/com/liato/bankdroid/db/Crypto.java app/src/main/java/com/liato/bankdroid/db/Crypto.java
index 29b2ac7..a0bfb75 100644
--- app/src/main/java/com/liato/bankdroid/db/Crypto.java
+++ app/src/main/java/com/liato/bankdroid/db/Crypto.java
@@ -1,15 +1,18 @@
 package com.liato.bankdroid.db;
+
 public class Crypto {
-	/*
-	 * The key used to encrypt all the account passwords before storing them in the database.
-	 * This key is not used in the market app.
-	 * 
-	 */
-	private final static String KEY = "KGLRqraqThYniEtasoCqfbjFDwctomjmiY4rvSJThyyU4qUTIPXNLhPxkivpFLgr";
 
-	public final static String getKey() {
-		/*
-		 * Manipulate the key before returning it.
+    /*
+     * The key used to encrypt all the account passwords before storing them in the database.
+     * This key is not used in the market app.
+     *
+     */
+    private final static String KEY
+            = "KGLRqraqThYniEtasoCqfbjFDwctomjmiY4rvSJThyyU4qUTIPXNLhPxkivpFLgr";
+
+    public final static String getKey() {
+                /*
+                 * Manipulate the key before returning it.
 		 * 
 		 * ...
 		 * 
@@ -19,6 +22,6 @@ public class Crypto {
 		 * 
 		 */
 
-		return KEY;
-	}
+        return KEY;
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 5e75711..1a54860 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -16,37 +16,40 @@
 
 package com.liato.bankdroid.db;
 
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
+
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
-import android.database.SQLException;
 import android.database.sqlite.SQLiteDatabase;
 import android.util.Log;
 
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
 
 
 public class DBAdapter {
 
     static final String TAG = "DBAdapter";
-    private DatabaseHelper mDbHelper;
-    private SQLiteDatabase mDb;
-    
+
     static final String DATABASE_NAME = "data";
+
     static final int DATABASE_VERSION = 11;
 
+    private DatabaseHelper mDbHelper;
+
+    private SQLiteDatabase mDb;
+
     /**
      * Constructor - takes the context to allow the database to be
      * opened/created
-     * 
+     *
      * @param ctx the Context within which to work
      */
     public DBAdapter(Context ctx) {
@@ -54,14 +57,33 @@ public class DBAdapter {
         mDb = mDbHelper.getWritableDatabase();
     }
 
+    /**
+     * @deprecated Only used during refactoring. Should be removed before next major version (2.0)
+     */
+    @Deprecated
+    public static void save(Bank bank, Context context) {
+        DBAdapter db = new DBAdapter(context);
+        long id = db.updateBank(bank);
+
+        bank.setDbid(id);
+    }
+
+    /**
+     * @deprecated Only used during refactoring. Should be removed before next major version (2.0)
+     */
+    @Deprecated
+    public static void disable(Bank bank, Context context) {
+        DBAdapter db = new DBAdapter(context);
+        db.disableBank(bank.getDbId());
+    }
+
     public long createBank(Bank bank) {
-    	return updateBank(bank);
+        return updateBank(bank);
     }
 
-    
     /**
      * Delete the bank with the given bankId
-     * 
+     *
      * @param bankId id of bank to delete
      */
     public int deleteBank(long bankId) {
@@ -69,58 +91,63 @@ public class DBAdapter {
         c += this.deleteAccounts(bankId);
         return c;
     }
-    
+
     /**
      * Delete the accounts for the given bankIdbank with the given rowId
-     * 
+     *
      * @param bankId id of bank to delete
-     */    
+     */
     public int deleteAccounts(long bankId) {
         int c = mDb.delete("accounts", "bankid=" + bankId, null);
         return c;
     }
 
-    
     public int deleteTransactions(String account) {
         int c = mDb.delete("transactions", "account='" + account + "'", null);
         return c;
-    }    
-    		
+    }
+
     /**
      * Return a Cursor over the list of all banks in the database
-     * 
+     *
      * @return Cursor over all banks
      */
     public Cursor fetchBanks() {
-        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"}, null, null, null, null, "_id asc");
+        return mDb.query("banks",
+                new String[]{"_id", "balance", "banktype", "username", "password", "disabled",
+                        "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"},
+                null, null, null, null, "_id asc");
     }
 
-    
     /**
      * Return a Cursor over the list of all accounts belonging to a bank
-     * 
+     *
      * @return Cursor over all accounts belonging to a bank
      */
     public Cursor fetchAccounts(long bankId) {
-        return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id", "acctype", "hidden", "notify", "currency", "aliasfor"}, "bankid="+bankId, null, null, null, null);
+        return mDb.query("accounts",
+                new String[]{"bankid", "balance", "name", "id", "acctype", "hidden", "notify",
+                        "currency", "aliasfor"}, "bankid=" + bankId, null, null, null, null);
     }
-    
+
     public Cursor fetchTransactions(String account) {
-        return mDb.query("transactions", new String[] {"transdate", "btransaction", "amount", "currency"}, "account='"+account+"'", null, null, null, null);
-    }    
+        return mDb.query("transactions",
+                new String[]{"transdate", "btransaction", "amount", "currency"},
+                "account='" + account + "'", null, null, null, null);
+    }
 
     public long updateBank(Bank bank) {
         Calendar cal = Calendar.getInstance();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        
-    	ContentValues initialValues = new ContentValues();
+
+        ContentValues initialValues = new ContentValues();
         initialValues.put("banktype", bank.getBanktypeId());
         initialValues.put("username", bank.getUsername());
         String password = "";
         try {
             password = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
-		} catch (Exception e) {
-            Log.w(TAG, "SimpleCrypto error: "+e.getMessage());
+        } catch (Exception e) {
+            Log.w(TAG, "SimpleCrypto error: " + e.getMessage());
         }
         initialValues.put("password", password);
         initialValues.put("disabled", 0);
@@ -130,93 +157,80 @@ public class DBAdapter {
         initialValues.put("extras", bank.getExtras());
         initialValues.put("updated", sdf.format(cal.getTime()));
         initialValues.put("hideAccounts", bank.getHideAccounts() ? 1 : 0);
-        
+
         long bankId = bank.getDbId();
         if (bankId == -1) {
-        	bankId = mDb.insert("banks", null, initialValues);
-        }
-        else {
-        	mDb.update("banks", initialValues, "_id="+bankId, null);
+            bankId = mDb.insert("banks", null, initialValues);
+        } else {
+            mDb.update("banks", initialValues, "_id=" + bankId, null);
             deleteAccounts(bankId);
         }
         if (bankId != -1) {
-	        ArrayList<Account> accounts = bank.getAccounts();
-	        for(Account acc : accounts) {
-	            ContentValues vals = new ContentValues();
-	            vals.put("bankid", bankId);
-	            vals.put("balance", acc.getBalance().toPlainString());
+            ArrayList<Account> accounts = bank.getAccounts();
+            for (Account acc : accounts) {
+                ContentValues vals = new ContentValues();
+                vals.put("bankid", bankId);
+                vals.put("balance", acc.getBalance().toPlainString());
                 vals.put("name", acc.getName());
-	            vals.put("id", new Long(bankId).toString()+"_"+acc.getId());
+                vals.put("id", new Long(bankId).toString() + "_" + acc.getId());
                 vals.put("hidden", acc.isHidden() ? 1 : 0);
                 vals.put("notify", acc.isNotify() ? 1 : 0);
                 vals.put("currency", acc.getCurrency());
                 vals.put("acctype", acc.getType());
                 vals.put("aliasfor", acc.getAliasfor());
-	            mDb.insert("accounts", null, vals);
-	            if (acc.getAliasfor() == null || acc.getAliasfor().length() == 0) {
-    	            List<Transaction> transactions = acc.getTransactions();
-    	            if (transactions != null && !transactions.isEmpty()) {
-    	                deleteTransactions(new Long(bankId).toString()+"_"+acc.getId());
-    		            for(Transaction transaction : transactions) {
-    			            ContentValues transvals = new ContentValues();
-    			            transvals.put("transdate", transaction.getDate());
-    			            transvals.put("btransaction", transaction.getTransaction());
-    			            transvals.put("amount", transaction.getAmount().toPlainString());
-    			            transvals.put("account", new Long(bankId).toString()+"_"+acc.getId());
-    			            transvals.put("currency", transaction.getCurrency());
-    			            mDb.insert("transactions", null, transvals);
-    		            }
-    	            }
-	            }
-	        }
+                mDb.insert("accounts", null, vals);
+                if (acc.getAliasfor() == null || acc.getAliasfor().length() == 0) {
+                    List<Transaction> transactions = acc.getTransactions();
+                    if (transactions != null && !transactions.isEmpty()) {
+                        deleteTransactions(new Long(bankId).toString() + "_" + acc.getId());
+                        for (Transaction transaction : transactions) {
+                            ContentValues transvals = new ContentValues();
+                            transvals.put("transdate", transaction.getDate());
+                            transvals.put("btransaction", transaction.getTransaction());
+                            transvals.put("amount", transaction.getAmount().toPlainString());
+                            transvals.put("account",
+                                    new Long(bankId).toString() + "_" + acc.getId());
+                            transvals.put("currency", transaction.getCurrency());
+                            mDb.insert("transactions", null, transvals);
+                        }
+                    }
+                }
+            }
         }
         return bankId;
     }
-    
+
     public void disableBank(long bankId) {
-    	if (bankId == -1) return;
+        if (bankId == -1) {
+            return;
+        }
         ContentValues initialValues = new ContentValues();
         initialValues.put("disabled", 1);
-    	mDb.update("banks", initialValues, "_id="+bankId, null);
+        mDb.update("banks", initialValues, "_id=" + bankId, null);
     }
-    
+
     public Cursor getBank(String bankId) {
-    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"}, "_id="+bankId, null, null, null, null);
-    	if (c != null) {
-    		c.moveToFirst();
-    	}
-		return c;
+        Cursor c = mDb.query("banks",
+                new String[]{"_id", "balance", "banktype", "username", "password", "disabled",
+                        "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"},
+                "_id=" + bankId, null, null, null, null);
+        if (c != null) {
+            c.moveToFirst();
+        }
+        return c;
     }
-    
+
     public Cursor getBank(long bankId) {
-    	return getBank(new Long(bankId).toString());
+        return getBank(new Long(bankId).toString());
     }
 
     public Cursor getAccount(String id) {
-    	Cursor c = mDb.query("accounts", new String[] {"id", "balance", "name", "bankid", "acctype", "hidden", "notify", "currency", "aliasfor"}, "id='"+id+"'", null, null, null, null);
-    	if (c != null) {
-    		c.moveToFirst();
-    	}
-		return c;
-    }
-
-    /**
-    * @deprecated Only used during refactoring. Should be removed before next major version (2.0)
-    */
-    @Deprecated
-    public static void save(Bank bank, Context context) {
-        DBAdapter db = new DBAdapter(context);
-        long id = db.updateBank(bank);
-
-        bank.setDbid(id);
-    }
-
-    /**
-    * @deprecated Only used during refactoring. Should be removed before next major version (2.0)
-    */
-    @Deprecated
-    public static void disable(Bank bank, Context context) {
-        DBAdapter db = new DBAdapter(context);
-        db.disableBank(bank.getDbId());
+        Cursor c = mDb.query("accounts",
+                new String[]{"id", "balance", "name", "bankid", "acctype", "hidden", "notify",
+                        "currency", "aliasfor"}, "id='" + id + "'", null, null, null, null);
+        if (c != null) {
+            c.moveToFirst();
+        }
+        return c;
     }
 }
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index ba1a430..1e23d09 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -22,69 +22,68 @@ import android.database.sqlite.SQLiteOpenHelper;
 import android.util.Log;
 
 /**
- * 
  * @since 8 jan 2011
  */
 final public class DatabaseHelper extends SQLiteOpenHelper {
 
     private static DatabaseHelper instance;
 
+    private DatabaseHelper(final Context context) {
+        super(context, DBAdapter.DATABASE_NAME, null,
+                DBAdapter.DATABASE_VERSION);
+    }
+
     public static synchronized DatabaseHelper getHelper(Context context) {
-        if(instance == null) {
+        if (instance == null) {
             instance = new DatabaseHelper(context);
         }
         return instance;
     }
 
-	private DatabaseHelper(final Context context) {
-		super(context, DBAdapter.DATABASE_NAME, null,
-				DBAdapter.DATABASE_VERSION);
-	}
-
-	@Override
-	public void onCreate(final SQLiteDatabase db) {
-		db.execSQL("create table banks (_id integer primary key autoincrement, "
-				+ "balance text not null, "
-				+ "banktype integer not null, "
-				+ "username text not null, "
-				+ "password text not null, "
-				+ "custname text, "
-				+ "updated text, "
-				+ "sortorder real, "
-				+ "currency text, "
-				+ "disabled integer, "
+    @Override
+    public void onCreate(final SQLiteDatabase db) {
+        db.execSQL("create table banks (_id integer primary key autoincrement, "
+                + "balance text not null, "
+                + "banktype integer not null, "
+                + "username text not null, "
+                + "password text not null, "
+                + "custname text, "
+                + "updated text, "
+                + "sortorder real, "
+                + "currency text, "
+                + "disabled integer, "
                 + "hideAccounts integer,"
-				+ "extras text);");
-		db.execSQL("create table accounts (bankid integer not null, "
-				+ "id text not null, "
-				+ "balance text not null, "
-				+ "acctype integer not null, "
-				+ "hidden integer not null, "
-				+ "notify integer not null, "
-				+ "currency text, "
-				+ "name text not null, "
-				+ "aliasfor text);");
-		db.execSQL("create table transactions (_id integer primary key autoincrement, "
-				+ "transdate text not null, "
-				+ "btransaction text not null, "
-				+ "amount text not null, "
-				+ "currency text, "
-				+ "account text not null);");
-	}
+                + "extras text);");
+        db.execSQL("create table accounts (bankid integer not null, "
+                + "id text not null, "
+                + "balance text not null, "
+                + "acctype integer not null, "
+                + "hidden integer not null, "
+                + "notify integer not null, "
+                + "currency text, "
+                + "name text not null, "
+                + "aliasfor text);");
+        db.execSQL("create table transactions (_id integer primary key autoincrement, "
+                + "transdate text not null, "
+                + "btransaction text not null, "
+                + "amount text not null, "
+                + "currency text, "
+                + "account text not null);");
+    }
 
-	@Override
-	public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
-			final int newVersion) {
-		Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
-				+ " to " + newVersion + ", which will destroy all old data");
+    @Override
+    public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
+            final int newVersion) {
+        Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
+                + " to " + newVersion + ", which will destroy all old data");
         // Version <= 1.7.2 
-		if (oldVersion <= 9) {
-		    // Add an "extras" field to the bank and and "alias for" field to the account.
+        if (oldVersion <= 9) {
+            // Add an "extras" field to the bank and and "alias for" field to the account.
             db.execSQL("ALTER TABLE banks ADD extras text;");
             db.execSQL("ALTER TABLE accounts ADD aliasfor text;");
-		}
+        }
         if (oldVersion <= 10) {
             db.execSQL("ALTER TABLE banks ADD hideAccounts interger;");
         }
-	}
+    }
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
index 04c7b54..0669e13 100644
--- app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
+++ app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
@@ -55,14 +55,17 @@ import android.util.Log;
 
 /**
  * Implementation of the Live View plug-in service.
- * 
+ *
  * @author firetech
  */
 public class LiveViewService extends Service {
-	// Announce intent information keys
-	public static final String INTENT_EXTRA_ANNOUNCE = "isAnnounce";
-	public static final String INTENT_EXTRA_TITLE = "title";
-	public static final String INTENT_EXTRA_TEXT = "text";
+
+    // Announce intent information keys
+    public static final String INTENT_EXTRA_ANNOUNCE = "isAnnounce";
+
+    public static final String INTENT_EXTRA_TITLE = "title";
+
+    public static final String INTENT_EXTRA_TEXT = "text";
 
     // Template menu icon file name.
     private static final String MENU_ICON_FILENAME = "plugin_icon.png";
@@ -75,47 +78,60 @@ public class LiveViewService extends Service {
 
     // Current plugin Id
     protected int mPluginId = 0;
-    
-    // Reference to LiveView application stub
-    private IPluginServiceV1 mLiveView = null;
 
     // Menu icon that will be shown in LiveView unit
     protected String mMenuIcon = null;
 
+    // Reference to LiveView application stub
+    private IPluginServiceV1 mLiveView = null;
+
     /**
-     * LiveView callback interface method.
+     * The service connection that is used to bind the plugin to the LiveView
+     * service.
+     *
+     * When connected to the service, the plugin is registered. When
+     * disconnected to the service, the plugin is unregistered.
      */
-    private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
-        Handler mCallbackHandler = new Handler();
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
 
-        
-        public String getPluginName() throws RemoteException {
-            return mPluginName;
-        }
+        @Override
+        public void onServiceConnected(final ComponentName className, IBinder service) {
+            Log.d(PluginConstants.LOG_TAG,
+                    "Enter LiveViewService.ServiceConnection.onServiceConnected.");
 
-       
-        public void openInPhone(final String openInPhoneAction) throws RemoteException {
-            mCallbackHandler.post(new Runnable() {
-                public void run() {
-                    LiveViewService.this.openInPhone(openInPhoneAction);
+            mLiveView = IPluginServiceV1.Stub.asInterface(service);
+
+            // Init adapter
+            LiveViewCallback lvCallback = new LiveViewCallback();
+
+            // Install plugin
+            try {
+                if (mLiveView != null) {
+                    // Register
+                    mPluginId = mLiveView
+                            .register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
+                    Log.d(PluginConstants.LOG_TAG, "Plugin registered with id: " + mPluginId);
                 }
-            });
+            } catch (RemoteException re) {
+                Log.e(PluginConstants.LOG_TAG, "Failed to install plugin. Stop self.");
+                stopSelf();
+            }
+
+            Log.d(PluginConstants.LOG_TAG, "Plugin registered. mPluginId: " + mPluginId);
         }
 
-		//Unused methods required by API.
-		public void startPlugin() throws RemoteException {}
-		public void stopPlugin() throws RemoteException {}
-		public void onUnregistered() throws RemoteException {}
-		public void displayCaps(int displayWidthPixels, int displayHeigthPixels)
-				throws RemoteException {}
-		public void button(String buttonType, boolean doublepress,
-				boolean longpress) throws RemoteException {}
-		public void screenMode(int screenMode) throws RemoteException {}
-    }
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            Log.d(PluginConstants.LOG_TAG,
+                    "Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
+            stopSelf();
+        }
+
+    };
 
     /**
      * Check if service is already running.
-     * 
+     *
      * @return running?
      */
     public static boolean isAlreadyRunning() {
@@ -145,43 +161,47 @@ public class LiveViewService extends Service {
         alreadyRunning = false;
     }
 
-	public void onStart(Intent intent, int startId) {
+    public void onStart(Intent intent, int startId) {
         super.onStart(intent, startId);
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
-        if (intent == null) return;
-		if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
-			Bundle extras = intent.getExtras();
-			if (extras != null) {
-				try {
-					if(mLiveView != null) {
-						mLiveView.sendAnnounce(mPluginId, mMenuIcon, extras.getString(INTENT_EXTRA_TITLE), 
-					    		extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(), "");
-						Log.d(PluginConstants.LOG_TAG, "Announce sent to LiveView Application");
-					} else {
-						Log.d(PluginConstants.LOG_TAG, "LiveView Application not reachable");
-					}
-				} catch(Exception e) {
-					Log.e(PluginConstants.LOG_TAG, "Failed to send announce", e);
-				}
-			}
-			
-		} else {
-			// We end up here when LiveView Application probes the plugin
-	        if (isAlreadyRunning()) {
-	            Log.d(PluginConstants.LOG_TAG, "Already started.");
-	        } else {
-	            // Init
-	            mPluginName = PluginUtils.getDynamicResourceString(this,
-	                    PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
-
-	            // Bind to LiveView
-	            connectToLiveView();
-
-	            // Singleton
-	            alreadyRunning = true;
-	        }
-		}
-	}
+        if (intent == null) {
+            return;
+        }
+        if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
+            Bundle extras = intent.getExtras();
+            if (extras != null) {
+                try {
+                    if (mLiveView != null) {
+                        mLiveView.sendAnnounce(mPluginId, mMenuIcon,
+                                extras.getString(INTENT_EXTRA_TITLE),
+                                extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(),
+                                "");
+                        Log.d(PluginConstants.LOG_TAG, "Announce sent to LiveView Application");
+                    } else {
+                        Log.d(PluginConstants.LOG_TAG, "LiveView Application not reachable");
+                    }
+                } catch (Exception e) {
+                    Log.e(PluginConstants.LOG_TAG, "Failed to send announce", e);
+                }
+            }
+
+        } else {
+            // We end up here when LiveView Application probes the plugin
+            if (isAlreadyRunning()) {
+                Log.d(PluginConstants.LOG_TAG, "Already started.");
+            } else {
+                // Init
+                mPluginName = PluginUtils.getDynamicResourceString(this,
+                        PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+
+                // Bind to LiveView
+                connectToLiveView();
+
+                // Singleton
+                alreadyRunning = true;
+            }
+        }
+    }
 
     @Override
     public IBinder onBind(final Intent intent) {
@@ -189,49 +209,6 @@ public class LiveViewService extends Service {
         return null;
     }
 
-    /**
-     * The service connection that is used to bind the plugin to the LiveView
-     * service.
-     * 
-     * When connected to the service, the plugin is registered. When
-     * disconnected to the service, the plugin is unregistered.
-     */
-    private ServiceConnection mServiceConnection = new ServiceConnection() {
-
-        @Override
-        public void onServiceConnected(final ComponentName className, IBinder service) {
-            Log.d(PluginConstants.LOG_TAG,
-                    "Enter LiveViewService.ServiceConnection.onServiceConnected.");
-
-            mLiveView = IPluginServiceV1.Stub.asInterface(service);
-
-            // Init adapter
-            LiveViewCallback lvCallback = new LiveViewCallback();
-
-            // Install plugin
-            try {
-            	if(mLiveView != null) {
-	                // Register
-	                mPluginId = mLiveView.register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
-	                Log.d(PluginConstants.LOG_TAG, "Plugin registered with id: " + mPluginId);
-	            }
-            } catch (RemoteException re) {
-                Log.e(PluginConstants.LOG_TAG, "Failed to install plugin. Stop self.");
-                stopSelf();
-            }
-
-            Log.d(PluginConstants.LOG_TAG, "Plugin registered. mPluginId: " + mPluginId);
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName className) {
-            Log.d(PluginConstants.LOG_TAG,
-                    "Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
-            stopSelf();
-        }
-
-    };
-
     /**
      * Connects to the LiveView service.
      */
@@ -246,16 +223,60 @@ public class LiveViewService extends Service {
         }
     }
 
-	/**
-	 * When a user presses the "open in phone" button on the LiveView device, this method is called.
-	 * 
-	 * Opens the MainActivity on the phone.
-	 */
-	protected void openInPhone(String openInPhoneAction) {
-		Log.d(PluginConstants.LOG_TAG, "openInPhone");
-		Intent i = new Intent(this, MainActivity.class)
-			.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-		startActivity(i);
-	}
+    /**
+     * When a user presses the "open in phone" button on the LiveView device, this method is
+     * called.
+     *
+     * Opens the MainActivity on the phone.
+     */
+    protected void openInPhone(String openInPhoneAction) {
+        Log.d(PluginConstants.LOG_TAG, "openInPhone");
+        Intent i = new Intent(this, MainActivity.class)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        startActivity(i);
+    }
+
+    /**
+     * LiveView callback interface method.
+     */
+    private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
+
+        Handler mCallbackHandler = new Handler();
+
+
+        public String getPluginName() throws RemoteException {
+            return mPluginName;
+        }
+
+
+        public void openInPhone(final String openInPhoneAction) throws RemoteException {
+            mCallbackHandler.post(new Runnable() {
+                public void run() {
+                    LiveViewService.this.openInPhone(openInPhoneAction);
+                }
+            });
+        }
+
+        //Unused methods required by API.
+        public void startPlugin() throws RemoteException {
+        }
+
+        public void stopPlugin() throws RemoteException {
+        }
+
+        public void onUnregistered() throws RemoteException {
+        }
+
+        public void displayCaps(int displayWidthPixels, int displayHeigthPixels)
+                throws RemoteException {
+        }
+
+        public void button(String buttonType, boolean doublepress,
+                boolean longpress) throws RemoteException {
+        }
+
+        public void screenMode(int screenMode) throws RemoteException {
+        }
+    }
 
 }
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
index 58f337f..a9db8a0 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
@@ -41,25 +41,33 @@ package com.liato.bankdroid.liveview;
 
 /**
  * Plugin common constants.
- * 
+ *
  * @author firetech
  */
 public final class PluginConstants {
-    private PluginConstants() {}
 
     // Broadcast receiver constants
     public static final String BROADCAST_COMMAND = "CMD";
+
     public static final String BROADCAST_COMMAND_PREFERENCES = "preferences";
+
     public static final String BROADCAST_COMMAND_START = "start";
+
     public static final String BROADCAST_COMMAND_PLUGIN_NAME = "pluginName";
 
     // Resource string constants
     public static final String RESOURCE_STRING_PLUGIN_NAME = "app_name";
 
     // LiveView Plugin interface intents
-    public static final String LIVEVIEW_SERVICE_BIND_INTENT = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
-    public static final String LIVEVIEW_BROADCAST_LAUNCH_EVENT = "com.sonyericsson.extras.liveview.LAUNCH_PLUGIN";
+    public static final String LIVEVIEW_SERVICE_BIND_INTENT
+            = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
+
+    public static final String LIVEVIEW_BROADCAST_LAUNCH_EVENT
+            = "com.sonyericsson.extras.liveview.LAUNCH_PLUGIN";
 
     // Log tag
     public static final String LOG_TAG = "BankDroidLiveViewPlugin";
+
+    private PluginConstants() {
+    }
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
index 0a30876..4ece0a1 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -48,42 +48,43 @@ import android.util.Log;
 
 /**
  * Receives broadcast intents from LiveView service.
- * 
+ *
  * @author firetech
  */
 public class PluginReceiver extends BroadcastReceiver {
-	
-	@Override
-	public void onReceive(Context context, Intent intent) {
-		String command = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND);
-		Log.d(PluginConstants.LOG_TAG, "Received command: " + command);
-		
-		if(command == null) {
-			return;
-		}
-		
-		if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_PREFERENCES)) {
-			String pluginName = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND_PLUGIN_NAME);
-			String myPluginName = PluginUtils.getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
 
-			if(pluginName != null && pluginName.contentEquals(myPluginName)) {
-				Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
-				
-				Intent prefsIntent = new Intent(context, SettingsActivity.class);
-				prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-				context.startActivity(prefsIntent);
-			}
-		}
-		else if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_START)) {
-			if(LiveViewService.isAlreadyRunning()) {
-			    Log.d(PluginConstants.LOG_TAG, "Service is already running.");
-			} else {
-				Log.d(PluginConstants.LOG_TAG, "Starting service!");
-				
-				context.startService(new Intent(context, LiveViewService.class));
-			}
-		}
-		
-	}
-	
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String command = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND);
+        Log.d(PluginConstants.LOG_TAG, "Received command: " + command);
+
+        if (command == null) {
+            return;
+        }
+
+        if (command.contentEquals(PluginConstants.BROADCAST_COMMAND_PREFERENCES)) {
+            String pluginName = intent.getExtras()
+                    .getString(PluginConstants.BROADCAST_COMMAND_PLUGIN_NAME);
+            String myPluginName = PluginUtils
+                    .getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+
+            if (pluginName != null && pluginName.contentEquals(myPluginName)) {
+                Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
+
+                Intent prefsIntent = new Intent(context, SettingsActivity.class);
+                prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(prefsIntent);
+            }
+        } else if (command.contentEquals(PluginConstants.BROADCAST_COMMAND_START)) {
+            if (LiveViewService.isAlreadyRunning()) {
+                Log.d(PluginConstants.LOG_TAG, "Service is already running.");
+            } else {
+                Log.d(PluginConstants.LOG_TAG, "Starting service!");
+
+                context.startService(new Intent(context, LiveViewService.class));
+            }
+        }
+
+    }
+
 }
\ No newline at end of file
diff --git app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
index d14a0bb..181a7ca 100644
--- app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
+++ app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
@@ -51,65 +51,58 @@ import java.io.IOException;
 
 /**
  * Utils for LiveView plugin.
- * 
+ *
  * @author firetech
  */
 public final class PluginUtils {
-    
+
     private PluginUtils() {
-        
+
     }
-    
+
     /**
      * Stores icon to phone file system
-     * 
+     *
      * @param resources Reference to project resources
-     * @param resource Reference to specific resource
-     * @param fileName The icon file name
+     * @param resource  Reference to specific resource
+     * @param fileName  The icon file name
      */
-    public static String storeIconToFile(Context ctx, Resources resources, int resource, String fileName) {
+    public static String storeIconToFile(Context ctx, Resources resources, int resource,
+            String fileName) {
         Log.d(PluginConstants.LOG_TAG, "Store icon to file.");
-        
-        if(resources == null) {
+
+        if (resources == null) {
             return "";
         }
-        
+
         Bitmap bitmap = BitmapFactory.decodeStream(resources.openRawResource(resource));
-        
+
         try {
             FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
             bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
             fos.flush();
-            fos.close(); 
-        } 
-        catch (IOException e) { 
+            fos.close();
+        } catch (IOException e) {
             Log.e(PluginConstants.LOG_TAG, "Failed to store to device", e);
         }
-        
+
         File iconFile = ctx.getFileStreamPath(fileName);
         Log.d(PluginConstants.LOG_TAG, "Icon stored. " + iconFile.getAbsolutePath());
-        
+
         return iconFile.getAbsolutePath();
     }
-    
+
     /**
      * Gets resource id dynamically
-     * 
-     * @param context
-     * @param resourceName
-     * @param resourceType
-     * @return
      */
-    public static int getDynamicResourceId(Context context, String resourceName, String resourceType) {
-        return context.getResources().getIdentifier(resourceName, resourceType, context.getPackageName());
+    public static int getDynamicResourceId(Context context, String resourceName,
+            String resourceType) {
+        return context.getResources()
+                .getIdentifier(resourceName, resourceType, context.getPackageName());
     }
-    
+
     /**
      * Gets resource string dynamically
-     * 
-     * @param context
-     * @param resourceName
-     * @return
      */
     public static String getDynamicResourceString(Context context, String resourceName) {
         int resourceId = getDynamicResourceId(context, resourceName, "string");
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
index 4e974d6..59e3fbb 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
@@ -19,12 +19,7 @@ package com.liato.bankdroid.lockpattern;
 import com.google.common.collect.Lists;
 
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
-import com.liato.bankdroid.R.string;
-import com.liato.bankdroid.lockpattern.LockPatternView.Cell;
 import com.liato.bankdroid.lockpattern.LockPatternView.DisplayMode;
-import com.liato.bankdroid.lockpattern.LockPatternView.OnPatternListener;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -46,7 +41,7 @@ import java.util.List;
  * - asks for confirmation / restart
  * - saves chosen password when confirmed
  */
-public class ChooseLockPattern extends Activity implements View.OnClickListener{
+public class ChooseLockPattern extends Activity implements View.OnClickListener {
 
     /**
      * Used by the choose lock pattern wizard to indicate the wizard is
@@ -58,7 +53,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
      * result.
      */
     static final int RESULT_FINISHED = RESULT_FIRST_USER;
-    
+
     // how long after a confirmation message is shown before moving on
     static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
 
@@ -67,190 +62,92 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
 
     private static final int ID_EMPTY_MESSAGE = -1;
 
+    private static final String KEY_UI_STAGE = "uiStage";
 
-    protected TextView mHeaderText;
-    protected LockPatternView mLockPatternView;
-    protected TextView mFooterText;
-    private TextView mFooterLeftButton;
-    private TextView mFooterRightButton;
-
-    protected List<LockPatternView.Cell> mChosenPattern = null;
-
-    protected LockPatternUtils mLockPatternUtils;
+    private static final String KEY_PATTERN_CHOICE = "chosenPattern";
 
     /**
      * The patten used during the help screen to show how to draw a pattern.
      */
     private final List<LockPatternView.Cell> mAnimatePattern =
             Collections.unmodifiableList(
-                Lists.newArrayList(
-                        LockPatternView.Cell.of(0, 0),
-                        LockPatternView.Cell.of(0, 1),
-                        LockPatternView.Cell.of(1, 1),
-                        LockPatternView.Cell.of(2, 1)
+                    Lists.newArrayList(
+                            LockPatternView.Cell.of(0, 0),
+                            LockPatternView.Cell.of(0, 1),
+                            LockPatternView.Cell.of(1, 1),
+                            LockPatternView.Cell.of(2, 1)
                     ));
 
+    protected TextView mHeaderText;
 
-    /**
-     * The pattern listener that responds according to a user choosing a new
-     * lock pattern.
-     */
-    protected LockPatternView.OnPatternListener mChooseNewLockPatternListener = new LockPatternView.OnPatternListener() {
-
-            public void onPatternStart() {
-                mLockPatternView.removeCallbacks(mClearPatternRunnable);
-                patternInProgress();
-            }
+    protected LockPatternView mLockPatternView;
 
-            public void onPatternCleared() {
-                mLockPatternView.removeCallbacks(mClearPatternRunnable);
-            }
+    protected TextView mFooterText;
 
-            public void onPatternDetected(List<LockPatternView.Cell> pattern) {
-                if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
-                    if (mChosenPattern == null) throw new IllegalStateException("null chosen pattern in stage 'need to confirm");
-                    if (mChosenPattern.equals(pattern)) {
-                        updateStage(Stage.ChoiceConfirmed);
-                    } else {
-                        updateStage(Stage.ConfirmWrong);
-                    }
-                } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
-                    if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
-                        updateStage(Stage.ChoiceTooShort);
-                    } else {
-                        mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
-                        updateStage(Stage.FirstChoiceValid);
-                    }
-                } else {
-                    throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
-                            + "entering the pattern.");
-                }
-            }
+    protected List<LockPatternView.Cell> mChosenPattern = null;
 
-            private void patternInProgress() {
-                mHeaderText.setText(R.string.lockpattern_recording_inprogress);
-                mFooterText.setText("");
-                mFooterLeftButton.setEnabled(false);
-                mFooterRightButton.setEnabled(false);
-            }
-     };
+    protected LockPatternUtils mLockPatternUtils;
 
+    private TextView mFooterLeftButton;
 
-    /**
-     * The states of the left footer button.
-     */
-    enum LeftButtonMode {
-        Cancel(R.string.lock_cancel, true),
-        CancelDisabled(R.string.lock_cancel, false),
-        Retry(R.string.lockpattern_retry_button_text, true),
-        RetryDisabled(R.string.lockpattern_retry_button_text, false),
-        Gone(ID_EMPTY_MESSAGE, false);
+    private TextView mFooterRightButton;
 
+    private Stage mUiStage = Stage.Introduction;
 
-        /**
-         * @param text The displayed text for this mode.
-         * @param enabled Whether the button should be enabled.
-         */
-        LeftButtonMode(int text, boolean enabled) {
-            this.text = text;
-            this.enabled = enabled;
+    private Runnable mClearPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
         }
-
-        final int text;
-        final boolean enabled;
-    }
+    };
 
     /**
-     * The states of the right button.
+     * The pattern listener that responds according to a user choosing a new
+     * lock pattern.
      */
-    enum RightButtonMode {
-        Continue(R.string.lockpattern_continue_button_text, true),
-        ContinueDisabled(R.string.lockpattern_continue_button_text, false),
-        Confirm(R.string.lockpattern_confirm_button_text, true),
-        ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
-        Ok(R.string.lock_ok, true);
+    protected LockPatternView.OnPatternListener mChooseNewLockPatternListener
+            = new LockPatternView.OnPatternListener() {
 
-        /**
-         * @param text The displayed text for this mode.
-         * @param enabled Whether the button should be enabled.
-         */
-        RightButtonMode(int text, boolean enabled) {
-            this.text = text;
-            this.enabled = enabled;
+        public void onPatternStart() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+            patternInProgress();
         }
 
-        final int text;
-        final boolean enabled;
-    }
-
-    /**
-     * Keep track internally of where the user is in choosing a pattern.
-     */
-    protected enum Stage {
-
-        Introduction(
-                R.string.lockpattern_recording_intro_header,
-                LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
-                R.string.lockpattern_recording_intro_footer, true),
-        HelpScreen(
-                R.string.lockpattern_settings_help_how_to_record,
-                LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
-        ChoiceTooShort(
-                R.string.lockpattern_recording_incorrect_too_short,
-                LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
-                ID_EMPTY_MESSAGE, true),
-        FirstChoiceValid(
-                R.string.lockpattern_pattern_entered_header,
-                LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
-        NeedToConfirm(
-                R.string.lockpattern_need_to_confirm,
-                LeftButtonMode.CancelDisabled, RightButtonMode.ConfirmDisabled,
-                ID_EMPTY_MESSAGE, true),
-        ConfirmWrong(
-                R.string.lockpattern_need_to_unlock_wrong,
-                LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
-                ID_EMPTY_MESSAGE, true),
-        ChoiceConfirmed(
-                R.string.lockpattern_pattern_confirmed_header,
-                LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
-
-
-        /**
-         * @param headerMessage The message displayed at the top.
-         * @param leftMode The mode of the left button.
-         * @param rightMode The mode of the right button.
-         * @param footerMessage The footer message.
-         * @param patternEnabled Whether the pattern widget is enabled.
-         */
-        Stage(int headerMessage,
-                LeftButtonMode leftMode,
-                RightButtonMode rightMode,
-                int footerMessage, boolean patternEnabled) {
-            this.headerMessage = headerMessage;
-            this.leftMode = leftMode;
-            this.rightMode = rightMode;
-            this.footerMessage = footerMessage;
-            this.patternEnabled = patternEnabled;
+        public void onPatternCleared() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
         }
 
-        final int headerMessage;
-        final LeftButtonMode leftMode;
-        final RightButtonMode rightMode;
-        final int footerMessage;
-        final boolean patternEnabled;
-    }
-
-    private Stage mUiStage = Stage.Introduction;
+        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+            if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
+                if (mChosenPattern == null) {
+                    throw new IllegalStateException(
+                            "null chosen pattern in stage 'need to confirm");
+                }
+                if (mChosenPattern.equals(pattern)) {
+                    updateStage(Stage.ChoiceConfirmed);
+                } else {
+                    updateStage(Stage.ConfirmWrong);
+                }
+            } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort) {
+                if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
+                    updateStage(Stage.ChoiceTooShort);
+                } else {
+                    mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
+                    updateStage(Stage.FirstChoiceValid);
+                }
+            } else {
+                throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
+                        + "entering the pattern.");
+            }
+        }
 
-    private Runnable mClearPatternRunnable = new Runnable() {
-        public void run() {
-            mLockPatternView.clearPattern();
+        private void patternInProgress() {
+            mHeaderText.setText(R.string.lockpattern_recording_inprogress);
+            mFooterText.setText("");
+            mFooterLeftButton.setEnabled(false);
+            mFooterRightButton.setEnabled(false);
         }
     };
 
-    private static final String KEY_UI_STAGE = "uiStage";
-    private static final String KEY_PATTERN_CHOICE = "chosenPattern";
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -260,7 +157,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
         requestWindowFeature(Window.FEATURE_NO_TITLE);
 
         setupViews();
-        
+
         // make it so unhandled touch events within the unlock screen go to the
         // lock pattern view.
         final LinearLayoutWithDefaultTouchRecepient topLayout
@@ -273,7 +170,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
             updateStage(Stage.Introduction);
             if (mLockPatternUtils.savedPatternExists()) {
                 confirmPattern();
-            } 
+            }
         } else {
             // restore from previous state
             final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
@@ -283,19 +180,19 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
             updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
         }
     }
-    
+
     /**
      * Keep all "find view" related stuff confined to this function since in
      * case someone needs to subclass and customize.
      */
     protected void setupViews() {
         setContentView(R.layout.choose_lock_pattern);
-        
+
         mHeaderText = (TextView) findViewById(R.id.headerText);
 
         mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
         mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
-        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());        
+        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
 
         mFooterText = (TextView) findViewById(R.id.footerText);
 
@@ -318,7 +215,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
                 finish();
             } else {
                 throw new IllegalStateException("left footer button pressed, but stage of " +
-                    mUiStage + " doesn't make sense");
+                        mUiStage + " doesn't make sense");
             }
         } else if (v == mFooterRightButton) {
 
@@ -336,8 +233,9 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
                 saveChosenPatternAndFinish();
             } else if (mUiStage.rightMode == RightButtonMode.Ok) {
                 if (mUiStage != Stage.HelpScreen) {
-                    throw new IllegalStateException("Help screen is only mode with ok button, but " +
-                            "stage is " + mUiStage);
+                    throw new IllegalStateException(
+                            "Help screen is only mode with ok button, but " +
+                                    "stage is " + mUiStage);
                 }
                 mLockPatternView.clearPattern();
                 mLockPatternView.setDisplayMode(DisplayMode.Correct);
@@ -364,6 +262,7 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
 
     /**
      * Launch screen to confirm the existing lock pattern.
+     *
      * @see #onActivityResult(int, int, android.content.Intent)
      */
     protected void confirmPattern() {
@@ -397,22 +296,21 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
 
         outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
         if (mChosenPattern != null) {
-            outState.putString(KEY_PATTERN_CHOICE, LockPatternUtils.patternToString(mChosenPattern));
+            outState.putString(KEY_PATTERN_CHOICE,
+                    LockPatternUtils.patternToString(mChosenPattern));
         }
     }
 
-
     /**
      * Updates the messages and buttons appropriate to what stage the user
      * is at in choosing a view.  This doesn't handle clearing out the pattern;
      * the pattern is expected to be in the right state.
-     * @param stage
      */
     protected void updateStage(Stage stage) {
 
         mUiStage = stage;
 
-        // header text, footer text, visibility and 
+        // header text, footer text, visibility and
         // enabled state all known from the stage
         if (stage == Stage.ChoiceTooShort) {
             mHeaderText.setText(
@@ -475,7 +373,6 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
         }
     }
 
-
     // clear the wrong pattern unless they have started a new one
     // already
     private void postClearPatternRunnable() {
@@ -493,8 +390,118 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
             mLockPatternUtils.setVisiblePatternEnabled(true);
             mLockPatternUtils.setTactileFeedbackEnabled(false);
         }
-        
+
         setResult(RESULT_FINISHED);
         finish();
     }
+
+
+    /**
+     * The states of the left footer button.
+     */
+    enum LeftButtonMode {
+        Cancel(R.string.lock_cancel, true),
+        CancelDisabled(R.string.lock_cancel, false),
+        Retry(R.string.lockpattern_retry_button_text, true),
+        RetryDisabled(R.string.lockpattern_retry_button_text, false),
+        Gone(ID_EMPTY_MESSAGE, false);
+
+        final int text;
+
+        final boolean enabled;
+
+        /**
+         * @param text    The displayed text for this mode.
+         * @param enabled Whether the button should be enabled.
+         */
+        LeftButtonMode(int text, boolean enabled) {
+            this.text = text;
+            this.enabled = enabled;
+        }
+    }
+
+
+    /**
+     * The states of the right button.
+     */
+    enum RightButtonMode {
+        Continue(R.string.lockpattern_continue_button_text, true),
+        ContinueDisabled(R.string.lockpattern_continue_button_text, false),
+        Confirm(R.string.lockpattern_confirm_button_text, true),
+        ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
+        Ok(R.string.lock_ok, true);
+
+        final int text;
+
+        final boolean enabled;
+
+        /**
+         * @param text    The displayed text for this mode.
+         * @param enabled Whether the button should be enabled.
+         */
+        RightButtonMode(int text, boolean enabled) {
+            this.text = text;
+            this.enabled = enabled;
+        }
+    }
+
+    /**
+     * Keep track internally of where the user is in choosing a pattern.
+     */
+    protected enum Stage {
+
+        Introduction(
+                R.string.lockpattern_recording_intro_header,
+                LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
+                R.string.lockpattern_recording_intro_footer, true),
+        HelpScreen(
+                R.string.lockpattern_settings_help_how_to_record,
+                LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
+        ChoiceTooShort(
+                R.string.lockpattern_recording_incorrect_too_short,
+                LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
+                ID_EMPTY_MESSAGE, true),
+        FirstChoiceValid(
+                R.string.lockpattern_pattern_entered_header,
+                LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
+        NeedToConfirm(
+                R.string.lockpattern_need_to_confirm,
+                LeftButtonMode.CancelDisabled, RightButtonMode.ConfirmDisabled,
+                ID_EMPTY_MESSAGE, true),
+        ConfirmWrong(
+                R.string.lockpattern_need_to_unlock_wrong,
+                LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
+                ID_EMPTY_MESSAGE, true),
+        ChoiceConfirmed(
+                R.string.lockpattern_pattern_confirmed_header,
+                LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
+
+        final int headerMessage;
+
+        final LeftButtonMode leftMode;
+
+        final RightButtonMode rightMode;
+
+        final int footerMessage;
+
+        final boolean patternEnabled;
+
+        /**
+         * @param headerMessage  The message displayed at the top.
+         * @param leftMode       The mode of the left button.
+         * @param rightMode      The mode of the right button.
+         * @param footerMessage  The footer message.
+         * @param patternEnabled Whether the pattern widget is enabled.
+         */
+        Stage(int headerMessage,
+                LeftButtonMode leftMode,
+                RightButtonMode rightMode,
+                int footerMessage, boolean patternEnabled) {
+            this.headerMessage = headerMessage;
+            this.leftMode = leftMode;
+            this.rightMode = rightMode;
+            this.footerMessage = footerMessage;
+            this.patternEnabled = patternEnabled;
+        }
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
index 61865f1..2341f03 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
@@ -17,9 +17,6 @@
 package com.liato.bankdroid.lockpattern;
 
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.drawable;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -30,39 +27,48 @@ import android.view.View;
 import android.widget.ImageView;
 
 public class ChooseLockPatternExample extends Activity implements View.OnClickListener {
+
+    protected static final String TAG = "Settings";
+
     private static final int REQUESTCODE_CHOOSE = 1;
+
     private static final long START_DELAY = 1000;
-    protected static final String TAG = "Settings";
+
     private View mNextButton;
+
     private View mSkipButton;
+
     private View mImageView;
+
     private AnimationDrawable mAnimation;
-    private Handler mHandler = new Handler();
+
     private Runnable mRunnable = new Runnable() {
         public void run() {
             startAnimation(mAnimation);
         }
     };
-   
+
+    private Handler mHandler = new Handler();
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.choose_lock_pattern_example);
         initViews();
     }
-    
+
     @Override
     protected void onResume() {
         super.onResume();
         mHandler.postDelayed(mRunnable, START_DELAY);
     }
-    
+
     @Override
     protected void onPause() {
         super.onPause();
         stopAnimation(mAnimation);
     }
-    
+
     public void onClick(View v) {
         if (v == mSkipButton) {
             // Canceling, so finish all
@@ -74,7 +80,7 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi
             startActivityForResult(intent, REQUESTCODE_CHOOSE);
         }
     }
-    
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == REQUESTCODE_CHOOSE && resultCode == ChooseLockPattern.RESULT_FINISHED) {
@@ -82,28 +88,30 @@ public class ChooseLockPatternExample extends Activity implements View.OnClickLi
             finish();
         }
     }
-    
+
     private void initViews() {
         mNextButton = findViewById(R.id.next_button);
         mNextButton.setOnClickListener(this);
-        
+
         mSkipButton = findViewById(R.id.skip_button);
         mSkipButton.setOnClickListener(this);
-        
+
         mImageView = (ImageView) findViewById(R.id.lock_anim);
         mImageView.setBackgroundResource(R.drawable.lock_anim);
         mImageView.setOnClickListener(this);
         mAnimation = (AnimationDrawable) mImageView.getBackground();
     }
-    
+
     protected void startAnimation(final AnimationDrawable animation) {
         if (animation != null && !animation.isRunning()) {
             animation.run();
         }
     }
-   
+
     protected void stopAnimation(final AnimationDrawable animation) {
-        if (animation != null && animation.isRunning()) animation.stop();
+        if (animation != null && animation.isRunning()) {
+            animation.stop();
+        }
     }
 }
 
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
index ead0f85..a4cc2ae 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
@@ -17,8 +17,6 @@
 package com.liato.bankdroid.lockpattern;
 
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -26,11 +24,13 @@ import android.os.Bundle;
 import android.view.View;
 
 public class ChooseLockPatternTutorial extends Activity implements View.OnClickListener {
+
     private static final int REQUESTCODE_EXAMPLE = 1;
-    
+
     private View mNextButton;
+
     private View mSkipButton;
-    
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -45,7 +45,7 @@ public class ChooseLockPatternTutorial extends Activity implements View.OnClickL
             initViews();
         }
     }
-    
+
     private void initViews() {
         setContentView(R.layout.choose_lock_pattern_tutorial);
         mNextButton = findViewById(R.id.next_button);
@@ -72,6 +72,6 @@ public class ChooseLockPatternTutorial extends Activity implements View.OnClickL
             finish();
         }
     }
-    
+
 }
 
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
index 1f96cf6..75bf336 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
@@ -18,24 +18,17 @@ package com.liato.bankdroid.lockpattern;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.anim;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
-import com.liato.bankdroid.R.string;
-import com.liato.bankdroid.lockpattern.LockPatternView.Cell;
-import com.liato.bankdroid.lockpattern.LockPatternView.DisplayMode;
-import com.liato.bankdroid.lockpattern.LockPatternView.OnPatternListener;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.CountDownTimer;
 import android.os.SystemClock;
-import android.os.Bundle;
-import android.view.WindowManager;
-import android.widget.TextView;
 import android.view.KeyEvent;
 import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
 
 import java.util.List;
 
@@ -54,8 +47,11 @@ public class ConfirmLockPattern extends Activity {
      * the caller does not supply.
      */
     public static final String HEADER_TEXT = "com.liato.bankdroid.header";
+
     public static final String FOOTER_TEXT = "com.liato.bankdroid.footer";
+
     public static final String HEADER_WRONG_TEXT = "com.liato.bankdroid.header_wrong";
+
     public static final String FOOTER_WRONG_TEXT = "com.liato.bankdroid.footer_wrong";
 
     // how long we wait to clear a wrong pattern
@@ -64,25 +60,64 @@ public class ConfirmLockPattern extends Activity {
     private static final String KEY_NUM_WRONG_ATTEMPTS = "num_wrong_attempts";
 
     private LockPatternView mLockPatternView;
+
     private LockPatternUtils mLockPatternUtils;
+
     private int mNumWrongConfirmAttempts;
+
     private CountDownTimer mCountdownTimer;
 
     private TextView mHeaderTextView;
+
     private TextView mFooterTextView;
 
     // caller-supplied text for various prompts
     private CharSequence mHeaderText;
+
     private CharSequence mFooterText;
+
     private CharSequence mHeaderWrongText;
+
     private CharSequence mFooterWrongText;
 
+    private Runnable mClearPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
+        }
+    };
 
-    private enum Stage {
-        NeedToUnlock,
-        NeedToUnlockWrong,
-        LockedOut
-    }
+    /**
+     * The pattern listener that responds according to a user confirming
+     * an existing lock pattern.
+     */
+    private LockPatternView.OnPatternListener mConfirmExistingLockPatternListener
+            = new LockPatternView.OnPatternListener() {
+
+        public void onPatternStart() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        }
+
+        public void onPatternCleared() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        }
+
+        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+            if (mLockPatternUtils.checkPattern(pattern)) {
+                setResult(RESULT_OK);
+                finish();
+            } else {
+                if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
+                        ++mNumWrongConfirmAttempts
+                                >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
+                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                    handleAttemptLockout(deadline);
+                } else {
+                    updateStage(Stage.NeedToUnlockWrong);
+                    postClearPatternRunnable();
+                }
+            }
+        }
+    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -102,7 +137,7 @@ public class ConfirmLockPattern extends Activity {
         final LinearLayoutWithDefaultTouchRecepient topLayout
                 = (LinearLayoutWithDefaultTouchRecepient) findViewById(
                 R.id.topLayout);
-        topLayout.setDefaultTouchRecepient(mLockPatternView);        
+        topLayout.setDefaultTouchRecepient(mLockPatternView);
 
         Intent intent = getIntent();
         if (intent != null) {
@@ -184,7 +219,7 @@ public class ConfirmLockPattern extends Activity {
                 } else {
                     mFooterTextView.setText(R.string.lockpattern_need_to_unlock_footer);
                 }
-                
+
                 mLockPatternView.setEnabled(true);
                 mLockPatternView.enableInput();
                 break;
@@ -199,7 +234,7 @@ public class ConfirmLockPattern extends Activity {
                 } else {
                     mFooterTextView.setText(R.string.lockpattern_need_to_unlock_wrong_footer);
                 }
-                
+
                 mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
                 mLockPatternView.setEnabled(true);
                 mLockPatternView.enableInput();
@@ -213,12 +248,6 @@ public class ConfirmLockPattern extends Activity {
         }
     }
 
-    private Runnable mClearPatternRunnable = new Runnable() {
-        public void run() {
-            mLockPatternView.clearPattern();
-        }
-    };
-
     // clear the wrong pattern unless they have started a new one
     // already
     private void postClearPatternRunnable() {
@@ -226,38 +255,6 @@ public class ConfirmLockPattern extends Activity {
         mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
     }
 
-    /**
-     * The pattern listener that responds according to a user confirming
-     * an existing lock pattern.
-     */
-    private LockPatternView.OnPatternListener mConfirmExistingLockPatternListener = new LockPatternView.OnPatternListener()  {
-
-        public void onPatternStart() {
-            mLockPatternView.removeCallbacks(mClearPatternRunnable);
-        }
-
-        public void onPatternCleared() {
-            mLockPatternView.removeCallbacks(mClearPatternRunnable);
-        }
-
-        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
-            if (mLockPatternUtils.checkPattern(pattern)) {
-                setResult(RESULT_OK);
-                finish();
-            } else {
-                if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
-                        ++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
-                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
-                    handleAttemptLockout(deadline);
-                } else {
-                    updateStage(Stage.NeedToUnlockWrong);
-                    postClearPatternRunnable();
-                }
-            }
-        }
-    };
-
-
     private void handleAttemptLockout(long elapsedRealtimeDeadline) {
         updateStage(Stage.LockedOut);
         long elapsedRealtime = SystemClock.elapsedRealtime();
@@ -267,7 +264,8 @@ public class ConfirmLockPattern extends Activity {
 
             @Override
             public void onTick(long millisUntilFinished) {
-                mHeaderTextView.setText(R.string.lockpattern_too_many_failed_confirmation_attempts_header);
+                mHeaderTextView
+                        .setText(R.string.lockpattern_too_many_failed_confirmation_attempts_header);
                 final int secondsCountdown = (int) (millisUntilFinished / 1000);
                 mFooterTextView.setText(getString(
                         R.string.lockpattern_too_many_failed_confirmation_attempts_footer,
@@ -287,4 +285,10 @@ public class ConfirmLockPattern extends Activity {
         super.finish();
         Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
     }
+
+    private enum Stage {
+        NeedToUnlock,
+        NeedToUnlockWrong,
+        LockedOut
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java app/src/main/java/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
index 0350369..7b7aaf2 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
@@ -19,8 +19,8 @@ package com.liato.bankdroid.lockpattern;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.view.View;
 import android.view.MotionEvent;
+import android.view.View;
 import android.widget.LinearLayout;
 
 
@@ -34,6 +34,7 @@ import android.widget.LinearLayout;
 public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout {
 
     private final Rect mTempRect = new Rect();
+
     private View mDefaultTouchRecepient;
 
     public LinearLayoutWithDefaultTouchRecepient(Context context) {
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index 49e7167..5176b21 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -16,13 +16,7 @@
 
 package com.liato.bankdroid.lockpattern;
 
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.List;
+import com.google.common.collect.Lists;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -34,17 +28,19 @@ import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.google.common.collect.Lists;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Utilities for the lock patten and its settings.
  */
 public class LockPatternUtils {
 
-    private static final String TAG = "LockPatternUtils";
-    
-    private static final String LOCK_PATTERN_FILE = "gesture.key";
-
     /**
      * The maximum number of incorrect attempts before the user is prevented
      * from trying again for {@link #FAILED_ATTEMPT_TIMEOUT_MS}.
@@ -78,18 +74,26 @@ public class LockPatternUtils {
      * attempt for it to be counted against the counts that affect
      * {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET}
      */
-    public static final int MIN_PATTERN_REGISTER_FAIL = 3;    
+    public static final int MIN_PATTERN_REGISTER_FAIL = 3;
+
+    private static final String TAG = "LockPatternUtils";
+
+    private static final String LOCK_PATTERN_FILE = "gesture.key";
 
     private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
+
     private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
-    private final static String PATTERN_EVER_CHOSEN = "lockscreen.patterneverchosen";
 
-    private final ContentResolver mContentResolver;
+    private final static String PATTERN_EVER_CHOSEN = "lockscreen.patterneverchosen";
 
     private static String sLockPatternFilename;
+
     private static Context mContext;
+
     private static SharedPreferences mPrefs;
-    
+
+    private final ContentResolver mContentResolver;
+
     /**
      * @param contentResolver Used to look up and save settings.
      */
@@ -105,9 +109,74 @@ public class LockPatternUtils {
         }
     }
 
+    /**
+     * Deserialize a pattern.
+     *
+     * @param string The pattern serialized with {@link #patternToString}
+     * @return The pattern.
+     */
+    public static List<LockPatternView.Cell> stringToPattern(String string) {
+        List<LockPatternView.Cell> result = Lists.newArrayList();
+
+        final byte[] bytes = string.getBytes();
+        for (int i = 0; i < bytes.length; i++) {
+            byte b = bytes[i];
+            result.add(LockPatternView.Cell.of(b / 3, b % 3));
+        }
+        return result;
+    }
+
+    /**
+     * Serialize a pattern.
+     *
+     * @param pattern The pattern.
+     * @return The pattern in string form.
+     */
+    public static String patternToString(List<LockPatternView.Cell> pattern) {
+        if (pattern == null) {
+            return "";
+        }
+        final int patternSize = pattern.size();
+
+        byte[] res = new byte[patternSize];
+        for (int i = 0; i < patternSize; i++) {
+            LockPatternView.Cell cell = pattern.get(i);
+            res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+        }
+        return new String(res);
+    }
+
+    /*
+     * Generate an SHA-1 hash for the pattern. Not the most secure, but it is
+     * at least a second level of protection. First level is that the file
+     * is in a location only readable by the system process.
+     * @param pattern the gesture pattern.
+     * @return the hash of the pattern in a byte array.
+     */
+    static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
+        if (pattern == null) {
+            return null;
+        }
+
+        final int patternSize = pattern.size();
+        byte[] res = new byte[patternSize];
+        for (int i = 0; i < patternSize; i++) {
+            LockPatternView.Cell cell = pattern.get(i);
+            res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+        }
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            byte[] hash = md.digest(res);
+            return hash;
+        } catch (NoSuchAlgorithmException nsa) {
+            return res;
+        }
+    }
+
     /**
      * Check to see if a pattern matches the saved pattern.  If no pattern exists,
      * always returns true.
+     *
      * @param pattern The pattern to check.
      * @return Whether the pattern matchees the stored one.
      */
@@ -132,6 +201,7 @@ public class LockPatternUtils {
 
     /**
      * Check to see if the user has stored a lock pattern.
+     *
      * @return Whether a saved pattern exists.
      */
     public boolean savedPatternExists() {
@@ -160,17 +230,17 @@ public class LockPatternUtils {
 
     /**
      * Save a lock pattern.
+     *
      * @param pattern The new pattern to save.
      */
     public void saveLockPattern(List<LockPatternView.Cell> pattern) {
         if (pattern == null) {
             Log.d(TAG, "Removing lock pattern");
-        }
-        else {
-            Log.d(TAG, "Saving lock pattern: "+LockPatternUtils.patternToString(pattern));
+        } else {
+            Log.d(TAG, "Saving lock pattern: " + LockPatternUtils.patternToString(pattern));
         }
         // Compute the hash
-        final byte[] hash  = LockPatternUtils.patternToHash(pattern);
+        final byte[] hash = LockPatternUtils.patternToHash(pattern);
         try {
             // Write the hash to file
             RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "rw");
@@ -191,68 +261,6 @@ public class LockPatternUtils {
         }
     }
 
-    /**
-     * Deserialize a pattern.
-     * @param string The pattern serialized with {@link #patternToString}
-     * @return The pattern.
-     */
-    public static List<LockPatternView.Cell> stringToPattern(String string) {
-        List<LockPatternView.Cell> result = Lists.newArrayList();
-
-        final byte[] bytes = string.getBytes();
-        for (int i = 0; i < bytes.length; i++) {
-            byte b = bytes[i];
-            result.add(LockPatternView.Cell.of(b / 3, b % 3));
-        }
-        return result;
-    }
-
-    /**
-     * Serialize a pattern.
-     * @param pattern The pattern.
-     * @return The pattern in string form.
-     */
-    public static String patternToString(List<LockPatternView.Cell> pattern) {
-        if (pattern == null) {
-            return "";
-        }
-        final int patternSize = pattern.size();
-
-        byte[] res = new byte[patternSize];
-        for (int i = 0; i < patternSize; i++) {
-            LockPatternView.Cell cell = pattern.get(i);
-            res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
-        }
-        return new String(res);
-    }
-    
-    /*
-     * Generate an SHA-1 hash for the pattern. Not the most secure, but it is
-     * at least a second level of protection. First level is that the file
-     * is in a location only readable by the system process.
-     * @param pattern the gesture pattern.
-     * @return the hash of the pattern in a byte array.
-     */
-    static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
-        if (pattern == null) {
-            return null;
-        }
-        
-        final int patternSize = pattern.size();
-        byte[] res = new byte[patternSize];
-        for (int i = 0; i < patternSize; i++) {
-            LockPatternView.Cell cell = pattern.get(i);
-            res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
-        }
-        try {
-            MessageDigest md = MessageDigest.getInstance("SHA-1");
-            byte[] hash = md.digest(res);
-            return hash;
-        } catch (NoSuchAlgorithmException nsa) {
-            return res;
-        }
-    }
-
     /**
      * @return Whether the lock pattern is enabled.
      */
@@ -298,6 +306,7 @@ public class LockPatternUtils {
     /**
      * Set and store the lockout deadline, meaning the user can't attempt his/her unlock
      * pattern until the deadline has passed.
+     *
      * @return the chosen deadline.
      */
     public long setLockoutAttemptDeadline() {
@@ -308,8 +317,8 @@ public class LockPatternUtils {
 
     /**
      * @return The elapsed time in millis in the future when the user is allowed to
-     *   attempt to enter his/her lock pattern, or 0 if the user is welcome to
-     *   enter a pattern.
+     * attempt to enter his/her lock pattern, or 0 if the user is welcome to
+     * enter a pattern.
      */
     public long getLockoutAttemptDeadline() {
         final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L);
@@ -322,8 +331,8 @@ public class LockPatternUtils {
 
     /**
      * @return Whether the user is permanently locked out until they verify their
-     *   credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
-     *   attempts.
+     * credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
+     * attempts.
      */
     public boolean isPermanentlyLocked() {
         return getBoolean(LOCKOUT_PERMANENT_KEY);
@@ -334,9 +343,10 @@ public class LockPatternUtils {
      * must authenticate via other means.  If false, that means the user has gone
      * out of permanent lock, so the existing (forgotten) lock pattern needs to
      * be cleared.
+     *
      * @param locked Whether the user is permanently locked out until they verify their
-     *   credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
-     *   attempts.
+     *               credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
+     *               attempts.
      */
     public void setPermanentlyLocked(boolean locked) {
         setBoolean(LOCKOUT_PERMANENT_KEY, locked);
@@ -349,7 +359,7 @@ public class LockPatternUtils {
 
     /**
      * @return A formatted string of the next alarm (for showing on the lock screen),
-     *   or null if there is no next alarm.
+     * or null if there is no next alarm.
      */
     public String getNextAlarm() {
         String nextAlarm = Settings.System.getString(mContentResolver,
@@ -367,7 +377,7 @@ public class LockPatternUtils {
     private void setBoolean(String systemSettingKey, boolean enabled) {
         Editor editor = mPrefs.edit();
         editor.putBoolean(systemSettingKey, enabled);
-        editor.commit();        
+        editor.commit();
     }
 
     private long getLong(String systemSettingKey, long def) {
@@ -377,7 +387,7 @@ public class LockPatternUtils {
     private void setLong(String systemSettingKey, long value) {
         Editor editor = mPrefs.edit();
         editor.putLong(systemSettingKey, value);
-        editor.commit(); 
+        editor.commit();
     }
 
 
diff --git app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
index a4a40f7..453a8d6 100644
--- app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
+++ app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
@@ -17,9 +17,6 @@
 package com.liato.bankdroid.lockpattern;
 
 
-import java.util.ArrayList;
-import java.util.List;
-
 import com.liato.bankdroid.R;
 
 import android.content.Context;
@@ -40,6 +37,9 @@ import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Displays and detects the user's unlock attempt, which is a drag of a finger
  * across 9 regions of the screen.
@@ -48,21 +48,14 @@ import android.view.View;
  * "correct" states.
  */
 public class LockPatternView extends View {
+
+    // TODO: make this common with PhoneWindow
+    static final int STATUS_BAR_HEIGHT = 25;
+
     // Vibrator pattern for creating a tactile bump
     private static final long[] VIBE_PATTERN = {0, 1, 40, 41};
 
     private static final boolean PROFILE_DRAWING = false;
-    private boolean mDrawingProfilingStarted = false;
-
-    private Paint mPaint = new Paint();
-    private Paint mPathPaint = new Paint();
-    protected int mPaddingLeft;
-    protected int mPaddingRight;
-    protected int mPaddingTop;
-    protected int mPaddingBottom;
-
-    // TODO: make this common with PhoneWindow
-    static final int STATUS_BAR_HEIGHT = 25;
 
     /**
      * How many milliseconds we spend animating each circle of a lock pattern
@@ -71,7 +64,26 @@ public class LockPatternView extends View {
      */
     private static final int MILLIS_PER_CIRCLE_ANIMATING = 700;
 
+    private final Path mCurrentPath = new Path();
+
+    private final Rect mInvalidate = new Rect();
+
+    protected int mPaddingLeft;
+
+    protected int mPaddingRight;
+
+    protected int mPaddingTop;
+
+    protected int mPaddingBottom;
+
+    private boolean mDrawingProfilingStarted = false;
+
+    private Paint mPaint = new Paint();
+
+    private Paint mPathPaint = new Paint();
+
     private OnPatternListener mOnPatternListener;
+
     private ArrayList<Cell> mPattern = new ArrayList<Cell>(9);
 
     /**
@@ -88,140 +100,49 @@ public class LockPatternView extends View {
      * - during animation: the current tip of the animating line
      */
     private float mInProgressX = -1;
+
     private float mInProgressY = -1;
 
     private long mAnimatingPeriodStart;
 
     private DisplayMode mPatternDisplayMode = DisplayMode.Correct;
+
     private boolean mInputEnabled = true;
+
     private boolean mInStealthMode = false;
+
     private boolean mTactileFeedbackEnabled = true;
+
     private boolean mPatternInProgress = false;
 
     private float mDiameterFactor = 0.5f;
+
     private float mHitFactor = 0.6f;
 
     private float mSquareWidth;
+
     private float mSquareHeight;
 
     private Bitmap mBitmapBtnDefault;
+
     private Bitmap mBitmapBtnTouched;
+
     private Bitmap mBitmapCircleDefault;
+
     private Bitmap mBitmapCircleGreen;
+
     private Bitmap mBitmapCircleRed;
 
     private Bitmap mBitmapArrowGreenUp;
-    private Bitmap mBitmapArrowRedUp;
 
-    private final Path mCurrentPath = new Path();
-    private final Rect mInvalidate = new Rect();
+    private Bitmap mBitmapArrowRedUp;
 
     private int mBitmapWidth;
-    private int mBitmapHeight;
-   
-
-    private Vibrator vibe; // Vibrator for creating tactile feedback
-
-    /**
-     * Represents a cell in the 3 X 3 matrix of the unlock pattern view.
-     */
-    public static class Cell {
-        int row;
-        int column;
-
-        // keep # objects limited to 9
-        static Cell[][] sCells = new Cell[3][3];
-        static {
-            for (int i = 0; i < 3; i++) {
-                for (int j = 0; j < 3; j++) {
-                    sCells[i][j] = new Cell(i, j);
-                }
-            }
-        }
-
-        /**
-         * @param row The row of the cell.
-         * @param column The column of the cell.
-         */
-        private Cell(int row, int column) {
-            checkRange(row, column);
-            this.row = row;
-            this.column = column;
-        }
-
-        public int getRow() {
-            return row;
-        }
-
-        public int getColumn() {
-            return column;
-        }
-
-        /**
-         * @param row The row of the cell.
-         * @param column The column of the cell.
-         */
-        public static synchronized Cell of(int row, int column) {
-            checkRange(row, column);
-            return sCells[row][column];
-        }
-
-        private static void checkRange(int row, int column) {
-            if (row < 0 || row > 2) {
-                throw new IllegalArgumentException("row must be in range 0-2");
-            }
-            if (column < 0 || column > 2) {
-                throw new IllegalArgumentException("column must be in range 0-2");
-            }
-        }
-
-        public String toString() {
-            return "(row=" + row + ",clmn=" + column + ")";
-        }
-    }
-
-    /**
-     * How to display the current pattern.
-     */
-    public enum DisplayMode {
-
-        /**
-         * The pattern drawn is correct (i.e draw it in a friendly color)
-         */
-        Correct,
-
-        /**
-         * Animate the pattern (for demo, and help).
-         */
-        Animate,
-
-        /**
-         * The pattern is wrong (i.e draw a foreboding color)
-         */
-        Wrong
-    }
 
-    /**
-     * The call back interface for detecting patterns entered by the user.
-     */
-    public static interface OnPatternListener {
+    private int mBitmapHeight;
 
-        /**
-         * A new pattern has begun.
-         */
-        void onPatternStart();
 
-        /**
-         * The pattern was cleared.
-         */
-        void onPatternCleared();
-
-        /**
-         * A pattern was detected from the user.
-         * @param pattern The pattern.
-         */
-        void onPatternDetected(List<Cell> pattern);
-    }
+    private Vibrator vibe; // Vibrator for creating tactile feedback
 
     public LockPatternView(Context context) {
         this(context, null);
@@ -230,7 +151,7 @@ public class LockPatternView extends View {
     public LockPatternView(Context context, AttributeSet attrs) {
         super(context, attrs);
         //vibe = new Vibrator();
-        vibe = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);  
+        vibe = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
 
         setClickable(true);
 
@@ -243,24 +164,23 @@ public class LockPatternView extends View {
         mPathPaint.setStrokeCap(Paint.Cap.ROUND);
 
         // lot's of bitmaps!
-        
+
         mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default);
         mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched);
         mBitmapCircleDefault = getBitmapFor(R.drawable.indicator_code_lock_point_area_default);
-        
+
         mBitmapCircleGreen = getBitmapFor(R.drawable.indicator_code_lock_point_area_green);
         mBitmapCircleRed = getBitmapFor(R.drawable.indicator_code_lock_point_area_red);
 
         mBitmapArrowGreenUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_green_up);
         mBitmapArrowRedUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_red_up);
-        
-        
+
         //mBitmapBtnDefault = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_default", null, null));
         //mBitmapBtnTouched = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_touched", null, null));
         //mBitmapCircleDefault = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_default", null, null));
         //mBitmapCircleGreen = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_green", null, null));
         //mBitmapCircleRed = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_red", null, null));
-        
+
         //mBitmapArrowGreenUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_green_up", null, null));
         //mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));
 
@@ -280,13 +200,6 @@ public class LockPatternView extends View {
         return mInStealthMode;
     }
 
-    /**
-     * @return Whether the view has tactile feedback enabled.
-     */
-    public boolean isTactileFeedbackEnabled() {
-        return mTactileFeedbackEnabled;
-    }
-
     /**
      * Set whether the view is in stealth mode.  If true, there will be no
      * visible feedback as the user enters the pattern.
@@ -297,6 +210,13 @@ public class LockPatternView extends View {
         mInStealthMode = inStealthMode;
     }
 
+    /**
+     * @return Whether the view has tactile feedback enabled.
+     */
+    public boolean isTactileFeedbackEnabled() {
+        return mTactileFeedbackEnabled;
+    }
+
     /**
      * Set whether the view will use tactile feedback.  If true, there will be
      * tactile feedback as the user enters the pattern.
@@ -309,6 +229,7 @@ public class LockPatternView extends View {
 
     /**
      * Set the call back for pattern detection.
+     *
      * @param onPatternListener The call back.
      */
     public void setOnPatternListener(
@@ -319,8 +240,9 @@ public class LockPatternView extends View {
     /**
      * Set the pattern explicitely (rather than waiting for the user to input
      * a pattern).
+     *
      * @param displayMode How to display the pattern.
-     * @param pattern The pattern.
+     * @param pattern     The pattern.
      */
     public void setPattern(DisplayMode displayMode, List<Cell> pattern) {
         mPattern.clear();
@@ -337,6 +259,7 @@ public class LockPatternView extends View {
      * Set the display mode of the current pattern.  This can be useful, for
      * instance, after detecting a pattern to tell this view whether change the
      * in progress result to correct or wrong.
+     *
      * @param displayMode The display mode.
      */
     public void setDisplayMode(DisplayMode displayMode) {
@@ -419,6 +342,7 @@ public class LockPatternView extends View {
      * Determines whether the point x, y will add a new point to the current
      * pattern (in addition to finding the cell, also makes heuristic choices
      * such as filling in gaps based on current pattern).
+     *
      * @param x The x coordinate.
      * @param y The y coordinate.
      */
@@ -453,7 +377,7 @@ public class LockPatternView extends View {
                 addCellToPattern(fillInGapCell);
             }
             addCellToPattern(cell);
-            if (mTactileFeedbackEnabled){
+            if (mTactileFeedbackEnabled) {
                 vibe.vibrate(VIBE_PATTERN, -1); // Generate tactile feedback
             }
             return cell;
@@ -486,6 +410,7 @@ public class LockPatternView extends View {
 
     /**
      * Helper method to find the row that y falls into.
+     *
      * @param y The y coordinate
      * @return The row that y falls in, or -1 if it falls in no row.
      */
@@ -507,6 +432,7 @@ public class LockPatternView extends View {
 
     /**
      * Helper method to find the column x fallis into.
+     *
      * @param x The x coordinate.
      * @return The column that x falls in, or -1 if it falls in no column.
      */
@@ -534,7 +460,7 @@ public class LockPatternView extends View {
         final float x = motionEvent.getX();
         final float y = motionEvent.getY();
         Cell hitCell;
-        switch(motionEvent.getAction()) {
+        switch (motionEvent.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 resetPattern();
                 hitCell = detectAndAddHit(x, y);
@@ -661,7 +587,8 @@ public class LockPatternView extends View {
 
                             if (patternSize >= 2) {
                                 // (re-using hitcell for old cell)
-                                hitCell = pattern.get(patternSize - 1 - (patternSize - patternSizePreHitDetect));
+                                hitCell = pattern.get(patternSize - 1 - (patternSize
+                                        - patternSizePreHitDetect));
                                 oldX = getCenterXForColumn(hitCell.column);
                                 oldY = getCenterYForRow(hitCell.row);
 
@@ -873,23 +800,20 @@ public class LockPatternView extends View {
         Matrix matrix = new Matrix();
         final int cellWidth = mBitmapCircleDefault.getWidth();
         final int cellHeight = mBitmapCircleDefault.getHeight();
-        
+
         // the up arrow bitmap is at 12:00, so find the rotation from x axis and add 90 degrees.
         final float theta = (float) Math.atan2(
                 (double) (endRow - startRow), (double) (endColumn - startColumn));
-        final float angle = (float) Math.toDegrees(theta) + 90.0f; 
-        
+        final float angle = (float) Math.toDegrees(theta) + 90.0f;
+
         // compose matrix
         matrix.setTranslate(leftX + offsetX, topY + offsetY); // transform to cell position
         matrix.preRotate(angle, cellWidth / 2.0f, cellHeight / 2.0f);  // rotate about cell center
         matrix.preTranslate((cellWidth - arrow.getWidth()) / 2.0f, 0.0f); // translate to 12:00 pos
-        canvas.drawBitmap(arrow, matrix, mPaint); 
+        canvas.drawBitmap(arrow, matrix, mPaint);
     }
 
     /**
-     * @param canvas
-     * @param leftX
-     * @param topY
      * @param partOfPattern Whether this circle is part of the pattern.
      */
     private void drawCircle(Canvas canvas, int leftX, int topY, boolean partOfPattern) {
@@ -952,15 +876,135 @@ public class LockPatternView extends View {
         mTactileFeedbackEnabled = ss.isTactileFeedbackEnabled();
     }
 
+    /**
+     * How to display the current pattern.
+     */
+    public enum DisplayMode {
+
+        /**
+         * The pattern drawn is correct (i.e draw it in a friendly color)
+         */
+        Correct,
+
+        /**
+         * Animate the pattern (for demo, and help).
+         */
+        Animate,
+
+        /**
+         * The pattern is wrong (i.e draw a foreboding color)
+         */
+        Wrong
+    }
+
+    /**
+     * The call back interface for detecting patterns entered by the user.
+     */
+    public static interface OnPatternListener {
+
+        /**
+         * A new pattern has begun.
+         */
+        void onPatternStart();
+
+        /**
+         * The pattern was cleared.
+         */
+        void onPatternCleared();
+
+        /**
+         * A pattern was detected from the user.
+         *
+         * @param pattern The pattern.
+         */
+        void onPatternDetected(List<Cell> pattern);
+    }
+
+    /**
+     * Represents a cell in the 3 X 3 matrix of the unlock pattern view.
+     */
+    public static class Cell {
+
+        // keep # objects limited to 9
+        static Cell[][] sCells = new Cell[3][3];
+
+        static {
+            for (int i = 0; i < 3; i++) {
+                for (int j = 0; j < 3; j++) {
+                    sCells[i][j] = new Cell(i, j);
+                }
+            }
+        }
+
+        int row;
+
+        int column;
+
+        /**
+         * @param row    The row of the cell.
+         * @param column The column of the cell.
+         */
+        private Cell(int row, int column) {
+            checkRange(row, column);
+            this.row = row;
+            this.column = column;
+        }
+
+        /**
+         * @param row    The row of the cell.
+         * @param column The column of the cell.
+         */
+        public static synchronized Cell of(int row, int column) {
+            checkRange(row, column);
+            return sCells[row][column];
+        }
+
+        private static void checkRange(int row, int column) {
+            if (row < 0 || row > 2) {
+                throw new IllegalArgumentException("row must be in range 0-2");
+            }
+            if (column < 0 || column > 2) {
+                throw new IllegalArgumentException("column must be in range 0-2");
+            }
+        }
+
+        public int getRow() {
+            return row;
+        }
+
+        public int getColumn() {
+            return column;
+        }
+
+        public String toString() {
+            return "(row=" + row + ",clmn=" + column + ")";
+        }
+    }
+
     /**
      * The parecelable for saving and restoring a lock pattern view.
      */
     private static class SavedState extends BaseSavedState {
 
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Creator<SavedState>() {
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+
         private final String mSerializedPattern;
+
         private final int mDisplayMode;
+
         private final boolean mInputEnabled;
+
         private final boolean mInStealthMode;
+
         private final boolean mTactileFeedbackEnabled;
 
         /**
@@ -987,7 +1031,7 @@ public class LockPatternView extends View {
             mInStealthMode = (Boolean) in.readValue(null);
             mTactileFeedbackEnabled = (Boolean) in.readValue(null);
         }
-        
+
         public String getSerializedPattern() {
             return mSerializedPattern;
         }
@@ -1004,7 +1048,7 @@ public class LockPatternView extends View {
             return mInStealthMode;
         }
 
-        public boolean isTactileFeedbackEnabled(){
+        public boolean isTactileFeedbackEnabled() {
             return mTactileFeedbackEnabled;
         }
 
@@ -1017,16 +1061,5 @@ public class LockPatternView extends View {
             dest.writeValue(mInStealthMode);
             dest.writeValue(mTactileFeedbackEnabled);
         }
-
-        public static final Parcelable.Creator<SavedState> CREATOR =
-                new Creator<SavedState>() {
-                    public SavedState createFromParcel(Parcel in) {
-                        return new SavedState(in);
-                    }
-
-                    public SavedState[] newArray(int size) {
-                        return new SavedState[size];
-                    }
-                };
     }
 }
diff --git app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
index f01362a..6ec8059 100644
--- app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -16,8 +16,7 @@
 
 package com.liato.bankdroid.provider;
 
-import java.util.HashMap;
-import java.util.Map;
+import com.liato.bankdroid.db.DatabaseHelper;
 
 import android.content.ContentProvider;
 import android.content.ContentValues;
@@ -31,203 +30,214 @@ import android.net.Uri;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
-import com.liato.bankdroid.db.DatabaseHelper;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * <p>
  * This is the implementation of the BankTransactionsProvider. It provides
  * access to the transaction data for specific banks.
  * </p>
- * 
+ *
  * @author Magnus Andersson
- * @since 8 jan 2011
  * @see IBankTransactionsProvider
+ * @since 8 jan 2011
  */
 public class BankTransactionsProvider extends ContentProvider implements
-		IBankTransactionsProvider {
-
-	private static final String CONTENT_PROVIDER_ENABLED = "content_provider_enabled";
-	private static final String CONTENT_PROVIDER_API_KEY = "content_provider_api_key";
-
-	private final static String TAG = "BankTransactionsProvider";
-	private final static int TRANSACTIONS = 0;
-	private final static int BANK_ACCOUNTS = 1;
-	private static final String WILD_CARD = "*";
-
-	private static final String BANK_TABLE = "banks"; 
-	private static final String ACCOUNT_TABLE = "accounts";
-	private static final String BANK_ACCOUNT_TABLES = BANK_TABLE + " LEFT JOIN " + ACCOUNT_TABLE + " ON banks."
-			+ BANK_ID + " = accounts.bankid";
-	private static final String TRANSACTIONS_TABLE = "transactions";
-
-	private DatabaseHelper dbHelper;
-	private final static UriMatcher uriMatcher;
-	private final static Map<String, String> bankAccountProjectionMap;
-	private final static Map<String, String> transProjectionMap;
-
-	static {
-		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-		uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD,
-				TRANSACTIONS);
-		uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD,
-				BANK_ACCOUNTS);
-
-		// Projections are "Poor mans views" of the data.
-		bankAccountProjectionMap = new HashMap<String, String>();
-
-		// Must match bankAccountProjection in
-		// IBankTransactionsProvider#bankAccountProjection
-		bankAccountProjectionMap.put(BANK_ID, BANK_ID);
-		bankAccountProjectionMap.put(BANK_NAME, BANK_NAME);
-		bankAccountProjectionMap.put(BANK_TYPE, BANK_TYPE);
-		bankAccountProjectionMap.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED);
-		bankAccountProjectionMap.put(ACC_ID, ACC_ID);
-		bankAccountProjectionMap.put(ACC_NAME, ACC_NAME);
-		// Table name has to be explicitly included here since Banks also have a column named balance.
-		bankAccountProjectionMap.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE); 
-		bankAccountProjectionMap.put(ACC_TYPE, ACC_TYPE);
-
-		transProjectionMap = new HashMap<String, String>();
-
-		// Must match transactionProjection in
-		// IBankTransactionsProvider#transactionProjection
-		transProjectionMap.put(TRANS_ID, TRANS_ID);
-		transProjectionMap.put(TRANS_DATE, TRANS_DATE);
-		transProjectionMap.put(TRANS_DESC, TRANS_DESC);
-		transProjectionMap.put(TRANS_AMT, TRANS_AMT);
-		transProjectionMap.put(TRANS_CUR, TRANS_CUR);
-		transProjectionMap.put(TRANS_ACCNT, TRANS_ACCNT);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int delete(final Uri uri, final String selection,
-			final String[] selectionArgs) {
-		throw new UnsupportedOperationException(
-				"This provider does not implement the delete method");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String getType(final Uri uri) {
-		Log.d(TAG, "Got URI " + uri.toString());
-
-		switch (uriMatcher.match(uri)) {
-		case BANK_ACCOUNTS:
-			return BANK_ACCOUNTS_MIME;
-		case TRANSACTIONS:
-			return TRANSACTIONS_MIME;
-		default:
-			throw new IllegalArgumentException("Unsupported URI: " + uri);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Uri insert(final Uri uri, final ContentValues values) {
-		throw new UnsupportedOperationException(
-				"This provider does not implement the insert method");
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean onCreate() {
-		dbHelper = DatabaseHelper.getHelper(getContext());
-		return true;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Cursor query(final Uri uri, final String[] projection,
-			final String selection, final String[] selectionArgs,
-			final String sortOrder) {
-
-		if (!isApiKeyEnabled(getContext())) {
-			return null;
-		}
-
-		final String apiKey = uri.getPathSegments().get(1);
-
-		Log.d(TAG, "Trying to access database with " + apiKey);
-
-		if (!apiKey.startsWith(API_KEY, 0)) {
-			return null;
-			// throw new IllegalArgumentException(API_KEY +
-			// "<API-KEY> must be a part of the URI!");
-		}
-
-		final String key = apiKey.replace(API_KEY, "");
-
-		if (!key.equals(getApiKey(getContext()))) {
-			return null;
-			// throw new
-			// IllegalAccessError("The supplied API_KEY does not exist");
-		}
-
-		final SQLiteDatabase db = dbHelper.getReadableDatabase();
-		SQLiteQueryBuilder qb;
-
-		if (BANK_ACCOUNTS_MIME.equals(getType(uri))) {
-			qb = new SQLiteQueryBuilder();
-			qb.setTables(BANK_ACCOUNT_TABLES);
-			qb.setProjectionMap(bankAccountProjectionMap);
-			qb.setDistinct(true);
-		} else if (TRANSACTIONS_MIME.equals(getType(uri))) {
-			qb = new SQLiteQueryBuilder();
-			qb.setTables(TRANSACTIONS_TABLE);
-			qb.setProjectionMap(transProjectionMap);
-		} else {
-			throw new IllegalArgumentException("Unsupported URI: " + uri);
-		}
-
-				
-		final Cursor cur = qb.query(db, projection, selection, selectionArgs,
-				null, null, sortOrder);
-
-		cur.setNotificationUri(getContext().getContentResolver(), uri);
-		return cur;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int update(final Uri uri, final ContentValues values,
-			final String selection, final String[] selectionArgs) {
-		throw new UnsupportedOperationException(
-				"This provider does not implement the update method");
-	}
-
-	public static String getApiKey(final Context ctx) {
-		final SharedPreferences prefs = PreferenceManager
-				.getDefaultSharedPreferences(ctx);
-		if (!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {
-			throw new IllegalStateException(
-					"Access to Content Provider is not enabled.");
-		}
-
-		final String apiKey = prefs.getString(CONTENT_PROVIDER_API_KEY, "");
-
-		if (apiKey.equals("")) {
-			throw new IllegalArgumentException("The API-Key must be set.");
-		}
-
-		return apiKey;
-	}
-
-	private boolean isApiKeyEnabled(final Context ctx) {
-		final SharedPreferences prefs = PreferenceManager
-				.getDefaultSharedPreferences(ctx);
-		return prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false);
-	}
+        IBankTransactionsProvider {
+
+    private static final String CONTENT_PROVIDER_ENABLED = "content_provider_enabled";
+
+    private static final String CONTENT_PROVIDER_API_KEY = "content_provider_api_key";
+
+    private final static String TAG = "BankTransactionsProvider";
+
+    private final static int TRANSACTIONS = 0;
+
+    private final static int BANK_ACCOUNTS = 1;
+
+    private static final String WILD_CARD = "*";
+
+    private static final String BANK_TABLE = "banks";
+
+    private static final String ACCOUNT_TABLE = "accounts";
+
+    private static final String BANK_ACCOUNT_TABLES = BANK_TABLE + " LEFT JOIN " + ACCOUNT_TABLE
+            + " ON banks."
+            + BANK_ID + " = accounts.bankid";
+
+    private static final String TRANSACTIONS_TABLE = "transactions";
+
+    private final static UriMatcher uriMatcher;
+
+    private final static Map<String, String> bankAccountProjectionMap;
+
+    private final static Map<String, String> transProjectionMap;
+
+    static {
+        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD,
+                TRANSACTIONS);
+        uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD,
+                BANK_ACCOUNTS);
+
+        // Projections are "Poor mans views" of the data.
+        bankAccountProjectionMap = new HashMap<String, String>();
+
+        // Must match bankAccountProjection in
+        // IBankTransactionsProvider#bankAccountProjection
+        bankAccountProjectionMap.put(BANK_ID, BANK_ID);
+        bankAccountProjectionMap.put(BANK_NAME, BANK_NAME);
+        bankAccountProjectionMap.put(BANK_TYPE, BANK_TYPE);
+        bankAccountProjectionMap.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED);
+        bankAccountProjectionMap.put(ACC_ID, ACC_ID);
+        bankAccountProjectionMap.put(ACC_NAME, ACC_NAME);
+        // Table name has to be explicitly included here since Banks also have a column named balance.
+        bankAccountProjectionMap.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE);
+        bankAccountProjectionMap.put(ACC_TYPE, ACC_TYPE);
+
+        transProjectionMap = new HashMap<String, String>();
+
+        // Must match transactionProjection in
+        // IBankTransactionsProvider#transactionProjection
+        transProjectionMap.put(TRANS_ID, TRANS_ID);
+        transProjectionMap.put(TRANS_DATE, TRANS_DATE);
+        transProjectionMap.put(TRANS_DESC, TRANS_DESC);
+        transProjectionMap.put(TRANS_AMT, TRANS_AMT);
+        transProjectionMap.put(TRANS_CUR, TRANS_CUR);
+        transProjectionMap.put(TRANS_ACCNT, TRANS_ACCNT);
+    }
+
+    private DatabaseHelper dbHelper;
+
+    public static String getApiKey(final Context ctx) {
+        final SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(ctx);
+        if (!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {
+            throw new IllegalStateException(
+                    "Access to Content Provider is not enabled.");
+        }
+
+        final String apiKey = prefs.getString(CONTENT_PROVIDER_API_KEY, "");
+
+        if (apiKey.equals("")) {
+            throw new IllegalArgumentException("The API-Key must be set.");
+        }
+
+        return apiKey;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int delete(final Uri uri, final String selection,
+            final String[] selectionArgs) {
+        throw new UnsupportedOperationException(
+                "This provider does not implement the delete method");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String getType(final Uri uri) {
+        Log.d(TAG, "Got URI " + uri.toString());
+
+        switch (uriMatcher.match(uri)) {
+            case BANK_ACCOUNTS:
+                return BANK_ACCOUNTS_MIME;
+            case TRANSACTIONS:
+                return TRANSACTIONS_MIME;
+            default:
+                throw new IllegalArgumentException("Unsupported URI: " + uri);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Uri insert(final Uri uri, final ContentValues values) {
+        throw new UnsupportedOperationException(
+                "This provider does not implement the insert method");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean onCreate() {
+        dbHelper = DatabaseHelper.getHelper(getContext());
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Cursor query(final Uri uri, final String[] projection,
+            final String selection, final String[] selectionArgs,
+            final String sortOrder) {
+
+        if (!isApiKeyEnabled(getContext())) {
+            return null;
+        }
+
+        final String apiKey = uri.getPathSegments().get(1);
+
+        Log.d(TAG, "Trying to access database with " + apiKey);
+
+        if (!apiKey.startsWith(API_KEY, 0)) {
+            return null;
+            // throw new IllegalArgumentException(API_KEY +
+            // "<API-KEY> must be a part of the URI!");
+        }
+
+        final String key = apiKey.replace(API_KEY, "");
+
+        if (!key.equals(getApiKey(getContext()))) {
+            return null;
+            // throw new
+            // IllegalAccessError("The supplied API_KEY does not exist");
+        }
+
+        final SQLiteDatabase db = dbHelper.getReadableDatabase();
+        SQLiteQueryBuilder qb;
+
+        if (BANK_ACCOUNTS_MIME.equals(getType(uri))) {
+            qb = new SQLiteQueryBuilder();
+            qb.setTables(BANK_ACCOUNT_TABLES);
+            qb.setProjectionMap(bankAccountProjectionMap);
+            qb.setDistinct(true);
+        } else if (TRANSACTIONS_MIME.equals(getType(uri))) {
+            qb = new SQLiteQueryBuilder();
+            qb.setTables(TRANSACTIONS_TABLE);
+            qb.setProjectionMap(transProjectionMap);
+        } else {
+            throw new IllegalArgumentException("Unsupported URI: " + uri);
+        }
+
+        final Cursor cur = qb.query(db, projection, selection, selectionArgs,
+                null, null, sortOrder);
+
+        cur.setNotificationUri(getContext().getContentResolver(), uri);
+        return cur;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int update(final Uri uri, final ContentValues values,
+            final String selection, final String[] selectionArgs) {
+        throw new UnsupportedOperationException(
+                "This provider does not implement the update method");
+    }
+
+    private boolean isApiKeyEnabled(final Context ctx) {
+        final SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(ctx);
+        return prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false);
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
index 159bd26..2602ff1 100644
--- app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
+++ app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
@@ -7,15 +7,16 @@ import java.net.UnknownHostException;
 
 public class NetworkUtils {
 
-    private NetworkUtils() {}
+    private NetworkUtils() {
+    }
 
     public static boolean isInternetAvailable() {
-        return ping(new byte[]{8,8,8,8}, 500);
+        return ping(new byte[]{8, 8, 8, 8}, 500);
     }
 
 
     public static boolean ping(byte[] ipAddress, int timeout) {
-        DatagramSocket datagramSocket= null;
+        DatagramSocket datagramSocket = null;
         try {
             datagramSocket = new DatagramSocket();
             datagramSocket.setSoTimeout(timeout);
@@ -26,7 +27,7 @@ public class NetworkUtils {
         } catch (SocketException | UnknownHostException e) {
             return false;
         } finally {
-            if(datagramSocket != null) {
+            if (datagramSocket != null) {
                 datagramSocket.close();
             }
         }
diff --git app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
index ff9c3c8..8ad02eb 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
@@ -28,101 +28,105 @@ import android.graphics.drawable.Drawable;
  * This drawable that draws a simple white and gray chessboard pattern.
  * It's pattern you will often see as a background behind a
  * partly transparent image in many applications.
+ *
  * @author Daniel Nilsson
  */
 public class AlphaPatternDrawable extends Drawable {
 
-	private int mRectangleSize = 10;
+    private int mRectangleSize = 10;
+
+    private Paint mPaint = new Paint();
+
+    private Paint mPaintWhite = new Paint();
+
+    private Paint mPaintGray = new Paint();
+
+    private int numRectanglesHorizontal;
 
-	private Paint mPaint = new Paint();
-	private Paint mPaintWhite = new Paint();
-	private Paint mPaintGray = new Paint();
+    private int numRectanglesVertical;
 
-	private int numRectanglesHorizontal;
-	private int numRectanglesVertical;
+    /**
+     * Bitmap in which the pattern will be cahched.
+     */
+    private Bitmap mBitmap;
 
-	/**
-	 * Bitmap in which the pattern will be cahched.
-	 */
-	private Bitmap		mBitmap;
+    public AlphaPatternDrawable(int rectangleSize) {
+        mRectangleSize = rectangleSize;
+        mPaintWhite.setColor(0xffffffff);
+        mPaintGray.setColor(0xffcbcbcb);
+    }
 
-	public AlphaPatternDrawable(int rectangleSize) {
-		mRectangleSize = rectangleSize;
-		mPaintWhite.setColor(0xffffffff);
-		mPaintGray.setColor(0xffcbcbcb);
-	}
+    @Override
+    public void draw(Canvas canvas) {
+        canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
+    }
 
-	@Override
-	public void draw(Canvas canvas) {
-		canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
-	}
+    @Override
+    public int getOpacity() {
+        return 0;
+    }
 
-	@Override
-	public int getOpacity() {
-		return 0;
-	}
+    @Override
+    public void setAlpha(int alpha) {
+        throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
+    }
 
-	@Override
-	public void setAlpha(int alpha) {
-		throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
-	}
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+        throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
+    }
 
-	@Override
-	public void setColorFilter(ColorFilter cf) {
-		throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
-	}
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
 
-	@Override
-	protected void onBoundsChange(Rect bounds) {
-		super.onBoundsChange(bounds);
+        int height = bounds.height();
+        int width = bounds.width();
 
-		int height = bounds.height();
-		int width = bounds.width();
+        numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
+        numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
 
-		numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
-		numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
+        generatePatternBitmap();
 
-		generatePatternBitmap();
+    }
 
-	}
+    /**
+     * This will generate a bitmap with the pattern
+     * as big as the rectangle we were allow to draw on.
+     * We do this to chache the bitmap so we don't need to
+     * recreate it each time draw() is called since it
+     * takes a few milliseconds.
+     */
+    private void generatePatternBitmap() {
 
-	/**
-	 * This will generate a bitmap with the pattern
-	 * as big as the rectangle we were allow to draw on.
-	 * We do this to chache the bitmap so we don't need to
-	 * recreate it each time draw() is called since it
-	 * takes a few milliseconds.
-	 */
-	private void generatePatternBitmap(){
+        if (getBounds().width() <= 0 || getBounds().height() <= 0) {
+            return;
+        }
 
-		if(getBounds().width() <= 0 || getBounds().height() <= 0){
-			return;
-		}
-		
-		mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
-		Canvas canvas = new Canvas(mBitmap);
+        mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
+        Canvas canvas = new Canvas(mBitmap);
 
-		Rect r = new Rect();
-		boolean verticalStartWhite = true;
-		for (int i = 0; i <= numRectanglesVertical; i++) {
+        Rect r = new Rect();
+        boolean verticalStartWhite = true;
+        for (int i = 0; i <= numRectanglesVertical; i++) {
 
-			boolean isWhite = verticalStartWhite;
-			for (int j = 0; j <= numRectanglesHorizontal; j++) {
+            boolean isWhite = verticalStartWhite;
+            for (int j = 0; j <= numRectanglesHorizontal; j++) {
 
-				r.top = i * mRectangleSize;
-				r.left = j * mRectangleSize;
-				r.bottom = r.top + mRectangleSize;
-				r.right = r.left + mRectangleSize;
+                r.top = i * mRectangleSize;
+                r.left = j * mRectangleSize;
+                r.bottom = r.top + mRectangleSize;
+                r.right = r.left + mRectangleSize;
 
-				canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
+                canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
 
-				isWhite = !isWhite;
-			}
+                isWhite = !isWhite;
+            }
 
-			verticalStartWhite = !verticalStartWhite;
+            verticalStartWhite = !verticalStartWhite;
 
-		}
+        }
 
-	}
+    }
 
 }
\ No newline at end of file
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
index 74cea76..f445cfd 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -26,105 +26,107 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.LinearLayout;
 
-public class ColorPickerDialog 
-	extends 
-		Dialog 
-	implements
-		ColorPickerView.OnColorChangedListener,
-		View.OnClickListener {
-
-	private ColorPickerView mColorPicker;
-
-	private ColorPickerPanelView mOldColor;
-	private ColorPickerPanelView mNewColor;
-
-	private OnColorChangedListener mListener;
-
-	public interface OnColorChangedListener {
-		public void onColorChanged(int color);
-	}
-	
-	public ColorPickerDialog(Context context, int initialColor) {
-		super(context);
-
-		init(initialColor);
-	}
-
-	private void init(int color) {
-		// To fight color branding.
-		getWindow().setFormat(PixelFormat.RGBA_8888);
-
-		setUp(color);
-
-	}
-
-	private void setUp(int color) {
-		
-		LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-		
-		View layout = inflater.inflate(R.layout.dialog_color_picker, null);
-
-		setContentView(layout);
-
-		setTitle(R.string.dialog_color_picker);
-		
-		mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
-		mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
-		mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
-		
-		((LinearLayout) mOldColor.getParent()).setPadding(
-			Math.round(mColorPicker.getDrawingOffset()), 
-			0, 
-			Math.round(mColorPicker.getDrawingOffset()), 
-			0
-		);	
-		
-		mOldColor.setOnClickListener(this);
-		mNewColor.setOnClickListener(this);
-		mColorPicker.setOnColorChangedListener(this);
-		mOldColor.setColor(color);
-		mColorPicker.setColor(color, true);
-
-	}
-
-	@Override
-	public void onColorChanged(int color) {
-
-		mNewColor.setColor(color);
+public class ColorPickerDialog
+        extends
+        Dialog
+        implements
+        ColorPickerView.OnColorChangedListener,
+        View.OnClickListener {
+
+    private ColorPickerView mColorPicker;
+
+    private ColorPickerPanelView mOldColor;
+
+    private ColorPickerPanelView mNewColor;
+
+    private OnColorChangedListener mListener;
+
+    public ColorPickerDialog(Context context, int initialColor) {
+        super(context);
+
+        init(initialColor);
+    }
+
+    private void init(int color) {
+        // To fight color branding.
+        getWindow().setFormat(PixelFormat.RGBA_8888);
+
+        setUp(color);
+
+    }
+
+    private void setUp(int color) {
+
+        LayoutInflater inflater = (LayoutInflater) getContext()
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        View layout = inflater.inflate(R.layout.dialog_color_picker, null);
+
+        setContentView(layout);
+
+        setTitle(R.string.dialog_color_picker);
+
+        mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
+        mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
+        mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
+
+        ((LinearLayout) mOldColor.getParent()).setPadding(
+                Math.round(mColorPicker.getDrawingOffset()),
+                0,
+                Math.round(mColorPicker.getDrawingOffset()),
+                0
+        );
+
+        mOldColor.setOnClickListener(this);
+        mNewColor.setOnClickListener(this);
+        mColorPicker.setOnColorChangedListener(this);
+        mOldColor.setColor(color);
+        mColorPicker.setColor(color, true);
+
+    }
+
+    @Override
+    public void onColorChanged(int color) {
+
+        mNewColor.setColor(color);
 
 		/*
-		if (mListener != null) {
+                if (mListener != null) {
 			mListener.onColorChanged(color);
 		}
 		*/
 
-	}
-
-	public void setAlphaSliderVisible(boolean visible) {
-		mColorPicker.setAlphaSliderVisible(visible);
-	}
-	
-	/**
-	 * Set a OnColorChangedListener to get notified when the color
-	 * selected by the user has changed.
-	 * @param listener
-	 */
-	public void setOnColorChangedListener(OnColorChangedListener listener){
-		mListener = listener;
-	}
-
-	public int getColor() {
-		return mColorPicker.getColor();
-	}
-
-	@Override
-	public void onClick(View v) {
-		if (v.getId() == R.id.new_color_panel) {
-			if (mListener != null) {
-				mListener.onColorChanged(mNewColor.getColor());
-			}
-		}
-		dismiss();
-	}
-	
+    }
+
+    public void setAlphaSliderVisible(boolean visible) {
+        mColorPicker.setAlphaSliderVisible(visible);
+    }
+
+    /**
+     * Set a OnColorChangedListener to get notified when the color
+     * selected by the user has changed.
+     */
+    public void setOnColorChangedListener(OnColorChangedListener listener) {
+        mListener = listener;
+    }
+
+    public int getColor() {
+        return mColorPicker.getColor();
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.new_color_panel) {
+            if (mListener != null) {
+                mListener.onColorChanged(mNewColor.getColor());
+            }
+        }
+        dismiss();
+    }
+
+    public interface OnColorChangedListener {
+
+        public void onColorChanged(int color);
+    }
+
 }
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
index b000366..5a2d72d 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
@@ -27,145 +27,145 @@ import android.view.View;
  * This class draws a panel which which will be filled with a color which can be set.
  * It can be used to show the currently selected color which you will get from
  * the {@link ColorPickerView}.
- * @author Daniel Nilsson
  *
+ * @author Daniel Nilsson
  */
 public class ColorPickerPanelView extends View {
 
-	/**
-	 * The width in pixels of the border
-	 * surrounding the color panel.
-	 */
-	private final static float	BORDER_WIDTH_PX = 1;
+    /**
+     * The width in pixels of the border
+     * surrounding the color panel.
+     */
+    private final static float BORDER_WIDTH_PX = 1;
+
+    private float mDensity = 1f;
+
+    private int mBorderColor = 0xff6E6E6E;
+
+    private int mColor = 0xff000000;
+
+    private Paint mBorderPaint;
 
-	private float mDensity = 1f;
+    private Paint mColorPaint;
 
-	private int 		mBorderColor = 0xff6E6E6E;
-	private int 		mColor = 0xff000000;
+    private RectF mDrawingRect;
 
-	private Paint		mBorderPaint;
-	private Paint		mColorPaint;
+    private RectF mColorRect;
 
-	private RectF		mDrawingRect;
-	private RectF		mColorRect;
+    private AlphaPatternDrawable mAlphaPattern;
 
-	private AlphaPatternDrawable mAlphaPattern;
 
+    public ColorPickerPanelView(Context context) {
+        this(context, null);
+    }
 
-	public ColorPickerPanelView(Context context){
-		this(context, null);
-	}
+    public ColorPickerPanelView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
 
-	public ColorPickerPanelView(Context context, AttributeSet attrs){
-		this(context, attrs, 0);
-	}
+    public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
 
-	public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
-		super(context, attrs, defStyle);
-		init();
-	}
+    private void init() {
+        mBorderPaint = new Paint();
+        mColorPaint = new Paint();
+        mDensity = getContext().getResources().getDisplayMetrics().density;
+    }
 
-	private void init(){
-		mBorderPaint = new Paint();
-		mColorPaint = new Paint();
-		mDensity = getContext().getResources().getDisplayMetrics().density;
-	}
 
+    @Override
+    protected void onDraw(Canvas canvas) {
 
-	@Override
-	protected void onDraw(Canvas canvas) {
+        final RectF rect = mColorRect;
 
-		final RectF	rect = mColorRect;
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(mDrawingRect, mBorderPaint);
+        }
 
-		if(BORDER_WIDTH_PX > 0){
-			mBorderPaint.setColor(mBorderColor);
-			canvas.drawRect(mDrawingRect, mBorderPaint);
-		}
+        if (mAlphaPattern != null) {
+            mAlphaPattern.draw(canvas);
+        }
 
-		if(mAlphaPattern != null){
-			mAlphaPattern.draw(canvas);
-		}
+        mColorPaint.setColor(mColor);
 
-		mColorPaint.setColor(mColor);
+        canvas.drawRect(rect, mColorPaint);
+    }
 
-		canvas.drawRect(rect, mColorPaint);
-	}
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 
-	@Override
-	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
 
-		int width = MeasureSpec.getSize(widthMeasureSpec);
-		int height = MeasureSpec.getSize(heightMeasureSpec);
+        setMeasuredDimension(width, height);
+    }
 
-		setMeasuredDimension(width, height);
-	}
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
 
-	@Override
-	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-		super.onSizeChanged(w, h, oldw, oldh);
+        mDrawingRect = new RectF();
+        mDrawingRect.left = getPaddingLeft();
+        mDrawingRect.right = w - getPaddingRight();
+        mDrawingRect.top = getPaddingTop();
+        mDrawingRect.bottom = h - getPaddingBottom();
 
-		mDrawingRect = new RectF();
-		mDrawingRect.left =  getPaddingLeft();
-		mDrawingRect.right  = w - getPaddingRight();
-		mDrawingRect.top = getPaddingTop();
-		mDrawingRect.bottom = h - getPaddingBottom();
+        setUpColorRect();
 
-		setUpColorRect();
+    }
 
-	}
+    private void setUpColorRect() {
+        final RectF dRect = mDrawingRect;
 
-	private void setUpColorRect(){
-		final RectF	dRect = mDrawingRect;
+        float left = dRect.left + BORDER_WIDTH_PX;
+        float top = dRect.top + BORDER_WIDTH_PX;
+        float bottom = dRect.bottom - BORDER_WIDTH_PX;
+        float right = dRect.right - BORDER_WIDTH_PX;
 
-		float left = dRect.left + BORDER_WIDTH_PX;
-		float top = dRect.top + BORDER_WIDTH_PX;
-		float bottom = dRect.bottom - BORDER_WIDTH_PX;
-		float right = dRect.right - BORDER_WIDTH_PX;
+        mColorRect = new RectF(left, top, right, bottom);
 
-		mColorRect = new RectF(left,top, right, bottom);
+        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
 
-		mAlphaPattern = new AlphaPatternDrawable((int)(5 * mDensity));
+        mAlphaPattern.setBounds(
+                Math.round(mColorRect.left),
+                Math.round(mColorRect.top),
+                Math.round(mColorRect.right),
+                Math.round(mColorRect.bottom)
+        );
 
-		mAlphaPattern.setBounds(
-			Math.round(mColorRect.left),
-			Math.round(mColorRect.top),
-			Math.round(mColorRect.right),
-			Math.round(mColorRect.bottom)
-		);
+    }
 
-	}
+    /**
+     * Get the color currently show by this view.
+     */
+    public int getColor() {
+        return mColor;
+    }
 
-	/**
-	 * Set the color that should be shown by this view.
-	 * @param color
-	 */
-	public void setColor(int color){
-		mColor = color;
-		invalidate();
-	}
+    /**
+     * Set the color that should be shown by this view.
+     */
+    public void setColor(int color) {
+        mColor = color;
+        invalidate();
+    }
 
-	/**
-	 * Get the color currently show by this view.
-	 * @return
-	 */
-	public int getColor(){
-		return mColor;
-	}
-
-	/**
-	 * Set the color of the border surrounding the panel.
-	 * @param color
-	 */
-	public void setBorderColor(int color){
-		mBorderColor = color;
-		invalidate();
-	}
-
-	/**
-	 * Get the color of the border surrounding the panel.
-	 */
-	public int getBorderColor(){
-		return mBorderColor;
-	}
+    /**
+     * Get the color of the border surrounding the panel.
+     */
+    public int getBorderColor() {
+        return mBorderColor;
+    }
+
+    /**
+     * Set the color of the border surrounding the panel.
+     */
+    public void setBorderColor(int color) {
+        mBorderColor = color;
+        invalidate();
+    }
 
 }
\ No newline at end of file
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
index 44bbf07..9ba4365 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -16,11 +16,10 @@
 
 package net.margaritov.preference.colorpicker;
 
-import android.R;
 import android.content.Context;
 import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.graphics.Bitmap.Config;
+import android.graphics.Color;
 import android.preference.Preference;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -30,165 +29,48 @@ import android.widget.LinearLayout;
 
 /**
  * A preference type that allows a user to choose a time
+ *
  * @author Sergey Margaritov
  */
 public class ColorPickerPreference
-	extends
-		Preference
-	implements
-		Preference.OnPreferenceClickListener,
-		ColorPickerDialog.OnColorChangedListener {
-
-	View mView;
-	int mDefaultValue = Color.BLACK;
-	private int mValue = Color.BLACK;
-	private float mDensity = 0;
-	private boolean mAlphaSliderEnabled = false;
-
-	private static final String androidns = "http://schemas.android.com/apk/res/android";
-
-	public ColorPickerPreference(Context context) {
-		super(context);
-		init(context, null);
-	}
-
-	public ColorPickerPreference(Context context, AttributeSet attrs) {
-		super(context, attrs);
-		init(context, attrs);
-	}
-
-	public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
-		super(context, attrs, defStyle);
-		init(context, attrs);
-	}
-	
-	@Override
-	protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
-		onColorChanged(restoreValue ? getValue() : (Integer) defaultValue);
-	}
-
-	private void init(Context context, AttributeSet attrs) {
-		mDensity = getContext().getResources().getDisplayMetrics().density;
-		setOnPreferenceClickListener(this);
-		if (attrs != null) {
-			String defaultValue = attrs.getAttributeValue(androidns, "defaultValue");
-			if (defaultValue.startsWith("#")) {
-				try {
-					mDefaultValue = convertToColorInt(defaultValue);
-				} catch (NumberFormatException e) {
-					Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
-					mDefaultValue = convertToColorInt("#FF000000");
-				}
-			} else {
-				int resourceId = attrs.getAttributeResourceValue(androidns, "defaultValue", 0);
-				if (resourceId != 0) {
-					mDefaultValue = context.getResources().getInteger(resourceId);
-				}
-			}
-			mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
-		}
-		mValue = mDefaultValue;
-	}
-
-	@Override
-	protected void onBindView(View view) {
-		super.onBindView(view);
-		mView = view;
-		setPreviewColor();
-	}
-
-	private void setPreviewColor() {
-		if (mView == null) return;
-		ImageView iView = new ImageView(getContext());
-		LinearLayout widgetFrameView = ((LinearLayout)mView.findViewById(android.R.id.widget_frame));
-		if (widgetFrameView == null) return;
-		widgetFrameView.setPadding(
-			widgetFrameView.getPaddingLeft(),
-			widgetFrameView.getPaddingTop(),
-			(int)(mDensity * 8),
-			widgetFrameView.getPaddingBottom()
-		);
-		// remove already create preview image
-		int count = widgetFrameView.getChildCount();
-		if (count > 0) {
-			widgetFrameView.removeViews(0, count);
-		}
-		widgetFrameView.setVisibility(View.VISIBLE);
-		widgetFrameView.addView(iView);
-		iView.setBackgroundDrawable(new AlphaPatternDrawable((int)(5 * mDensity)));
-		iView.setImageBitmap(getPreviewBitmap());
-	}
-
-	private Bitmap getPreviewBitmap() {
-		int d = (int) (mDensity * 31); //30dip
-		int color = getValue();
-		Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
-		int w = bm.getWidth();
-		int h = bm.getHeight();
-		int c = color;
-		for (int i = 0; i < w; i++) {
-			for (int j = i; j < h; j++) {
-				c = (i <= 1 || j <= 1 || i >= w-2 || j >= h-2) ? Color.GRAY : color;
-				bm.setPixel(i, j, c);
-				if (i != j) {
-					bm.setPixel(j, i, c);
-				}
-			}
-		}
-
-		return bm;
-	}
-
-	public int getValue() {
-		try {
-			if (isPersistent()) {
-				mValue = getPersistedInt(mDefaultValue);
-			}
-		} catch (ClassCastException e) {
-			mValue = mDefaultValue;
-		}
-
-		return mValue;
-	}
-
-	@Override
-	public void onColorChanged(int color) {
-		if (isPersistent()) {
-			persistInt(color);
-		}
-		mValue = color;
-		setPreviewColor();
-		try {
-			getOnPreferenceChangeListener().onPreferenceChange(this, color);
-		} catch (NullPointerException e) {
-
-		}
-	}
-
-	public boolean onPreferenceClick(Preference preference) {
-		ColorPickerDialog picker = new ColorPickerDialog(getContext(), getValue());
-		picker.setOnColorChangedListener(this);
-		if (mAlphaSliderEnabled) {
-			picker.setAlphaSliderVisible(true);
-		}
-		picker.show();
-
-		return false;
-	}
-
-	/**
-	 * Toggle Alpha Slider visibility (by default it's disabled)
-	 * @param enable
-	 */
-	public void setAlphaSliderEnabled(boolean enable) {
-		mAlphaSliderEnabled = enable;
-	}
-
-	/**
-	 * For custom purposes. Not used by ColorPickerPreferrence
-	 * @param color
-	 * @author Unknown
-	 */
+        extends
+        Preference
+        implements
+        Preference.OnPreferenceClickListener,
+        ColorPickerDialog.OnColorChangedListener {
+
+    private static final String androidns = "http://schemas.android.com/apk/res/android";
+
+    View mView;
+
+    int mDefaultValue = Color.BLACK;
+
+    private int mValue = Color.BLACK;
+
+    private float mDensity = 0;
+
+    private boolean mAlphaSliderEnabled = false;
+
+    public ColorPickerPreference(Context context) {
+        super(context);
+        init(context, null);
+    }
+
+    public ColorPickerPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context, attrs);
+    }
+
+    public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context, attrs);
+    }
+
+    /**
+     * For custom purposes. Not used by ColorPickerPreferrence
+     *
+     * @author Unknown
+     */
     public static String convertToARGB(int color) {
         String alpha = Integer.toHexString(Color.alpha(color));
         String red = Integer.toHexString(Color.red(color));
@@ -216,15 +98,14 @@ public class ColorPickerPreference
 
     /**
      * For custom purposes. Not used by ColorPickerPreferrence
-     * @param argb
-     * @throws NumberFormatException
+     *
      * @author Unknown
      */
     public static int convertToColorInt(String argb) throws NumberFormatException {
 
-    	if (argb.startsWith("#")) {
-    		argb = argb.replace("#", "");
-    	}
+        if (argb.startsWith("#")) {
+            argb = argb.replace("#", "");
+        }
 
         int alpha = -1, red = -1, green = -1, blue = -1;
 
@@ -233,8 +114,7 @@ public class ColorPickerPreference
             red = Integer.parseInt(argb.substring(2, 4), 16);
             green = Integer.parseInt(argb.substring(4, 6), 16);
             blue = Integer.parseInt(argb.substring(6, 8), 16);
-        }
-        else if (argb.length() == 6) {
+        } else if (argb.length() == 6) {
             alpha = 255;
             red = Integer.parseInt(argb.substring(0, 2), 16);
             green = Integer.parseInt(argb.substring(2, 4), 16);
@@ -244,4 +124,131 @@ public class ColorPickerPreference
         return Color.argb(alpha, red, green, blue);
     }
 
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        onColorChanged(restoreValue ? getValue() : (Integer) defaultValue);
+    }
+
+    private void init(Context context, AttributeSet attrs) {
+        mDensity = getContext().getResources().getDisplayMetrics().density;
+        setOnPreferenceClickListener(this);
+        if (attrs != null) {
+            String defaultValue = attrs.getAttributeValue(androidns, "defaultValue");
+            if (defaultValue.startsWith("#")) {
+                try {
+                    mDefaultValue = convertToColorInt(defaultValue);
+                } catch (NumberFormatException e) {
+                    Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
+                    mDefaultValue = convertToColorInt("#FF000000");
+                }
+            } else {
+                int resourceId = attrs.getAttributeResourceValue(androidns, "defaultValue", 0);
+                if (resourceId != 0) {
+                    mDefaultValue = context.getResources().getInteger(resourceId);
+                }
+            }
+            mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider",
+                    false);
+        }
+        mValue = mDefaultValue;
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        mView = view;
+        setPreviewColor();
+    }
+
+    private void setPreviewColor() {
+        if (mView == null) {
+            return;
+        }
+        ImageView iView = new ImageView(getContext());
+        LinearLayout widgetFrameView = ((LinearLayout) mView
+                .findViewById(android.R.id.widget_frame));
+        if (widgetFrameView == null) {
+            return;
+        }
+        widgetFrameView.setPadding(
+                widgetFrameView.getPaddingLeft(),
+                widgetFrameView.getPaddingTop(),
+                (int) (mDensity * 8),
+                widgetFrameView.getPaddingBottom()
+        );
+        // remove already create preview image
+        int count = widgetFrameView.getChildCount();
+        if (count > 0) {
+            widgetFrameView.removeViews(0, count);
+        }
+        widgetFrameView.setVisibility(View.VISIBLE);
+        widgetFrameView.addView(iView);
+        iView.setBackgroundDrawable(new AlphaPatternDrawable((int) (5 * mDensity)));
+        iView.setImageBitmap(getPreviewBitmap());
+    }
+
+    private Bitmap getPreviewBitmap() {
+        int d = (int) (mDensity * 31); //30dip
+        int color = getValue();
+        Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
+        int w = bm.getWidth();
+        int h = bm.getHeight();
+        int c = color;
+        for (int i = 0; i < w; i++) {
+            for (int j = i; j < h; j++) {
+                c = (i <= 1 || j <= 1 || i >= w - 2 || j >= h - 2) ? Color.GRAY : color;
+                bm.setPixel(i, j, c);
+                if (i != j) {
+                    bm.setPixel(j, i, c);
+                }
+            }
+        }
+
+        return bm;
+    }
+
+    public int getValue() {
+        try {
+            if (isPersistent()) {
+                mValue = getPersistedInt(mDefaultValue);
+            }
+        } catch (ClassCastException e) {
+            mValue = mDefaultValue;
+        }
+
+        return mValue;
+    }
+
+    @Override
+    public void onColorChanged(int color) {
+        if (isPersistent()) {
+            persistInt(color);
+        }
+        mValue = color;
+        setPreviewColor();
+        try {
+            getOnPreferenceChangeListener().onPreferenceChange(this, color);
+        } catch (NullPointerException e) {
+
+        }
+    }
+
+    public boolean onPreferenceClick(Preference preference) {
+        ColorPickerDialog picker = new ColorPickerDialog(getContext(), getValue());
+        picker.setOnColorChangedListener(this);
+        if (mAlphaSliderEnabled) {
+            picker.setAlphaSliderVisible(true);
+        }
+        picker.show();
+
+        return false;
+    }
+
+    /**
+     * Toggle Alpha Slider visibility (by default it's disabled)
+     */
+    public void setAlphaSliderEnabled(boolean enable) {
+        mAlphaSliderEnabled = enable;
+    }
+
 }
\ No newline at end of file
diff --git app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
index e515922..87b32b1 100644
--- app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
+++ app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -22,12 +22,12 @@ import android.graphics.Color;
 import android.graphics.ComposeShader;
 import android.graphics.LinearGradient;
 import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.RectF;
 import android.graphics.Shader;
-import android.graphics.Paint.Align;
-import android.graphics.Paint.Style;
 import android.graphics.Shader.TileMode;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
@@ -38,918 +38,918 @@ import android.view.View;
  * to select a color. A slider for the alpha channel is
  * also available. Enable it by setting
  * setAlphaSliderVisible(boolean) to true.
+ *
  * @author Daniel Nilsson
  */
 public class ColorPickerView extends View {
 
-	private final static int	PANEL_SAT_VAL = 0;
-	private final static int	PANEL_HUE = 1;
-	private final static int	PANEL_ALPHA = 2;
-
-	/**
-	 * The width in pixels of the border
-	 * surrounding all color panels.
-	 */
-	private final static float	BORDER_WIDTH_PX = 1;
-
-	/**
-	 * The width in dp of the hue panel.
-	 */
-	private float 		HUE_PANEL_WIDTH = 30f;
-	/**
-	 * The height in dp of the alpha panel
-	 */
-	private float		ALPHA_PANEL_HEIGHT = 20f;
-	/**
-	 * The distance in dp between the different
-	 * color panels.
-	 */
-	private float 		PANEL_SPACING = 10f;
-	/**
-	 * The radius in dp of the color palette tracker circle.
-	 */
-	private float 		PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
-	/**
-	 * The dp which the tracker of the hue or alpha panel
-	 * will extend outside of its bounds.
-	 */
-	private float		RECTANGLE_TRACKER_OFFSET = 2f;
-
-
-	private float 		mDensity = 1f;
-
-	private OnColorChangedListener	mListener;
-
-	private Paint 		mSatValPaint;
-	private Paint		mSatValTrackerPaint;
-
-	private Paint		mHuePaint;
-	private Paint		mHueTrackerPaint;
-
-	private Paint		mAlphaPaint;
-	private Paint		mAlphaTextPaint;
-
-	private Paint		mBorderPaint;
-
-	private Shader		mValShader;
-	private Shader		mSatShader;
-	private Shader		mHueShader;
-	private Shader		mAlphaShader;
-
-	private int			mAlpha = 0xff;
-	private float		mHue = 360f;
-	private float 		mSat = 0f;
-	private float 		mVal = 0f;
-
-	private String		mAlphaSliderText = "";
-	private int 		mSliderTrackerColor = 0xff1c1c1c;
-	private int 		mBorderColor = 0xff6E6E6E;
-	private boolean		mShowAlphaPanel = false;
-
-	/*
-	 * To remember which panel that has the "focus" when
-	 * processing hardware button data.
-	 */
-	private int			mLastTouchedPanel = PANEL_SAT_VAL;
-
-	/**
-	 * Offset from the edge we must have or else
-	 * the finger tracker will get clipped when
-	 * it is drawn outside of the view.
-	 */
-	private float 		mDrawingOffset;
-
+    private final static int PANEL_SAT_VAL = 0;
+
+    /*
+     * To remember which panel that has the "focus" when
+     * processing hardware button data.
+     */
+    private int mLastTouchedPanel = PANEL_SAT_VAL;
+
+    private final static int PANEL_HUE = 1;
+
+    private final static int PANEL_ALPHA = 2;
+
+    /**
+     * The width in pixels of the border
+     * surrounding all color panels.
+     */
+    private final static float BORDER_WIDTH_PX = 1;
+
+    /**
+     * The width in dp of the hue panel.
+     */
+    private float HUE_PANEL_WIDTH = 30f;
+
+    /**
+     * The height in dp of the alpha panel
+     */
+    private float ALPHA_PANEL_HEIGHT = 20f;
+
+    /**
+     * The distance in dp between the different
+     * color panels.
+     */
+    private float PANEL_SPACING = 10f;
+
+    /**
+     * The radius in dp of the color palette tracker circle.
+     */
+    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
+
+    /**
+     * The dp which the tracker of the hue or alpha panel
+     * will extend outside of its bounds.
+     */
+    private float RECTANGLE_TRACKER_OFFSET = 2f;
+
+    private float mDensity = 1f;
+
+    private OnColorChangedListener mListener;
+
+    private Paint mSatValPaint;
+
+    private Paint mSatValTrackerPaint;
+
+    private Paint mHuePaint;
+
+    private Paint mHueTrackerPaint;
+
+    private Paint mAlphaPaint;
+
+    private Paint mAlphaTextPaint;
+
+    private Paint mBorderPaint;
+
+    private Shader mValShader;
+
+    private Shader mSatShader;
+
+    private Shader mHueShader;
+
+    private Shader mAlphaShader;
+
+    private int mAlpha = 0xff;
+
+    private float mHue = 360f;
 
-	/*
-	 * Distance form the edges of the view
-	 * of where we are allowed to draw.
-	 */
-	private RectF	mDrawingRect;
+    private float mSat = 0f;
 
-	private RectF	mSatValRect;
-	private RectF 	mHueRect;
-	private RectF	mAlphaRect;
+    private float mVal = 0f;
 
-	private AlphaPatternDrawable	mAlphaPattern;
+    private String mAlphaSliderText = "";
 
-	private Point	mStartTouchPoint = null;
+    private int mSliderTrackerColor = 0xff1c1c1c;
 
-	public interface OnColorChangedListener {
-		public void onColorChanged(int color);
-	}
+    private int mBorderColor = 0xff6E6E6E;
 
-	public ColorPickerView(Context context){
-		this(context, null);
-	}
+    private boolean mShowAlphaPanel = false;
 
-	public ColorPickerView(Context context, AttributeSet attrs) {
-		this(context, attrs, 0);
-	}
+    /**
+     * Offset from the edge we must have or else
+     * the finger tracker will get clipped when
+     * it is drawn outside of the view.
+     */
+    private float mDrawingOffset;
 
-	public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
-		super(context, attrs, defStyle);
-		init();
-	}
 
-	private void init(){
-	    if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 11) {
-	        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-	    }
-		mDensity = getContext().getResources().getDisplayMetrics().density;
-		PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
-		RECTANGLE_TRACKER_OFFSET *= mDensity;
-		HUE_PANEL_WIDTH *= mDensity;
-		ALPHA_PANEL_HEIGHT *= mDensity;
-		PANEL_SPACING = PANEL_SPACING * mDensity;
+    /*
+     * Distance form the edges of the view
+     * of where we are allowed to draw.
+     */
+    private RectF mDrawingRect;
 
-		mDrawingOffset = calculateRequiredOffset();
+    private RectF mSatValRect;
 
-		initPaintTools();
+    private RectF mHueRect;
 
-		//Needed for receiving trackball motion events.
-		setFocusable(true);
-		setFocusableInTouchMode(true);
-	}
+    private RectF mAlphaRect;
 
-	private void initPaintTools(){
+    private AlphaPatternDrawable mAlphaPattern;
 
-		mSatValPaint = new Paint();
-		mSatValTrackerPaint = new Paint();
-		mHuePaint = new Paint();
-		mHueTrackerPaint = new Paint();
-		mAlphaPaint = new Paint();
-		mAlphaTextPaint = new Paint();
-		mBorderPaint = new Paint();
+    private Point mStartTouchPoint = null;
 
+    public ColorPickerView(Context context) {
+        this(context, null);
+    }
 
-		mSatValTrackerPaint.setStyle(Style.STROKE);
-		mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
-		mSatValTrackerPaint.setAntiAlias(true);
+    public ColorPickerView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
 
-		mHueTrackerPaint.setColor(mSliderTrackerColor);
-		mHueTrackerPaint.setStyle(Style.STROKE);
-		mHueTrackerPaint.setStrokeWidth(2f * mDensity);
-		mHueTrackerPaint.setAntiAlias(true);
+    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
 
-		mAlphaTextPaint.setColor(0xff1c1c1c);
-		mAlphaTextPaint.setTextSize(14f * mDensity);
-		mAlphaTextPaint.setAntiAlias(true);
-		mAlphaTextPaint.setTextAlign(Align.CENTER);
-		mAlphaTextPaint.setFakeBoldText(true);
+    private void init() {
+        if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 11) {
+            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+        }
+        mDensity = getContext().getResources().getDisplayMetrics().density;
+        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
+        RECTANGLE_TRACKER_OFFSET *= mDensity;
+        HUE_PANEL_WIDTH *= mDensity;
+        ALPHA_PANEL_HEIGHT *= mDensity;
+        PANEL_SPACING = PANEL_SPACING * mDensity;
 
+        mDrawingOffset = calculateRequiredOffset();
 
-	}
+        initPaintTools();
 
-	private float calculateRequiredOffset(){
-		float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
-		offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
+        //Needed for receiving trackball motion events.
+        setFocusable(true);
+        setFocusableInTouchMode(true);
+    }
 
-		return offset * 1.5f;
-	}
+    private void initPaintTools() {
 
-	private int[] buildHueColorArray(){
+        mSatValPaint = new Paint();
+        mSatValTrackerPaint = new Paint();
+        mHuePaint = new Paint();
+        mHueTrackerPaint = new Paint();
+        mAlphaPaint = new Paint();
+        mAlphaTextPaint = new Paint();
+        mBorderPaint = new Paint();
 
-		int[] hue = new int[361];
+        mSatValTrackerPaint.setStyle(Style.STROKE);
+        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
+        mSatValTrackerPaint.setAntiAlias(true);
 
-		int count = 0;
-		for(int i = hue.length -1; i >= 0; i--, count++){
-			hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
-		}
+        mHueTrackerPaint.setColor(mSliderTrackerColor);
+        mHueTrackerPaint.setStyle(Style.STROKE);
+        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
+        mHueTrackerPaint.setAntiAlias(true);
 
-		return hue;
-	}
+        mAlphaTextPaint.setColor(0xff1c1c1c);
+        mAlphaTextPaint.setTextSize(14f * mDensity);
+        mAlphaTextPaint.setAntiAlias(true);
+        mAlphaTextPaint.setTextAlign(Align.CENTER);
+        mAlphaTextPaint.setFakeBoldText(true);
 
 
-	@Override
-	protected void onDraw(Canvas canvas) {
+    }
 
-		if(mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) return;
+    private float calculateRequiredOffset() {
+        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
+        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
 
-		drawSatValPanel(canvas);
-		drawHuePanel(canvas);
-		drawAlphaPanel(canvas);
+        return offset * 1.5f;
+    }
 
-	}
+    private int[] buildHueColorArray() {
 
-	private void drawSatValPanel(Canvas canvas){
+        int[] hue = new int[361];
 
-		final RectF	rect = mSatValRect;
+        int count = 0;
+        for (int i = hue.length - 1; i >= 0; i--, count++) {
+            hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
+        }
 
-		if(BORDER_WIDTH_PX > 0){
-			mBorderPaint.setColor(mBorderColor);
-			canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
-		}
+        return hue;
+    }
 
-		if (mValShader == null) {
-			mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
-					0xffffffff, 0xff000000, TileMode.CLAMP);
-		}
+    @Override
+    protected void onDraw(Canvas canvas) {
 
-		int rgb = Color.HSVToColor(new float[]{mHue,1f,1f});
+        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) {
+            return;
+        }
 
-		mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
-				0xffffffff, rgb, TileMode.CLAMP);
-		ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
-		mSatValPaint.setShader(mShader);
+        drawSatValPanel(canvas);
+        drawHuePanel(canvas);
+        drawAlphaPanel(canvas);
 
-		canvas.drawRect(rect, mSatValPaint);
+    }
 
-		Point p = satValToPoint(mSat, mVal);
+    private void drawSatValPanel(Canvas canvas) {
 
-		mSatValTrackerPaint.setColor(0xff000000);
-		canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
+        final RectF rect = mSatValRect;
 
-		mSatValTrackerPaint.setColor(0xffdddddd);
-		canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX,
+                    rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
+        }
 
-	}
+        if (mValShader == null) {
+            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
+                    0xffffffff, 0xff000000, TileMode.CLAMP);
+        }
 
-	private void drawHuePanel(Canvas canvas){
+        int rgb = Color.HSVToColor(new float[]{mHue, 1f, 1f});
 
-		final RectF rect = mHueRect;
+        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
+                0xffffffff, rgb, TileMode.CLAMP);
+        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
+        mSatValPaint.setShader(mShader);
 
-		if(BORDER_WIDTH_PX > 0){
-			mBorderPaint.setColor(mBorderColor);
-			canvas.drawRect(rect.left - BORDER_WIDTH_PX,
-					rect.top - BORDER_WIDTH_PX,
-					rect.right + BORDER_WIDTH_PX,
-					rect.bottom + BORDER_WIDTH_PX,
-					mBorderPaint);
-		}
+        canvas.drawRect(rect, mSatValPaint);
 
-		if (mHueShader == null) {
-			mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
-			mHuePaint.setShader(mHueShader);
-		}
+        Point p = satValToPoint(mSat, mVal);
 
-		canvas.drawRect(rect, mHuePaint);
+        mSatValTrackerPaint.setColor(0xff000000);
+        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity,
+                mSatValTrackerPaint);
 
-		float rectHeight = 4 * mDensity / 2;
+        mSatValTrackerPaint.setColor(0xffdddddd);
+        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
 
-		Point p = hueToPoint(mHue);
+    }
 
-		RectF r = new RectF();
-		r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
-		r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
-		r.top = p.y - rectHeight;
-		r.bottom = p.y + rectHeight;
+    private void drawHuePanel(Canvas canvas) {
 
+        final RectF rect = mHueRect;
 
-		canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
+                    rect.top - BORDER_WIDTH_PX,
+                    rect.right + BORDER_WIDTH_PX,
+                    rect.bottom + BORDER_WIDTH_PX,
+                    mBorderPaint);
+        }
 
-	}
+        if (mHueShader == null) {
+            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
+                    buildHueColorArray(), null, TileMode.CLAMP);
+            mHuePaint.setShader(mHueShader);
+        }
 
-	private void drawAlphaPanel(Canvas canvas){
+        canvas.drawRect(rect, mHuePaint);
 
-		if(!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return;
+        float rectHeight = 4 * mDensity / 2;
 
-		final RectF rect = mAlphaRect;
+        Point p = hueToPoint(mHue);
 
-		if(BORDER_WIDTH_PX > 0){
-			mBorderPaint.setColor(mBorderColor);
-			canvas.drawRect(rect.left - BORDER_WIDTH_PX,
-					rect.top - BORDER_WIDTH_PX,
-					rect.right + BORDER_WIDTH_PX,
-					rect.bottom + BORDER_WIDTH_PX,
-					mBorderPaint);
-		}
+        RectF r = new RectF();
+        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
+        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
+        r.top = p.y - rectHeight;
+        r.bottom = p.y + rectHeight;
 
+        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
 
-		mAlphaPattern.draw(canvas);
+    }
 
-		float[] hsv = new float[]{mHue,mSat,mVal};
-		int color = Color.HSVToColor(hsv);
-		int acolor = Color.HSVToColor(0, hsv);
+    private void drawAlphaPanel(Canvas canvas) {
 
-		mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
-				color, acolor, TileMode.CLAMP);
+        if (!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) {
+            return;
+        }
 
+        final RectF rect = mAlphaRect;
 
-		mAlphaPaint.setShader(mAlphaShader);
+        if (BORDER_WIDTH_PX > 0) {
+            mBorderPaint.setColor(mBorderColor);
+            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
+                    rect.top - BORDER_WIDTH_PX,
+                    rect.right + BORDER_WIDTH_PX,
+                    rect.bottom + BORDER_WIDTH_PX,
+                    mBorderPaint);
+        }
 
-		canvas.drawRect(rect, mAlphaPaint);
+        mAlphaPattern.draw(canvas);
 
-		if(mAlphaSliderText != null && mAlphaSliderText!= ""){
-			canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
-		}
+        float[] hsv = new float[]{mHue, mSat, mVal};
+        int color = Color.HSVToColor(hsv);
+        int acolor = Color.HSVToColor(0, hsv);
 
-		float rectWidth = 4 * mDensity / 2;
+        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
+                color, acolor, TileMode.CLAMP);
 
-		Point p = alphaToPoint(mAlpha);
+        mAlphaPaint.setShader(mAlphaShader);
 
-		RectF r = new RectF();
-		r.left = p.x - rectWidth;
-		r.right = p.x + rectWidth;
-		r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
-		r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
+        canvas.drawRect(rect, mAlphaPaint);
 
-		canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
+        if (mAlphaSliderText != null && mAlphaSliderText != "") {
+            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity,
+                    mAlphaTextPaint);
+        }
 
-	}
+        float rectWidth = 4 * mDensity / 2;
 
+        Point p = alphaToPoint(mAlpha);
 
-	private Point hueToPoint(float hue){
+        RectF r = new RectF();
+        r.left = p.x - rectWidth;
+        r.right = p.x + rectWidth;
+        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
+        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
 
-		final RectF rect = mHueRect;
-		final float height = rect.height();
+        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
 
-		Point p = new Point();
+    }
 
-		p.y = (int) (height - (hue * height / 360f) + rect.top);
-		p.x = (int) rect.left;
+    private Point hueToPoint(float hue) {
 
-		return p;
-	}
+        final RectF rect = mHueRect;
+        final float height = rect.height();
 
-	private Point satValToPoint(float sat, float val){
+        Point p = new Point();
 
-		final RectF rect = mSatValRect;
-		final float height = rect.height();
-		final float width = rect.width();
+        p.y = (int) (height - (hue * height / 360f) + rect.top);
+        p.x = (int) rect.left;
 
-		Point p = new Point();
+        return p;
+    }
 
-		p.x = (int) (sat * width + rect.left);
-		p.y = (int) ((1f - val) * height + rect.top);
+    private Point satValToPoint(float sat, float val) {
 
-		return p;
-	}
+        final RectF rect = mSatValRect;
+        final float height = rect.height();
+        final float width = rect.width();
 
-	private Point alphaToPoint(int alpha){
+        Point p = new Point();
 
-		final RectF rect = mAlphaRect;
-		final float width = rect.width();
+        p.x = (int) (sat * width + rect.left);
+        p.y = (int) ((1f - val) * height + rect.top);
 
-		Point p = new Point();
+        return p;
+    }
 
-		p.x = (int) (width - (alpha * width / 0xff) + rect.left);
-		p.y = (int) rect.top;
+    private Point alphaToPoint(int alpha) {
 
-		return p;
+        final RectF rect = mAlphaRect;
+        final float width = rect.width();
 
-	}
+        Point p = new Point();
 
-	private float[] pointToSatVal(float x, float y){
+        p.x = (int) (width - (alpha * width / 0xff) + rect.left);
+        p.y = (int) rect.top;
 
-		final RectF rect = mSatValRect;
-		float[] result = new float[2];
+        return p;
 
-		float width = rect.width();
-		float height = rect.height();
+    }
 
-		if (x < rect.left){
-			x = 0f;
-		}
-		else if(x > rect.right){
-			x = width;
-		}
-		else{
-			x = x - rect.left;
-		}
+    private float[] pointToSatVal(float x, float y) {
 
-		if (y < rect.top){
-			y = 0f;
-		}
-		else if(y > rect.bottom){
-			y = height;
-		}
-		else{
-			y = y - rect.top;
-		}
+        final RectF rect = mSatValRect;
+        float[] result = new float[2];
 
+        float width = rect.width();
+        float height = rect.height();
 
-		result[0] = 1.f / width * x;
-		result[1] = 1.f - (1.f / height * y);
+        if (x < rect.left) {
+            x = 0f;
+        } else if (x > rect.right) {
+            x = width;
+        } else {
+            x = x - rect.left;
+        }
 
-		return result;
-	}
+        if (y < rect.top) {
+            y = 0f;
+        } else if (y > rect.bottom) {
+            y = height;
+        } else {
+            y = y - rect.top;
+        }
 
-	private float pointToHue(float y){
+        result[0] = 1.f / width * x;
+        result[1] = 1.f - (1.f / height * y);
 
-		final RectF rect = mHueRect;
+        return result;
+    }
 
-		float height = rect.height();
+    private float pointToHue(float y) {
 
-		if (y < rect.top){
-			y = 0f;
-		}
-		else if(y > rect.bottom){
-			y = height;
-		}
-		else{
-			y = y - rect.top;
-		}
+        final RectF rect = mHueRect;
 
-		return 360f - (y * 360f / height);
-	}
+        float height = rect.height();
 
-	private int pointToAlpha(int x){
+        if (y < rect.top) {
+            y = 0f;
+        } else if (y > rect.bottom) {
+            y = height;
+        } else {
+            y = y - rect.top;
+        }
 
-		final RectF rect = mAlphaRect;
-		final int width = (int) rect.width();
+        return 360f - (y * 360f / height);
+    }
 
-		if(x < rect.left){
-			x = 0;
-		}
-		else if(x > rect.right){
-			x = width;
-		}
-		else{
-			x = x - (int)rect.left;
-		}
+    private int pointToAlpha(int x) {
 
-		return 0xff - (x * 0xff / width);
+        final RectF rect = mAlphaRect;
+        final int width = (int) rect.width();
 
-	}
+        if (x < rect.left) {
+            x = 0;
+        } else if (x > rect.right) {
+            x = width;
+        } else {
+            x = x - (int) rect.left;
+        }
 
+        return 0xff - (x * 0xff / width);
 
-	@Override
-	public boolean onTrackballEvent(MotionEvent event) {
+    }
 
-		float x = event.getX();
-		float y = event.getY();
+    @Override
+    public boolean onTrackballEvent(MotionEvent event) {
 
-		boolean update = false;
+        float x = event.getX();
+        float y = event.getY();
 
+        boolean update = false;
 
-		if(event.getAction() == MotionEvent.ACTION_MOVE){
+        if (event.getAction() == MotionEvent.ACTION_MOVE) {
 
-			switch(mLastTouchedPanel){
+            switch (mLastTouchedPanel) {
 
-			case PANEL_SAT_VAL:
+                case PANEL_SAT_VAL:
 
-				float sat, val;
+                    float sat, val;
 
-				sat = mSat + x/50f;
-				val = mVal - y/50f;
+                    sat = mSat + x / 50f;
+                    val = mVal - y / 50f;
 
-				if(sat < 0f){
-					sat = 0f;
-				}
-				else if(sat > 1f){
-					sat = 1f;
-				}
+                    if (sat < 0f) {
+                        sat = 0f;
+                    } else if (sat > 1f) {
+                        sat = 1f;
+                    }
 
-				if(val < 0f){
-					val = 0f;
-				}
-				else if(val > 1f){
-					val = 1f;
-				}
+                    if (val < 0f) {
+                        val = 0f;
+                    } else if (val > 1f) {
+                        val = 1f;
+                    }
 
-				mSat = sat;
-				mVal = val;
+                    mSat = sat;
+                    mVal = val;
 
-				update = true;
+                    update = true;
 
-				break;
+                    break;
 
-			case PANEL_HUE:
+                case PANEL_HUE:
 
-				float hue = mHue - y * 10f;
+                    float hue = mHue - y * 10f;
 
-				if(hue < 0f){
-					hue = 0f;
-				}
-				else if(hue > 360f){
-					hue = 360f;
-				}
+                    if (hue < 0f) {
+                        hue = 0f;
+                    } else if (hue > 360f) {
+                        hue = 360f;
+                    }
 
-				mHue = hue;
+                    mHue = hue;
 
-				update = true;
+                    update = true;
 
-				break;
+                    break;
 
-			case PANEL_ALPHA:
+                case PANEL_ALPHA:
 
-				if(!mShowAlphaPanel || mAlphaRect == null){
-					update = false;
-				}
-				else{
+                    if (!mShowAlphaPanel || mAlphaRect == null) {
+                        update = false;
+                    } else {
 
-					int alpha = (int) (mAlpha - x*10);
+                        int alpha = (int) (mAlpha - x * 10);
 
-					if(alpha < 0){
-						alpha = 0;
-					}
-					else if(alpha > 0xff){
-						alpha = 0xff;
-					}
+                        if (alpha < 0) {
+                            alpha = 0;
+                        } else if (alpha > 0xff) {
+                            alpha = 0xff;
+                        }
 
-					mAlpha = alpha;
+                        mAlpha = alpha;
 
+                        update = true;
+                    }
 
-					update = true;
-				}
+                    break;
+            }
 
-				break;
-			}
 
+        }
 
-		}
+        if (update) {
 
+            if (mListener != null) {
+                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
+            }
 
-		if(update){
+            invalidate();
+            return true;
+        }
 
-			if(mListener != null){
-				mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
-			}
+        return super.onTrackballEvent(event);
+    }
 
-			invalidate();
-			return true;
-		}
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
 
+        boolean update = false;
 
-		return super.onTrackballEvent(event);
-	}
+        switch (event.getAction()) {
 
-	@Override
-	public boolean onTouchEvent(MotionEvent event) {
+            case MotionEvent.ACTION_DOWN:
 
-		boolean update = false;
+                mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
 
-		switch(event.getAction()){
+                update = moveTrackersIfNeeded(event);
 
-		case MotionEvent.ACTION_DOWN:
+                break;
 
-			mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
+            case MotionEvent.ACTION_MOVE:
 
-			update = moveTrackersIfNeeded(event);
+                update = moveTrackersIfNeeded(event);
 
-			break;
+                break;
 
-		case MotionEvent.ACTION_MOVE:
+            case MotionEvent.ACTION_UP:
 
-			update = moveTrackersIfNeeded(event);
+                mStartTouchPoint = null;
 
-			break;
+                update = moveTrackersIfNeeded(event);
 
-		case MotionEvent.ACTION_UP:
+                break;
 
-			mStartTouchPoint = null;
+        }
 
-			update = moveTrackersIfNeeded(event);
+        if (update) {
 
-			break;
+            if (mListener != null) {
+                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
+            }
 
-		}
+            invalidate();
+            return true;
+        }
 
-		if(update){
+        return super.onTouchEvent(event);
+    }
 
-			if(mListener != null){
-				mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
-			}
+    private boolean moveTrackersIfNeeded(MotionEvent event) {
 
-			invalidate();
-			return true;
-		}
+        if (mStartTouchPoint == null) {
+            return false;
+        }
 
+        boolean update = false;
 
-		return super.onTouchEvent(event);
-	}
+        int startX = mStartTouchPoint.x;
+        int startY = mStartTouchPoint.y;
 
-	private boolean moveTrackersIfNeeded(MotionEvent event){
+        if (mHueRect.contains(startX, startY)) {
+            mLastTouchedPanel = PANEL_HUE;
 
-		if(mStartTouchPoint == null) return false;
+            mHue = pointToHue(event.getY());
 
-		boolean update = false;
+            update = true;
+        } else if (mSatValRect.contains(startX, startY)) {
 
-		int startX = mStartTouchPoint.x;
-		int startY = mStartTouchPoint.y;
+            mLastTouchedPanel = PANEL_SAT_VAL;
 
+            float[] result = pointToSatVal(event.getX(), event.getY());
 
-		if(mHueRect.contains(startX, startY)){
-			mLastTouchedPanel = PANEL_HUE;
+            mSat = result[0];
+            mVal = result[1];
 
-			mHue = pointToHue(event.getY());
+            update = true;
+        } else if (mAlphaRect != null && mAlphaRect.contains(startX, startY)) {
 
-			update = true;
-		}
-		else if(mSatValRect.contains(startX, startY)){
+            mLastTouchedPanel = PANEL_ALPHA;
 
-			mLastTouchedPanel = PANEL_SAT_VAL;
+            mAlpha = pointToAlpha((int) event.getX());
 
-			float[] result = pointToSatVal(event.getX(), event.getY());
+            update = true;
+        }
 
-			mSat = result[0];
-			mVal = result[1];
+        return update;
+    }
 
-			update = true;
-		}
-		else if(mAlphaRect != null && mAlphaRect.contains(startX, startY)){
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 
-			mLastTouchedPanel = PANEL_ALPHA;
+        int width = 0;
+        int height = 0;
 
-			mAlpha = pointToAlpha((int)event.getX());
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
-			update = true;
-		}
+        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
+        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
 
+        widthAllowed = chooseWidth(widthMode, widthAllowed);
+        heightAllowed = chooseHeight(heightMode, heightAllowed);
 
-		return update;
-	}
+        if (!mShowAlphaPanel) {
 
-	@Override
-	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
 
-		int width = 0;
-		int height = 0;
-		
-		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-		
-		int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
-		int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
-		
-		widthAllowed = chooseWidth(widthMode, widthAllowed);
-		heightAllowed = chooseHeight(heightMode, heightAllowed);
-		
-		if(!mShowAlphaPanel){
-			
-			height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
+            //If calculated height (based on the width) is more than the allowed height.
+            if (height > heightAllowed || getTag().equals("landscape")) {
+                height = heightAllowed;
+                width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
+            } else {
+                width = widthAllowed;
+            }
+        } else {
 
-			//If calculated height (based on the width) is more than the allowed height.
-			if(height > heightAllowed || getTag().equals("landscape")) {
-				height = heightAllowed;
-				width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
-			}
-			else{
-				width = widthAllowed;
-			}
-		}
-		else{
+            width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
 
-			width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
+            if (width > widthAllowed) {
+                width = widthAllowed;
+                height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
+            } else {
+                height = heightAllowed;
+            }
 
-			if(width > widthAllowed){
-				width = widthAllowed;
-				height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
-			}
-			else{
-				height = heightAllowed;
-			}
+        }
 
-		}
-		
-		setMeasuredDimension(width, height);
-	}
+        setMeasuredDimension(width, height);
+    }
 
-	private int chooseWidth(int mode, int size){
-		if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
-			return size;
-		} else { // (mode == MeasureSpec.UNSPECIFIED)
-			return getPrefferedWidth();
-		}
-	}
+    private int chooseWidth(int mode, int size) {
+        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
+            return size;
+        } else { // (mode == MeasureSpec.UNSPECIFIED)
+            return getPrefferedWidth();
+        }
+    }
 
-	private int chooseHeight(int mode, int size){
-		if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
-			return size;
-		} else { // (mode == MeasureSpec.UNSPECIFIED)
-			return getPrefferedHeight();
-		}
-	}
+    private int chooseHeight(int mode, int size) {
+        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
+            return size;
+        } else { // (mode == MeasureSpec.UNSPECIFIED)
+            return getPrefferedHeight();
+        }
+    }
 
-	private int getPrefferedWidth(){
+    private int getPrefferedWidth() {
 
-		int width = getPrefferedHeight();
+        int width = getPrefferedHeight();
 
-		if(mShowAlphaPanel){
-			width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
-		}
+        if (mShowAlphaPanel) {
+            width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
+        }
 
+        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
 
-		return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
+    }
 
-	}
+    private int getPrefferedHeight() {
 
-	private int getPrefferedHeight(){
+        int height = (int) (200 * mDensity);
 
-		int height = (int)(200 * mDensity);
+        if (mShowAlphaPanel) {
+            height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+        }
 
-		if(mShowAlphaPanel){
-			height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
-		}
+        return height;
+    }
 
-		return height;
-	}
-
-
-
-	@Override
-	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-		super.onSizeChanged(w, h, oldw, oldh);
-
-		mDrawingRect = new RectF();
-		mDrawingRect.left = mDrawingOffset + getPaddingLeft();
-		mDrawingRect.right  = w - mDrawingOffset - getPaddingRight();
-		mDrawingRect.top = mDrawingOffset + getPaddingTop();
-		mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
-
-		setUpSatValRect();
-		setUpHueRect();
-		setUpAlphaRect();
-	}
-
-	private void setUpSatValRect(){
-
-		final RectF	dRect = mDrawingRect;
-		float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
-
-		if(mShowAlphaPanel){
-			panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
-		}
-
-		float left = dRect.left + BORDER_WIDTH_PX;
-		float top = dRect.top + BORDER_WIDTH_PX;
-		float bottom = top + panelSide;
-		float right = left + panelSide;
-
-		mSatValRect = new RectF(left,top, right, bottom);
-	}
-
-	private void setUpHueRect(){
-		final RectF	dRect = mDrawingRect;
-
-		float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
-		float top = dRect.top + BORDER_WIDTH_PX;
-		float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
-		float right = dRect.right - BORDER_WIDTH_PX;
-
-		mHueRect = new RectF(left, top, right, bottom);
-	}
-
-	private void setUpAlphaRect() {
-
-		if(!mShowAlphaPanel) return;
-
-		final RectF	dRect = mDrawingRect;
-
-		float left = dRect.left + BORDER_WIDTH_PX;
-		float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
-		float bottom = dRect.bottom - BORDER_WIDTH_PX;
-		float right = dRect.right - BORDER_WIDTH_PX;
-
-		mAlphaRect = new RectF(left, top, right, bottom);
-
-		mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
-		mAlphaPattern.setBounds(
-			Math.round(mAlphaRect.left), 
-			Math.round(mAlphaRect.top), 
-			Math.round(mAlphaRect.right), 
-			Math.round(mAlphaRect.bottom)
-		);
-
-	}
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
 
+        mDrawingRect = new RectF();
+        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
+        mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
+        mDrawingRect.top = mDrawingOffset + getPaddingTop();
+        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
 
-	/**
-	 * Set a OnColorChangedListener to get notified when the color
-	 * selected by the user has changed.
-	 * @param listener
-	 */
-	public void setOnColorChangedListener(OnColorChangedListener listener){
-		mListener = listener;
-	}
-
-	/**
-	 * Set the color of the border surrounding all panels.
-	 * @param color
-	 */
-	public void setBorderColor(int color){
-		mBorderColor = color;
-		invalidate();
-	}
-
-	/**
-	 * Get the color of the border surrounding all panels.
-	 */
-	public int getBorderColor(){
-		return mBorderColor;
-	}
-
-	/**
-	 * Get the current color this view is showing.
-	 * @return the current color.
-	 */
-	public int getColor(){
-		return Color.HSVToColor(mAlpha, new float[]{mHue,mSat,mVal});
-	}
-
-	/**
-	 * Set the color the view should show.
-	 * @param color The color that should be selected.
-	 */
-	public void setColor(int color){
-		setColor(color, false);
-	}
-
-	/**
-	 * Set the color this view should show.
-	 * @param color The color that should be selected.
-	 * @param callback If you want to get a callback to
-	 * your OnColorChangedListener.
-	 */
-	public void setColor(int color, boolean callback){
-
-		int alpha = Color.alpha(color);
-		int red = Color.red(color);
-		int blue = Color.blue(color);
-		int green = Color.green(color);
-
-		float[] hsv = new float[3];
-
-		Color.RGBToHSV(red, green, blue, hsv);
-
-		mAlpha = alpha;
-		mHue = hsv[0];
-		mSat = hsv[1];
-		mVal = hsv[2];
-
-		if(callback && mListener != null){
-			mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
-		}
-
-		invalidate();
-	}
-
-	/**
-	 * Get the drawing offset of the color picker view.
-	 * The drawing offset is the distance from the side of
-	 * a panel to the side of the view minus the padding.
-	 * Useful if you want to have your own panel below showing
-	 * the currently selected color and want to align it perfectly.
-	 * @return The offset in pixels.
-	 */
-	public float getDrawingOffset(){
-		return mDrawingOffset;
-	}
-
-	/**
-	 * Set if the user is allowed to adjust the alpha panel. Default is false.
-	 * If it is set to false no alpha will be set.
-	 * @param visible
-	 */
-	public void setAlphaSliderVisible(boolean visible){
-
-		if(mShowAlphaPanel != visible){
-			mShowAlphaPanel = visible;
+        setUpSatValRect();
+        setUpHueRect();
+        setUpAlphaRect();
+    }
+
+    private void setUpSatValRect() {
+
+        final RectF dRect = mDrawingRect;
+        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
+
+        if (mShowAlphaPanel) {
+            panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+        }
+
+        float left = dRect.left + BORDER_WIDTH_PX;
+        float top = dRect.top + BORDER_WIDTH_PX;
+        float bottom = top + panelSide;
+        float right = left + panelSide;
+
+        mSatValRect = new RectF(left, top, right, bottom);
+    }
+
+    private void setUpHueRect() {
+        final RectF dRect = mDrawingRect;
+
+        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
+        float top = dRect.top + BORDER_WIDTH_PX;
+        float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING
+                + ALPHA_PANEL_HEIGHT) : 0);
+        float right = dRect.right - BORDER_WIDTH_PX;
+
+        mHueRect = new RectF(left, top, right, bottom);
+    }
+
+    private void setUpAlphaRect() {
+
+        if (!mShowAlphaPanel) {
+            return;
+        }
+
+        final RectF dRect = mDrawingRect;
+
+        float left = dRect.left + BORDER_WIDTH_PX;
+        float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
+        float bottom = dRect.bottom - BORDER_WIDTH_PX;
+        float right = dRect.right - BORDER_WIDTH_PX;
+
+        mAlphaRect = new RectF(left, top, right, bottom);
+
+        mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
+        mAlphaPattern.setBounds(
+                Math.round(mAlphaRect.left),
+                Math.round(mAlphaRect.top),
+                Math.round(mAlphaRect.right),
+                Math.round(mAlphaRect.bottom)
+        );
+
+    }
+
+    /**
+     * Set a OnColorChangedListener to get notified when the color
+     * selected by the user has changed.
+     */
+    public void setOnColorChangedListener(OnColorChangedListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Get the color of the border surrounding all panels.
+     */
+    public int getBorderColor() {
+        return mBorderColor;
+    }
+
+    /**
+     * Set the color of the border surrounding all panels.
+     */
+    public void setBorderColor(int color) {
+        mBorderColor = color;
+        invalidate();
+    }
+
+    /**
+     * Get the current color this view is showing.
+     *
+     * @return the current color.
+     */
+    public int getColor() {
+        return Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal});
+    }
+
+    /**
+     * Set the color the view should show.
+     *
+     * @param color The color that should be selected.
+     */
+    public void setColor(int color) {
+        setColor(color, false);
+    }
+
+    /**
+     * Set the color this view should show.
+     *
+     * @param color    The color that should be selected.
+     * @param callback If you want to get a callback to
+     *                 your OnColorChangedListener.
+     */
+    public void setColor(int color, boolean callback) {
+
+        int alpha = Color.alpha(color);
+        int red = Color.red(color);
+        int blue = Color.blue(color);
+        int green = Color.green(color);
+
+        float[] hsv = new float[3];
+
+        Color.RGBToHSV(red, green, blue, hsv);
+
+        mAlpha = alpha;
+        mHue = hsv[0];
+        mSat = hsv[1];
+        mVal = hsv[2];
+
+        if (callback && mListener != null) {
+            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
+        }
+
+        invalidate();
+    }
+
+    /**
+     * Get the drawing offset of the color picker view.
+     * The drawing offset is the distance from the side of
+     * a panel to the side of the view minus the padding.
+     * Useful if you want to have your own panel below showing
+     * the currently selected color and want to align it perfectly.
+     *
+     * @return The offset in pixels.
+     */
+    public float getDrawingOffset() {
+        return mDrawingOffset;
+    }
+
+    /**
+     * Set if the user is allowed to adjust the alpha panel. Default is false.
+     * If it is set to false no alpha will be set.
+     */
+    public void setAlphaSliderVisible(boolean visible) {
+
+        if (mShowAlphaPanel != visible) {
+            mShowAlphaPanel = visible;
 
 			/*
-			 * Reset all shader to force a recreation.
+                         * Reset all shader to force a recreation.
 			 * Otherwise they will not look right after
 			 * the size of the view has changed.
 			 */
-			mValShader = null;
-			mSatShader = null;
-			mHueShader = null;
-			mAlphaShader = null;;
-
-			requestLayout();
-		}
-
-	}
-
-	public void setSliderTrackerColor(int color){
-		mSliderTrackerColor = color;
-
-		mHueTrackerPaint.setColor(mSliderTrackerColor);
-
-		invalidate();
-	}
-
-	public int getSliderTrackerColor(){
-		return mSliderTrackerColor;
-	}
-
-	/**
-	 * Set the text that should be shown in the
-	 * alpha slider. Set to null to disable text.
-	 * @param res string resource id.
-	 */
-	public void setAlphaSliderText(int res){
-		String text = getContext().getString(res);
-		setAlphaSliderText(text);
-	}
-
-	/**
-	 * Set the text that should be shown in the
-	 * alpha slider. Set to null to disable text.
-	 * @param text Text that should be shown.
-	 */
-	public void setAlphaSliderText(String text){
-		mAlphaSliderText = text;
-		invalidate();
-	}
-
-	/**
-	 * Get the current value of the text
-	 * that will be shown in the alpha
-	 * slider.
-	 * @return
-	 */
-	public String getAlphaSliderText(){
-		return mAlphaSliderText;
-	}
+            mValShader = null;
+            mSatShader = null;
+            mHueShader = null;
+            mAlphaShader = null;
+            ;
+
+            requestLayout();
+        }
+
+    }
+
+    public int getSliderTrackerColor() {
+        return mSliderTrackerColor;
+    }
+
+    public void setSliderTrackerColor(int color) {
+        mSliderTrackerColor = color;
+
+        mHueTrackerPaint.setColor(mSliderTrackerColor);
+
+        invalidate();
+    }
+
+    /**
+     * Set the text that should be shown in the
+     * alpha slider. Set to null to disable text.
+     *
+     * @param res string resource id.
+     */
+    public void setAlphaSliderText(int res) {
+        String text = getContext().getString(res);
+        setAlphaSliderText(text);
+    }
+
+    /**
+     * Get the current value of the text
+     * that will be shown in the alpha
+     * slider.
+     */
+    public String getAlphaSliderText() {
+        return mAlphaSliderText;
+    }
+
+    /**
+     * Set the text that should be shown in the
+     * alpha slider. Set to null to disable text.
+     *
+     * @param text Text that should be shown.
+     */
+    public void setAlphaSliderText(String text) {
+        mAlphaSliderText = text;
+        invalidate();
+    }
+
+    public interface OnColorChangedListener {
+
+        public void onColorChanged(int color);
+    }
 }
\ No newline at end of file
diff --git app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
index 5648b38..8fdaeb4 100644
--- app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
+++ app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -19,82 +19,87 @@ import javax.crypto.spec.SecretKeySpec;
  * ...
  * String cleartext = SimpleCrypto.decrypt(masterpassword, crypto)
  * </pre>
+ *
  * @author ferenc.hechler
  */
 public class SimpleCrypto {
 
-	public static String encrypt(String seed, String cleartext) throws Exception {
-		byte[] rawKey = getRawKey(seed.getBytes());
-		byte[] result = encrypt(rawKey, cleartext.getBytes());
-		return toHex(result);
-	}
-	
-	public static String decrypt(String seed, String encrypted) throws Exception {
-		byte[] rawKey = getRawKey(seed.getBytes());
-		byte[] enc = toByte(encrypted);
-		byte[] result = decrypt(rawKey, enc);
-		return new String(result);
-	}
-
-	private static byte[] getRawKey(byte[] seed) throws Exception {
-		KeyGenerator kgen = KeyGenerator.getInstance("AES");
-		SecureRandom sr;
-		if (android.os.Build.VERSION.SDK_INT >= 17) {
-			sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
-		} else {
-			sr = SecureRandom.getInstance("SHA1PRNG");
-		}
-		sr.setSeed(seed);
-	    kgen.init(128, sr); // 192 and 256 bits may not be available
-	    SecretKey skey = kgen.generateKey();
-	    byte[] raw = skey.getEncoded();
-	    return raw;
-	}
-
-	
-	private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
-	    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
-		Cipher cipher = Cipher.getInstance("AES");
-	    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
-	    byte[] encrypted = cipher.doFinal(clear);
-		return encrypted;
-	}
-
-	private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
-	    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
-		Cipher cipher = Cipher.getInstance("AES");
-	    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
-	    byte[] decrypted = cipher.doFinal(encrypted);
-		return decrypted;
-	}
-
-	public static String toHex(String txt) {
-		return toHex(txt.getBytes());
-	}
-	public static String fromHex(String hex) {
-		return new String(toByte(hex));
-	}
-	
-	public static byte[] toByte(String hexString) {
-		int len = hexString.length()/2;
-		byte[] result = new byte[len];
-		for (int i = 0; i < len; i++)
-			result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
-		return result;
-	}
-
-	public static String toHex(byte[] buf) {
-		if (buf == null)
-			return "";
-		StringBuffer result = new StringBuffer(2*buf.length);
-		for (int i = 0; i < buf.length; i++) {
-			appendHex(result, buf[i]);
-		}
-		return result.toString();
-	}
-	private final static String HEX = "0123456789ABCDEF";
-	private static void appendHex(StringBuffer sb, byte b) {
-		sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
-	}
-	
+    private final static String HEX = "0123456789ABCDEF";
+
+    public static String encrypt(String seed, String cleartext) throws Exception {
+        byte[] rawKey = getRawKey(seed.getBytes());
+        byte[] result = encrypt(rawKey, cleartext.getBytes());
+        return toHex(result);
+    }
+
+    public static String decrypt(String seed, String encrypted) throws Exception {
+        byte[] rawKey = getRawKey(seed.getBytes());
+        byte[] enc = toByte(encrypted);
+        byte[] result = decrypt(rawKey, enc);
+        return new String(result);
+    }
+
+    private static byte[] getRawKey(byte[] seed) throws Exception {
+        KeyGenerator kgen = KeyGenerator.getInstance("AES");
+        SecureRandom sr;
+        if (android.os.Build.VERSION.SDK_INT >= 17) {
+            sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
+        } else {
+            sr = SecureRandom.getInstance("SHA1PRNG");
+        }
+        sr.setSeed(seed);
+        kgen.init(128, sr); // 192 and 256 bits may not be available
+        SecretKey skey = kgen.generateKey();
+        byte[] raw = skey.getEncoded();
+        return raw;
+    }
+
+    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
+        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+        Cipher cipher = Cipher.getInstance("AES");
+        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
+        byte[] encrypted = cipher.doFinal(clear);
+        return encrypted;
+    }
+
+    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
+        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+        Cipher cipher = Cipher.getInstance("AES");
+        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
+        byte[] decrypted = cipher.doFinal(encrypted);
+        return decrypted;
+    }
+
+    public static String toHex(String txt) {
+        return toHex(txt.getBytes());
+    }
+
+    public static String fromHex(String hex) {
+        return new String(toByte(hex));
+    }
+
+    public static byte[] toByte(String hexString) {
+        int len = hexString.length() / 2;
+        byte[] result = new byte[len];
+        for (int i = 0; i < len; i++) {
+            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
+        }
+        return result;
+    }
+
+    public static String toHex(byte[] buf) {
+        if (buf == null) {
+            return "";
+        }
+        StringBuffer result = new StringBuffer(2 * buf.length);
+        for (int i = 0; i < buf.length; i++) {
+            appendHex(result, buf[i]);
+        }
+        return result.toString();
+    }
+
+    private static void appendHex(StringBuffer sb, byte b) {
+        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
+    }
+
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
index 6fdb08c..2435e76 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
@@ -16,14 +16,7 @@
 
 package com.liato.bankdroid;
 
-import java.lang.reflect.Method;
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
 
@@ -36,58 +29,68 @@ import android.os.Build;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-import com.liato.bankdroid.legacy.R;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
 
 public class Helpers {
-	private static String USER_AGENT;
-    private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD",
-        "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
-        "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
-        "BZD", "CAD", "CDF", "CHF", "CLP", "CNY", "COP", "CRC",
-        "CUP", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD",
-        "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP",
-        "GEL", "GGP", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
-        "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "IMP",
-        "INR", "IQD", "IRR", "ISK", "JEP", "JMD", "JOD", "JPY",
-        "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD",
-        "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL",
-        "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP",
-        "MRO", "MTL", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN",
-        "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB",
-        "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON",
-        "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK",
-        "SGD", "SHP", "SLL", "SOS", "SPL", "SRD", "STD", "SVC",
-        "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TOP", "TRY",
-        "TTD", "TVD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU",
-        "UZS", "VEB", "VEF", "VND", "VUV", "WST", "XAF", "XAG",
-        "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER",
-        "ZAR", "ZMK", "ZWD"};
+
+    private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS",
+            "AUD",
+            "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
+            "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
+            "BZD", "CAD", "CDF", "CHF", "CLP", "CNY", "COP", "CRC",
+            "CUP", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD",
+            "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP",
+            "GEL", "GGP", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
+            "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "IMP",
+            "INR", "IQD", "IRR", "ISK", "JEP", "JMD", "JOD", "JPY",
+            "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD",
+            "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL",
+            "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP",
+            "MRO", "MTL", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN",
+            "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB",
+            "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON",
+            "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK",
+            "SGD", "SHP", "SLL", "SOS", "SPL", "SRD", "STD", "SVC",
+            "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TOP", "TRY",
+            "TTD", "TVD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU",
+            "UZS", "VEB", "VEF", "VND", "VUV", "WST", "XAF", "XAG",
+            "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER",
+            "ZAR", "ZMK", "ZWD"};
 
     private final static String[][] symMappings = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"},
-        {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"},
-        {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"},
-        {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"},
-        {"Bs", "VEF"}, {"Ft", "HUF"}, {"Gs", "PYG"},
-        {"KM", "BAM"}, {"Kč", "CZK"}, {"Lek", "ALL"},
-        {"S/.", "PEN"}, {"Ls", "LVL"}, {"Lt", "LTL"},
-        {"MT", "MZN"}, {"Php", "PHP"}, {"RM", "MYR"},
-        {"Rp", "IDR"}, {"TL", "TRY"}, {"kn", "HRK"},
-        {"kr", "SEK"}, {"lei", "RON"}, {"p.", "BYR"},
-        {"L", "HNL"}, {"S", "SOS"}, {"P", "BWP"},
-        {"Q", "GTQ"}, {"R", "ZAR"}, {"zł", "PLN"},
-        {"¢", "GHC"}, {"£", "GBP"}, {"¥", "JPY"},
-        {"ƒ", "ANG"}, {"Дин.", "RSD"}, {"ден", "MKD"},
-        {"лв", "BGN"}, {"ман", "AZN"}, {"руб", "RUB"},
-        {"؋", "AFN"}, {"฿", "THB"}, {"៛", "KHR"},
-        {"₡", "CRC"}, {"₤", "TRL"}, {"₦", "NGN"},
-        {"₨", "PKR"}, {"₩", "KRW"}, {"₪", "ILS"},
-        {"₫", "VND"}, {"€", "EUR"}, {"₭", "LAK"},
-        {"₮", "MNT"}, {"₱", "CUP"}, {"₴", "UAH"},
-        {"﷼", "SAR"}, 
-    }; 
-    
+            {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"},
+            {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"},
+            {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"},
+            {"Bs", "VEF"}, {"Ft", "HUF"}, {"Gs", "PYG"},
+            {"KM", "BAM"}, {"Kč", "CZK"}, {"Lek", "ALL"},
+            {"S/.", "PEN"}, {"Ls", "LVL"}, {"Lt", "LTL"},
+            {"MT", "MZN"}, {"Php", "PHP"}, {"RM", "MYR"},
+            {"Rp", "IDR"}, {"TL", "TRY"}, {"kn", "HRK"},
+            {"kr", "SEK"}, {"lei", "RON"}, {"p.", "BYR"},
+            {"L", "HNL"}, {"S", "SOS"}, {"P", "BWP"},
+            {"Q", "GTQ"}, {"R", "ZAR"}, {"zł", "PLN"},
+            {"¢", "GHC"}, {"£", "GBP"}, {"¥", "JPY"},
+            {"ƒ", "ANG"}, {"Дин.", "RSD"}, {"ден", "MKD"},
+            {"лв", "BGN"}, {"ман", "AZN"}, {"руб", "RUB"},
+            {"؋", "AFN"}, {"฿", "THB"}, {"៛", "KHR"},
+            {"₡", "CRC"}, {"₤", "TRL"}, {"₦", "NGN"},
+            {"₨", "PKR"}, {"₩", "KRW"}, {"₪", "ILS"},
+            {"₫", "VND"}, {"€", "EUR"}, {"₭", "LAK"},
+            {"₮", "MNT"}, {"₱", "CUP"}, {"₴", "UAH"},
+            {"﷼", "SAR"},
+    };
+
     private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
+    private static String USER_AGENT;
+
     public static BigDecimal parseBalance(String balance) {
         if (balance == null) {
             return new BigDecimal(0);
@@ -98,44 +101,47 @@ public class Helpers {
             String b = balance.substring(balance.lastIndexOf("."));
             balance = balance.substring(0, balance.lastIndexOf("."));
             balance = balance.replace(".", "");
-            balance = balance+b;
+            balance = balance + b;
         }
         BigDecimal ret;
         try {
             ret = new BigDecimal(balance);
-        }
-        catch (NumberFormatException e) {
-            Log.e("parseBalance", "Unable to parse: "+balance);
+        } catch (NumberFormatException e) {
+            Log.e("parseBalance", "Unable to parse: " + balance);
             ret = new BigDecimal(0);
         }
         return ret;
     }
-    public static String formatBalance(BigDecimal balance, String curr, boolean round, DecimalFormat format) {
+
+    public static String formatBalance(BigDecimal balance, String curr, boolean round,
+            DecimalFormat format) {
         DecimalFormatSymbols dfs = new DecimalFormatSymbols();
         dfs.setDecimalSeparator(',');
         dfs.setGroupingSeparator(' ');
         DecimalFormat currency = format;
         if (currency == null) {
-	        if (!round) {
-	            currency = new DecimalFormat("#,##0.00 ");
-	        }
-	        else {
-	            currency = new DecimalFormat("#,##0 ");  
-	        }
+            if (!round) {
+                currency = new DecimalFormat("#,##0.00 ");
+            } else {
+                currency = new DecimalFormat("#,##0 ");
+            }
         }
         currency.setDecimalFormatSymbols(dfs);
-        return currency.format(balance.doubleValue())+curr;
+        return currency.format(balance.doubleValue()) + curr;
     }
+
     public static String formatBalance(BigDecimal balance, String curr) {
         return formatBalance(balance, curr, false, null);
     }
+
     public static String formatBalance(Double balance, String curr) {
         return formatBalance(new BigDecimal(balance), curr);
     }
 
     static public void setActivityAnimation(Activity activity, int in, int out) {
         try {
-            Method method = Activity.class.getMethod("overridePendingTransition", new Class[]{int.class, int.class});
+            Method method = Activity.class
+                    .getMethod("overridePendingTransition", new Class[]{int.class, int.class});
             method.invoke(activity, in, out);
         } catch (Exception e) {
             // Can't change animation, so do nothing
@@ -145,41 +151,45 @@ public class Helpers {
     public static String parseCurrency(String text, String def) {
         text = text != null ? text.toLowerCase() : "";
         for (String currency : currencies) {
-            if (text.contains(currency)) return currency;
+            if (text.contains(currency)) {
+                return currency;
+            }
         }
         for (String[] symCur : symMappings) {
-            if (text.contains(symCur[0])) return symCur[1];
+            if (text.contains(symCur[0])) {
+                return symCur[1];
+            }
         }
         return def;
     }
-    
-    public static String renderForm(String action, List <NameValuePair> postData) {
+
+    public static String renderForm(String action, List<NameValuePair> postData) {
         StringBuilder form = new StringBuilder();
         form.append("<form id=\"submitform\" method=\"POST\" action=\"")
-        .append(action)
-        .append("\">");
+                .append(action)
+                .append("\">");
         for (NameValuePair p : postData) {
             form.append("<input type=\"hidden\" name=\"")
-            .append(p.getName())
-            .append("\" value=\"")
-            .append(p.getValue())
-            .append("\" />");
+                    .append(p.getName())
+                    .append("\" value=\"")
+                    .append(p.getValue())
+                    .append("\" />");
         }
         form.append("</form>");
         return form.toString();
-        
+
     }
-    
+
 
     /**
      * Determines what year a transaction belongs to.
-     * 
+     *
      * If the given <code>day</code> of the given <code>month</code> for the current year
      * is in the future the transaction is probably from last year.
-     * 
-     * @param month     The month, where January is 1.
-     * @param day       The day of the month, starting from 1.
-     * @return          An ISO 8601 formatted date.
+     *
+     * @param month The month, where January is 1.
+     * @param day   The day of the month, starting from 1.
+     * @return An ISO 8601 formatted date.
      */
     public static String getTransactionDate(String month, String day) {
         return getTransactionDate(Integer.parseInt(month), Integer.parseInt(day));
@@ -187,18 +197,18 @@ public class Helpers {
 
     /**
      * Determines what year a transaction belongs to.
-     * 
+     *
      * If the given <code>day</code> of the given <code>month</code> for the current year
      * is in the future the transaction is probably from last year.
-     * 
-     * @param month     The month, where January is 1.
-     * @param day       The day of the month, starting from 1.
-     * @return          An ISO 8601 formatted date.
+     *
+     * @param month The month, where January is 1.
+     * @param day   The day of the month, starting from 1.
+     * @return An ISO 8601 formatted date.
      */
     public static String getTransactionDate(int month, int day) {
         month--; // Java-months start at 0
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        Calendar cal = Calendar.getInstance(); 
+        Calendar cal = Calendar.getInstance();
         int currentYear = cal.get(Calendar.YEAR);
         cal.set(currentYear, month, day, 0, 0);
         if (cal.getTime().after(Calendar.getInstance().getTime())) {
@@ -207,30 +217,32 @@ public class Helpers {
         }
         return sdf.format(cal.getTime());
     }
-    
+
     /**
      * Remove HTML from a string.
-     * 
-     * @param text      The string containing HTML.
-     * @return          The same string with all HTML removed.
+     *
+     * @param text The string containing HTML.
+     * @return The same string with all HTML removed.
      */
     public static String removeHtml(String text) {
         return text.replaceAll("<[^>]+>", "");
     }
-    
+
     public static String formatDate(Date date) {
-    	return DATE_FORMAT.format(date);
+        return DATE_FORMAT.format(date);
     }
-    
+
     public static String getAppUserAgentString(Context context) {
-    	if (USER_AGENT != null) return USER_AGENT;
+        if (USER_AGENT != null) {
+            return USER_AGENT;
+        }
         String appName = context.getResources().getString(R.string.app_name);
         String appVersion = "";
         int height = 0;
         int width = 0;
         DisplayMetrics display = context.getResources().getDisplayMetrics();
         Configuration config = context.getResources().getConfiguration();
- 
+
         // Always send screen dimension for portrait mode
         if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
             height = display.widthPixels;
@@ -239,29 +251,31 @@ public class Helpers {
             width = display.widthPixels;
             height = display.heightPixels;
         }
- 
+
         try {
-            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_CONFIGURATIONS);
+            PackageInfo packageInfo = context.getPackageManager()
+                    .getPackageInfo(context.getPackageName(), PackageManager.GET_CONFIGURATIONS);
             appVersion = packageInfo.versionName;
         } catch (PackageManager.NameNotFoundException ignore) {
             // this should never happen, we are looking up ourself
         }
- 
+
         // Tries to conform to default android UA string without the Safari / webkit noise, plus adds the screen dimensions
-        USER_AGENT = String.format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %12$s Build/%7$s; %8$s) %9$dX%10$d %11$s %12$s"
-            , appName
-            , appVersion
-            , System.getProperty("os.name", "Linux")
-            , Build.VERSION.RELEASE
-            , config.locale.getLanguage().toLowerCase()
-            , config.locale.getCountry().toLowerCase()
-            , Build.ID
-            , Build.BRAND
-            , width
-            , height
-            , Build.MANUFACTURER
-            , Build.MODEL);
+        USER_AGENT = String
+                .format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %12$s Build/%7$s; %8$s) %9$dX%10$d %11$s %12$s"
+                        , appName
+                        , appVersion
+                        , System.getProperty("os.name", "Linux")
+                        , Build.VERSION.RELEASE
+                        , config.locale.getLanguage().toLowerCase()
+                        , config.locale.getCountry().toLowerCase()
+                        , Build.ID
+                        , Build.BRAND
+                        , width
+                        , height
+                        , Build.MANUFACTURER
+                        , Build.MODEL);
         return USER_AGENT;
-    }    
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
index d65072f..0b47ef7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
@@ -16,141 +16,152 @@
 
 package com.liato.bankdroid.banking;
 
+import com.liato.bankdroid.provider.IAccountTypes;
+
 import java.math.BigDecimal;
 import java.util.List;
 
-import com.liato.bankdroid.provider.IAccountTypes;
-
 public class Account implements IAccountTypes {
-	private String name;
-	private BigDecimal balance;
-	private String id;
-	private Bank bank = null;
-	private long bankId = -1;
-	private int type = Account.REGULAR;
-	private boolean hidden = false;
-	private boolean notify = true;
-	private String currency;
-	private List<Transaction> transactions;
-	private String aliasfor;
-
-	public List<Transaction> getTransactions() {
-		return transactions;
-	}
-
-	public void setTransactions(final List<Transaction> transactions) {
-		this.transactions = transactions;
-	}
-
-	public Account(final String name, final BigDecimal balance,
-			final String id, final long bankId, final int type,
-			final String currency) {
-		this.name = name;
-		this.balance = balance;
-		this.id = id;
-		this.bankId = bankId;
-		this.type = type;
-		this.currency = currency;
-	}
-
-	public Account(final String name, final BigDecimal balance,
-			final String id, final long bankId) {
-		this(name, balance, id, bankId, REGULAR, "SEK");
-	}
-
-	public Account(final String name, final BigDecimal balance,
-			final String id, final long bankId, final int type) {
-		this(name, balance, id, bankId, type, "SEK");
-	}
-
-	public Account(final String name, final BigDecimal balance, final String id) {
-		this(name, balance, id, -1L);
-	}
-
-	public Account(final String name, final BigDecimal balance,
-			final String id, final int type) {
-		this(name, balance, id, -1L, type);
-	}
-
-	public Account(final String name, final BigDecimal balance,
-			final String id, final int type, final String currency) {
-		this(name, balance, id, -1L, type, currency);
-	}
-
-	public boolean isNotify() {
-		return notify;
-	}
-
-	public void setNotify(final boolean notify) {
-		this.notify = notify;
-	}
-
-	public void setBalance(final BigDecimal balance) {
-		this.balance = balance;
-	}
-
-	public BigDecimal getBalance() {
-		return balance;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(final String name) {
-		this.name = name;
-	}
-
-	public String getId() {
-		return id;
-	}
-	
-	public void setId(String id) {
-	    this.id = id;
-	}
-
-	public Bank getBank() {
-		return bank;
-	}
-
-	public void setBank(final Bank bank) {
-		this.bank = bank;
-	}
-
-	public long getBankDbId() {
-		return bankId;
-	}
-
-	public void setType(final int type) {
-		this.type = type;
-	}
-
-	public int getType() {
-		return type;
-	}
-
-	public boolean isHidden() {
-		return this.hidden;
-	}
-
-	public void setHidden(final boolean hidden) {
-		this.hidden = hidden;
-	}
-
-	public String getCurrency() {
-		return currency;
-	}
-
-	public void setCurrency(final String currency) {
-		this.currency = currency;
-	}
-	
+
+    private String name;
+
+    private BigDecimal balance;
+
+    private String id;
+
+    private Bank bank = null;
+
+    private long bankId = -1;
+
+    private int type = Account.REGULAR;
+
+    private boolean hidden = false;
+
+    private boolean notify = true;
+
+    private String currency;
+
+    private List<Transaction> transactions;
+
+    private String aliasfor;
+
+    public Account(final String name, final BigDecimal balance,
+            final String id, final long bankId, final int type,
+            final String currency) {
+        this.name = name;
+        this.balance = balance;
+        this.id = id;
+        this.bankId = bankId;
+        this.type = type;
+        this.currency = currency;
+    }
+
+    public Account(final String name, final BigDecimal balance,
+            final String id, final long bankId) {
+        this(name, balance, id, bankId, REGULAR, "SEK");
+    }
+
+    public Account(final String name, final BigDecimal balance,
+            final String id, final long bankId, final int type) {
+        this(name, balance, id, bankId, type, "SEK");
+    }
+
+    public Account(final String name, final BigDecimal balance, final String id) {
+        this(name, balance, id, -1L);
+    }
+
+    public Account(final String name, final BigDecimal balance,
+            final String id, final int type) {
+        this(name, balance, id, -1L, type);
+    }
+
+    public Account(final String name, final BigDecimal balance,
+            final String id, final int type, final String currency) {
+        this(name, balance, id, -1L, type, currency);
+    }
+
+    public List<Transaction> getTransactions() {
+        return transactions;
+    }
+
+    public void setTransactions(final List<Transaction> transactions) {
+        this.transactions = transactions;
+    }
+
+    public boolean isNotify() {
+        return notify;
+    }
+
+    public void setNotify(final boolean notify) {
+        this.notify = notify;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public void setBalance(final BigDecimal balance) {
+        this.balance = balance;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Bank getBank() {
+        return bank;
+    }
+
+    public void setBank(final Bank bank) {
+        this.bank = bank;
+    }
+
+    public long getBankDbId() {
+        return bankId;
+    }
+
+    public int getType() {
+        return type;
+    }
+
+    public void setType(final int type) {
+        this.type = type;
+    }
+
+    public boolean isHidden() {
+        return this.hidden;
+    }
+
+    public void setHidden(final boolean hidden) {
+        this.hidden = hidden;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(final String currency) {
+        this.currency = currency;
+    }
+
     public String getAliasfor() {
         return aliasfor;
     }
 
     public void setAliasfor(final String aliasfor) {
         this.aliasfor = aliasfor;
-    }	
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index f3bfed5..4350fc4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -16,12 +16,12 @@
 
 package com.liato.bankdroid.banking;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.http.NameValuePair;
@@ -34,54 +34,96 @@ import android.content.res.Resources.NotFoundException;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class Bank implements Comparable<Bank>, IBankTypes {
+
     protected String TAG = "Bank";
-	protected String NAME = "Bank";
-	protected String NAME_SHORT = "bank";
-	protected int BANKTYPE_ID = 0;
-	protected String URL;
+
+    protected String NAME = "Bank";
+
+    protected String NAME_SHORT = "bank";
+
+    protected int BANKTYPE_ID = 0;
+
+    protected String URL;
+
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-    protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+
+    protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT
+            | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+
     protected int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT;
+
     protected String INPUT_HINT_USERNAME = null;
+
     protected boolean INPUT_HIDDEN_USERNAME = false;
+
     protected boolean INPUT_HIDDEN_PASSWORD = false;
+
     protected boolean INPUT_HIDDEN_EXTRAS = true;
+
     protected int INPUT_TITLETEXT_USERNAME = R.string.username;
+
     protected int INPUT_TITLETEXT_PASSWORD = R.string.password;
+
     protected int INPUT_TITLETEXT_EXTRAS = R.string.extras_field;
+
     protected boolean STATIC_BALANCE = false;
+
     protected boolean BROKEN = false;
+
     protected boolean DISPLAY_DECIMALS = true;
+
     protected boolean WEB_VIEW_ENABLED = true;
+
     protected Context context;
+
     protected Resources res;
 
     protected String username;
+
     protected String password;
+
     protected String customName;
+
     protected String extras;
+
     protected String currency = "SEK";
+
     protected ArrayList<Account> accounts = new ArrayList<Account>();
+
     protected HashMap<String, Account> oldAccounts;
+
     protected BigDecimal balance = new BigDecimal(0);
+
     protected boolean disabled = false;
+
     protected long dbid = -1;
+
     protected Urllib urlopen = null;
+
     protected boolean hideAccounts = false;
 
-    public boolean toggleHideAccounts() { return hideAccounts = !hideAccounts; }
+    public Bank(Context context) {
+        this.context = context;
+        this.res = this.context.getResources();
+    }
+
+    public boolean toggleHideAccounts() {
+        return hideAccounts = !hideAccounts;
+    }
 
-    public boolean getHideAccounts() { return hideAccounts; }
+    public boolean getHideAccounts() {
+        return hideAccounts;
+    }
 
     public Urllib getUrlopen() {
         return urlopen;
@@ -95,11 +137,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.dbid = dbid;
     }
 
-    public Bank(Context context) {
-        this.context = context;
-        this.res = this.context.getResources();
-    }
-
     public void update(String username, String password) throws BankException, LoginException,
             BankChoiceException, IOException {
         this.username = username;
@@ -110,7 +147,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         balance = new BigDecimal(0);
         oldAccounts = new HashMap<String, Account>();
-        for(Account account: accounts) {
+        for (Account account : accounts) {
             oldAccounts.put(account.getId(), account);
         }
         accounts = new ArrayList<Account>();
@@ -124,7 +161,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         if (urlopen == null) {
             urlopen = login();
         }
-        for (Account account: accounts) {
+        for (Account account : accounts) {
             updateTransactions(account, urlopen);
         }
     }
@@ -138,6 +175,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             urlopen.close();
         }
     }
+
     public ArrayList<Account> getAccounts() {
         return this.accounts;
     }
@@ -153,19 +191,28 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return password;
     }
 
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
     public String getUsername() {
         return username;
     }
 
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
     public BigDecimal getBalance() {
         if (STATIC_BALANCE) {
             return balance;
-        }
-        else {
-            BigDecimal bal = new BigDecimal(0); 
+        } else {
+            BigDecimal bal = new BigDecimal(0);
             for (Account account : accounts) {
                 if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
-                    if (!account.isHidden() && (account.getAliasfor() == null || account.getAliasfor().length() == 0) && account.getBalance() != null) {
+                    if (!account.isHidden() && (account.getAliasfor() == null
+                            || account.getAliasfor().length() == 0)
+                            && account.getBalance() != null) {
                         bal = bal.add(account.getBalance());
                     }
                 }
@@ -183,11 +230,12 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public String getDisplayName() {
-        if (customName != null && customName.length() > 0) return customName;
+        if (customName != null && customName.length() > 0) {
+            return customName;
+        }
         return username;
     }
 
-
     public String getCustomName() {
         return customName;
     }
@@ -195,21 +243,22 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public void setCustomName(String customName) {
         this.customName = customName;
     }
-    
+
     public String getExtras() {
         return this.extras;
     }
 
     public void setExtras(String extras) {
         this.extras = extras;
-    }    
+    }
 
     public String getShortName() {
         return NAME_SHORT;
     }
 
     public void setData(String username, String password, BigDecimal balance,
-            boolean disabled, long dbid, String currency, String customName, String extras, int hideAccounts) {
+            boolean disabled, long dbid, String currency, String customName, String extras,
+            int hideAccounts) {
         this.username = username;
         this.password = password;
         this.balance = balance;
@@ -218,7 +267,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.currency = currency;
         this.customName = customName;
         this.extras = extras;
-        this.hideAccounts = hideAccounts==1 ? true : false;
+        this.hideAccounts = hideAccounts == 1 ? true : false;
     }
 
     public String getCurrency() {
@@ -237,20 +286,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return disabled;
     }
 
-
     public void setDisabled(boolean disabled) {
         this.disabled = disabled;
     }
 
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
     public String getURL() {
         return URL;
     }
@@ -266,7 +305,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public int getInputTypeExtras() {
         return INPUT_TYPE_EXTRAS;
     }
-    
+
     public String getInputHintUsername() {
         return INPUT_HINT_USERNAME;
     }
@@ -278,10 +317,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public boolean isInputPasswordHidden() {
         return INPUT_HIDDEN_PASSWORD;
     }
-    
+
     public boolean isInputExtrasHidden() {
         return INPUT_HIDDEN_EXTRAS;
-    }    
+    }
 
     public int getInputTitleUsername() {
         return INPUT_TITLETEXT_USERNAME;
@@ -305,7 +344,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public int getImageResource() {
-        return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
+        return res.getIdentifier("logo_" + NAME_SHORT, "drawable", context.getPackageName());
     }
 
     public int compareTo(Bank another) {
@@ -331,12 +370,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         String preloader = "Error...";
         try {
             preloader = IOUtils.toString(context.getResources().openRawResource(R.raw.loading));
-        }
-        catch (NotFoundException e1) {
+        } catch (NotFoundException e1) {
             // TODO Auto-generated catch block
             e1.printStackTrace();
-        }
-        catch (IOException e1) {
+        } catch (IOException e1) {
             // TODO Auto-generated catch block
             e1.printStackTrace();
         }
@@ -344,39 +381,42 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         try {
             LoginPackage lp = preLogin();
             if (lp == null) {
-                throw new BankException("No automatic login for this bank. preLogin() is not implemented or has failed.");
+                throw new BankException(
+                        "No automatic login for this bank. preLogin() is not implemented or has failed.");
             }
             //TODO: Skip the form submission. Login using Bank.login(...) and transfer cookies to webview. The user is now logged in
             //      and can me directed to any page.
             String html = "";
             if (!lp.isLoggedIn()) {
                 html = String.format(preloader,
-                        "function go(){document.getElementById('submitform').submit(); }", // Javascript function
-                        Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
+                        "function go(){document.getElementById('submitform').submit(); }",
+                        // Javascript function
+                        Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())
+                                + "<script type=\"text/javascript\">setTimeout('go()', 1000);</script>"
+                        // HTML
                 );
             } else {
                 html = String.format(preloader,
-                        String.format("function go(){window.location=\"%s\" }", lp.getLoginTarget()), // Javascript function
+                        String.format("function go(){window.location=\"%s\" }",
+                                lp.getLoginTarget()), // Javascript function
                         "<script type=\"text/javascript\">setTimeout('go()', 100);</script>" // HTML
                 );
             }
 
             CookieStore cookies = urlopen.getHttpclient().getCookieStore();
             return new SessionPackage(html, cookies);
-        }
-        catch (ClientProtocolException e) {
+        } catch (ClientProtocolException e) {
             Log.e(TAG, e.getMessage());
-        }
-        catch (IOException e) {
+        } catch (IOException e) {
             Log.e(TAG, e.getMessage());
-        }
-        catch (BankException e) {
+        } catch (BankException e) {
             Log.e(TAG, e.getMessage());
         }
         String html = String.format(preloader,
-                String.format("function go(){window.location=\"%s\" }", this.URL), // Javascript function
+                String.format("function go(){window.location=\"%s\" }", this.URL),
+                // Javascript function
                 "<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
-        );          
+        );
         return new SessionPackage(html, null);
     }
 
@@ -384,28 +424,52 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return null;
     }
 
+    public boolean getDisplayDecimals() {
+        return DISPLAY_DECIMALS;
+    }
+
+    protected Context getContext() {
+        return context;
+    }
+
+    public DecimalFormat getDecimalFormatter() {
+        return null;
+    }
+
     public static class SessionPackage {
+
         private String html;
+
         private CookieStore cookiestore;
+
         public SessionPackage(String html, CookieStore cookiestore) {
             this.html = html;
             this.cookiestore = cookiestore;
         }
+
         public String getHtml() {
             return html;
         }
+
         public CookieStore getCookiestore() {
             return cookiestore;
         }
-    }    
+    }
 
     public static class LoginPackage {
+
         private String response;
+
         private Urllib urllib;
+
         private List<NameValuePair> postData;
+
         private String loginTarget;
+
         private boolean isLoggedIn = false;
-        public LoginPackage(Urllib urllib, List<NameValuePair> postData, String response, String loginTarget) {
+
+        public LoginPackage(Urllib urllib, List<NameValuePair> postData, String response,
+                String loginTarget) {
             this.urllib = urllib;
             this.postData = postData;
             this.response = response;
@@ -415,33 +479,26 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         public void setIsLoggedIn(boolean loggedIn) {
             this.isLoggedIn = loggedIn;
         }
+
         public String getResponse() {
             return response;
         }
+
         public Urllib getUrllib() {
             return urllib;
         }
+
         public List<NameValuePair> getPostData() {
             return postData;
         }
+
         public String getLoginTarget() {
             return loginTarget;
         }
+
         public boolean isLoggedIn() {
             return this.isLoggedIn;
         }
-    }    
-    
-    public boolean getDisplayDecimals() {
-        return DISPLAY_DECIMALS;
-    }
-    
-    protected Context getContext() {
-    	return context;
-    }
-    
-    public DecimalFormat getDecimalFormatter() {
-    	return null;
     }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankChoice.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankChoice.java
index e3ac614..166619f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankChoice.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankChoice.java
@@ -17,30 +17,37 @@
 package com.liato.bankdroid.banking;
 
 public class BankChoice {
+
     private String name;
+
     private String id;
-	public BankChoice(String name, String id) {
-		this.name = name;
-		this.id = id;
-	}
+
+    public BankChoice(String name, String id) {
+        this.name = name;
+        this.id = id;
+    }
+
     /**
      * @return the name
      */
     public String getName() {
         return name;
     }
+
     /**
      * @param name the name to set
      */
     public void setName(String name) {
         this.name = name;
     }
+
     /**
      * @return the id
      */
     public String getId() {
         return id;
     }
+
     /**
      * @param id the id to set
      */
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 4c6d61e..e98332d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -1,9 +1,5 @@
 package com.liato.bankdroid.banking;
 
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
@@ -13,8 +9,8 @@ import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
-import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.Bredband2VoIP;
+import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.DanskeBank;
@@ -77,6 +73,10 @@ import com.liato.bankdroid.banking.banks.swedbank.SwedbankYouth;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
 import java.util.ArrayList;
 
 public class LegacyBankFactory {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
index f87f167..f9fcbf7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
@@ -19,47 +19,51 @@ package com.liato.bankdroid.banking;
 import java.math.BigDecimal;
 
 public class Transaction implements Comparable<Transaction> {
-	private String date;
-	private String transaction;
-	private BigDecimal amount;
-	private String currency;
-	
-	public Transaction(String date, String transaction, BigDecimal amount, String currency) {
-		this.date = date;
-		this.transaction = transaction;
-		this.amount = amount;
-		this.currency = currency;
-	}
+
+    private String date;
+
+    private String transaction;
+
+    private BigDecimal amount;
+
+    private String currency;
+
+    public Transaction(String date, String transaction, BigDecimal amount, String currency) {
+        this.date = date;
+        this.transaction = transaction;
+        this.amount = amount;
+        this.currency = currency;
+    }
 
     public Transaction(String date, String transaction, BigDecimal amount) {
         this(date, transaction, amount, "SEK");
-    }	
+    }
 
-	public String getDate() {
-		return date;
-	}
+    public String getDate() {
+        return date;
+    }
 
-	public void setDate(String date) {
-		this.date = date;
-	}
+    public void setDate(String date) {
+        this.date = date;
+    }
 
-	public String getTransaction() {
-		return transaction;
-	}
+    public String getTransaction() {
+        return transaction;
+    }
 
-	public void setTransaction(String transaction) {
-		this.transaction = transaction;
-	}
+    public void setTransaction(String transaction) {
+        this.transaction = transaction;
+    }
 
-	public BigDecimal getAmount() {
-		return amount;
-	}
+    public BigDecimal getAmount() {
+        return amount;
+    }
 
-	public void setAmount(BigDecimal amount) {
-		this.amount = amount;
-	}
+    public void setAmount(BigDecimal amount) {
+        this.amount = amount;
+    }
 
-	public String getCurrency() {
+    public String getCurrency() {
         return currency;
     }
 
@@ -68,13 +72,13 @@ public class Transaction implements Comparable<Transaction> {
     }
 
     @Override
-	public int compareTo(Transaction another) {
-		try {
+    public int compareTo(Transaction another) {
+        try {
             Integer thisdate = Integer.parseInt(date.replaceAll("-", ""));
             Integer thatdate = Integer.parseInt((another).getDate().replaceAll("-", ""));
             return thatdate - thisdate;
-        } catch(NumberFormatException e) {
+        } catch (NumberFormatException e) {
             return 0;
         }
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index d2653ec..bc7a65c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -16,12 +16,16 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -32,26 +36,25 @@ import android.content.Context;
 import android.text.InputType;
 import android.text.TextUtils;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.legacy.R;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class AbsIkanoPartner extends Bank {
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
 
-    private String response = null;
     protected String structId;
 
+    private String response = null;
+
     public AbsIkanoPartner(Context context) {
         super(context);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
@@ -60,7 +63,8 @@ public abstract class AbsIkanoPartner extends Bank {
         super.STATIC_BALANCE = true;
     }
 
-    public AbsIkanoPartner(String username, String password, Context context) throws BankException, LoginException,
+    public AbsIkanoPartner(String username, String password, Context context)
+            throws BankException, LoginException,
             BankChoiceException, IOException {
         this(context);
         this.update(username, password);
@@ -68,18 +72,22 @@ public abstract class AbsIkanoPartner extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
-        response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
+        response = urlopen
+                .open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
 
         Document d = Jsoup.parse(response);
         Element viewstate = d.getElementById("__VIEWSTATE");
         if (viewstate == null || TextUtils.isEmpty(viewstate.val())) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
 
         Element eventvalidation = d.getElementById("__EVENTVALIDATION");
         if (eventvalidation == null || TextUtils.isEmpty(eventvalidation.val())) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
 
         Element userField = d.select("#LoginSpan input[type=text]").first();
@@ -87,7 +95,8 @@ public abstract class AbsIkanoPartner extends Bank {
         Element submitField = d.select("#LoginCustomerDiv input[type=submit]").first();
 
         if (userField == null || passField == null || submitField == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " login fields.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login fields.");
         }
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewstate.val()));
@@ -95,7 +104,8 @@ public abstract class AbsIkanoPartner extends Bank {
         postData.add(new BasicNameValuePair(userField.attr("name"), username));
         postData.add(new BasicNameValuePair(passField.attr("name"), password));
         postData.add(new BasicNameValuePair(submitField.attr("name"), submitField.val()));
-        return new LoginPackage(urlopen, postData, response, "https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+        return new LoginPackage(urlopen, postData, response,
+                "https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
 
     }
 
@@ -103,18 +113,20 @@ public abstract class AbsIkanoPartner extends Bank {
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
-                    || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")
-                    || response.contains("elaktig självbetjäningskod")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
+        if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
+                || response.contains("ontrollera personnummer") || response
+                .contains("elaktig inloggningskod")
+                || response.contains("elaktig självbetjäningskod")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
         return urlopen;
     }
 
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -133,7 +145,8 @@ public abstract class AbsIkanoPartner extends Bank {
                 Element currency = el.select("> span:eq(2)").first();
                 Element balance = el.select("> span:eq(1)").first();
                 if (name != null && balance != null && currency != null) {
-                    Account account = new Account(name.text().trim(), Helpers.parseBalance(balance.text()),
+                    Account account = new Account(name.text().trim(),
+                            Helpers.parseBalance(balance.text()),
                             Integer.toString(accId));
                     account.setCurrency(Helpers.parseCurrency(currency.text(), "SEK"));
                     if (accId > 0) {
@@ -153,9 +166,11 @@ public abstract class AbsIkanoPartner extends Bank {
             es = d.select("#ShowCustomerTransactionPurchasesInformationDiv table tr:has(td)");
             for (Element el : es) {
                 if (el.childNodeSize() == 6) {
-                    Transaction transaction = new Transaction(el.child(0).text().trim(), el.child(1).text().trim(),
+                    Transaction transaction = new Transaction(el.child(0).text().trim(),
+                            el.child(1).text().trim(),
                             Helpers.parseBalance(el.child(2).text()));
-                    transaction.setCurrency(Helpers.parseCurrency(el.child(3).text().trim(), "SEK"));
+                    transaction
+                            .setCurrency(Helpers.parseCurrency(el.child(3).text().trim(), "SEK"));
                     transactions.add(transaction);
                 }
             }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 060a3f6..9c1c784 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -15,22 +15,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -41,100 +25,135 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AkeliusInvest extends Bank {
-	private static final String TAG = "AkeliusInvest";
-	private static final String NAME = "Akelius Invest";
-	private static final String NAME_SHORT = "akeliusinvest";
-	private static final String URL = "https://online.akeliusinvest.com/";
-	private static final int BANKTYPE_ID = IBankTypes.AKELIUSINVEST;
+
+    private static final String TAG = "AkeliusInvest";
+
+    private static final String NAME = "Akelius Invest";
+
+    private static final String NAME_SHORT = "akeliusinvest";
+
+    private static final String URL = "https://online.akeliusinvest.com/";
+
+    private static final int BANKTYPE_ID = IBankTypes.AKELIUSINVEST;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "XXXXXXX";
+
     private static final boolean STATIC_BALANCE = true;
 
-	private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
-	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+><a[^?]+\\?selectedaccount=([^\"]+)\">([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
+
+    private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reAccounts = Pattern.compile(
+            "<tr>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+><a[^?]+\\?selectedaccount=([^\"]+)\">([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    //private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    //private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    // private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern
+            .compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>",
+                    Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
     private HashMap<String, String> mIdMappings = new HashMap<String, String>();
-	
-	public AkeliusInvest(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    public AkeliusInvest(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
-	}
+    }
 
-	public AkeliusInvest(String username, String password, Context context) throws BankException,
+    public AkeliusInvest(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_akeliusinvest));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_akeliusinvest));
         String response = urlopen.open("https://online.akeliusinvest.com/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" logintoken.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " logintoken.");
         }
         String strLogintoken = matcher.group(1);
-        
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("action", "login"));
         postData.add(new BasicNameValuePair("logintoken", strLogintoken));
         postData.add(new BasicNameValuePair("df_username", username));
         postData.add(new BasicNameValuePair("df_password", password));
         postData.add(new BasicNameValuePair("Language", "SV"));
         postData.add(new BasicNameValuePair("IdleTime", "900"));
-   
-        return new LoginPackage(urlopen, postData, response, "https://online.akeliusinvest.com/login.mws");
+
+        return new LoginPackage(urlopen, postData, response,
+                "https://online.akeliusinvest.com/login.mws");
     }
-    
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		Matcher matcher = reError.matcher(response);
-		if (matcher.find()) {
-		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-		    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
-		        throw new LoginException(errormsg);
-		    }
-		    else {
-	            throw new BankException(errormsg);
-			}
-		}
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        Matcher matcher = reError.matcher(response);
+        if (matcher.find()) {
+            String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+            if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ")
+                    || errormsg.contains("fyra siffror")) {
+                throw new LoginException(errormsg);
+            } else {
+                throw new BankException(errormsg);
+            }
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
 
         String response = urlopen.open("https://online.akeliusinvest.com/AccountPortfolio.mws");
-        Matcher	matcher = reAccounts.matcher(response);
+        Matcher matcher = reAccounts.matcher(response);
         int accId = 0;
-		while (matcher.find()) {
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                ICA					AKELIUSINVEST
@@ -151,41 +170,51 @@ public class AkeliusInvest extends Bank {
 //				}
 
             mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());
-			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
-            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
+            accounts.add(new Account(
+                    Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)",
+                    Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
+            Account account = new Account(
+                    Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)",
+                    Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
             account.setAliasfor(matcher.group(1).trim());
             accounts.add(account);
 
             balance = balance.add(Helpers.parseBalance(matcher.group(5)));
             accId++;
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
-        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+        super.updateTransactions(account, urlopen);
+        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) {
+            return; // No transactions for "saldo"-accounts
+        }
         String accountId = mIdMappings.get(account.getId());
-		String response = null;
-		Matcher matcher;
-		response = urlopen.open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="+accountId);
-		matcher = reTransactions.matcher(response);
-		/* 				ICA-banken	Akelius Invest
+        String response = null;
+        Matcher matcher;
+        response = urlopen
+                .open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="
+                        + accountId);
+        matcher = reTransactions.matcher(response);
+                /* 				ICA-banken	Akelius Invest
 		 * Beskrivning	1			2
 		 * Datum		2			1
 		 * Belopp		3			3
 		 */
-			
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
-			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-		}
-
-		account.setTransactions(transactions);
-	}		
+
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
+        }
+
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 58e3baa..c8a84fe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -16,22 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -42,101 +26,136 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AkeliusSpar extends Bank {
-	private static final String TAG = "AkeliusSpar";
-	private static final String NAME = "Akelius Spar";
-	private static final String NAME_SHORT = "akeliusspar";
-	private static final String URL = "https://www.online.akeliusspar.se/";
-	private static final int BANKTYPE_ID = IBankTypes.AKELIUSSPAR;
+
+    private static final String TAG = "AkeliusSpar";
+
+    private static final String NAME = "Akelius Spar";
+
+    private static final String NAME_SHORT = "akeliusspar";
+
+    private static final String URL = "https://www.online.akeliusspar.se/";
+
+    private static final int BANKTYPE_ID = IBankTypes.AKELIUSSPAR;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "YYYYMMDDNNNN";
+
     private static final boolean STATIC_BALANCE = true;
 
-	private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
-	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]*>([^<]+)</td>\\s*<td[^>]*><a[^?]+\\?selectedaccount=([^\"]+)\"[^>]*>([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
+
+    private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reAccounts = Pattern.compile(
+            "<tr>\\s*<td[^>]*>([^<]+)</td>\\s*<td[^>]*><a[^?]+\\?selectedaccount=([^\"]+)\"[^>]*>([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    //private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    //private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    // private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern
+            .compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>",
+                    Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
     private HashMap<String, String> mIdMappings = new HashMap<String, String>();
-	
-	public AkeliusSpar(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    public AkeliusSpar(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
-	}
+    }
 
-	public AkeliusSpar(String username, String password, Context context) throws BankException,
+    public AkeliusSpar(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_akeliusspar));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_akeliusspar));
         String response = urlopen.open("https://www.online.akeliusspar.se/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" logintoken.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " logintoken.");
         }
         String strLogintoken = matcher.group(1);
-        
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("action", "login"));
         postData.add(new BasicNameValuePair("logintoken", strLogintoken));
         postData.add(new BasicNameValuePair("df_username", username));
         postData.add(new BasicNameValuePair("df_password", password));
         postData.add(new BasicNameValuePair("Language", "SV"));
         postData.add(new BasicNameValuePair("IdleTime", "900"));
-   
-        return new LoginPackage(urlopen, postData, response, "https://www.online.akeliusspar.se/login.mws");
+
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.online.akeliusspar.se/login.mws");
+    }
+
+    public Urllib login() throws LoginException, BankException, IOException {
+
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        Matcher matcher = reError.matcher(response);
+        if (matcher.find()) {
+            String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+            if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ")
+                    || errormsg.contains("fyra siffror")) {
+                throw new LoginException(errormsg);
+            } else {
+                throw new BankException(errormsg);
+            }
+        }
+        return urlopen;
     }
-    
-	public Urllib login() throws LoginException, BankException, IOException {
-
-		LoginPackage lp = preLogin();
-		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		Matcher matcher = reError.matcher(response);
-		if (matcher.find()) {
-		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-		    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
-		        throw new LoginException(errormsg);
-		    }
-		    else {
-	             throw new BankException(errormsg);
-		    }
-		}
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-
-		String response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
-		Matcher	matcher = reAccounts.matcher(response);
-		int accId = 0;
-		while (matcher.find()) {
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+
+        String response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
+        Matcher matcher = reAccounts.matcher(response);
+        int accId = 0;
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                ICA					AKELIUSINVEST
@@ -153,42 +172,52 @@ public class AkeliusSpar extends Bank {
 //				}
 
             mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());
-			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
-            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
+            accounts.add(new Account(
+                    Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)",
+                    Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
+            Account account = new Account(
+                    Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)",
+                    Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
             account.setAliasfor(matcher.group(1).trim());
 
             accounts.add(account);
             balance = balance.add(Helpers.parseBalance(matcher.group(5)));
             accId++;
-		}
-    	if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
-        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+        super.updateTransactions(account, urlopen);
+        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) {
+            return; // No transactions for "saldo"-accounts
+        }
         String accountId = mIdMappings.get(account.getId());
-		String response = null;
-		Matcher matcher;
-
-		response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+accountId);
-		matcher = reTransactions.matcher(response);
-		/* 				ICA-banken	Akelius Invest
+        String response = null;
+        Matcher matcher;
+
+        response = urlopen
+                .open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="
+                        + accountId);
+        matcher = reTransactions.matcher(response);
+                /* 				ICA-banken	Akelius Invest
 		 * Beskrivning	1			2
 		 * Datum		2			1
 		 * Belopp		3			3
 		 */
-			
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
-			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-		}
-
-		account.setTransactions(transactions);
-	}		
+
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
+        }
+
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 10aba12..b9e84d3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -16,25 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -45,18 +26,46 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AmericanExpress extends Bank {
+
     private static final String TAG = "AmericanExpress";
+
     private static final String NAME = "American Express";
+
     private static final String NAME_SHORT = "americanexpress";
+
     private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
+
     private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
 
-    private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccounts = Pattern.compile(
+            "leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reTransactions = Pattern.compile(
+            "id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     private String response = null;
 
@@ -77,20 +86,25 @@ public class AmericanExpress extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress_global));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
+                R.raw.cert_americanexpress, R.raw.cert_americanexpress2,
+                R.raw.cert_americanexpress_global));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
 
         postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
-        postData.add(new BasicNameValuePair("DestPage", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("DestPage",
+                "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
         postData.add(new BasicNameValuePair("Face", "sv_SE"));
         postData.add(new BasicNameValuePair("brandname", ""));
-        postData.add(new BasicNameValuePair("TARGET", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("TARGET",
+                "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
         postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
         postData.add(new BasicNameValuePair("Logon", "Continue..."));
-        postData.add(new BasicNameValuePair("devicePrint", "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
+        postData.add(new BasicNameValuePair("devicePrint",
+                "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
         postData.add(new BasicNameValuePair("REMEMBERME", "on"));
         postData.add(new BasicNameValuePair("manage", "option1"));
         postData.add(new BasicNameValuePair("UserID", username));
@@ -98,7 +112,8 @@ public class AmericanExpress extends Bank {
         postData.add(new BasicNameValuePair("Password", password));
         postData.add(new BasicNameValuePair("PWD", password));
 
-        return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
+        return new LoginPackage(urlopen, postData, response,
+                "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
     }
 
     @Override
@@ -113,9 +128,10 @@ public class AmericanExpress extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException,IOException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -131,7 +147,7 @@ public class AmericanExpress extends Bank {
              * 3: Name                  SAS EuroBonus American Express&reg; Card
              * 4: Amount                1.111,11 kr
              * 
-             */   			    
+             */
             accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
                     Helpers.parseBalance(matcher.group(4)).negate(),
                     matcher.group(2).trim()));
@@ -149,7 +165,9 @@ public class AmericanExpress extends Bank {
             BankException, IOException {
         super.updateTransactions(account, urlopen);
 
-        response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
+        response = urlopen.open(
+                "https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index="
+                        + account.getId());
         Matcher matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 
@@ -170,10 +188,9 @@ public class AmericanExpress extends Bank {
                 transactionDate = sdfFrom.parse(matcher.group(1).trim());
                 String strDate = sdfTo.format(transactionDate);
                 transactions.add(new Transaction(strDate,
-                                                 Html.fromHtml(matcher.group(2)).toString().trim(),
-                                                 Helpers.parseBalance(matcher.group(3).trim()).negate()));
-            }
-            catch (ParseException e) {
+                        Html.fromHtml(matcher.group(2)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(3).trim()).negate()));
+            } catch (ParseException e) {
                 Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
             }
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 1eb93d2..b933506 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -16,12 +16,15 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -29,55 +32,59 @@ import org.jsoup.nodes.Element;
 import android.content.Context;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AppeakPoker extends Bank {
 
-	private static final String TAG = "AppeakPoker";
-	private static final String NAME = "Appeak Poker";
-	private static final String NAME_SHORT = "appeakpoker";
-	private static final String URL = "http://poker.appeak.se/";
-	private static final int BANKTYPE_ID = Bank.APPEAKPOKER;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-	private static final boolean INPUT_HIDDEN_PASSWORD = true;
-	private String mChips = null;
-
-	public AppeakPoker(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME= INPUT_TYPE_USERNAME;
-		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
+    private static final String TAG = "AppeakPoker";
+
+    private static final String NAME = "Appeak Poker";
+
+    private static final String NAME_SHORT = "appeakpoker";
+
+    private static final String URL = "http://poker.appeak.se/";
+
+    private static final int BANKTYPE_ID = Bank.APPEAKPOKER;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
+    private static final boolean INPUT_HIDDEN_PASSWORD = true;
+
+    private String mChips = null;
+
+    public AppeakPoker(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
         super.DISPLAY_DECIMALS = false;
         currency = "chips";
-	}
+    }
 
-	public AppeakPoker(String username, String password, Context context) throws BankException,
+    public AppeakPoker(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	protected LoginPackage preLogin() throws BankException, IOException {
-		urlopen = new Urllib(context);
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		return new LoginPackage(urlopen, postData, "", String.format("http://poker.appeak.se/playerInfo/?username=%s", username));
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context);
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        return new LoginPackage(urlopen, postData, "",
+                String.format("http://poker.appeak.se/playerInfo/?username=%s", username));
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         String response = urlopen.open(lp.getLoginTarget());
         Document d = Jsoup.parse(response);
@@ -85,27 +92,28 @@ public class AppeakPoker extends Bank {
         if (e == null) {
             throw new LoginException(res.getText(R.string.invalid_username).toString());
         } else {
-        	mChips = e.html();
+            mChips = e.html();
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null) {
+            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
-        return urlopen;		
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null) {
-			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-		}
-		login();
-		if (mChips != null) {
-			Account account = new Account("Chips", Helpers.parseBalance(mChips.replaceAll("\\D", "")), "1");
-			account.setCurrency("chips");
+        login();
+        if (mChips != null) {
+            Account account = new Account("Chips",
+                    Helpers.parseBalance(mChips.replaceAll("\\D", "")), "1");
+            account.setCurrency("chips");
             balance = account.getBalance();
             accounts.add(account);
-		}
+        }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         super.updateComplete();
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
index 5c6ef98..16ed51c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
@@ -15,21 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Audi extends AbsIkanoPartner {
+
     private static final String TAG = "Audi";
+
     private static final String NAME = "AudiKortet";
+
     private static final String NAME_SHORT = "audi";
-    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2177";
+
+    private static final String URL
+            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2177";
+
     private static final int BANKTYPE_ID = Bank.AUDI;
 
     public Audi(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 97fc37c..5575575 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -16,12 +16,13 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 public class AvanzaMini extends Avanza {
+
     public AvanzaMini(Context context) {
         super(context);
         TAG = "AvanzaMini";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index f4652a0..44533df 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -16,134 +16,153 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.Urllib;
 
 public class BetterGlobe extends Bank {
-	private static final String TAG = "BetterGlobe";
-	private static final String NAME = "Better Globe";
-	private static final String NAME_SHORT = "betterglobe";
-	private static final String URL = "http://betterglobe.com";
-	private static final int BANKTYPE_ID = IBankTypes.BETTERGLOBE;
+
+    private static final String TAG = "BetterGlobe";
+
+    private static final String NAME = "Better Globe";
+
+    private static final String NAME_SHORT = "betterglobe";
+
+    private static final String URL = "http://betterglobe.com";
+
+    private static final int BANKTYPE_ID = IBankTypes.BETTERGLOBE;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "AID code";
+
     private static final boolean STATIC_BALANCE = true;
 
-	private Pattern reBalance  = Pattern.compile("Totalt på BG-kontot\\s*([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reForecast = Pattern.compile("Din totala bruttovinst:.*?€([^<]+).*Köpekostnader:.*?€([^<]+).*Din totala nettovinst:.*?€([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTrees    = Pattern.compile("Totalt? antal ägda träd:</td>\\s*<td.*?>(\\d+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	public BetterGlobe(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-		super.currency = "EUR";
-	}
-
-	public BetterGlobe(String username, String password, Context context) throws BankException,
+    private Pattern reBalance = Pattern.compile("Totalt på BG-kontot\\s*([^<]+)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reForecast = Pattern.compile(
+            "Din totala bruttovinst:.*?€([^<]+).*Köpekostnader:.*?€([^<]+).*Din totala nettovinst:.*?€([^<]+)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reTrees = Pattern.compile("Totalt? antal ägda träd:</td>\\s*<td.*?>(\\d+)</td>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    public BetterGlobe(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.currency = "EUR";
+    }
+
+    public BetterGlobe(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context);
         urlopen.setAllowCircularRedirects(true);
-		HashMap<String, String> headers = urlopen.getHeaders();
-		headers.put("Referer","http://betterglobe.com/login.aspx?lang=sv-SE");
-    	List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        HashMap<String, String> headers = urlopen.getHeaders();
+        headers.put("Referer", "http://betterglobe.com/login.aspx?lang=sv-SE");
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
         postData.add(new BasicNameValuePair("btnLogin", ""));
-        return new LoginPackage(urlopen, postData, "", "http://betterglobe.com/Login.aspx?rememberMe=False");
+        return new LoginPackage(urlopen, postData, "",
+                "http://betterglobe.com/Login.aspx?rememberMe=False");
+    }
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher;
+        String response = urlopen.open("http://betterglobe.com/bgaccount.aspx/report");
+        matcher = reBalance.matcher(response);
+
+        while (matcher.find()) {
+            Account tillgangligt = new Account("Tillgängligt",
+                    Helpers.parseBalance(matcher.group(1)), "tillgangligt");
+            tillgangligt.setCurrency("EUR");
+            accounts.add(tillgangligt);
+            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+        }
+
+        response = urlopen.open("http://betterglobe.com/mytrees.aspx/Valueforecast");
+        matcher = reForecast.matcher(response);
+
+        while (matcher.find()) {
+            Account inkop = new Account("Inköp", Helpers.parseBalance(matcher.group(2)), "inkop");
+            Account netto = new Account("Beräknad vinst", Helpers.parseBalance(matcher.group(3)),
+                    "netto");
+            Account brutto = new Account("Beräknat slutvärde",
+                    Helpers.parseBalance(matcher.group(1)), "brutto");
+            inkop.setCurrency("EUR");
+            brutto.setCurrency("EUR");
+            netto.setCurrency("EUR");
+            accounts.add(inkop);
+            accounts.add(brutto);
+            accounts.add(netto);
+            balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+            ;
+        }
+
+        response = urlopen.open("http://betterglobe.com/mytrees.aspx");
+        matcher = reTrees.matcher(response);
+
+        while (matcher.find()) {
+            Account trees = new Account("Innehav", Helpers.parseBalance(matcher.group(1)), "trees");
+            trees.setCurrency("träd");
+            accounts.add(trees);
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
     }
-    
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		Matcher matcher;
-		String response = urlopen.open("http://betterglobe.com/bgaccount.aspx/report");
-		matcher = reBalance.matcher(response);
-
-		while (matcher.find()) {
-			Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(1)), "tillgangligt");
-			tillgangligt.setCurrency("EUR");
-			accounts.add(tillgangligt);
-			balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-		}
-
-		response = urlopen.open("http://betterglobe.com/mytrees.aspx/Valueforecast");
-		matcher = reForecast.matcher(response);
-
-		while (matcher.find()) {
-			Account inkop  = new Account("Inköp",              Helpers.parseBalance(matcher.group(2)), "inkop");
-			Account netto  = new Account("Beräknad vinst",     Helpers.parseBalance(matcher.group(3)), "netto");
-			Account brutto = new Account("Beräknat slutvärde", Helpers.parseBalance(matcher.group(1)), "brutto");
-			inkop.setCurrency("EUR");
-			brutto.setCurrency("EUR");
-			netto.setCurrency("EUR");
-			accounts.add(inkop);
-			accounts.add(brutto);
-			accounts.add(netto);
-			balance = balance.add(Helpers.parseBalance(matcher.group(2)));;
-		}
-
-		response = urlopen.open("http://betterglobe.com/mytrees.aspx");
-		matcher = reTrees.matcher(response);
-
-		while (matcher.find()) {
-			Account trees = new Account("Innehav", Helpers.parseBalance(matcher.group(1)), "trees");
-			trees.setCurrency("träd");
-			accounts.add(trees);
-		}
-
-	    if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index 6c63336..9670523 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -15,26 +15,25 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -43,12 +42,19 @@ import java.util.List;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bioklubben extends Bank {
+
     private static final String TAG = "Bioklubben";
+
     private static final String NAME = "Bioklubben";
+
     private static final String NAME_SHORT = "bioklubben";
+
     private static final String URL = "http://bioklubben.sf.se/Start.aspx";
+
     private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
+
     private static final boolean DISPLAY_DECIMALS = false;
+
     private String response = null;
 
     public Bioklubben(Context context) {
@@ -59,7 +65,8 @@ public class Bioklubben extends Bank {
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
         super.DISPLAY_DECIMALS = DISPLAY_DECIMALS;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+                | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
         super.INPUT_HINT_USERNAME = context.getString(R.string.email);
         currency = context.getString(R.string.points);
     }
@@ -79,26 +86,32 @@ public class Bioklubben extends Bank {
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("__VIEWSTATE");
         if (e == null || e.attr("value") == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = e.attr("value");
 
         e = d.getElementById("__EVENTVALIDATION");
         if (e == null || e.attr("value") == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
         String eventValidation = e.attr("value");
 
-
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
+        postData.add(new BasicNameValuePair("__EVENTTARGET",
+                "ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
         postData.add(new BasicNameValuePair("ctl00_toolkitscriptmanager_HiddenField", ""));
-        postData.add(new BasicNameValuePair("ctl00$toolkitscriptmanager", "ctl00$UpdatePanel|ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
-        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$LoginNameTextBox", username));
-        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$PasswordTextBox", password));
+        postData.add(new BasicNameValuePair("ctl00$toolkitscriptmanager",
+                "ctl00$UpdatePanel|ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
+        postData.add(new BasicNameValuePair(
+                "ctl00$ContentPlaceHolder1$LoginUserControl$LoginNameTextBox", username));
+        postData.add(
+                new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$PasswordTextBox",
+                        password));
         return new LoginPackage(urlopen, postData, response, "http://bioklubben.sf.se/Start.aspx");
     }
 
@@ -114,14 +127,17 @@ public class Bioklubben extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        Document d = Jsoup.parse(urlopen.open("http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
+        Document d = Jsoup.parse(urlopen.open(
+                "http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
         Element e = d.getElementById("ctl00_ContentPlaceHolder1_BonusPointsLabel");
         if (e == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " points element.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " points element.");
         }
         BigDecimal b = Helpers.parseBalance(e.text());
         Account a = new Account("Poäng", b, "1");
@@ -133,7 +149,9 @@ public class Bioklubben extends Bank {
         List<Transaction> transactions = new ArrayList<Transaction>();
         if (es != null) {
             for (Element el : es) {
-                transactions.add(new Transaction(el.child(0).text().trim(), el.child(1).text().trim(), Helpers.parseBalance(el.child(2).text())));
+                transactions.add(
+                        new Transaction(el.child(0).text().trim(), el.child(1).text().trim(),
+                                Helpers.parseBalance(el.child(2).text())));
             }
         }
         a.setTransactions(transactions);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 1783c19..b1dad07 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -16,32 +16,40 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
+
 import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.util.EntityUtils;
 import org.json.JSONException;
 import org.json.JSONObject;
+
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
+
 import eu.nullbyte.android.urllib.Urllib;
 
 public class BlekingeTrafiken extends Bank {
+
     private static final String TAG = "Blekingetrafiken";
+
     private static final String NAME = "Blekingetrafiken";
+
     private static final String NAME_SHORT = "blekingetrafiken";
+
     private static final String URL = "https://www.blekingetrafiken.se";
+
     private static final int BANKTYPE_ID = IBankTypes.BLEKINGETRAFIKEN;
+
     private String response = null;
 
     public BlekingeTrafiken(Context context) {
@@ -75,11 +83,11 @@ public class BlekingeTrafiken extends Bank {
 
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
-        urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
-        urlopen.addHeader("Accept","application/json");
+        urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
+        urlopen.addHeader("Accept", "application/json");
         HttpResponse httpResponse = urlopen.openAsHttpResponse(URL + "/webshop/card/balance/",
                 new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
-        if(httpResponse.getStatusLine().getStatusCode() != 200) {
+        if (httpResponse.getStatusLine().getStatusCode() != 200) {
             throw new BankException(res.getText(R.string.invalid_card_number).toString());
         }
         response = EntityUtils.toString(httpResponse.getEntity());
@@ -104,7 +112,7 @@ public class BlekingeTrafiken extends Bank {
             balance = balance.add(a.getBalance());
 
             accountJSONObject = accountJSONObject.optJSONObject("Autoload");
-            if (accountJSONObject !=  null) {
+            if (accountJSONObject != null) {
                 a = new Account(" - Kommande -",
                         Helpers.parseBalance(accountJSONObject.getString("Value")),
                         "1");
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 7b3dba1..c1dcee5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -16,24 +16,22 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -45,12 +43,21 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bredband2VoIP extends Bank {
+
     private static final String API_URL = "https://portal.bredband2.com/";
 
-    private Pattern reSaldoUrl = Pattern.compile("<a href=\"/voip/digisipbalance/iPhoneProviderID/(\\d+)/\" class=\"digisipBalance\" target=\"_blank\">Saldo</a>", Pattern.CASE_INSENSITIVE);
-    private Pattern reSaldo = Pattern.compile("<td class=\"white\">(\\d+.\\d{2}) kr", Pattern.CASE_INSENSITIVE);
+    private Pattern reSaldoUrl = Pattern.compile(
+            "<a href=\"/voip/digisipbalance/iPhoneProviderID/(\\d+)/\" class=\"digisipBalance\" target=\"_blank\">Saldo</a>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reSaldo = Pattern.compile("<td class=\"white\">(\\d+.\\d{2}) kr",
+            Pattern.CASE_INSENSITIVE);
+
     private Pattern reInvoiceUrl = Pattern.compile("<a href=\"([^\"]+)\"/\" class=\"invoice\"");
-    private Pattern reTransactions = Pattern.compile("^\\s+([\\d-]+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)", Pattern.MULTILINE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "^\\s+([\\d-]+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)", Pattern.MULTILINE);
+
     private String response = null;
 
     public Bredband2VoIP(Context context) {
@@ -71,7 +78,8 @@ public class Bredband2VoIP extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bredband2));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_bredband2));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("cUsername", username));
         postData.add(new BasicNameValuePair("cPassword", password));
@@ -97,7 +105,8 @@ public class Bredband2VoIP extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -106,7 +115,8 @@ public class Bredband2VoIP extends Bank {
             Matcher mSaldoUrl = reSaldoUrl.matcher(response);
             while (mSaldoUrl.find()) {
                 String account = mSaldoUrl.group(1);
-                String r = urlopen.open(API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
+                String r = urlopen.open(
+                        API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
                 Matcher mSaldo = reSaldo.matcher(r);
                 if (mSaldo.find()) {
                     accounts.add(new Account(account,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index e28b6dd..7932051 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -17,131 +17,152 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class BrummerKF extends Bank {
-	private static final String TAG = "BrummerKF";
-	private static final String NAME = "Brummer KF & Pension";
-	private static final String NAME_SHORT = "brummer_kf";
-	private static final String URL = "https://www.brummer.se/";
-	private static final int BANKTYPE_ID = IBankTypes.BRUMMER_KF;
+
+    private static final String TAG = "BrummerKF";
+
+    private static final String NAME = "Brummer KF & Pension";
+
+    private static final String NAME_SHORT = "brummer_kf";
+
+    private static final String URL = "https://www.brummer.se/";
+
+    private static final int BANKTYPE_ID = IBankTypes.BRUMMER_KF;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "YYYYMMDDNNNN";
+
     private static final boolean STATIC_BALANCE = true;
 
-	private Pattern reError = Pattern.compile("<li>(Personnummer och l.*?senord matchar ej\\.)</li>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reViewstate = Pattern.compile("\"__VIEWSTATE\"\\s+value=\"(.*?)\"", Pattern.DOTALL);
-	private Pattern reEventValidation = Pattern.compile("\"__EVENTVALIDATION\"\\s+value=\"(.*?)\"", Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("<td.*?>\\s*<a.*?>\\s*(.*?)&nbsp;(.*?)\\s*</a>\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*<a.*?>\\s*Avtalsinformation\\s*</a>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	String response;
-	
-	public BrummerKF(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+    String response;
+
+    private Pattern reError = Pattern
+            .compile("<li>(Personnummer och l.*?senord matchar ej\\.)</li>",
+                    Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reViewstate = Pattern.compile("\"__VIEWSTATE\"\\s+value=\"(.*?)\"",
+            Pattern.DOTALL);
+
+    private Pattern reEventValidation = Pattern.compile(
+            "\"__EVENTVALIDATION\"\\s+value=\"(.*?)\"", Pattern.DOTALL);
+
+    private Pattern reAccounts = Pattern.compile(
+            "<td.*?>\\s*<a.*?>\\s*(.*?)&nbsp;(.*?)\\s*</a>\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*<a.*?>\\s*Avtalsinformation\\s*</a>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    public BrummerKF(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
-	}
+    }
 
-	public BrummerKF(String username, String password, Context context) throws BankException,
+    public BrummerKF(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_brummer));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_brummer));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.brummer.se/sv/online/privat/Login/");
-        
+
         Matcher mViewstate = reViewstate.matcher(response);
         if (!mViewstate.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" Viewstate.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " Viewstate.");
         }
-        String viewstate       = mViewstate.group(1);
-        
+        String viewstate = mViewstate.group(1);
+
         Matcher mEventValidation = reEventValidation.matcher(response);
         if (!mEventValidation.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
-        String eventvalidation       = mEventValidation.group(1);
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        String eventvalidation = mEventValidation.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewstate));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventvalidation));
         postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtUsername", username));
         postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtPassword", password));
         postData.add(new BasicNameValuePair("ctl00$cphMainRegion$btnLogin", "Logga in"));
         postData.add(new BasicNameValuePair("ctl00$ctl08", "sv"));
-        postData.add(new BasicNameValuePair("ctl00$ucHeader$ctl01$loginView$ctl01$ddlQuickMenu", "-1"));
-        return new LoginPackage(urlopen, postData, response, "https://www.brummer.se/sv/online/privat/Login/");
+        postData.add(
+                new BasicNameValuePair("ctl00$ucHeader$ctl01$loginView$ctl01$ddlQuickMenu", "-1"));
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.brummer.se/sv/online/privat/Login/");
     }
-    
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-		Matcher matcher = reError.matcher(response);
-		if (matcher.find()) {
-		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-		    if (errormsg.contains("Personnummer")) {
-		        throw new LoginException(errormsg);
-		    }
-		    else {
-                 throw new BankException(errormsg);
-		    }
-		}
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		Matcher matcher;
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+        Matcher matcher = reError.matcher(response);
+        if (matcher.find()) {
+            String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+            if (errormsg.contains("Personnummer")) {
+                throw new LoginException(errormsg);
+            } else {
+                throw new BankException(errormsg);
+            }
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher;
 
         response = urlopen.open("https://www.brummer.se/sv/online/privat/");
-		matcher = reAccounts.matcher(response);
-			
-		while (matcher.find()) {
+        matcher = reAccounts.matcher(response);
+
+        while (matcher.find()) {
             /*
              * 1: Kontonamn
              * 2: Kontonummer
@@ -151,12 +172,13 @@ public class BrummerKF extends Bank {
              * 6: Marknadsvärde (kronor)
              */
 
-			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(6).trim()), matcher.group(2)));
+            accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(6).trim()), matcher.group(2)));
 
-			balance = balance.add(Helpers.parseBalance(matcher.group(6)));
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	}
+            balance = balance.add(Helpers.parseBalance(matcher.group(6)));
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index c8d3e61..e4f88c5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -16,16 +16,17 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
@@ -33,56 +34,74 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class CSN extends Bank {
-	private static final String TAG = "CSN";
-	private static final String NAME = "CSN";
-	private static final String NAME_SHORT = "csn";
-	private static final String URL = "https://www.csn.se/bas/inloggning/pinkod.do";
-	private static final int BANKTYPE_ID = IBankTypes.CSN;
+
+    private static final String TAG = "CSN";
+
+    private static final String NAME = "CSN";
+
+    private static final String NAME_SHORT = "csn";
+
+    private static final String URL = "https://www.csn.se/bas/inloggning/pinkod.do";
+
+    private static final int BANKTYPE_ID = IBankTypes.CSN;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
     private static final boolean STATIC_BALANCE = true;
-	
-    private Pattern reLoginError = Pattern.compile("<h3>Observera</h3>\\s*<ul>\\s*<li>([^<]+)</li>", Pattern.CASE_INSENSITIVE);
-    private Pattern reBalance = Pattern.compile("aktuellStudieskuld\\.do\\?metod=init&(?:amp;)?SpecNr=(\\d{1,})\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\">([^<]+)</", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reCompletedPayments = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\"[^>]+>([^<]+)</", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private String response = null;
-	
-	public CSN(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    private Pattern reLoginError = Pattern.compile("<h3>Observera</h3>\\s*<ul>\\s*<li>([^<]+)</li>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reBalance = Pattern.compile(
+            "aktuellStudieskuld\\.do\\?metod=init&(?:amp;)?SpecNr=(\\d{1,})\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\">([^<]+)</",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reCompletedPayments = Pattern.compile(
+            "<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\"[^>]+>([^<]+)</",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private String response = null;
+
+    public CSN(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
     }
 
-	public CSN(String username, String password, Context context) throws BankException,
+    public CSN(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_csn));
@@ -90,46 +109,49 @@ public class CSN extends Bank {
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://www.csn.se/bas/");
         response = urlopen.open("https://www.csn.se/bas/inloggning/pinkod.do");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("javascript", "on"));
 
         response = urlopen.open("https://www.csn.se/bas/javascript", postData);
 
         postData.clear();
-        
+
         postData.add(new BasicNameValuePair("metod", "validerapinkod"));
         postData.add(new BasicNameValuePair("pnr", username));
         postData.add(new BasicNameValuePair("pinkod", password));
-        return new LoginPackage(urlopen, postData, response, "https://www.csn.se/bas/inloggning/Pinkod.do");
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.csn.se/bas/inloggning/Pinkod.do");
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException, IOException {
+    public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		Matcher matcher = reLoginError.matcher(response);
-		if (matcher.find()) {
-		    throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
-		}
-		if (!response.contains("Inloggad&nbsp;som")) {
-			throw new BankException(res.getText(R.string.unable_to_login).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-
-		response = urlopen.open("https://www.csn.se/aterbetalning/hurStorArMinSkuld/aktuellStudieskuld.do?javascript=off");
-		Matcher matcher;
-		matcher = reBalance.matcher(response);
-		int i = 0;
-		while (matcher.find()) {
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        Matcher matcher = reLoginError.matcher(response);
+        if (matcher.find()) {
+            throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
+        }
+        if (!response.contains("Inloggad&nbsp;som")) {
+            throw new BankException(res.getText(R.string.unable_to_login).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        response = urlopen.open(
+                "https://www.csn.se/aterbetalning/hurStorArMinSkuld/aktuellStudieskuld.do?javascript=off");
+        Matcher matcher;
+        matcher = reBalance.matcher(response);
+        int i = 0;
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -138,34 +160,37 @@ public class CSN extends Bank {
              * 3: Amount            123,456
              *
              */
-		    BigDecimal amount = Helpers.parseBalance(matcher.group(3).replace(",", "")).negate();
-		    Account account = new Account(
+            BigDecimal amount = Helpers.parseBalance(matcher.group(3).replace(",", "")).negate();
+            Account account = new Account(
                     Html.fromHtml(matcher.group(2)).toString().trim(),
                     amount,
                     matcher.group(1).trim(),
                     Account.LOANS);
-		    if (i > 0) {
-		        account.setAliasfor("0");
-		    }
-			accounts.add(account);
-			balance = balance.add(amount);
-			i++;
-		}
-			
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-	    }
+            if (i > 0) {
+                account.setAliasfor("0");
+            }
+            accounts.add(account);
+            balance = balance.add(amount);
+            i++;
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
-	
+    }
+
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
-        if (account.getAliasfor() == null || account.getAliasfor().length() == 0) return;
-        
+        if (account.getAliasfor() == null || account.getAliasfor().length() == 0) {
+            return;
+        }
+
         Matcher matcher;
-        response = urlopen.open("https://www.csn.se/studiemedel/utbetalningar/utbetalningar.do?javascript=off");
+        response = urlopen.open(
+                "https://www.csn.se/studiemedel/utbetalningar/utbetalningar.do?javascript=off");
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
@@ -179,10 +204,12 @@ public class CSN extends Bank {
              *
              */
             transactions.add(new Transaction(matcher.group(1).trim(),
-                    Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
+                    Html.fromHtml(matcher.group(2)).toString().trim() + " (" + Html
+                            .fromHtml(matcher.group(3)).toString().trim() + ")",
                     Helpers.parseBalance(matcher.group(4).replace(",", ""))));
         }
-        response = urlopen.open("https://www.csn.se/aterbetalning/vadSkallJagBetalUnderAret/betalningstillfallen.do?javascript=off");
+        response = urlopen.open(
+                "https://www.csn.se/aterbetalning/vadSkallJagBetalUnderAret/betalningstillfallen.do?javascript=off");
         matcher = reTransactions.matcher(response);
         while (matcher.find()) {
             /*
@@ -195,11 +222,13 @@ public class CSN extends Bank {
              *
              */
             transactions.add(new Transaction(matcher.group(1).trim(),
-                    Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
+                    Html.fromHtml(matcher.group(2)).toString().trim() + " (" + Html
+                            .fromHtml(matcher.group(3)).toString().trim() + ")",
                     Helpers.parseBalance(matcher.group(4).replace(",", "")).negate()));
         }
 
-        response = urlopen.open("https://www.csn.se/aterbetalning/harMinaInbetalningarKommitIn/registreradeInbetalningar.do?javascript=off");
+        response = urlopen.open(
+                "https://www.csn.se/aterbetalning/harMinaInbetalningarKommitIn/registreradeInbetalningar.do?javascript=off");
         matcher = reCompletedPayments.matcher(response);
         while (matcher.find()) {
             /*
@@ -217,5 +246,5 @@ public class CSN extends Bank {
 
         Collections.sort(transactions, Collections.reverseOrder());
         account.setTransactions(transactions);
-    }	
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 47b4da7..701c22c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -1,9 +1,12 @@
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -15,87 +18,93 @@ import org.apache.http.util.EntityUtils;
 import android.content.Context;
 import android.text.InputType;
 
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class Chalmrest extends Bank {
-	private static final String TAG = "Chalmrest";
-	private static final String NAME = "Chalmrest";
-	private static final String NAME_SHORT = "chalmrest";
-	private static final int BANKTYPE_ID = IBankTypes.CHALMREST;
-
-	public Chalmrest(Context context) {
-		super(context);
-
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
-		super.INPUT_HINT_USERNAME = "XXXXXXXXXXXXXXXX";
-		super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
-		super.INPUT_HIDDEN_PASSWORD = true;
-	}
-
-	public Chalmrest(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Chalmrest";
+
+    private static final String NAME = "Chalmrest";
+
+    private static final String NAME_SHORT = "chalmrest";
+
+    private static final int BANKTYPE_ID = IBankTypes.CHALMREST;
+
+    public Chalmrest(Context context) {
+        super(context);
+
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
+        super.INPUT_HINT_USERNAME = "XXXXXXXXXXXXXXXX";
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+        super.INPUT_HIDDEN_PASSWORD = true;
+    }
+
+    public Chalmrest(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || username.length() == 0) 
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		
-		try {
-			String cardNr = username;
-			
-			HttpClient httpclient = new DefaultHttpClient();
-			HttpGet httpget = new HttpGet("http://kortladdning.chalmerskonferens.se/bgw.aspx?type=getCardAndArticles&card=" + cardNr);
-			HttpResponse response = httpclient.execute(httpget);
-			HttpEntity entity = response.getEntity();
-			if (entity == null)
-				throw new BankException("Couldn't connect!");
-			
-		    String s1 = EntityUtils.toString(entity);		    
-		    Pattern pattern = Pattern.compile("<ExtendedInfo Name=\"Kortvarde\" Type=\"System.Double\" >(.*?)</ExtendedInfo>");
-		    Matcher matcher = pattern.matcher(s1);
-		    
-		    if (!matcher.find()) 
-		    	throw new BankException("Couldn't parse value!"); 
-
-		    String value = matcher.group(1);
-		    
-		    StringBuilder sb = new StringBuilder();
-		    int last = 0;
-		    Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
-		    while (match.find()) {
-		    	sb.append(value.substring(last, match.start()));
-		    	int i = Integer.parseInt(match.group(1), 16);
-		    	sb.append((char)i);
-		    	last = match.end();
-		    }
-		    sb.append(value.substring(last));
-		    value = sb.toString().replace(',', '.');
-		    
-		    matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
-		    if (!matcher.find())
-		    	throw new BankException("Coldn't parse name!");
-		    String name = matcher.group(1);
-		    
-		    accounts.add(new Account(name, BigDecimal.valueOf(Double.parseDouble(value)), "1"));
-		}
-		catch (Exception e)
-		{
-			throw new BankException(e.getMessage(), e);
-		}
-		super.updateComplete();
-	}
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || username.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        try {
+            String cardNr = username;
+
+            HttpClient httpclient = new DefaultHttpClient();
+            HttpGet httpget = new HttpGet(
+                    "http://kortladdning.chalmerskonferens.se/bgw.aspx?type=getCardAndArticles&card="
+                            + cardNr);
+            HttpResponse response = httpclient.execute(httpget);
+            HttpEntity entity = response.getEntity();
+            if (entity == null) {
+                throw new BankException("Couldn't connect!");
+            }
+
+            String s1 = EntityUtils.toString(entity);
+            Pattern pattern = Pattern.compile(
+                    "<ExtendedInfo Name=\"Kortvarde\" Type=\"System.Double\" >(.*?)</ExtendedInfo>");
+            Matcher matcher = pattern.matcher(s1);
+
+            if (!matcher.find()) {
+                throw new BankException("Couldn't parse value!");
+            }
+
+            String value = matcher.group(1);
+
+            StringBuilder sb = new StringBuilder();
+            int last = 0;
+            Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
+            while (match.find()) {
+                sb.append(value.substring(last, match.start()));
+                int i = Integer.parseInt(match.group(1), 16);
+                sb.append((char) i);
+                last = match.end();
+            }
+            sb.append(value.substring(last));
+            value = sb.toString().replace(',', '.');
+
+            matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
+            if (!matcher.find()) {
+                throw new BankException("Coldn't parse name!");
+            }
+            String name = matcher.group(1);
+
+            accounts.add(new Account(name, BigDecimal.valueOf(Double.parseDouble(value)), "1"));
+        } catch (Exception e) {
+            throw new BankException(e.getMessage(), e);
+        }
+        super.updateComplete();
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
index d94f410..cd6bc86 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Chevrolet extends SEBKortBase {
-	private static final String TAG = "Chevrolet";
-	private static final String NAME = "Chevrolet Big Plus Card";
-	private static final String NAME_SHORT = "chevrolet";
-	private static final int BANKTYPE_ID = Bank.CHEVROLET;
-
-	public Chevrolet(Context context) {
-		super(context, "chse", "0086");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Chevrolet(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Chevrolet";
+
+    private static final String NAME = "Chevrolet Big Plus Card";
+
+    private static final String NAME_SHORT = "chevrolet";
+
+    private static final int BANKTYPE_ID = Bank.CHEVROLET;
+
+    public Chevrolet(Context context) {
+        super(context, "chse", "0086");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Chevrolet(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "chse", "0086");
-	}
+        super(username, password, context, "chse", "0086");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index b890d75..da5f903 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -16,16 +16,17 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
@@ -33,63 +34,80 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class DanskeBank extends Bank {
-	private static final String TAG = "DanskeBank";
-	private static final String NAME = "DanskeBank";
-	private static final String NAME_SHORT = "danskebank";
-	private static final String URL = "https://mobil.danskebank.se/XI?WP=XAI&WO=Logon&WA=MBSELogon&gsSprog=SE&gsBrand=OEB";
-	private static final int BANKTYPE_ID = IBankTypes.DANSKEBANK;
+
+    private static final String TAG = "DanskeBank";
+
+    private static final String NAME = "DanskeBank";
+
+    private static final String NAME_SHORT = "danskebank";
+
+    private static final String URL
+            = "https://mobil.danskebank.se/XI?WP=XAI&WO=Logon&WA=MBSELogon&gsSprog=SE&gsBrand=OEB";
+
+    private static final int BANKTYPE_ID = IBankTypes.DANSKEBANK;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-	
+
     private Pattern reSessionId = Pattern.compile("WSES=([^\"& ]+)", Pattern.CASE_INSENSITIVE);
+
     private Pattern rePersonnr = Pattern.compile("WAFT=([^\"& ]+)", Pattern.CASE_INSENSITIVE);
-	private Pattern reAccounts = Pattern.compile("<a\\shref=\"[^\"]+KBList[^\"]+WCI=([^\"]+)\">([^<]+)</a><br/>([^<]+)<br/>Saldo:([^<]+)<br/>Disponibelt:([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<a\\shref=\"[^\"]+KBDetVis[^\"]+\">([^<]+)</a><br/>Datum:([^<]+)<br/>Belopp:([^<]+)<br/>Status:([^<]+)<", Pattern.CASE_INSENSITIVE);
-	
-	private String response = null;
-	private String mSessionId = null;
-	private String mPersonnr = null;
-
-	public DanskeBank(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    private Pattern reAccounts = Pattern.compile(
+            "<a\\shref=\"[^\"]+KBList[^\"]+WCI=([^\"]+)\">([^<]+)</a><br/>([^<]+)<br/>Saldo:([^<]+)<br/>Disponibelt:([^<]+)<",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<a\\shref=\"[^\"]+KBDetVis[^\"]+\">([^<]+)</a><br/>Datum:([^<]+)<br/>Belopp:([^<]+)<br/>Status:([^<]+)<",
+            Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    private String mSessionId = null;
+
+    private String mPersonnr = null;
+
+    public DanskeBank(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-	}
+    }
 
-	public DanskeBank(String username, String password, Context context) throws BankException,
+    public DanskeBank(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_danskebank));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_danskebank));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://mobil.danskebank.se/");
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm - dd.MM.yyyy");
         postData.add(new BasicNameValuePair("gsSprog", "SE"));
         postData.add(new BasicNameValuePair("gsBrand", "OEB"));
@@ -113,47 +131,50 @@ public class DanskeBank extends Bank {
         postData.add(new BasicNameValuePair("gsLand", "SE"));
         postData.add(new BasicNameValuePair("gsAftlnr", username));
         postData.add(new BasicNameValuePair("gsLogon", password));
-       
+
         return new LoginPackage(urlopen, postData, response, "https://mobil.danskebank.se/XI");
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("et personnummer eller servicekod du angett")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen = login();
-		Matcher matcher;
-		matcher = reSessionId.matcher(response);
-		if (matcher.find()) {
-		    mSessionId = matcher.group(1);
-		}
-		else {
-		    throw new BankException(res.getText(R.string.unable_to_find).toString() + " session id.");
-		}
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("et personnummer eller servicekod du angett")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher;
+        matcher = reSessionId.matcher(response);
+        if (matcher.find()) {
+            mSessionId = matcher.group(1);
+        } else {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " session id.");
+        }
         matcher = rePersonnr.matcher(response);
         if (matcher.find()) {
             mPersonnr = matcher.group(1);
-        }
-        else {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " personnummer.");
+        } else {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " personnummer.");
         }
 
-		response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s", mSessionId, mPersonnr));
-		matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
+        response = urlopen.open(String.format(
+                "https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s",
+                mSessionId, mPersonnr));
+        matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
@@ -164,36 +185,40 @@ public class DanskeBank extends Bank {
              * 5: Balance (disp.)       1.124,56
              *
              */
-		    String name = Html.fromHtml(matcher.group(2)).toString().trim();
-		    Account account = new Account(name, Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim());
-		    if (name.contains("lån") || name.contains("Lån")) {
-		        account.setType(Account.LOANS);
-		    }
-		    else {
-	             balance = balance.add(Helpers.parseBalance(matcher.group(5)));
-		    }
-			accounts.add(account);
-		}
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-		super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            String name = Html.fromHtml(matcher.group(2)).toString().trim();
+            Account account = new Account(name, Helpers.parseBalance(matcher.group(5)),
+                    matcher.group(1).trim());
+            if (name.contains("lån") || name.contains("Lån")) {
+                account.setType(Account.LOANS);
+            } else {
+                balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+            }
+            accounts.add(account);
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
+        super.updateTransactions(account, urlopen);
 
-		//No transaction history for loans, funds and credit cards.
-		int accType = account.getType();
-		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
+        //No transaction history for loans, funds and credit cards.
+        int accType = account.getType();
+        if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) {
+            return;
+        }
 
-		response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s", mPersonnr, mSessionId, account.getId()));
-		Matcher matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
+        response = urlopen.open(String.format(
+                "https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s",
+                mPersonnr, mSessionId, account.getId()));
+        Matcher matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
@@ -203,8 +228,10 @@ public class DanskeBank extends Bank {
              * 4: Status                Väntar | Utförd
              *
              */
-			transactions.add(new Transaction(Html.fromHtml(matcher.group(2)).toString().trim(), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-		}
-		account.setTransactions(transactions);
-	}	
+            transactions.add(new Transaction(Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
+        }
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 650e71a..f34b1af 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -17,82 +17,102 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class DinersClub extends Bank {
-	private static final String TAG = "DinersClub";
-	private static final String NAME = "Diners Club";
-	private static final String NAME_SHORT = "dinersclub";
-	private static final String URL = "https://secure.dinersclub.se/dcs/login.aspx";
-	private static final int BANKTYPE_ID = IBankTypes.DINERSCLUB;
-	
+
+    private static final String TAG = "DinersClub";
+
+    private static final String NAME = "Diners Club";
+
+    private static final String NAME_SHORT = "dinersclub";
+
+    private static final String URL = "https://secure.dinersclub.se/dcs/login.aspx";
+
+    private static final int BANKTYPE_ID = IBankTypes.DINERSCLUB;
+
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalance = Pattern.compile("class=\"card\"[^>]+>\\s*<div[^>]+>\\s*<b>([^<]+)</b>\\s*<br ?/>\\s*<span[^>]+>([^<]+)</span>\\s*</div>\\s*<div[^>]+>\\s*<strong[^>]+>[^<]+</strong>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
-	private Pattern reInvoices = Pattern.compile("<tr[^>]+>\\s*<td class=\"right\">\\s*<a href='((Invoice|Nonbilled).aspx\\?card=\\d+&bdate=[\\d-]+)'>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<tr[^>]+>\\s*<td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*([\\d-]+)\\s*</a>\\s*</td><td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td><td class=\"right\">\\s*(?:<span[^>]+>\\s*<a[^>]+>([^<]+)</a></span>\\s*)?</td><td class=\"right\">\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE);
-
-	private String response = null;
-	private String invoiceUrl;
-	
-	public DinersClub(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public DinersClub(String username, String password, Context context) throws BankException,
+
+    private Pattern reEventValidation = Pattern
+            .compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+
+    private Pattern reBalance = Pattern.compile(
+            "class=\"card\"[^>]+>\\s*<div[^>]+>\\s*<b>([^<]+)</b>\\s*<br ?/>\\s*<span[^>]+>([^<]+)</span>\\s*</div>\\s*<div[^>]+>\\s*<strong[^>]+>[^<]+</strong>([^<]+)</div>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reInvoices = Pattern.compile(
+            "<tr[^>]+>\\s*<td class=\"right\">\\s*<a href='((Invoice|Nonbilled).aspx\\?card=\\d+&bdate=[\\d-]+)'>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<tr[^>]+>\\s*<td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*([\\d-]+)\\s*</a>\\s*</td><td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td><td class=\"right\">\\s*(?:<span[^>]+>\\s*<a[^>]+>([^<]+)</a></span>\\s*)?</td><td class=\"right\">\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td>\\s*</tr>",
+            Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    private String invoiceUrl;
+
+    public DinersClub(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public DinersClub(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
         response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
 
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = matcher.group(1);
 
         matcher = reEventValidation.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
-        String eventValidation = matcher.group(1);            
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        String eventValidation = matcher.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
@@ -101,39 +121,40 @@ public class DinersClub extends Bank {
         postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", password));
         postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
 
-        return new LoginPackage(urlopen, postData, response, "https://secure.dinersclub.se/dcs/login.aspx");
+        return new LoginPackage(urlopen, postData, response,
+                "https://secure.dinersclub.se/dcs/login.aspx");
     }
 
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("Har du glömt ditt lösenord")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		if (!"https://secure.dinersclub.se/dcs/eSaldo/Default.aspx".equalsIgnoreCase(urlopen.getCurrentURI())) {
-		    try {
+        if (response.contains("Har du glömt ditt lösenord")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        if (!"https://secure.dinersclub.se/dcs/eSaldo/Default.aspx".equalsIgnoreCase(
+                urlopen.getCurrentURI())) {
+            try {
                 response = urlopen.open("https://secure.dinersclub.se/dcs/eSaldo/Default.aspx");
-            }
-            catch (ClientProtocolException e) {
+            } catch (ClientProtocolException e) {
                 throw new BankException(e.getMessage(), e);
-            }
-            catch (IOException e) {
+            } catch (IOException e) {
                 throw new BankException(e.getMessage(), e);
             }
-		}
+        }
 
-		Matcher matcher = reBalance.matcher(response);
-		if (matcher.find()) {
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -142,9 +163,10 @@ public class DinersClub extends Bank {
              * 3: Balance           3.331,79 kr
              * 
              */
-		    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "1"));
-		    balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-		}
+            accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3)), "1"));
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+        }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
@@ -152,29 +174,29 @@ public class DinersClub extends Bank {
         /* Detect invoice dates - needed to find the transactions */
         matcher = reInvoices.matcher(response);
         if (matcher.find()) {
-        	invoiceUrl = matcher.group(1);
-        }
-        else {
-        	invoiceUrl = null;
+            invoiceUrl = matcher.group(1);
+        } else {
+            invoiceUrl = null;
         }
 
         super.updateComplete();
-	}
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
-		String response = null;
-		Matcher matcher;
+        super.updateTransactions(account, urlopen);
+        String response = null;
+        Matcher matcher;
 
 		/* We're going to look at all the pages until we find one that has transactions on it */
-		response = urlopen.open(String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
-		matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        response = urlopen.open(
+                String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 
-		while (matcher.find()) {
-			/*
+        while (matcher.find()) {
+                        /*
 			 * Capture groups:
 			 * GROUP				EXAMPLE DATA
 			 * 1: Trans. date		2010-10-06
@@ -183,8 +205,9 @@ public class DinersClub extends Bank {
 			 * 4: Amount			2.462,00 kr
 			 */
 
-			transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(4))));
-		}
-		account.setTransactions(transactions);
-	}
+            transactions.add(new Transaction(matcher.group(1), matcher.group(2),
+                    Helpers.parseBalance(matcher.group(4))));
+        }
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
index e47962a..7cf7fd6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Djurgarden extends SEBKortBase {
-	private static final String TAG = "Djurgarden";
-	private static final String NAME = "Djurgårdskortet MasterCard";
-	private static final String NAME_SHORT = "djurgarden";
-	private static final int BANKTYPE_ID = Bank.DJURGARDEN;
-
-	public Djurgarden(Context context) {
-		super(context, "djse", "0116");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Djurgarden(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Djurgarden";
+
+    private static final String NAME = "Djurgårdskortet MasterCard";
+
+    private static final String NAME_SHORT = "djurgarden";
+
+    private static final int BANKTYPE_ID = Bank.DJURGARDEN;
+
+    public Djurgarden(Context context) {
+        super(context, "djse", "0116");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Djurgarden(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "djse", "0116");
-	}
+        super(username, password, context, "djse", "0116");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index 184a1a6..b9bb0f7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -1,61 +1,74 @@
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class EasyCard extends Bank {
-    private static final String TAG         = "EasyCard";
-    private static final String NAME        = "EasyCard";
-    private static final String NAME_SHORT  = "easycard";
-    private static final String URL         = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
-    private static final int BANKTYPE_ID    = IBankTypes.EASYCARD;
 
-    private static final int INPUT_TYPE_USERNAME    = InputType.TYPE_CLASS_NUMBER;
+    private static final String TAG = "EasyCard";
+
+    private static final String NAME = "EasyCard";
+
+    private static final String NAME_SHORT = "easycard";
+
+    private static final String URL = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
+
+    private static final int BANKTYPE_ID = IBankTypes.EASYCARD;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+
     private static final String INPUT_HINT_USERNAME = "XXXXXXXXX";
 
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_NUMBER;
 
-    private Pattern reAccounts      = Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactions  = Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
-    private Pattern rePostData      = Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile(
+            "<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern rePostData = Pattern.compile(
+            "<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>",
+            Pattern.CASE_INSENSITIVE);
 
     private String response = null;
 
     public EasyCard(Context context) {
         super(context);
 
-        super.TAG                   = TAG;
-        super.NAME                  = NAME;
-        super.NAME_SHORT            = NAME_SHORT;
-        super.BANKTYPE_ID           = BANKTYPE_ID;
-        super.URL                   = URL;
-        super.INPUT_TYPE_USERNAME   = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME   = INPUT_HINT_USERNAME;
-        super.INPUT_TYPE_PASSWORD   = INPUT_TYPE_PASSWORD;
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
     }
 
     public EasyCard(String username, String password, Context context) throws BankException,
@@ -67,9 +80,10 @@ public class EasyCard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
 
-        urlopen                         = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_easycard));
-        response                        = urlopen.open(EasyCard.URL);
-        List<NameValuePair> postData    = new ArrayList<NameValuePair>();
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_easycard));
+        response = urlopen.open(EasyCard.URL);
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
 
         // Find hidden required fields.
         Matcher matcher = rePostData.matcher(response);
@@ -77,13 +91,18 @@ public class EasyCard extends Bank {
         // Populate hidden fields
         while (matcher.find()) {
             // 1 == name, 2 == value
-            postData.add(new BasicNameValuePair(matcher.group(1).toString(), matcher.group(2).toString()));
+            postData.add(new BasicNameValuePair(matcher.group(1).toString(),
+                    matcher.group(2).toString()));
         }
 
         // Our data + button value
-        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", username));
-        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$password", password));
-        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$ctl00", "Logga in"));
+        postData.add(new BasicNameValuePair(
+                "ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", username));
+        postData.add(
+                new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$password",
+                        password));
+        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$ctl00",
+                "Logga in"));
 
         return new LoginPackage(urlopen, postData, response, EasyCard.URL);
     }
@@ -91,10 +110,10 @@ public class EasyCard extends Bank {
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
-        response        = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
         // The string "Valuta" is always present on successful login.
-        if(response.contains("Inloggningen misslyckades")) {
+        if (response.contains("Inloggningen misslyckades")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         } else if (response.contains("sedan du") || !response.contains("Valuta")) {
             throw new BankException(res.getText(R.string.unable_to_login).toString());
@@ -104,10 +123,11 @@ public class EasyCard extends Bank {
 
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
-    
+
         super.update();
 
-        if (username == null || password == null || username.length() != 9 || password.length() == 0) {
+        if (username == null || password == null || username.length() != 9
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -118,20 +138,25 @@ public class EasyCard extends Bank {
 
         if (matcher.find()) {
             // Our data!
-            String account_number           = matcher.group(1).toString().trim(); // 123123123
-            
-            if(!account_number.equalsIgnoreCase(this.username)) {
+            String account_number = matcher.group(1).toString().trim(); // 123123123
+
+            if (!account_number.equalsIgnoreCase(this.username)) {
                 throw new BankException(res.getText(R.string.unable_to_login).toString());
             }
-            
-            BigDecimal credit_left_amount   = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3 748,87
-            BigDecimal credit_amount        = Helpers.parseBalance(matcher.group(4).toString().trim()); // 30 000,00
-            BigDecimal credit_spent_amount  = credit_amount.subtract(credit_left_amount).negate(); // 26 251,13
-            
+
+            BigDecimal credit_left_amount = Helpers.parseBalance(
+                    matcher.group(2).toString().trim()); // 3 748,87
+            BigDecimal credit_amount = Helpers.parseBalance(
+                    matcher.group(4).toString().trim()); // 30 000,00
+            BigDecimal credit_spent_amount = credit_amount.subtract(credit_left_amount)
+                    .negate(); // 26 251,13
+
             // Construct accounts
-            Account credit_spent = new Account("Saldo", credit_spent_amount, this.username + ":saldo", Account.CCARD);
-            Account credit_left  = new Account("Kredit", credit_left_amount, this.username + ":kredit", Account.OTHER);
-            
+            Account credit_spent = new Account("Saldo", credit_spent_amount,
+                    this.username + ":saldo", Account.CCARD);
+            Account credit_left = new Account("Kredit", credit_left_amount,
+                    this.username + ":kredit", Account.OTHER);
+
             accounts.add(credit_spent);
             accounts.add(credit_left);
         }
@@ -143,28 +168,27 @@ public class EasyCard extends Bank {
 
         super.updateComplete();
     }
-    
+
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
-            BankException, IOException
-    {
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
-        
+
         // Find transactions
-        Matcher matcher                     = reTransactions.matcher(response);
+        Matcher matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-     
+
         while (matcher.find()) {
-            String date         = matcher.group(1).toString().trim(); // 2013-01-15
-            String transaction  = matcher.group(2).toString().trim(); // EBG HOSPITALITY
-            BigDecimal amount   = Helpers.parseBalance(matcher.group(3).toString()); // 214,00
+            String date = matcher.group(1).toString().trim(); // 2013-01-15
+            String transaction = matcher.group(2).toString().trim(); // EBG HOSPITALITY
+            BigDecimal amount = Helpers.parseBalance(matcher.group(3).toString()); // 214,00
 
             transactions.add(new Transaction(date, transaction, amount.negate()));
         }
-        
+
         account.setTransactions(transactions);
     }
-    
+
     @Override
     public void closeConnection() {
         super.closeConnection();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index b576c12..8b08872 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -36,6 +33,9 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -43,7 +43,9 @@ import java.util.List;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class EspressoHouse extends Bank {
+
     private static final String API_URL = "http://www.espressohouse.com/coffee-card/min-sida/";
+
     private Document dResponse = null;
 
     public EspressoHouse(Context context) {
@@ -52,7 +54,8 @@ public class EspressoHouse extends Bank {
         NAME = "Espresso House";
         NAME_SHORT = "espressohouse";
         BANKTYPE_ID = IBankTypes.ESPRESSOHOUSE;
-        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+                | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
         INPUT_TITLETEXT_USERNAME = R.string.email;
     }
 
@@ -70,11 +73,14 @@ public class EspressoHouse extends Bank {
         urlopen.setFollowRedirects(false);
         postData.add(new BasicNameValuePair("__EVENTTARGET",
                 "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$LoginButton"));
-        postData.add(new BasicNameValuePair("ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$UserName",
+        postData.add(new BasicNameValuePair(
+                "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$UserName",
                 username));
-        postData.add(new BasicNameValuePair("ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$Password",
+        postData.add(new BasicNameValuePair(
+                "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$Password",
                 password));
-        HttpResponse httpResponse = urlopen.openAsHttpResponse("http://www.espressohouse.com/coffee-card/logga-inladda/", postData, true);
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(
+                "http://www.espressohouse.com/coffee-card/logga-inladda/", postData, true);
         LoginPackage lp = new LoginPackage(urlopen, postData, null, API_URL);
         if (httpResponse.getStatusLine().getStatusCode() == 302) {
             lp.setIsLoggedIn(true);
@@ -94,7 +100,8 @@ public class EspressoHouse extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -111,7 +118,8 @@ public class EspressoHouse extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException {
         List<Element> eBalance = dResponse.select(".lineTotalAmount");
         List<Element> eTransaction = dResponse.select(".lineTime");
         List<Transaction> transactions = new ArrayList<>();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 370b5f6..e2f3c84 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -16,21 +16,25 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class EurobonusMastercard extends SEBKortBase {
+
     private static final String TAG = "EurobonusMastercard";
+
     private static final String NAME = "SAS EuroBonus MasterCard (Sweden)";
+
     private static final String NAME_SHORT = "ebmaster";
+
     private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
 
     public EurobonusMastercard(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index fa9e560..62e891c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -16,21 +16,25 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class EurobonusMastercardDk extends SEBKortBase {
+
     private static final String TAG = "EurobonusMastercardDk";
+
     private static final String NAME = "SAS EuroBonus MasterCard (Denmark)";
+
     private static final String NAME_SHORT = "ebmaster_dk";
+
     private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_DK;
 
     public EurobonusMastercardDk(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index 1170215..ee66bc5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -16,35 +16,39 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class EurobonusMastercardNo extends SEBKortBase {
-	private static final String TAG = "EurobonusMastercardNo";
-	private static final String NAME = "SAS EuroBonus MasterCard (Norway)";
-	private static final String NAME_SHORT = "ebmaster_no";
-	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_NO;
-
-	public EurobonusMastercardNo(Context context) {
-		super(context, "sano", "0117");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
+
+    private static final String TAG = "EurobonusMastercardNo";
+
+    private static final String NAME = "SAS EuroBonus MasterCard (Norway)";
+
+    private static final String NAME_SHORT = "ebmaster_no";
+
+    private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_NO;
+
+    public EurobonusMastercardNo(Context context) {
+        super(context, "sano", "0117");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
         super.currency = "NOK";
     }
-	
-	public EurobonusMastercardNo(String username, String password, Context context)
+
+    public EurobonusMastercardNo(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
-		super(username, password, context, "sano", "0117");
-	}
+        super(username, password, context, "sano", "0117");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
index b6b6a51..1a295dc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -16,25 +16,29 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class Eurocard extends SEBKortBase {
-	private static final String TAG = "Eurocard";
-	private static final String NAME = "Eurocard";
-	private static final String NAME_SHORT = "eurocard";
-	private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
+
+    private static final String TAG = "Eurocard";
+
+    private static final String NAME = "Eurocard";
+
+    private static final String NAME_SHORT = "eurocard";
+
+    private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
 
     public Eurocard(Context context) {
-        super(context, "ecse", "0005", "secure.eurocard.se", new int[] {R.raw.cert_eurocard});
+        super(context, "ecse", "0005", "secure.eurocard.se", new int[]{R.raw.cert_eurocard});
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
@@ -43,7 +47,8 @@ public class Eurocard extends SEBKortBase {
 
     public Eurocard(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
-        super(username, password, context, "ecse", "0005", "secure.eurocard.se", new int[] {R.raw.cert_eurocard});
+        super(username, password, context, "ecse", "0005", "secure.eurocard.se",
+                new int[]{R.raw.cert_eurocard});
     }
-	
+
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index fd5c7fe..10a9369 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -17,122 +17,138 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-//import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
+//import com.liato.bankdroid.banking.Transaction;
+
 public class Everydaycard extends Bank {
-	private static final String TAG = "Everydaycard";
-	private static final String NAME = "Everydaycard";
-	private static final String NAME_SHORT = "everydaycard";
-	private static final String URL = "http://www.everydaycard.se/mobil/";
-	private static final int BANKTYPE_ID = IBankTypes.EVERYDAYCARD;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
+    private static final String TAG = "Everydaycard";
+
+    private static final String NAME = "Everydaycard";
+
+    private static final String NAME_SHORT = "everydaycard";
+
+    private static final String URL = "http://www.everydaycard.se/mobil/";
+
+    private static final int BANKTYPE_ID = IBankTypes.EVERYDAYCARD;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-	
-	private Pattern reSaldo = Pattern.compile("Utnyttjad kredit \\(sek\\)</td>\\s*<td></td>\\s*<td>([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reBonus = Pattern.compile("Aktuell bonus \\(sek\\)</td>\\s*<td>.*</td>\\s*<td>([^<]+)<", Pattern.CASE_INSENSITIVE);
-//	private Pattern reAccountTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reSaldo = Pattern.compile(
+            "Utnyttjad kredit \\(sek\\)</td>\\s*<td></td>\\s*<td>([^<]+)<",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reBonus = Pattern.compile(
+            "Aktuell bonus \\(sek\\)</td>\\s*<td>.*</td>\\s*<td>([^<]+)<",
+            Pattern.CASE_INSENSITIVE);
+
+    //	private Pattern reAccountTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 //	private Pattern reBonusTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	public Everydaycard(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public Everydaycard(String username, String password, Context context)
+    private String response = null;
+
+    public Everydaycard(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public Everydaycard(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-    
+        this(context);
+        this.update(username, password);
+    }
+
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-    	return preLoginInternal("http://valuta.g2solutions.se/mobil/web/logonSubmit.do");
+        return preLoginInternal("http://valuta.g2solutions.se/mobil/web/logonSubmit.do");
     }
-    
+
 //    private LoginPackage preLoginNonMobile() throws BankException,
 //            ClientProtocolException, IOException {
 //    	return preLoginInternal("https://valuta.g2solutions.se/valuta/web/logonSubmit.do");
 //    }
 
     private LoginPackage preLoginInternal(String url) throws BankException, IOException {
-    	urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
-    	List <NameValuePair> postData = new ArrayList <NameValuePair>();
-    	postData.add(new BasicNameValuePair("nextPage", "firstPage"));                
-    	postData.add(new BasicNameValuePair("username", username));
-    	postData.add(new BasicNameValuePair("password", password));
-    	return new LoginPackage(urlopen, postData, response, url);
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("nextPage", "firstPage"));
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        return new LoginPackage(urlopen, postData, response, url);
     }
-    
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		//LoginPackage lp = preLoginNonMobile();
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("Felaktigt Login")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-	
-		Matcher matcher = reBonus.matcher(response);
- 		if (matcher.find()) {
- 			BigDecimal bonusBalance = Helpers.parseBalance(matcher.group(1));
-			Account account = new Account("Bonus", bonusBalance, "Bonus", Account.OTHER);
-			balance = balance.add(bonusBalance);
-			accounts.add(account);
-		}
-
-		matcher = reSaldo.matcher(response);
- 		if (matcher.find()) {
- 			BigDecimal accountBalance = Helpers.parseBalance(matcher.group(1)).negate();
-			Account account = new Account("Everydaycard", accountBalance, "1", Account.CCARD);
-			balance = balance.add(accountBalance);
-			accounts.add(account);
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        //LoginPackage lp = preLoginNonMobile();
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Felaktigt Login")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        Matcher matcher = reBonus.matcher(response);
+        if (matcher.find()) {
+            BigDecimal bonusBalance = Helpers.parseBalance(matcher.group(1));
+            Account account = new Account("Bonus", bonusBalance, "Bonus", Account.OTHER);
+            balance = balance.add(bonusBalance);
+            accounts.add(account);
+        }
+
+        matcher = reSaldo.matcher(response);
+        if (matcher.find()) {
+            BigDecimal accountBalance = Helpers.parseBalance(matcher.group(1)).negate();
+            Account account = new Account("Everydaycard", accountBalance, "1", Account.CCARD);
+            balance = balance.add(accountBalance);
+            accounts.add(account);
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
+    }
 
 //	@Override
 //    public void updateAllTransactions() throws LoginException, BankException {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 95ace26..80a4b75 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -16,97 +16,112 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class FirstCard extends Bank {
-	private static final String TAG = "FirstCard";
-	private static final String NAME = "First Card";
-	private static final String NAME_SHORT = "firstcard";
-	private static final String URL = "https://www.firstcard.se/login.jsp";
-	private static final int BANKTYPE_ID = IBankTypes.FIRSTCARD;
+
+    private static final String TAG = "FirstCard";
+
+    private static final String NAME = "First Card";
+
+    private static final String NAME_SHORT = "firstcard";
+
+    private static final String URL = "https://www.firstcard.se/login.jsp";
+
+    private static final int BANKTYPE_ID = IBankTypes.FIRSTCARD;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-	
-	private Pattern reAccounts = Pattern.compile("translist\\.jsp\\?p=a&(?:amp;)?cardID=([^\"]+)\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("pagecolumns\">(\\d{6})</td>\\s*<td>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	public FirstCard(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public FirstCard(String username, String password, Context context) throws BankException,
+
+    private Pattern reAccounts = Pattern.compile(
+            "translist\\.jsp\\?p=a&(?:amp;)?cardID=([^\"]+)\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "pagecolumns\">(\\d{6})</td>\\s*<td>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<",
+            Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    public FirstCard(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public FirstCard(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_firstcard));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_firstcard));
         response = urlopen.open("https://www.firstcard.se/login.jsp");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("op", "login"));                
-        postData.add(new BasicNameValuePair("errorpage", "login.jsp"));                
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("op", "login"));
+        postData.add(new BasicNameValuePair("errorpage", "login.jsp"));
         postData.add(new BasicNameValuePair("pnr", username));
         postData.add(new BasicNameValuePair("intpwd", password));
         return new LoginPackage(urlopen, postData, null, "https://www.firstcard.se/login.jsp");
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("Logga in med din kod")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-
-		response = urlopen.open("https://www.firstcard.se/mkol/index.jsp");
-		Matcher matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
-			/*
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Logga in med din kod")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        response = urlopen.open("https://www.firstcard.se/mkol/index.jsp");
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
+                        /*
 			 * Capture groups:
 			 * GROUP				EXAMPLE DATA
 			 * 1: id				kdKPq4ghlcy9wpXymSzzS46wWQcS_0OT
@@ -114,26 +129,28 @@ public class FirstCard extends Bank {
 			 * 3: amount 			9 824,08
 			 *
 			 */
-			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-		}
+            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+        }
 
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
 
         super.updateComplete();
-	}
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
+        super.updateTransactions(account, urlopen);
 
-		response = urlopen.open("https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
-		Matcher matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
+        response = urlopen.open(
+                "https://www.firstcard.se/mkol/translist.jsp?p=a&cardID=" + account.getId());
+        Matcher matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
 			/*
 			 * Capture groups:
 			 * GROUP						EXAMPLE DATA
@@ -144,10 +161,13 @@ public class FirstCard extends Bank {
 			 * 5: amount in local currency	24,08
 			 *
 			 */
-			String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
-			strDate = "20"+strDate.charAt(0)+strDate.charAt(1)+"-"+strDate.charAt(2)+strDate.charAt(3)+"-"+strDate.charAt(4)+strDate.charAt(5);
-			transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)).negate()));
-		}
-		account.setTransactions(transactions);
-	}
+            String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
+            strDate = "20" + strDate.charAt(0) + strDate.charAt(1) + "-" + strDate.charAt(2)
+                    + strDate.charAt(3) + "-" + strDate.charAt(4) + strDate.charAt(5);
+            transactions.add(new Transaction(strDate,
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(5)).negate()));
+        }
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index ece96f9..3e92776 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -1,60 +1,80 @@
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.util.EntityUtils;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ForexBank extends Bank {
+
     // Logon url: https://nettbank.edb.com/mobilepayment/index.jsp?n_bank=0087&nativeapp=android
     private static final String TAG = "ForexBank";
+
     private static final String NAME = "Forex Bank";
+
     private static final String NAME_SHORT = "forex";
+
     private static final String URL = "https://www.forex.se/";
+
     private static final int BANKTYPE_ID = IBankTypes.FOREX;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
     private static final boolean STATIC_BALANCE = false;
+
     private static final String BASE_URL = "https://nettbank.edb.com";
 
     private Pattern reFormAction = Pattern.compile("form action=\"(.*)\"\\s", Pattern.MULTILINE);
+
     private Pattern reTranId = Pattern.compile("p_tranid\" value=\"(\\d+)\"", Pattern.MULTILINE);
-    private Pattern reFallbackQuery = Pattern.compile("fallbackQuery\"\\svalue=\"(.*)\"", Pattern.MULTILINE);
 
-    private Pattern reAccountIds = Pattern.compile("ransactions\\?cvokey=(.\\d+)", Pattern.MULTILINE);
-    private Pattern reAccountNumbers = Pattern.compile("account_number.*\\>(\\d+)", Pattern.MULTILINE);
+    private Pattern reFallbackQuery = Pattern.compile("fallbackQuery\"\\svalue=\"(.*)\"",
+            Pattern.MULTILINE);
+
+    private Pattern reAccountIds = Pattern.compile("ransactions\\?cvokey=(.\\d+)",
+            Pattern.MULTILINE);
+
+    private Pattern reAccountNumbers = Pattern.compile("account_number.*\\>(\\d+)",
+            Pattern.MULTILINE);
+
     private Pattern reAccountName = Pattern.compile("account_name.*\\>(.+)<", Pattern.MULTILINE);
-    private Pattern reAccountBalance = Pattern.compile("balance.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
-    private Pattern reDisposable = Pattern.compile("disposable.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
 
-    private Pattern reTransactions = Pattern.compile("item\\stransaction.+?(\\d{4}-\\d{2}-\\d{2}?).+?(-?\\d+,\\d{2}).*?left\">\\s+(.+?)\\s+</div>", Pattern.MULTILINE | Pattern.DOTALL);
+    private Pattern reAccountBalance = Pattern.compile("balance.*\\>(\\d+,\\d\\d)",
+            Pattern.MULTILINE);
+
+    private Pattern reDisposable = Pattern.compile("disposable.*\\>(\\d+,\\d\\d)",
+            Pattern.MULTILINE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "item\\stransaction.+?(\\d{4}-\\d{2}-\\d{2}?).+?(-?\\d+,\\d{2}).*?left\">\\s+(.+?)\\s+</div>",
+            Pattern.MULTILINE | Pattern.DOTALL);
 
     public ForexBank(Context context) {
         super(context);
@@ -77,33 +97,32 @@ public class ForexBank extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_forexbank));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_forexbank));
         String baseUrl = "https://nettbank.edb.com";
-        String res = urlopen.open(baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
+        String res = urlopen.open(
+                baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
         String formAction = "";
         String tranId = "";
         String fallbackQuery = "";
 
         // Get post action
         Matcher mFormAction = reFormAction.matcher(res);
-        if(mFormAction.find())
-        {
+        if (mFormAction.find()) {
             formAction = mFormAction.group(1);
             //System.err.println(mFormAction.group(1));
         }
 
         // Get transaction id hidden param
         Matcher mTranId = reTranId.matcher(res);
-        if(mTranId.find())
-        {
+        if (mTranId.find()) {
             tranId = mTranId.group(1);
             //System.err.println(mTranId.group(1));
         }
 
         // Weird param, lets include it!
         Matcher mFallbackQuery = reFallbackQuery.matcher(res);
-        if(mFallbackQuery.find())
-        {
+        if (mFallbackQuery.find()) {
             fallbackQuery = mFallbackQuery.group(1);
             //System.err.println(mTranId.group(1));
         }
@@ -125,11 +144,12 @@ public class ForexBank extends Bank {
         LoginPackage lp = preLogin();
 
         // Post
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(BASE_URL + lp.getLoginTarget(), lp.getPostData(), false);
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(BASE_URL + lp.getLoginTarget(),
+                lp.getPostData(), false);
 
         String result = EntityUtils.toString(httpResponse.getEntity());
 
-        if(!result.contains("/mobilepayment/transigo/logon/logout")) {
+        if (!result.contains("/mobilepayment/transigo/logon/logout")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
@@ -138,7 +158,8 @@ public class ForexBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         /*
@@ -156,7 +177,7 @@ public class ForexBank extends Bank {
 
         // Go to main menu
         String result = urlopen.open("https://nettbank.edb.com/mobilepayment/transigo/menu/menu1");
-        result = result.replace("&nbsp;",""); // Remove non-breaking spaces, they fuck up balances
+        result = result.replace("&nbsp;", ""); // Remove non-breaking spaces, they fuck up balances
 
         Matcher mAccountIds = reAccountIds.matcher(result);
         Matcher mAccountNumbers = reAccountNumbers.matcher(result);
@@ -164,12 +185,16 @@ public class ForexBank extends Bank {
         Matcher mAccountBalances = reAccountBalance.matcher(result);
         Matcher mDisposables = reDisposable.matcher(result);
 
-        while(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
-            if(!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
-                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mDisposables.group(1).trim()), mAccountIds.group(1))); //Disponibelt
-            }
-            else {
-                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(1).trim()), mAccountIds.group(1)));
+        while (mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find()
+                && mAccountBalances.find()) {
+            if (!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
+                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(),
+                        Helpers.parseBalance(mDisposables.group(1).trim()),
+                        mAccountIds.group(1))); //Disponibelt
+            } else {
+                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(),
+                        Helpers.parseBalance(mAccountBalances.group(1).trim()),
+                        mAccountIds.group(1)));
             }
 
             balance = balance.add(Helpers.parseBalance(mAccountBalances.group(1)));
@@ -184,14 +209,17 @@ public class ForexBank extends Bank {
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
-        String accountId = account.getId(); 
+        String accountId = account.getId();
         Matcher matcher;
-        String response = urlopen.open(BASE_URL + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey=" + accountId);
+        String response = urlopen.open(BASE_URL
+                + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey="
+                + accountId);
         response = response.replace("&nbsp;", "");
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
-            transactions.add(new Transaction(matcher.group(1).trim(), matcher.group(3).trim(), Helpers.parseBalance(matcher.group(2))));
+            transactions.add(new Transaction(matcher.group(1).trim(), matcher.group(3).trim(),
+                    Helpers.parseBalance(matcher.group(2))));
         }
         account.setTransactions(transactions);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 2dc3b34..a568dff 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -17,146 +17,169 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Handelsbanken extends Bank {
-	private static final String TAG = "Handelsbanken";
-	private static final String NAME = "Handelsbanken";
-	private static final String NAME_SHORT = "handelsbanken";
-	private static final String URL = "https://m.handelsbanken.se/";
-	private static final int BANKTYPE_ID = IBankTypes.HANDELSBANKEN;
+
+    private static final String TAG = "Handelsbanken";
+
+    private static final String NAME = "Handelsbanken";
+
+    private static final String NAME_SHORT = "handelsbanken";
+
+    private static final String URL = "https://m.handelsbanken.se/";
+
+    private static final int BANKTYPE_ID = IBankTypes.HANDELSBANKEN;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
-	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"[^\"]*?/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK(?:&nbsp;|\\s*)?([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
-	private Pattern reLoginUrl = Pattern.compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Logga",Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE);
-
-	private ArrayList<String> accountIds = new ArrayList<String>();
-	private String response = null;
-	
-	public Handelsbanken(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public Handelsbanken(String username, String password, Context context) throws BankException,
+    private Pattern reBalance = Pattern.compile(
+            "block-link\\s*\"\\s*href=\"[^\"]*?/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK(?:&nbsp;|\\s*)?([0-9\\s.,-ÃÂ]+)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reAccountsUrl = Pattern
+            .compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Konton<",
+                    Pattern.CASE_INSENSITIVE);
+
+    private Pattern reLoginUrl = Pattern
+            .compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Logga",
+                    Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<",
+            Pattern.CASE_INSENSITIVE);
+
+    private ArrayList<String> accountIds = new ArrayList<String>();
+
+    private String response = null;
+
+    public Handelsbanken(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public Handelsbanken(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-	
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
         response = urlopen.open("https://m.handelsbanken.se/primary/");
         Matcher matcher = reLoginUrl.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login url.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login url.");
         }
-        String strLoginUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        String strLoginUrl = "https://m.handelsbanken.se/primary/_-" + matcher.group(1);
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("pin", password));
         postData.add(new BasicNameValuePair("execute", "true"));
         return new LoginPackage(urlopen, postData, response, strLoginUrl);
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("ontrollera dina uppgifter")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("ontrollera dina uppgifter")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
 
         Matcher matcher = reAccountsUrl.matcher(response);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
-		}
-		String strAccountsUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);
-		response = urlopen.open(strAccountsUrl);
-		matcher = reBalance.matcher(response);
-		Integer accountId = 0;
-		while (matcher.find()) {
-			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			accountIds.add(matcher.group(1));
-			accountId += 1;
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " accounts url.");
+        }
+        String strAccountsUrl = "https://m.handelsbanken.se/primary/_-" + matcher.group(1);
+        response = urlopen.open(strAccountsUrl);
+        matcher = reBalance.matcher(response);
+        Integer accountId = 0;
+        while (matcher.find()) {
+            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+            accountIds.add(matcher.group(1));
+            accountId += 1;
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
-	
+    }
 
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
-		Matcher matcher;
-		String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-		response = urlopen.open("https://m.handelsbanken.se/primary/_-"+accountWebId);
-		matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
-			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-		}
-
-		// Sort transactions by date
-		Collections.sort(transactions, new Comparator<Transaction>() {
-                public int compare(Transaction t1, Transaction t2) {
-                   return t2.compareTo(t1);
-                }
+        super.updateTransactions(account, urlopen);
+        Matcher matcher;
+        String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
+        response = urlopen.open("https://m.handelsbanken.se/primary/_-" + accountWebId);
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
+        }
+
+        // Sort transactions by date
+        Collections.sort(transactions, new Comparator<Transaction>() {
+            public int compare(Transaction t1, Transaction t2) {
+                return t2.compareTo(t1);
+            }
         });
         account.setTransactions(transactions);
-	}
+    }
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index 93b3301..d36685f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -17,13 +17,17 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -33,28 +37,29 @@ import org.jsoup.select.Elements;
 import android.content.Context;
 import android.text.InputType;
 import android.text.TextUtils;
-import android.util.Log;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Hemkop extends Bank {
+
     private static final String TAG = "Hemkop";
+
     private static final String NAME = "Hemköp Kundkort";
+
     private static final String NAME_SHORT = "hemkop";
+
     private static final String URL = "https://www.hemkop.se/Mina-sidor/Logga-in/";
+
     private static final int BANKTYPE_ID = IBankTypes.HEMKOP;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
 
     private String response = null;
@@ -77,28 +82,29 @@ public class Hemkop extends Bank {
     }
 
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_hemkop));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_hemkop));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.hemkop.se/Mina-sidor/Logga-in/");
-        
+
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("__VIEWSTATE");
         if (e == null || e.attr("value") == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = e.attr("value");
 
         e = d.getElementById("__EVENTVALIDATION");
         if (e == null || e.attr("value") == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
         String eventValidation = e.attr("value");
-        
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl00$MainContent$BtnLogin"));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
@@ -108,7 +114,8 @@ public class Hemkop extends Bank {
         postData.add(new BasicNameValuePair("ctl00$uiTopMenu$Search", ""));
         postData.add(new BasicNameValuePair("ctl00$MainContent$tbUsername", username));
         postData.add(new BasicNameValuePair("ctl00$MainContent$tbPassword", password));
-        return new LoginPackage(urlopen, postData, response, "https://www.hemkop.se/Mina-sidor/Logga-in/");
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.hemkop.se/Mina-sidor/Logga-in/");
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
@@ -124,23 +131,25 @@ public class Hemkop extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
         urlopen = login();
-        
+
         Document d = Jsoup.parse(response);
-    	Elements amounts = d.select(".bonusStatement .amount");
-    	Elements names = d.select(".bonusStatement .label");
+        Elements amounts = d.select(".bonusStatement .amount");
+        Elements names = d.select(".bonusStatement .label");
         for (int i = 0; i < Math.min(amounts.size(), names.size()); i++) {
-        	Element amount = amounts.get(i);
-        	Element name = names.get(i);
-    		BigDecimal accountBalance = Helpers.parseBalance(amount.ownText());
-    		Account account = new Account(name.ownText().replace(":", "").trim(), accountBalance, String.format("acc_%d", i));
-    		if (i > 0) {
-    			account.setAliasfor("acc_0");
-    		}
+            Element amount = amounts.get(i);
+            Element name = names.get(i);
+            BigDecimal accountBalance = Helpers.parseBalance(amount.ownText());
+            Account account = new Account(name.ownText().replace(":", "").trim(), accountBalance,
+                    String.format("acc_%d", i));
+            if (i > 0) {
+                account.setAliasfor("acc_0");
+            }
             accounts.add(account);
             balance = balance.add(accountBalance);
         }
@@ -148,31 +157,32 @@ public class Hemkop extends Bank {
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
-        
+
         Account account = accounts.get(0);
 
         response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
         d = Jsoup.parse(response);
-    	Elements es = d.select(".transactions tbody tr");
+        Elements es = d.select(".transactions tbody tr");
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         for (Element e : es) {
             Transaction t = new Transaction(e.child(1).ownText().trim(),
-            					e.child(0).ownText().trim(),
+                    e.child(0).ownText().trim(),
                     Helpers.parseBalance(e.child(3).ownText()));
             if (!TextUtils.isEmpty(e.child(2).ownText())) {
                 t.setCurrency(Helpers.parseCurrency(e.child(2).ownText().trim(), "SEK"));
             }
             transactions.add(t);
-    	}
+        }
         account.setTransactions(transactions);
 
         es = d.select(".currentBalance,.disposable");
         int i = 0;
         for (Element e : es) {
-        	Account a = new Account(e.child(0).ownText().trim(), Helpers.parseBalance(e.child(1).ownText()), String.format("acc_cc_%d", i));
-        	a.setAliasfor("acc_0");
-        	accounts.add(a);
-        	i++;
+            Account a = new Account(e.child(0).ownText().trim(),
+                    Helpers.parseBalance(e.child(1).ownText()), String.format("acc_cc_%d", i));
+            a.setAliasfor("acc_0");
+            accounts.add(a);
+            i++;
         }
 
         super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
index 96db0e6..0ca9fff 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
@@ -15,21 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class IKEA extends AbsIkanoPartner {
+
     private static final String TAG = "IKEA";
+
     private static final String NAME = "IKEA HANDLA kort";
+
     private static final String NAME_SHORT = "ikea";
-    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
+
+    private static final String URL
+            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
+
     private static final int BANKTYPE_ID = Bank.IKEA;
 
     public IKEA(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 7259cf4..aecca66 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -16,14 +16,17 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
@@ -31,34 +34,50 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class IkanoBank extends Bank {
+
     private static final String TAG = "IkanoBank";
+
     private static final String NAME = "Ikano Bank";
+
     private static final String NAME_SHORT = "ikanobank";
+
     private static final String URL = "https://secure.ikanobank.se/engines/page.aspx?structid=1895";
+
     private static final int BANKTYPE_ID = IBankTypes.IKANOBANK;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reErrorMessage = Pattern.compile("<div\\s*class=\"(?:error|message)-box-inner\">\\s*<div>\\s*<p>(.+)</p");
+    private Pattern reEventValidation = Pattern.compile(
+            "__EVENTVALIDATION\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reAccounts = Pattern.compile(
+            "(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reErrorMessage = Pattern.compile(
+            "<div\\s*class=\"(?:error|message)-box-inner\">\\s*<div>\\s*<p>(.+)</p");
+
     private String response = null;
 
     public IkanoBank(Context context) {
@@ -80,30 +99,32 @@ public class IkanoBank extends Bank {
     }
 
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanobank));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_ikanobank));
         response = urlopen.open("https://secure.ikanobank.se/login");
         Matcher matcher;
         if (response.contains("Banken är stängd")) {
             matcher = reErrorMessage.matcher(response);
             if (matcher.find()) {
                 throw new BankException(Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
-            } 
+            }
         }
         matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String strViewState = matcher.group(1);
         matcher = reEventValidation.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
         String strEventValidation = matcher.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
         postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl02$lbLogin"));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
@@ -111,19 +132,22 @@ public class IkanoBank extends Bank {
         postData.add(new BasicNameValuePair("ctl02$txtSocialSecurityNumber", username));
         postData.add(new BasicNameValuePair("ctl02$txtPinCode", password));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        return new LoginPackage(urlopen, postData, response, "https://secure.ikanobank.se/engines/page.aspx?structid=1895");
+        return new LoginPackage(urlopen, postData, response,
+                "https://secure.ikanobank.se/engines/page.aspx?structid=1895");
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("Ogiltigt personnummer") || response.contains("felaktigt personnummer")) {
+        if (response.contains("Ogiltigt personnummer") || response.contains(
+                "felaktigt personnummer")) {
             Matcher matcher = reErrorMessage.matcher(response);
             if (matcher.find()) {
-                throw new LoginException(Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
-            }
-            else {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+                throw new LoginException(
+                        Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
+            } else {
+                throw new LoginException(
+                        res.getText(R.string.invalid_username_password).toString());
             }
 
         }
@@ -133,7 +157,8 @@ public class IkanoBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -148,8 +173,9 @@ public class IkanoBank extends Bank {
              * 3: Account number        123456
              * 4: Balance               316 000,39
              * 
-             */    
-            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()), matcher.group(1).trim()));
+             */
+            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4).trim()), matcher.group(1).trim()));
             balance = balance.add(Helpers.parseBalance(matcher.group(4)));
         }
 
@@ -177,14 +203,15 @@ public class IkanoBank extends Bank {
             Log.e(TAG, "Unable to find EventValidation. L161.");
             return;
         }
-        String strEventValidation = matcher.group(1);       
+        String strEventValidation = matcher.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__EVENTTARGET", account.getId().replace("_", "$")));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
+        response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787",
+                postData);
 
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index ac510ca..926bfca 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -16,26 +16,25 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -45,12 +44,19 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Jojo extends Bank {
+
     private static final String TAG = "Jojo";
+
     private static final String NAME = "Jojo Reskassa";
+
     private static final String NAME_SHORT = "jojo";
+
     private static final String URL = "https://www.shop.skanetrafiken.se";
+
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+            | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 
     private static final String NAME_NOT_SET = "KortnamnSaknas";
 
@@ -98,7 +104,8 @@ public class Jojo extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -106,7 +113,7 @@ public class Jojo extends Bank {
         Document d = Jsoup.parse(response);
         Elements cards = d.select(".my_cards_allinfo table tbody");
         if (!cards.isEmpty()) {
-            for(Element card : cards) {
+            for (Element card : cards) {
                 String cardNumber = card.select("tr:first-child td").text().trim();
                 BigDecimal saldo = getSaldo(cardNumber);
                 String name = card.select("tr:nth-child(2) td").text().trim();
@@ -126,13 +133,13 @@ public class Jojo extends Bank {
     private BigDecimal getSaldo(String cardNumber) {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("cardno", cardNumber));
-        postData.add(new BasicNameValuePair("fromlist","1"));
+        postData.add(new BasicNameValuePair("fromlist", "1"));
         postData.add(new BasicNameValuePair("ST_CHECK_SALDO", "1"));
         try {
-            String saldoData = urlopen.open(URL + "/saldodata.html",postData,true);
+            String saldoData = urlopen.open(URL + "/saldodata.html", postData, true);
             Document saldoDocument = Jsoup.parse(saldoData);
             Elements saldo = saldoDocument.select("td.greenrow.right h3");
-            if(!saldo.isEmpty()) {
+            if (!saldo.isEmpty()) {
                 return Helpers.parseBalance(saldo.first().text().trim());
             }
         } catch (IOException e) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index 2b8f392..a1e1da2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -1,13 +1,16 @@
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
@@ -15,38 +18,51 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Marginalen extends Bank {
-	private static final String TAG = "Marginalen";
+
+    private static final String TAG = "Marginalen";
+
     private static final String NAME = "Marginalen Bank";
+
     private static final String NAME_SHORT = "marginalen";
+
     private static final String BASE_URL = "https://secure1.marginalen.se/marginalen/";
-	private static final int BANKTYPE_ID = IBankTypes.MARGINALEN;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
+    private static final int BANKTYPE_ID = IBankTypes.MARGINALEN;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-	
-	private Pattern reLoginLink = Pattern.compile("href=\"(engine\\?usecase=pin&[a-zA-Z0-9;=&._]+)");
-	private Pattern reHash = Pattern.compile("name=\"hash\" value=\"([a-zA-Z0-9]+)\"");
-	private Pattern reGuid = Pattern.compile("name=\"guid\" value=\"([a-zA-Z0-9]+)\"");
-	private Pattern reAccountLink = Pattern.compile("href=\"(engine\\?[a-zA-Z0-9;=&._]+menuid=15[a-zA-Z0-9;=&._]+)\"");
-	private Pattern reAccounts = Pattern.compile("<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td>\\s*<a href=\"(engine\\?usecase=account[a-zA-Z0-9;=&._]+)\">([0-9]+)</a>\\s*</td>\\s*<td class=\"aright\">\\s*([0-9.,]+)\\s*[a-zA-Z&;]+\\s*</td>");
-	private Pattern reTransactions = Pattern.compile("href=\"engine\\?usecase=transactiondetails.*tabindex=\"4\">([0-9\\-]+)</a>\\s*</td>\\s*<td>\\s*(.*?)\\s*</td>\\s*<td class=\"aright\">\\s*([\\-0-9\\.,]+)&nbsp;");
-	
-	private String accountUrl = "";
-    
-	String response;
+
+    String response;
+
+    private Pattern reLoginLink = Pattern
+            .compile("href=\"(engine\\?usecase=pin&[a-zA-Z0-9;=&._]+)");
+
+    private Pattern reHash = Pattern.compile("name=\"hash\" value=\"([a-zA-Z0-9]+)\"");
+
+    private Pattern reGuid = Pattern.compile("name=\"guid\" value=\"([a-zA-Z0-9]+)\"");
+
+    private Pattern reAccountLink = Pattern
+            .compile("href=\"(engine\\?[a-zA-Z0-9;=&._]+menuid=15[a-zA-Z0-9;=&._]+)\"");
+
+    private Pattern reAccounts = Pattern.compile(
+            "<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td>\\s*<a href=\"(engine\\?usecase=account[a-zA-Z0-9;=&._]+)\">([0-9]+)</a>\\s*</td>\\s*<td class=\"aright\">\\s*([0-9.,]+)\\s*[a-zA-Z&;]+\\s*</td>");
+
+    private Pattern reTransactions = Pattern.compile(
+            "href=\"engine\\?usecase=transactiondetails.*tabindex=\"4\">([0-9\\-]+)</a>\\s*</td>\\s*<td>\\s*(.*?)\\s*</td>\\s*<td class=\"aright\">\\s*([\\-0-9\\.,]+)&nbsp;");
+
+    private String accountUrl = "";
+
     public Marginalen(Context context) {
         super(context);
         super.TAG = TAG;
@@ -56,41 +72,47 @@ public class Marginalen extends Bank {
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
-    
+
     public Marginalen(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-    
+        this(context);
+        this.update(username, password);
+    }
+
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_marginalen, R.raw.cert_marginalen2));
+        urlopen = new Urllib(context, CertificateReader
+                .getCertificates(context, R.raw.cert_marginalen, R.raw.cert_marginalen2));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open(BASE_URL + "engine");
         matcher = reLoginLink.matcher(response);
 
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " login link.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login link.");
         }
         String url = BASE_URL + matcher.group(1);
         url = url.replaceAll("&amp;", "&");
         response = urlopen.open(url);
 
         matcher = reHash.matcher(response);
-        if (!matcher.find())
-        	throw new BankException(res.getText(R.string.unable_to_find).toString() + " hash value.");
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " hash value.");
+        }
 
         String hash = matcher.group(1);
 
         matcher = reGuid.matcher(response);
-        if (!matcher.find())
-        	throw new BankException(res.getText(R.string.unable_to_find).toString() + " GUID value.");
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " GUID value.");
+        }
 
         String guid = matcher.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("usecase", "base"));
         postData.add(new BasicNameValuePair("command", "formcommand"));
         postData.add(new BasicNameValuePair("commandorigin", "0.pin_logon_step1_view_handler"));
@@ -104,32 +126,35 @@ public class Marginalen extends Bank {
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
-    	LoginPackage lp = preLogin();
-    	response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
-		if (response.contains("Felmeddelande")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+        if (response.contains("Felmeddelande")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
 
-		Matcher matcher;
-		matcher = reAccountLink.matcher(response);
-		if (!matcher.find())
-        	throw new BankException(res.getText(R.string.unable_to_find).toString() + " accounts link.");
-		accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
+        Matcher matcher;
+        matcher = reAccountLink.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " accounts link.");
+        }
+        accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
 
-	    return urlopen;
+        return urlopen;
     }
-    
+
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
-    	super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-	    response = urlopen.open(accountUrl);
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        response = urlopen.open(accountUrl);
         Matcher matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -139,26 +164,28 @@ public class Marginalen extends Bank {
              * 4: Amount            100.000,00
              *
              */
-			Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2), Long.parseLong(matcher.group(3)));
-			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-			accounts.add(account);
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	    super.updateComplete();
+            Account account = new Account(Html.fromHtml(matcher.group(1)).toString(),
+                    Helpers.parseBalance(matcher.group(4)), matcher.group(2),
+                    Long.parseLong(matcher.group(3)));
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+            accounts.add(account);
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
     }
-    
+
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
-		Matcher matcher;
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        super.updateTransactions(account, urlopen);
+        Matcher matcher;
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         response = urlopen.open(BASE_URL + account.getId().replaceAll("&amp;", "&"));
 
         matcher = reTransactions.matcher(response);
         while (matcher.find()) {
-        	/*
+                /*
         	 * Capture groups:
         	 * GROUP                    EXAMPLE DATA
         	 * 1: Date                  2011-04-06
@@ -166,8 +193,10 @@ public class Marginalen extends Bank {
         	 * 3: Amount                -20
         	 *
         	 */
-        	transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
         }
-		account.setTransactions(transactions);
-	}
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 307a559..0051b93 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -16,11 +16,14 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
@@ -30,91 +33,100 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.Urllib;
 
 public class McDonalds extends Bank {
 
-	private static final String TAG = "McDonalds";
-	private static final String NAME = "McDonald's Presentkort";
-	private static final String NAME_SHORT = "mcdonalds";
-	private static final String URL = "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm";
-	private static final int BANKTYPE_ID = Bank.MCDONALDS;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-	private static final boolean INPUT_HIDDEN_PASSWORD = true;
-	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;
+    private static final String TAG = "McDonalds";
+
+    private static final String NAME = "McDonald's Presentkort";
+
+    private static final String NAME_SHORT = "mcdonalds";
+
+    private static final String URL = "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm";
+
+    private static final int BANKTYPE_ID = Bank.MCDONALDS;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
+    private static final boolean INPUT_HIDDEN_PASSWORD = true;
+
+    private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;
 
     private Pattern reBalance = Pattern.compile("saldo:\\s*([0-9,. -]+)\\s*kronor");
-    private Pattern reTransactions = Pattern.compile("<tr><td>(\\d{2}-\\d{2}-\\d{2})\\s*\\d{2}:\\d{2}</td><td>([^<]+)</td><td>[^<]+</td><td>([^<]+)</td></tr>");
-	private String response = "";
-
-	public McDonalds(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME= INPUT_TYPE_USERNAME;
-		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
-		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
-	}
-
-	public McDonalds(String username, String password, Context context) throws BankException,
+
+    private Pattern reTransactions = Pattern.compile(
+            "<tr><td>(\\d{2}-\\d{2}-\\d{2})\\s*\\d{2}:\\d{2}</td><td>([^<]+)</td><td>[^<]+</td><td>([^<]+)</td></tr>");
+
+    private String response = "";
+
+    public McDonalds(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
+        super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+    }
+
+    public McDonalds(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
 
-	@Override
-	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-		urlopen = new Urllib(context);
+    @Override
+    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+        urlopen = new Urllib(context);
 
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("__Click", "0"));
-		postData.add(new BasicNameValuePair("CardNumber", username));
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__Click", "0"));
+        postData.add(new BasicNameValuePair("CardNumber", username));
 
-		return new LoginPackage(urlopen, postData, response, "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm&Seq=1");
-	}
+        return new LoginPackage(urlopen, postData, response,
+                "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm&Seq=1");
+    }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
         if (response.contains("felaktigt kortnummer")) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
-        return urlopen;		
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || username.length() != 19) {
-			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-		}
-		login();
-		Matcher matcher = reBalance.matcher(response);
-		if (matcher.find()) {
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || username.length() != 19) {
+            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+        }
+        login();
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
              * 1: balance               845
              * 
-             */    		    
-		    Account account = new Account("Presentkort", Helpers.parseBalance(matcher.group(1)), "1");
+             */
+            Account account = new Account("Presentkort", Helpers.parseBalance(matcher.group(1)),
+                    "1");
             balance = Helpers.parseBalance(matcher.group(1));
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		    matcher = reTransactions.matcher(response);
-	        while (matcher.find()) {
+            matcher = reTransactions.matcher(response);
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
@@ -123,16 +135,16 @@ public class McDonalds extends Bank {
                  * 3: Amount                -144
                  * 
                  */
-                transactions.add(new Transaction("20"+matcher.group(1).trim(),
+                transactions.add(new Transaction("20" + matcher.group(1).trim(),
                         Html.fromHtml(matcher.group(2)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(3))));	            
+                        Helpers.parseBalance(matcher.group(3))));
                 account.setTransactions(transactions);
-	        }
+            }
             accounts.add(account);
-		}
+        }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         super.updateComplete();
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index a258223..9e7ddef 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -1,25 +1,23 @@
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -27,20 +25,33 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-public class Meniga extends Bank{
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Meniga extends Bank {
+
     private static final String TAG = "Meniga";
+
     private static final String NAME = "Meniga";
+
     private static final String NAME_SHORT = "meniga";
+
     private static final String URL = "https://www.meniga.is/";
+
     private static final int BANKTYPE_ID = IBankTypes.MENIGA;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-    private static final String INPUT_HINT_USERNAME = "name@company.com";
 
-    private Pattern reAccounts = Pattern.compile("\\?account=([^']+)'[^>]*>\\s*<div\\s*class=\"account-info\">[^<]*<span\\s*class=\"bold\">([^<]+)</span>\\s*(?:</div>\\s*<div\\s*class=\"account-status\">)\\s*<span\\s*class=\"(minus|plus)\">([^<]+)</span>");
-    private Pattern reTransactions = Pattern.compile("\"Id\":([^,]*),.*?\"Text\":\"([^\"]*)\".*?\"OriginalDate\":\".?.?Date\\(([^\\)]*)\\).*?\"Amount\":([^,]*),");
+    private static final String INPUT_HINT_USERNAME = "name@company.com";
 
     String response;
 
+    private Pattern reAccounts = Pattern.compile(
+            "\\?account=([^']+)'[^>]*>\\s*<div\\s*class=\"account-info\">[^<]*<span\\s*class=\"bold\">([^<]+)</span>\\s*(?:</div>\\s*<div\\s*class=\"account-status\">)\\s*<span\\s*class=\"(minus|plus)\">([^<]+)</span>");
+
+    private Pattern reTransactions = Pattern.compile(
+            "\"Id\":([^,]*),.*?\"Text\":\"([^\"]*)\".*?\"OriginalDate\":\".?.?Date\\(([^\\)]*)\\).*?\"Amount\":([^,]*),");
+
     public Meniga(Context context) {
         super(context);
         super.TAG = TAG;
@@ -61,7 +72,8 @@ public class Meniga extends Bank{
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_meniga));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_meniga));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.meniga.is/Mobile");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
@@ -86,7 +98,8 @@ public class Meniga extends Bank{
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -103,9 +116,10 @@ public class Meniga extends Bank{
              * 4: Balance            5 678
              *
              */
-            String balanceString ;
+            String balanceString;
             balanceString = matcher.group(4) + ".00";
-            Account account = new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(balanceString), matcher.group(1).trim());
+            Account account = new Account(Html.fromHtml(matcher.group(2)).toString(),
+                    Helpers.parseBalance(balanceString), matcher.group(1).trim());
             account.setCurrency("ISK");
             balance = balance.add(Helpers.parseBalance(matcher.group(4)));
             accounts.add(account);
@@ -121,13 +135,15 @@ public class Meniga extends Bank{
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
-        if (account.getType() == Account.OTHER) return;
+        if (account.getType() == Account.OTHER) {
+            return;
+        }
 
         String response;
         Matcher matcher;
 
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-        response = urlopen.open("https://www.meniga.is/Transactions?account="+account.getId());
+        response = urlopen.open("https://www.meniga.is/Transactions?account=" + account.getId());
         matcher = reTransactions.matcher(response);
         while (matcher.find()) {
             /*
@@ -141,8 +157,10 @@ public class Meniga extends Bank{
              *
              */
             Long date = Long.valueOf(matcher.group(3));
-            SimpleDateFormat ft = new SimpleDateFormat ("yy-MM-dd");
-            Transaction transaction = new Transaction(ft.format(date), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4)));
+            SimpleDateFormat ft = new SimpleDateFormat("yy-MM-dd");
+            Transaction transaction = new Transaction(ft.format(date),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4)));
             transaction.setCurrency("ISK");
             transactions.add(transaction);
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index 8bfc5dd..09d10c3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -36,6 +33,9 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -45,6 +45,7 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class MinPension extends Bank {
+
     public MinPension(Context context) {
         super(context);
         TAG = "MinPension";
@@ -52,7 +53,8 @@ public class MinPension extends Bank {
         NAME_SHORT = "minpension";
         BANKTYPE_ID = IBankTypes.MINPENSION;
         INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD;;
+        INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+        ;
         INPUT_HINT_USERNAME = res.getText(R.string.pno).toString();
     }
 
@@ -66,7 +68,8 @@ public class MinPension extends Bank {
     protected LoginPackage preLogin() throws BankException,
             IOException {
         List<NameValuePair> postData = new ArrayList<>();
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_minpension));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_minpension));
         String response = urlopen.open("https://www.minpension.se/AjaxifyContent/795");
         Document jDoc = Jsoup.parse(response);
         Element el = jDoc.select("input[name=__RequestVerificationToken]").first();
@@ -76,7 +79,8 @@ public class MinPension extends Bank {
         postData.add(new BasicNameValuePair("__RequestVerificationToken", el.val()));
         postData.add(new BasicNameValuePair("viewModel.Personnummer", username));
         postData.add(new BasicNameValuePair("viewModel.Kod", password));
-        LoginPackage lp = new LoginPackage(urlopen, postData, null, "https://www.minpension.se/inloggning/personlig-kod");
+        LoginPackage lp = new LoginPackage(urlopen, postData, null,
+                "https://www.minpension.se/inloggning/personlig-kod");
         return lp;
     }
 
@@ -88,7 +92,8 @@ public class MinPension extends Bank {
         if (!response.contains("LoggaUt.aspx")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-        response = urlopen.open("https://www.minpension.se/mina-sidor/redirect?path=MinPension%2FDefault.aspx&bodyMargin=0");
+        response = urlopen.open(
+                "https://www.minpension.se/mina-sidor/redirect?path=MinPension%2FDefault.aspx&bodyMargin=0");
         Document document = Jsoup.parse(response);
         Element e = document.select("#authenticationResult").first();
         if (e == null) {
@@ -104,7 +109,8 @@ public class MinPension extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -153,7 +159,9 @@ public class MinPension extends Bank {
         }
 
         balance = BigDecimal.ZERO;
-        for (Transaction t : transactions) balance = balance.add(t.getAmount());
+        for (Transaction t : transactions) {
+            balance = balance.add(t.getAmount());
+        }
         Account account = new Account(name, balance, name, Account.REGULAR, "");
         account.setTransactions(transactions);
         return account;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 88777b8..db2f10f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -16,14 +16,16 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
@@ -31,91 +33,100 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class MobilbankenBase extends Bank {
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    
+
+    protected String targetId;
 
     private Pattern reTimestamp = Pattern.compile("name=\"user(\\d{1,})\"");
+
     private Pattern reMsisdn = Pattern.compile("name=\"msisdn\"\\s*value=\"([^\"]+)\" />");
-    private Pattern reAccounts = Pattern.compile("accountmovement\\.html\\?account_no=([^\"]+)\">([^<]+)</a></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+><span[^>]+>([^<]+)</span></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>[^<]+<span[^>]+>([^<]+)</");
-    private Pattern reTransactions = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*</div>\\s*<table[^>]+>\\s*<tr>\\s*<td[^>]+>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>([^<]+)</span>\\s*</td>\\s*</tr>\\s*</table>\\s*<div[^>]+>\\s*(\\d{4}\\.\\d{2}\\.\\d{2})\\s*</div>\\s*");
+
+    private Pattern reAccounts = Pattern.compile(
+            "accountmovement\\.html\\?account_no=([^\"]+)\">([^<]+)</a></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+><span[^>]+>([^<]+)</span></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>[^<]+<span[^>]+>([^<]+)</");
+
+    private Pattern reTransactions = Pattern.compile(
+            "<a[^>]+>([^<]+)</a>\\s*</div>\\s*<table[^>]+>\\s*<tr>\\s*<td[^>]+>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>([^<]+)</span>\\s*</td>\\s*</tr>\\s*</table>\\s*<div[^>]+>\\s*(\\d{4}\\.\\d{2}\\.\\d{2})\\s*</div>\\s*");
+
     private String response = null;
-	protected String targetId;
-	
 
-	public MobilbankenBase(Context context) {
-		super(context);
+
+    public MobilbankenBase(Context context) {
+        super(context);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
+    }
 
-	public MobilbankenBase(String username, String password, Context context) throws BankException,
+    public MobilbankenBase(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         String postUrl = String.format("https://mobil-banken.se/%s/login.html", targetId);
         response = urlopen.open(postUrl);
         Matcher matcher = reMsisdn.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" msisdn.");
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " msisdn.");
         }
         String msisdn = matcher.group(1);
         matcher = reTimestamp.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" timestamp.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " timestamp.");
         }
         String timestamp = matcher.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("msisdn", msisdn));
-        postData.add(new BasicNameValuePair("user"+timestamp, username));
-        postData.add(new BasicNameValuePair("password"+timestamp, password));
+        postData.add(new BasicNameValuePair("user" + timestamp, username));
+        postData.add(new BasicNameValuePair("password" + timestamp, password));
         return new LoginPackage(urlopen, postData, response, postUrl);
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		
-		if (response.contains("eller pinkod")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen = login();
-		Matcher matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+        if (response.contains("eller pinkod")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -126,25 +137,27 @@ public abstract class MobilbankenBase extends Bank {
              * 5: Amount            ?
              *   
              */
-			accounts.add(new Account(
-			        Html.fromHtml(matcher.group(2)).toString().trim(),
-			        Helpers.parseBalance(matcher.group(5)),
-			        matcher.group(1).trim()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(5)));
-		}
-		
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	}
-	
+            accounts.add(new Account(
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(5)),
+                    matcher.group(1).trim()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+    }
+
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
 
         Matcher matcher;
-        response = urlopen.open(String.format("https://mobil-banken.se/%s/accountmovement.html?account_no=%s", targetId, account.getId()));
+        response = urlopen.open(String
+                .format("https://mobil-banken.se/%s/accountmovement.html?account_no=%s", targetId,
+                        account.getId()));
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         while (matcher.find()) {
@@ -162,5 +175,5 @@ public abstract class MobilbankenBase extends Bank {
                     Helpers.parseBalance(matcher.group(2))));
         }
         account.setTransactions(transactions);
-    }   	
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index a990c6d..e86a6b8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -1,148 +1,162 @@
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class NordeaDK extends Bank {
 
-	private static final String TAG = "NordeaDK";
-	private static final String NAME = "Nordea DK";
-	private static final String NAME_SHORT = "nordea_dk";
-	private static final String URL = "https://m.nordea.dk/";
-	private static final int BANKTYPE_ID = IBankTypes.NORDEA_DK;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-	private static final String INPUT_HINT_USERNAME = "DDMMÅÅ-XXXX";
-
-	private final String currency = "DKK";
-
-	private String prefix;
-	private String referer;
-
-	private Pattern reLoginUrl = Pattern.compile(
-			"<input.*?name=\"prefix\".*?value=\"([^\"]+)\"",
-			Pattern.CASE_INSENSITIVE);
-	private Pattern reAccounts = Pattern
-			.compile(
-					"<a.*?href=\"(.*?AccountTransactions.*?productidx=([0-9]+).*?)[^>]+>\\s*<span[^>]+>(.*?)</span>\\s*<span[^>]+>\\s*(.*?)</span>",
-					Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern
-			.compile(
-					"<tr [^>]+>\\s*<td.*?[^>]+>\\s*(.*?)[.]{1}\\s*</td>\\s*<td[^>]*>\\s*(.*?)\\s*</td>\\s*<td[^>]+>\\s*(.*?)\\s*</td>\\s*</tr>",
-					Pattern.CASE_INSENSITIVE);
-	private Pattern rePrefix = Pattern.compile(
-			"<a id=\"logout\" href=.*?prefix=([0-9-]+)",
-			Pattern.CASE_INSENSITIVE);
-	private Pattern reOldTransactions = Pattern.compile("<a.*?class=\".*?prev_btn.*?\".*?href=\".*?AccountTransactions",Pattern.CASE_INSENSITIVE);
-	
-	private Pattern reTransactionYear = Pattern.compile("<h3[^>]+>.*?([0-9]{4})</h3>",Pattern.CASE_INSENSITIVE);
-	
-	private String response;
-
-	public NordeaDK(Context context) {
-		super(context);
-
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.currency = "DKK";
-		this.response = null;
-		this.prefix = "";
-	}
-
-	public NordeaDK(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	protected LoginPackage preLogin() throws BankException, IOException {
-		if (urlopen == null) {
-            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
-		}
-		response = urlopen
-				.open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
-		response = urlopen.open("https://www.netbank.nordea.dk/mnetbank/logon.jsp");
-		Matcher matcher = reLoginUrl.matcher(response);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find)
-					.toString() + " login url.");
-		}
-		String strLoginUrl = "https://www.netbank.nordea.dk/mnetbank/servlet/Logon";
-		this.referer = strLoginUrl;
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("user_id", username));
-		postData.add(new BasicNameValuePair("logon_code", password));
-		postData.add(new BasicNameValuePair("command", "1"));
-		this.prefix = matcher.group(1);
-		postData.add(new BasicNameValuePair("prefix", matcher.group(1)));
-		return new LoginPackage(urlopen, postData, response, strLoginUrl);
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("class=\"icon error_icon\"")) {
-			throw new LoginException(res.getText(
-						R.string.invalid_username_password).toString());
-		}
-		this.updatePrefix();
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException,
-			BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0
-				|| password.length() == 0) {
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		Matcher matcher = reAccounts.matcher(response);
-
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find)
-					.toString() + " accounts url.");
-		}
-		matcher.reset();
-		while (matcher.find()) {
-			/*
+    private static final String TAG = "NordeaDK";
+
+    private static final String NAME = "Nordea DK";
+
+    private static final String NAME_SHORT = "nordea_dk";
+
+    private static final String URL = "https://m.nordea.dk/";
+
+    private static final int BANKTYPE_ID = IBankTypes.NORDEA_DK;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
+    private static final String INPUT_HINT_USERNAME = "DDMMÅÅ-XXXX";
+
+    private final String currency = "DKK";
+
+    private String prefix;
+
+    private String referer;
+
+    private Pattern reLoginUrl = Pattern.compile(
+            "<input.*?name=\"prefix\".*?value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reAccounts = Pattern
+            .compile(
+                    "<a.*?href=\"(.*?AccountTransactions.*?productidx=([0-9]+).*?)[^>]+>\\s*<span[^>]+>(.*?)</span>\\s*<span[^>]+>\\s*(.*?)</span>",
+                    Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern
+            .compile(
+                    "<tr [^>]+>\\s*<td.*?[^>]+>\\s*(.*?)[.]{1}\\s*</td>\\s*<td[^>]*>\\s*(.*?)\\s*</td>\\s*<td[^>]+>\\s*(.*?)\\s*</td>\\s*</tr>",
+                    Pattern.CASE_INSENSITIVE);
+
+    private Pattern rePrefix = Pattern.compile(
+            "<a id=\"logout\" href=.*?prefix=([0-9-]+)",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reOldTransactions = Pattern
+            .compile("<a.*?class=\".*?prev_btn.*?\".*?href=\".*?AccountTransactions",
+                    Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactionYear = Pattern
+            .compile("<h3[^>]+>.*?([0-9]{4})</h3>", Pattern.CASE_INSENSITIVE);
+
+    private String response;
+
+    public NordeaDK(Context context) {
+        super(context);
+
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.currency = "DKK";
+        this.response = null;
+        this.prefix = "";
+    }
+
+    public NordeaDK(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        if (urlopen == null) {
+            urlopen = new Urllib(context,
+                    CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
+        }
+        response = urlopen
+                .open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
+        response = urlopen.open("https://www.netbank.nordea.dk/mnetbank/logon.jsp");
+        Matcher matcher = reLoginUrl.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find)
+                    .toString() + " login url.");
+        }
+        String strLoginUrl = "https://www.netbank.nordea.dk/mnetbank/servlet/Logon";
+        this.referer = strLoginUrl;
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("user_id", username));
+        postData.add(new BasicNameValuePair("logon_code", password));
+        postData.add(new BasicNameValuePair("command", "1"));
+        this.prefix = matcher.group(1);
+        postData.add(new BasicNameValuePair("prefix", matcher.group(1)));
+        return new LoginPackage(urlopen, postData, response, strLoginUrl);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("class=\"icon error_icon\"")) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_username_password).toString());
+        }
+        this.updatePrefix();
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException,
+            BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher = reAccounts.matcher(response);
+
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find)
+                    .toString() + " accounts url.");
+        }
+        matcher.reset();
+        while (matcher.find()) {
+                        /*
 			 * Capture groups:
 			 * GROUP 		EXAMPLE DATA
 			 * 1: Link		https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
@@ -150,64 +164,65 @@ public class NordeaDK extends Bank {
 			 * 3: Name 		Check-in-konto
 			 * 4: Amount	1.234,56
 			 */
-			String name = Html.fromHtml(matcher.group(3)).toString().trim();
-			String id = matcher.group(2).toString().trim();
-			BigDecimal amount = Helpers.parseBalance(matcher.group(4));
-
-			accounts.add(new Account(name, amount, id, Account.REGULAR,
-					this.currency));
-			balance = balance.add(amount);
-
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found)
-					.toString());
-		}
-		this.updatePrefix();
-		super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen)
-			throws LoginException, BankException, IOException {
-		super.updateTransactions(account, urlopen);
-
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-		transactions.addAll(updateMonthTransactions(account, urlopen, false));
-
-		//Get last months' transactions
-		Matcher oldTransactionMatcher = reOldTransactions.matcher(response);
-		if(oldTransactionMatcher.find()) {
-			transactions.addAll(updateMonthTransactions(account,urlopen,true));
-		}
-		
-		account.setTransactions(transactions);
-
-	}
-
-	private ArrayList<Transaction> updateMonthTransactions(Account account,
-			Urllib urlopen, boolean oldTransactions) throws BankException, IOException {
-		String command = "command=";
-		command += (oldTransactions) ? "1" : "0";
-		String url = "https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions?productidx="
-				+ account.getId() + "&prefix=" + this.prefix + "&" + command;
-
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-		Matcher matcher;
-		urlopen.addHeader("referer", this.referer);
-		this.response = urlopen.open(url);
-		this.updatePrefix();
-		this.referer = url;
-
-		Matcher transYear = reTransactionYear.matcher(response);
-		String year = "";
-		if(transYear.find()) {
-			year = Html.fromHtml(transYear.group(1)).toString().trim();
-		}
-
-		matcher = reTransactions.matcher(response);
+            String name = Html.fromHtml(matcher.group(3)).toString().trim();
+            String id = matcher.group(2).toString().trim();
+            BigDecimal amount = Helpers.parseBalance(matcher.group(4));
+
+            accounts.add(new Account(name, amount, id, Account.REGULAR,
+                    this.currency));
+            balance = balance.add(amount);
+
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found)
+                    .toString());
+        }
+        this.updatePrefix();
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException, IOException {
+        super.updateTransactions(account, urlopen);
+
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+        transactions.addAll(updateMonthTransactions(account, urlopen, false));
+
+        //Get last months' transactions
+        Matcher oldTransactionMatcher = reOldTransactions.matcher(response);
+        if (oldTransactionMatcher.find()) {
+            transactions.addAll(updateMonthTransactions(account, urlopen, true));
+        }
+
+        account.setTransactions(transactions);
+
+    }
+
+    private ArrayList<Transaction> updateMonthTransactions(Account account,
+            Urllib urlopen, boolean oldTransactions) throws BankException, IOException {
+        String command = "command=";
+        command += (oldTransactions) ? "1" : "0";
+        String url =
+                "https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions?productidx="
+                        + account.getId() + "&prefix=" + this.prefix + "&" + command;
+
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+        Matcher matcher;
+        urlopen.addHeader("referer", this.referer);
+        this.response = urlopen.open(url);
+        this.updatePrefix();
+        this.referer = url;
+
+        Matcher transYear = reTransactionYear.matcher(response);
+        String year = "";
+        if (transYear.find()) {
+            year = Html.fromHtml(transYear.group(1)).toString().trim();
+        }
+
+        matcher = reTransactions.matcher(response);
 		/*
 		 * Capture groups:
 		 * GROUP 	EXAMPLE 	DATA
@@ -216,25 +231,25 @@ public class NordeaDK extends Bank {
 		 * 3: 		Amount 		906.56
 		 */
 
-		while (matcher.find()) {
-			String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
-			String text = Html.fromHtml(matcher.group(2)).toString().trim();
-			BigDecimal amount = Helpers.parseBalance(matcher.group(3));
-			String date = year+"-"+monthDate.substring(3,5)+"-"+monthDate.substring(0,2);
-
-			Transaction transaction = new Transaction(date, text, amount,
-					super.currency);
-			transactions.add(transaction);
-		}
-    	return transactions;
-	}
-
-	private void updatePrefix() throws BankException {
-		Matcher matcher = rePrefix.matcher(this.response);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find)
-					.toString());
-		}
-		this.prefix = Html.fromHtml(matcher.group(1)).toString().trim();
-	}
+        while (matcher.find()) {
+            String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
+            String text = Html.fromHtml(matcher.group(2)).toString().trim();
+            BigDecimal amount = Helpers.parseBalance(matcher.group(3));
+            String date = year + "-" + monthDate.substring(3, 5) + "-" + monthDate.substring(0, 2);
+
+            Transaction transaction = new Transaction(date, text, amount,
+                    super.currency);
+            transactions.add(transaction);
+        }
+        return transactions;
+    }
+
+    private void updatePrefix() throws BankException {
+        Matcher matcher = rePrefix.matcher(this.response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find)
+                    .toString());
+        }
+        this.prefix = Html.fromHtml(matcher.group(1)).toString().trim();
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index ff32ff6..a23781b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -16,14 +16,16 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 import org.jsoup.Jsoup;
@@ -33,28 +35,34 @@ import org.jsoup.nodes.Element;
 import android.content.Context;
 import android.text.Html;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnet extends Bank {
+
     private static final String TAG = "Nordnet";
+
     private static final String NAME = "Nordnet";
+
     private static final String NAME_SHORT = "nordnet";
+
     private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
+
     private static final int BANKTYPE_ID = IBankTypes.NORDNET;
 
     private Pattern reAccounts =
-            Pattern.compile("<span class=\"bullet\">·<\\/span>\\n\\t\\t\\t\\t\\t\\t<span>(.*?)<\\/span>");
-    private Pattern reBalance = Pattern.compile("<div class=\\\"value\\\">\\n(.*?)\\n\\t\\t<\\/div>");
+            Pattern.compile(
+                    "<span class=\"bullet\">·<\\/span>\\n\\t\\t\\t\\t\\t\\t<span>(.*?)<\\/span>");
+
+    private Pattern reBalance = Pattern.compile(
+            "<div class=\\\"value\\\">\\n(.*?)\\n\\t\\t<\\/div>");
+
     private String response = null;
 
     public Nordnet(Context context) {
@@ -72,33 +80,37 @@ public class Nordnet extends Bank {
         this.update(username, password);
     }
 
-    
+
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnet));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_nordnet));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
 
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("input1");
         if (e == null || "".equals(e.attr("name"))) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" username field.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " username field.");
         }
         String loginFieldName = e.attr("name");
         e = d.getElementById("pContHidden");
         if (e == null || "".equals(e.attr("name"))) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" password field.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " password field.");
         }
         String loginFieldPassword = e.attr("name");
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("checksum", ""));
         postData.add(new BasicNameValuePair("referer", ""));
         postData.add(new BasicNameValuePair("encryption", "0"));
         postData.add(new BasicNameValuePair(loginFieldName, username));
         postData.add(new BasicNameValuePair(loginFieldPassword, password));
-        
-        return new LoginPackage(urlopen, postData, response, "https://www.nordnet.se/mux/login/login.html");
+
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.nordnet.se/mux/login/login.html");
     }
 
     @Override
@@ -114,7 +126,8 @@ public class Nordnet extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -127,7 +140,7 @@ public class Nordnet extends Bank {
              * 1: Account name and number      Investeringssparkonto 1234567   | Sparkonto 1234 567890 1
              *
              */
-            if(matcher_b.find()) {
+            if (matcher_b.find()) {
                 /*
                 * Capture groups:
                 * GROUP                EXAMPLE DATA
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index d484c9d..e7a9948 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -16,101 +16,114 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnetdirekt extends Bank {
-	private static final String TAG = "Nordnetdirekt";
-	private static final String NAME = "Nordnetdirekt";
-	private static final String NAME_SHORT = "nordnetdirekt";
-	private static final String URL = "https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html";
-	private static final int BANKTYPE_ID = IBankTypes.NORDNETDIREKT;
-
-	private static final int INPUT_TITLETEXT_EXTRAS = R.string.nordnetdirekt_extras_title;
-	private static final int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
-	private static final boolean INPUT_HIDDEN_EXTRAS = false;
-    
-    private Pattern reBalance = Pattern.compile("left\">\\s*<table[^>]+>\\s*<caption[^>]+>([^<]+)</caption>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>");
-	private String response = null;
-	
-	public Nordnetdirekt(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    private static final String TAG = "Nordnetdirekt";
+
+    private static final String NAME = "Nordnetdirekt";
+
+    private static final String NAME_SHORT = "nordnetdirekt";
+
+    private static final String URL
+            = "https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html";
+
+    private static final int BANKTYPE_ID = IBankTypes.NORDNETDIREKT;
+
+    private static final int INPUT_TITLETEXT_EXTRAS = R.string.nordnetdirekt_extras_title;
+
+    private static final int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT
+            | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+
+    private static final boolean INPUT_HIDDEN_EXTRAS = false;
+
+    private Pattern reBalance = Pattern.compile(
+            "left\">\\s*<table[^>]+>\\s*<caption[^>]+>([^<]+)</caption>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>");
+
+    private String response = null;
+
+    public Nordnetdirekt(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TITLETEXT_EXTRAS = INPUT_TITLETEXT_EXTRAS;
         super.INPUT_TYPE_EXTRAS = INPUT_TYPE_EXTRAS;
         super.INPUT_HIDDEN_EXTRAS = INPUT_HIDDEN_EXTRAS;
-	}
+    }
 
-	public Nordnetdirekt(String username, String password, Context context) throws BankException,
+    public Nordnetdirekt(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html");
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("a4", "sv"));
         postData.add(new BasicNameValuePair("a3", "ADSE"));
         postData.add(new BasicNameValuePair("usa", "7"));
         postData.add(new BasicNameValuePair("a1", username));
         postData.add(new BasicNameValuePair("a2", password));
         postData.add(new BasicNameValuePair("nyckel", extras));
-        return new LoginPackage(urlopen, postData, response, "https://www.nordnetdirekt.se/mux/inloggad/lib/login.html");
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.nordnetdirekt.se/mux/inloggad/lib/login.html");
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("fel vid inloggningen")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		Matcher matcher = reBalance.matcher(response);
-		if (matcher.find()) {
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("fel vid inloggningen")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -127,12 +140,12 @@ public class Nordnetdirekt extends Bank {
                     "Värdepapper",
                     Helpers.parseBalance(matcher.group(3)),
                     "2"));
-			balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+            balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index 989842a..d6bd9a8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -17,74 +17,89 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class OKQ8 extends Bank {
-	private static final String TAG = "OKQ8";
-	private static final String NAME = "OKQ8 VISA";
-	private static final String NAME_SHORT = "okq8";
-	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
-	private static final int BANKTYPE_ID = IBankTypes.OKQ8;
+
+    private static final String TAG = "OKQ8";
+
+    private static final String NAME = "OKQ8 VISA";
+
+    private static final String NAME_SHORT = "okq8";
+
+    private static final String URL
+            = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
+
+    private static final int BANKTYPE_ID = IBankTypes.OKQ8;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
     private static final boolean STATIC_BALANCE = true;
-	
-	private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
-	private Pattern reBalance = Pattern.compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("style=\"white-space: nowrap\">([^<]*)</td>\\s*<td[^>]*>[^<]*</td>\\s*<td[^>]*>[^<]*</td>\\s*<td[^>]*>([^<]*)</td>\\s*<td[^>]*><div[^>]*>([^<]*)</div></td>", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	
-	public OKQ8(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-	}
-
-	public OKQ8(String username, String password, Context context) throws BankException,
+
+    private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reBalance = Pattern
+            .compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "style=\"white-space: nowrap\">([^<]*)</td>\\s*<td[^>]*>[^<]*</td>\\s*<td[^>]*>[^<]*</td>\\s*<td[^>]*>([^<]*)</td>\\s*<td[^>]*><div[^>]*>([^<]*)</div></td>",
+            Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    public OKQ8(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public OKQ8(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_okq8));
         Date d = new Date();
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        response = urlopen.open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        response = urlopen
+                .open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
         //p_tranid is the epoch time in milliseconds
         postData.add(new BasicNameValuePair("p_tranid", Long.toString(d.getTime())));
         postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
@@ -92,20 +107,21 @@ public class OKQ8 extends Bank {
         postData.add(new BasicNameValuePair("empty_pwd", ""));
         postData.add(new BasicNameValuePair("user_id", username.toUpperCase()));
         postData.add(new BasicNameValuePair("password", password));
-        return new LoginPackage(urlopen, postData, response, "https://nettbank.edb.com/Logon/logon/step1");
+        return new LoginPackage(urlopen, postData, response,
+                "https://nettbank.edb.com/Logon/logon/step1");
     }
 
-	public Urllib login() throws LoginException, BankException, IOException {
+    public Urllib login() throws LoginException, BankException, IOException {
         Matcher matcher;
         String value = null;
 
-			LoginPackage lp = preLogin();
-			List <NameValuePair> postData = lp.getPostData();
-			response = urlopen.open(lp.getLoginTarget(), postData);
-			if (!response.contains("LOGON_OK")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
+        LoginPackage lp = preLogin();
+        List<NameValuePair> postData = lp.getPostData();
+        response = urlopen.open(lp.getLoginTarget(), postData);
+        if (!response.contains("LOGON_OK")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
 			/*
 			 * After login ok we end up at an intermediate login page with a submit
 			 * form that contains information that must be passed to the next page:
@@ -114,99 +130,97 @@ public class OKQ8 extends Bank {
 			 * <input type="hidden" name="failed_logon_attempts" value="xxx"/>
 			 * <input type="hidden" name="login_service_url" value="xxx"/>
 			 */
-			matcher = reLoginRedir.matcher(response);
-			postData.clear();
-			if(!matcher.find())
-			{
-				throw new LoginException("Could not find value for 'so'.");
-			}
-			value = matcher.group(1);
-			postData.add(new BasicNameValuePair("so", value));
-			
-			if(!matcher.find())
-			{
-				throw new LoginException("Could not find value for 'last_logon_time'.");
-			}
-			value = matcher.group(1);
-			postData.add(new BasicNameValuePair("last_logon_time", value));
-			
-			if(!matcher.find())
-			{
-				throw new LoginException("Could not find value for 'failed_logon_attempts'.");
-			}
-			value = matcher.group(1);
-			postData.add(new BasicNameValuePair("failed_logon_attempts", value));
-			
-			if(!matcher.find())
-			{
-				throw new LoginException("Could not find value for 'login_service_url'.");
-			}
-			value = matcher.group(1);
-			postData.add(new BasicNameValuePair("login_service_url", value));
-			
-			response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8", postData);
-			
-			if(response.contains("HTML REDIRECT"))
-			{
-				throw new LoginException("Login failed.");
-			}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		if (response == null) {
-			urlopen = login();
-		}
+        matcher = reLoginRedir.matcher(response);
+        postData.clear();
+        if (!matcher.find()) {
+            throw new LoginException("Could not find value for 'so'.");
+        }
+        value = matcher.group(1);
+        postData.add(new BasicNameValuePair("so", value));
+
+        if (!matcher.find()) {
+            throw new LoginException("Could not find value for 'last_logon_time'.");
+        }
+        value = matcher.group(1);
+        postData.add(new BasicNameValuePair("last_logon_time", value));
+
+        if (!matcher.find()) {
+            throw new LoginException("Could not find value for 'failed_logon_attempts'.");
+        }
+        value = matcher.group(1);
+        postData.add(new BasicNameValuePair("failed_logon_attempts", value));
+
+        if (!matcher.find()) {
+            throw new LoginException("Could not find value for 'login_service_url'.");
+        }
+        value = matcher.group(1);
+        postData.add(new BasicNameValuePair("login_service_url", value));
+
+        response = urlopen
+                .open("https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8", postData);
+
+        if (response.contains("HTML REDIRECT")) {
+            throw new LoginException("Login failed.");
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        if (response == null) {
+            urlopen = login();
+        }
 		/*
 		 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
 		 * The balance is the first value (of three) that are matched by reBalance expression.
 		 */
-		Matcher matcher = reBalance.matcher(response);
-		if(matcher.find())
-		{
-		    accounts.add(new Account("Kvar att utnyttja" , Helpers.parseBalance(matcher.group(1)), "1"));
-		    balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-		}
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
+            accounts.add(
+                    new Account("Kvar att utnyttja", Helpers.parseBalance(matcher.group(1)), "1"));
+            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+        }
 		/*
 		 * Find the next value that is "Saldo". Add a new account but don't add to the balance.
 		 */
-		if(matcher.find())
-		{
-		    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2"));
-		    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)).negate(), "4"));
-		}
+        if (matcher.find()) {
+            accounts.add(new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "2"));
+            accounts.add(
+                    new Account("Saldo", Helpers.parseBalance(matcher.group(1)).negate(), "4"));
+        }
 		/*
 		 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.
 		 */
-		if(matcher.find())
-		{
-		    accounts.add(new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3"));
-		}
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+        if (matcher.find()) {
+            accounts.add(new Account("Köpgräns", Helpers.parseBalance(matcher.group(1)), "3"));
+        }
 
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
 
-		response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
+        response = urlopen
+                .open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
 
-		matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
 			/*
 			 * Capture group 1 = date
 			 * Capture group 2 = text
 			 * Capture group 3 = amount
 			 * Negate the amount since buys are reported as positive.
 			 */
-			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)).negate()));
-		}
-		accounts.get(0).setTransactions(transactions);
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3)).negate()));
+        }
+        accounts.get(0).setTransactions(transactions);
         super.updateComplete();
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
index f16884f..043699f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Opel extends SEBKortBase {
-	private static final String TAG = "Opel";
-	private static final String NAME = "OpelKortet";
-	private static final String NAME_SHORT = "opel";
-	private static final int BANKTYPE_ID = Bank.OPEL;
-
-	public Opel(Context context) {
-		super(context, "opse", "0107");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Opel(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Opel";
+
+    private static final String NAME = "OpelKortet";
+
+    private static final String NAME_SHORT = "opel";
+
+    private static final int BANKTYPE_ID = Bank.OPEL;
+
+    public Opel(Context context) {
+        super(context, "opse", "0107");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Opel(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "opse", "0107");
-	}
+        super(username, password, context, "opse", "0107");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 46ef3da..ce3e44e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -16,159 +16,182 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Ostgotatrafiken extends Bank {
-	private static final String TAG = "Östgötatrafiken";
-	private static final String NAME = "Östgötatrafiken";
-	private static final String NAME_SHORT = "ogt";
-	private static final String URL = "https://www.ostgotatrafiken.se/Priser--biljetter/Mina-sidor/Login/";
-	private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN;
-
-	private Pattern reViewState = Pattern.compile("<input [^>]+ id=\"javax.faces.ViewState\"[^>]* value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-	private Pattern reMoreCards = Pattern.compile("<li><a [^>]+ id=\"(form1cardOverviewTabs[^\"]+)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-	private Pattern reCardNumber = Pattern.compile(">Kortnummer: (\\d+)<", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-	private Pattern reCardName = Pattern.compile("<li class=\"selected\">.*?>(\\w+?)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-	private Pattern reCardBalance = Pattern.compile(">Saldo<.*?>\\s*(\\d+)\\s*kr\\s*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-	private String response = null;
-
-	public Ostgotatrafiken(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public Ostgotatrafiken(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Östgötatrafiken";
+
+    private static final String NAME = "Östgötatrafiken";
+
+    private static final String NAME_SHORT = "ogt";
+
+    private static final String URL
+            = "https://www.ostgotatrafiken.se/Priser--biljetter/Mina-sidor/Login/";
+
+    private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN;
+
+    private Pattern reViewState = Pattern.compile(
+            "<input [^>]+ id=\"javax.faces.ViewState\"[^>]* value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+
+    private Pattern reMoreCards = Pattern.compile(
+            "<li><a [^>]+ id=\"(form1cardOverviewTabs[^\"]+)\"",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+
+    private Pattern reCardNumber = Pattern.compile(">Kortnummer: (\\d+)<",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+
+    private Pattern reCardName = Pattern.compile("<li class=\"selected\">.*?>(\\w+?)</span>",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+
+    private Pattern reCardBalance = Pattern.compile(">Saldo<.*?>\\s*(\\d+)\\s*kr\\s*</span>",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+
+    private String response = null;
+
+    public Ostgotatrafiken(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Ostgotatrafiken(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	protected LoginPackage preLogin() throws BankException, IOException {
-		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview));
-
-		List <NameValuePair> postData = new ArrayList <NameValuePair>();
-		postData.add(new BasicNameValuePair("Username", username));
-		postData.add(new BasicNameValuePair("Password", password));
-		postData.add(new BasicNameValuePair("Login", "Logga in"));
-
-		return new LoginPackage(urlopen, postData, response, URL);
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (!response.contains("Logga ut")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
+                R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview));
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("Username", username));
+        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("Login", "Logga in"));
+
+        return new LoginPackage(urlopen, postData, response, URL);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (!response.contains("Logga ut")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
         return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		String cardOverviewUrl = "https://webtick.ostgotatrafiken.se/webtick/user/pages/CardOverview.iface";
-		response = urlopen.open(cardOverviewUrl);
-		parseTravelCardBalanceFromServerResponse(response);
-
-		Matcher viewStateMatcher = reViewState.matcher(response);
-		if (!viewStateMatcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState");
-		}
-		Matcher moreCardsMatcher = reMoreCards.matcher(response);
-		while (moreCardsMatcher.find()) {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("form1cardOverviewTabs:j_idcl", moreCardsMatcher.group(1)));
-			postData.add(new BasicNameValuePair("ice.focus", moreCardsMatcher.group(1)));
-			postData.add(new BasicNameValuePair(moreCardsMatcher.group(1), moreCardsMatcher.group(1)));
-			postData.add(new BasicNameValuePair("form1cardOverviewTabs", "form1cardOverviewTabs"));
-			postData.add(new BasicNameValuePair("ice.event.captured", moreCardsMatcher.group(1)));
-			postData.add(new BasicNameValuePair("javax.faces.source", moreCardsMatcher.group(1)));
-			postData.add(new BasicNameValuePair("javax.faces.ViewState", viewStateMatcher.group(1)));
-
-			postData.add(new BasicNameValuePair("icefacesCssUpdates", ""));
-			postData.add(new BasicNameValuePair("javax.faces.partial.event", "click"));
-			postData.add(new BasicNameValuePair("javax.faces.partial.execute", "@all"));
-			postData.add(new BasicNameValuePair("javax.faces.partial.render", "@all"));
-			postData.add(new BasicNameValuePair("ice.event.type", "onclick"));
-			postData.add(new BasicNameValuePair("ice.event.alt", "false"));
-			postData.add(new BasicNameValuePair("ice.event.ctrl", "false"));
-			postData.add(new BasicNameValuePair("ice.event.shift", "false"));
-			postData.add(new BasicNameValuePair("ice.event.meta", "false"));
-			postData.add(new BasicNameValuePair("ice.event.x", "606"));
-			postData.add(new BasicNameValuePair("ice.event.y", "362"));
-			postData.add(new BasicNameValuePair("ice.event.left", "true"));
-			postData.add(new BasicNameValuePair("ice.event.right", "false"));
-			postData.add(new BasicNameValuePair("ice.submit.type", "ice.s"));
-			postData.add(new BasicNameValuePair("ice.submit.serialization", "form"));
-			postData.add(new BasicNameValuePair("javax.faces.partial.ajax", "true"));
-
-			// ice.event.target is sent by browser, but not needed by
-			// server so don't bother parsing response for its correct value
-			//postData.add(new BasicNameValuePair("ice.event.target", "form1cardOverviewTabs:j_idt240:1:j_idt243"));
-
-			// ice.window and ice.view are sent by browser, but by not sending
-			// these to server we get an HTML response which can be parsed
-			// just like the initial response. If including ice.window and
-			// ice.view in POST the server will give us XML data back which
-			// would need separate parsing.
-			//postData.add(new BasicNameValuePair("ice.window", "p7htbwx9t8"));
-			//postData.add(new BasicNameValuePair("ice.view", "vcuag6esom"));
-
-			urlopen.addHeader("Faces-Request", "partial/ajax");
-			response = urlopen.open(cardOverviewUrl, postData);
-			parseTravelCardBalanceFromServerResponse(response);
-		}
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-		super.updateComplete();
-	}
-
-	private void parseTravelCardBalanceFromServerResponse(String response) {
-		Matcher cardNameMatcher = reCardName.matcher(response);
-		Matcher cardNumberMatcher = reCardNumber.matcher(response);
-		Matcher balanceMatcher = reCardBalance.matcher(response);
-
-		if (cardNameMatcher.find() && cardNumberMatcher.find() && balanceMatcher.find()) {
-			String cardName = cardNameMatcher.group(1);
-			String cardNumber = cardNumberMatcher.group(1);
-			String cardBalance = balanceMatcher.group(1);
-
-			accounts.add(new Account(cardName, Helpers.parseBalance(cardBalance), cardNumber));
-			balance = balance.add(Helpers.parseBalance(cardBalance));
-		}
-	}
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        String cardOverviewUrl
+                = "https://webtick.ostgotatrafiken.se/webtick/user/pages/CardOverview.iface";
+        response = urlopen.open(cardOverviewUrl);
+        parseTravelCardBalanceFromServerResponse(response);
+
+        Matcher viewStateMatcher = reViewState.matcher(response);
+        if (!viewStateMatcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState");
+        }
+        Matcher moreCardsMatcher = reMoreCards.matcher(response);
+        while (moreCardsMatcher.find()) {
+            List<NameValuePair> postData = new ArrayList<NameValuePair>();
+            postData.add(new BasicNameValuePair("form1cardOverviewTabs:j_idcl",
+                    moreCardsMatcher.group(1)));
+            postData.add(new BasicNameValuePair("ice.focus", moreCardsMatcher.group(1)));
+            postData.add(
+                    new BasicNameValuePair(moreCardsMatcher.group(1), moreCardsMatcher.group(1)));
+            postData.add(new BasicNameValuePair("form1cardOverviewTabs", "form1cardOverviewTabs"));
+            postData.add(new BasicNameValuePair("ice.event.captured", moreCardsMatcher.group(1)));
+            postData.add(new BasicNameValuePair("javax.faces.source", moreCardsMatcher.group(1)));
+            postData.add(
+                    new BasicNameValuePair("javax.faces.ViewState", viewStateMatcher.group(1)));
+
+            postData.add(new BasicNameValuePair("icefacesCssUpdates", ""));
+            postData.add(new BasicNameValuePair("javax.faces.partial.event", "click"));
+            postData.add(new BasicNameValuePair("javax.faces.partial.execute", "@all"));
+            postData.add(new BasicNameValuePair("javax.faces.partial.render", "@all"));
+            postData.add(new BasicNameValuePair("ice.event.type", "onclick"));
+            postData.add(new BasicNameValuePair("ice.event.alt", "false"));
+            postData.add(new BasicNameValuePair("ice.event.ctrl", "false"));
+            postData.add(new BasicNameValuePair("ice.event.shift", "false"));
+            postData.add(new BasicNameValuePair("ice.event.meta", "false"));
+            postData.add(new BasicNameValuePair("ice.event.x", "606"));
+            postData.add(new BasicNameValuePair("ice.event.y", "362"));
+            postData.add(new BasicNameValuePair("ice.event.left", "true"));
+            postData.add(new BasicNameValuePair("ice.event.right", "false"));
+            postData.add(new BasicNameValuePair("ice.submit.type", "ice.s"));
+            postData.add(new BasicNameValuePair("ice.submit.serialization", "form"));
+            postData.add(new BasicNameValuePair("javax.faces.partial.ajax", "true"));
+
+            // ice.event.target is sent by browser, but not needed by
+            // server so don't bother parsing response for its correct value
+            //postData.add(new BasicNameValuePair("ice.event.target", "form1cardOverviewTabs:j_idt240:1:j_idt243"));
+
+            // ice.window and ice.view are sent by browser, but by not sending
+            // these to server we get an HTML response which can be parsed
+            // just like the initial response. If including ice.window and
+            // ice.view in POST the server will give us XML data back which
+            // would need separate parsing.
+            //postData.add(new BasicNameValuePair("ice.window", "p7htbwx9t8"));
+            //postData.add(new BasicNameValuePair("ice.view", "vcuag6esom"));
+
+            urlopen.addHeader("Faces-Request", "partial/ajax");
+            response = urlopen.open(cardOverviewUrl, postData);
+            parseTravelCardBalanceFromServerResponse(response);
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    private void parseTravelCardBalanceFromServerResponse(String response) {
+        Matcher cardNameMatcher = reCardName.matcher(response);
+        Matcher cardNumberMatcher = reCardNumber.matcher(response);
+        Matcher balanceMatcher = reCardBalance.matcher(response);
+
+        if (cardNameMatcher.find() && cardNumberMatcher.find() && balanceMatcher.find()) {
+            String cardName = cardNameMatcher.group(1);
+            String cardNumber = cardNumberMatcher.group(1);
+            String cardBalance = balanceMatcher.group(1);
+
+            accounts.add(new Account(cardName, Helpers.parseBalance(cardBalance), cardNumber));
+            balance = balance.add(Helpers.parseBalance(cardBalance));
+        }
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 51bd126..1229ce2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -16,96 +16,106 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Osuuspankki extends Bank {
-	private static final String TAG = "Osuuspankki";
-	private static final String NAME = "Osuuspankki";
-	private static final String NAME_SHORT = "osuuspankki";
-	private static final String URL = "https://www.op.fi/op?kielikoodi=sv";
-	private static final int BANKTYPE_ID = IBankTypes.OSUUSPANKKI;
-	
-	private Pattern reAccounts = Pattern.compile("href=\"\\?id=(\\d{1,})&(?:amp;)?tilinro=([^&]+)&[^>]+>([^<]+)</a>\\s*<br\\s?/>\\s*<span[^>]+>\\s*<b>([^<]+)</b>([^<]+)</span>");
-	private Pattern reTransactions = Pattern.compile("<tr[^>]*>\\s*<td>\\s*<div\\s*class=\"Ensimmainen\">\\s*(\\d{2}\\.\\d{2})\\.<br.?/>\\s*\\s*(\\d{2}\\.\\d{2})\\.\\s*</div>\\s*</td>\\s*<td>\\s*<div>([^<]+)<br.?/>.*?</div>\\s*</td>\\s*<td>\\s*<div\\s*class=\"Nowrap\">\\s*<a[^>]+>([^<]+)<br.?/>\\s*</a>.*?</div>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]*>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	private String response = null;
-
-	public Osuuspankki(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public Osuuspankki(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Osuuspankki";
+
+    private static final String NAME = "Osuuspankki";
+
+    private static final String NAME_SHORT = "osuuspankki";
+
+    private static final String URL = "https://www.op.fi/op?kielikoodi=sv";
+
+    private static final int BANKTYPE_ID = IBankTypes.OSUUSPANKKI;
+
+    private Pattern reAccounts = Pattern.compile(
+            "href=\"\\?id=(\\d{1,})&(?:amp;)?tilinro=([^&]+)&[^>]+>([^<]+)</a>\\s*<br\\s?/>\\s*<span[^>]+>\\s*<b>([^<]+)</b>([^<]+)</span>");
+
+    private Pattern reTransactions = Pattern.compile(
+            "<tr[^>]*>\\s*<td>\\s*<div\\s*class=\"Ensimmainen\">\\s*(\\d{2}\\.\\d{2})\\.<br.?/>\\s*\\s*(\\d{2}\\.\\d{2})\\.\\s*</div>\\s*</td>\\s*<td>\\s*<div>([^<]+)<br.?/>.*?</div>\\s*</td>\\s*<td>\\s*<div\\s*class=\"Nowrap\">\\s*<a[^>]+>([^<]+)<br.?/>\\s*</a>.*?</div>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]*>([^<]+)</div>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private String response = null;
+
+    public Osuuspankki(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Osuuspankki(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_osuuspankki, R.raw.cert_osuuspankki_mobile));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
+                R.raw.cert_osuuspankki, R.raw.cert_osuuspankki_mobile));
         response = urlopen.open("https://www.op.fi/op?kielikoodi=sv");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("REQUEST_LOGIN_ATTEMPTED", "true"));
         postData.add(new BasicNameValuePair("REQUEST_PREVIOUS_QUERYSTRING", ""));
         postData.add(new BasicNameValuePair("x", "24"));
         postData.add(new BasicNameValuePair("y", "5"));
         postData.add(new BasicNameValuePair("USERNAME", username));
         postData.add(new BasicNameValuePair("PWD", password));
-       
+
         return new LoginPackage(urlopen, postData, response, "https://www.op.fi/op?kielikoodi=sv");
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
-		if (response.contains("du nya koder genom att bes")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+        if (response.contains("du nya koder genom att bes")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
         return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		Matcher matcher;
-		matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher;
+        matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
@@ -116,35 +126,38 @@ public class Osuuspankki extends Bank {
              * 5: Currency              &nbsp;&euro;
              * 
              */
-		    String currency = Helpers.parseCurrency(Html.fromHtml(matcher.group(5)).toString().trim(), "EUR");
-		    Account account = new Account(Html.fromHtml(matcher.group(3)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim());
-		    account.setCurrency(currency);
+            String currency = Helpers.parseCurrency(
+                    Html.fromHtml(matcher.group(5)).toString().trim(), "EUR");
+            Account account = new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim());
+            account.setCurrency(currency);
             //Bonuskonto
-		    if ("12701".equals(matcher.group(1))) {
-		        account.setType(Account.OTHER);
-		    }
+            if ("12701".equals(matcher.group(1))) {
+                account.setType(Account.OTHER);
+            }
             this.setCurrency(currency);
-			accounts.add(account);
-			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-		}
-		
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	    super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            accounts.add(account);
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
+        super.updateTransactions(account, urlopen);
 
-		Matcher matcher;
+        Matcher matcher;
 
-        response = urlopen.open(String.format("https://www.op.fi/?id=%s&tilinro=%s&ecb=1&srcpl=4", (account.getType() == Account.OTHER ? "12701" : "12401"),account.getId()));
-		matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
+        response = urlopen.open(String.format("https://www.op.fi/?id=%s&tilinro=%s&ecb=1&srcpl=4",
+                (account.getType() == Account.OTHER ? "12701" : "12401"), account.getId()));
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
@@ -155,13 +168,13 @@ public class Osuuspankki extends Bank {
              * 5: Amount in EUR         -3,99
              *
              */
-		    String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split(".");
-		    Transaction transaction = new Transaction(Helpers.getTransactionDate(date[1], date[0]),
+            String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split(".");
+            Transaction transaction = new Transaction(Helpers.getTransactionDate(date[1], date[0]),
                     Html.fromHtml(matcher.group(3)).toString().trim(),
                     Helpers.parseBalance(matcher.group(5)));
-		    transaction.setCurrency(account.getCurrency());
-			transactions.add(transaction);
-		}
-		account.setTransactions(transactions);
-	}
+            transaction.setCurrency(account.getCurrency());
+            transactions.add(transaction);
+        }
+        account.setTransactions(transactions);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index fbd6f26..7ed55db 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -16,14 +16,16 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -34,31 +36,45 @@ import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PayPal extends Bank {
+
     private static final String TAG = "PayPal";
+
     private static final String NAME = "PayPal";
+
     private static final String NAME_SHORT = "paypal";
+
     private static final String URL = "https://www.paypal.com/";
+
     private static final int BANKTYPE_ID = IBankTypes.PAYPAL;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+            | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+
     private static final boolean STATIC_BALANCE = true;
 
-    private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>", Pattern.CASE_INSENSITIVE);
-    private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reBalance = Pattern.compile(
+            "PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reAccounts = Pattern.compile(
+            "row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>",
+            Pattern.CASE_INSENSITIVE);
+
     private String response = null;
+
     public PayPal(Context context) {
         super(context);
         super.TAG = TAG;
@@ -76,24 +92,25 @@ public class PayPal extends Bank {
         this.update(username, password);
     }
 
-    
+
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal));
-        urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_paypal));
+        urlopen.setUserAgent(
+                "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
         Document d = Jsoup.parse(response);
         Element e = d.select("form[name=login_form]").first();
-        
+
         String strPostUrl;
         if (e != null && !TextUtils.isEmpty(e.attr("action"))) {
             strPostUrl = e.attr("action").trim();
+        } else {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " post url.");
         }
-        else {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
-        }
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("login_email", username));
         postData.add(new BasicNameValuePair("login_password", password));
         postData.add(new BasicNameValuePair("target_page", "0"));
@@ -102,12 +119,16 @@ public class PayPal extends Bank {
         postData.add(new BasicNameValuePair("browser_name", "undefined"));
         postData.add(new BasicNameValuePair("browser_version", "undefined"));
         postData.add(new BasicNameValuePair("operating_system", "Windows"));
-        postData.add(new BasicNameValuePair("bp_mid", "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
-        postData.add(new BasicNameValuePair("bp_ks1", "v=1;l=16;Di0:2663Di1:48Ui0:15Ui1:81Di2:176Di3:48Ui2:32Ui3:96Di4:384Ui4:48Di5:352Ui5:48Di6:128Ui6:80Di7:112Ui7:48Di8:113Ui8:79Di9:125Ui9:51Di10:98Ui10:72Di11:227Ui11:51Di12:80Ui12:80Di13:128Ui13:64Di14:48Ui14:80Di15:416Ui15:80"));
+        postData.add(new BasicNameValuePair("bp_mid",
+                "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
+        postData.add(new BasicNameValuePair("bp_ks1",
+                "v=1;l=16;Di0:2663Di1:48Ui0:15Ui1:81Di2:176Di3:48Ui2:32Ui3:96Di4:384Ui4:48Di5:352Ui5:48Di6:128Ui6:80Di7:112Ui7:48Di8:113Ui8:79Di9:125Ui9:51Di10:98Ui10:72Di11:227Ui11:51Di12:80Ui12:80Di13:128Ui13:64Di14:48Ui14:80Di15:416Ui15:80"));
         postData.add(new BasicNameValuePair("bp_ks2", ""));
         postData.add(new BasicNameValuePair("bp_ks3", ""));
-        postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
-        postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
+        postData.add(new BasicNameValuePair("flow_name",
+                "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
+        postData.add(new BasicNameValuePair("fso",
+                "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
         return new LoginPackage(urlopen, postData, response, strPostUrl);
     }
 
@@ -115,7 +136,8 @@ public class PayPal extends Bank {
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-        if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
+        if (response.contains("If you still can't log in") || response.contains(
+                "both your email address and password")) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         if (response.contains("your last action could not be completed")) {
@@ -127,12 +149,15 @@ public class PayPal extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
 
-        response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
+        response = urlopen.open(
+                "https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access=" + ((int) (
+                        System.currentTimeMillis() / 1000L)));
         Matcher matcher = reAccounts.matcher(response);
         int accId = 1;
         while (matcher.find()) {
@@ -144,7 +169,8 @@ public class PayPal extends Bank {
              * 3: currency          SEK
              *
              */
-            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ""+accId);
+            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(2)), "" + accId);
             account.setCurrency(matcher.group(3).trim());
             accounts.add(account);
             accId++;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index 51cf772..e9b6650 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -33,6 +30,9 @@ import org.apache.http.message.BasicNameValuePair;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -43,15 +43,26 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Payson extends Bank {
+
     private static final String TAG = "Payson";
+
     private static final String NAME = "Payson";
+
     private static final String NAME_SHORT = "payson";
+
     private static final String URL = "https://www.payson.se/signin/";
+
     private static final int BANKTYPE_ID = IBankTypes.PAYSON;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 
-    private Pattern reVerificationToken = Pattern.compile("<input[^>]+name=\"__RequestVerificationToken\"[^>]+value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT
+            | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+
+    private Pattern reVerificationToken = Pattern.compile(
+            "<input[^>]+name=\"__RequestVerificationToken\"[^>]+value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+
     private String response = null;
+
     private JSONObject userInfo = null;
 
     public Payson(Context context) {
@@ -72,11 +83,13 @@ public class Payson extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_payson));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_payson));
         response = urlopen.open(URL);
         Matcher matcher = reVerificationToken.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " RequestVerificationToken");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " RequestVerificationToken");
         }
         String verificationToken = matcher.group(1);
 
@@ -85,7 +98,8 @@ public class Payson extends Bank {
         postData.add(new BasicNameValuePair("Username", username));
         postData.add(new BasicNameValuePair("Password", password));
         postData.add(new BasicNameValuePair("RedirectAfterLogin", ""));
-        return new LoginPackage(urlopen, postData, response, "https://www.payson.se/myaccount/account/SignIn/");
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.payson.se/myaccount/account/SignIn/");
     }
 
     @Override
@@ -93,7 +107,8 @@ public class Payson extends Bank {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            userInfo = new JSONObject(urlopen.open("https://www.payson.se/myaccount/user/getuserinfo"));
+            userInfo = new JSONObject(
+                    urlopen.open("https://www.payson.se/myaccount/user/getuserinfo"));
         } catch (JSONException e) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
@@ -103,7 +118,8 @@ public class Payson extends Bank {
     @Override
     public void update() throws BankChoiceException, BankException, LoginException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index 8a23d9a..be949bc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -16,91 +16,104 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PlusGirot extends Bank {
-	private static final String TAG = "PlusGirot";
-	private static final String NAME = "PlusGirot";
-	private static final String NAME_SHORT = "plusgirot";
-	private static final String URL = "https://kontoutdrag.plusgirot.se/";
-	private static final int BANKTYPE_ID = IBankTypes.PLUSGIROT;
-
-    private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+><font[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</f", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	
-	public PlusGirot(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public PlusGirot(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "PlusGirot";
+
+    private static final String NAME = "PlusGirot";
+
+    private static final String NAME_SHORT = "plusgirot";
+
+    private static final String URL = "https://kontoutdrag.plusgirot.se/";
+
+    private static final int BANKTYPE_ID = IBankTypes.PLUSGIROT;
+
+    private Pattern reAccounts = Pattern.compile(
+            "<tr>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+><font[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<a[^>]+>([^<]+)</a>\\s*</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</f",
+            Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    public PlusGirot(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public PlusGirot(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_plusgirot));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_plusgirot));
         // Request first page to get cookies
         response = urlopen.open("https://kontoutdrag.plusgirot.se/ku/html/epostllg.htm");
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("KONTO", username));
         postData.add(new BasicNameValuePair("PIN_KOD", password));
-        return new LoginPackage(urlopen, postData, response, "https://kontoutdrag.plusgirot.se/ku/bgya006/init");
+        return new LoginPackage(urlopen, postData, response,
+                "https://kontoutdrag.plusgirot.se/ku/bgya006/init");
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("elaktigt kontonummer"))  {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("elaktigt kontonummer")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
 
         Matcher matcher = reAccounts.matcher(response);
-		if (matcher.find()) {
+        if (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -110,21 +123,22 @@ public class PlusGirot extends Bank {
              * 4: Credit            24,68
              *
              */
-		    Account account = new Account(matcher.group(2).trim() + " (" + Html.fromHtml(matcher.group(1)).toString().trim() + ")",
-		                                    Helpers.parseBalance(matcher.group(3)),
-		                                    matcher.group(2).trim().replaceAll("[^0-9]*", ""));
-			accounts.add(account);
-			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-		}
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-
-
-		matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
+            Account account = new Account(
+                    matcher.group(2).trim() + " (" + Html.fromHtml(matcher.group(1)).toString()
+                            .trim() + ")",
+                    Helpers.parseBalance(matcher.group(3)),
+                    matcher.group(2).trim().replaceAll("[^0-9]*", ""));
+            accounts.add(account);
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -134,12 +148,13 @@ public class PlusGirot extends Bank {
              * 4: Amount            -100,00
              *
              */
-			transactions.add(
-			        new Transaction(matcher.group(1).trim(),
-			        Html.fromHtml(matcher.group(2)).toString().trim() + " " + Html.fromHtml(matcher.group(3)).toString().trim(),
-			        Helpers.parseBalance(matcher.group(4))));
-		}
-		accounts.get(0).setTransactions(transactions);
+            transactions.add(
+                    new Transaction(matcher.group(1).trim(),
+                            Html.fromHtml(matcher.group(2)).toString().trim() + " " + Html.fromHtml(
+                                    matcher.group(3)).toString().trim(),
+                            Helpers.parseBalance(matcher.group(4))));
+        }
+        accounts.get(0).setTransactions(transactions);
         super.updateComplete();
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
index b4f2c2a..2ee4315 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
@@ -16,21 +16,27 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Preem extends AbsIkanoPartner {
+
     private static final String TAG = "Preem";
+
     private static final String NAME = "Preem Privatkort";
+
     private static final String NAME_SHORT = "preem";
-    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
+
+    private static final String URL
+            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
+
     private static final int BANKTYPE_ID = Bank.PREEM;
 
     public Preem(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
index 21207f8..0a22cd4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Quintessentially extends SEBKortBase {
-	private static final String TAG = "Quintessentially";
-	private static final String NAME = "Quintessentially Credit Card";
-	private static final String NAME_SHORT = "quintessentially";
-	private static final int BANKTYPE_ID = Bank.QUINTESSENTIALLY;
-
-	public Quintessentially(Context context) {
-		super(context, "quse", "0119");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Quintessentially(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Quintessentially";
+
+    private static final String NAME = "Quintessentially Credit Card";
+
+    private static final String NAME_SHORT = "quintessentially";
+
+    private static final int BANKTYPE_ID = Bank.QUINTESSENTIALLY;
+
+    public Quintessentially(Context context) {
+        super(context, "quse", "0119");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Quintessentially(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "quse", "0119");
-	}
+        super(username, password, context, "quse", "0119");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index 0d0a027..3c863cb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -16,36 +16,41 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ResursBank extends Bank {
-    private Pattern reAccounts = Pattern.compile("kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reAccounts = Pattern.compile(
+            "kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</",
+            Pattern.CASE_INSENSITIVE);
 
     private String response = null;
 
@@ -66,13 +71,15 @@ public class ResursBank extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_resursbank));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_resursbank));
         response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("kontonummer", username));
         postData.add(new BasicNameValuePair("password", password));
         postData.add(new BasicNameValuePair("page", "privat"));
-        return new LoginPackage(urlopen, postData, response, "https://secure.resurs.se/internetbank/login.jsp");
+        return new LoginPackage(urlopen, postData, response,
+                "https://secure.resurs.se/internetbank/login.jsp");
     }
 
     @Override
@@ -89,7 +96,8 @@ public class ResursBank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -106,26 +114,27 @@ public class ResursBank extends Bank {
              * 5: Kvar att utnyttja     0,00 kr
              * 
              */
-            String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll("[^0-9]*", "");
+            String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll(
+                    "[^0-9]*", "");
             accounts.add(new Account("Beviljad kredit",
                     Helpers.parseBalance(matcher.group(2)),
-                    "b_"+accountId));
+                    "b_" + accountId));
 
             BigDecimal utnyttjad = Helpers.parseBalance(matcher.group(3));
             utnyttjad = utnyttjad.add(Helpers.parseBalance(matcher.group(4)));
             utnyttjad = utnyttjad.negate();
             accounts.add(new Account("Utnyttjad kredit",
                     utnyttjad,
-                    "u_"+accountId));
+                    "u_" + accountId));
 
             balance = balance.add(Helpers.parseBalance(matcher.group(3)));
             balance = balance.add(utnyttjad);
             accounts.add(new Account("Reserverat belopp",
                     Helpers.parseBalance(matcher.group(4)),
-                    "r_"+accountId));
+                    "r_" + accountId));
             accounts.add(new Account("Disponibelt",
                     Helpers.parseBalance(matcher.group(5)),
-                    "k_"+accountId));
+                    "k_" + accountId));
         }
 
         if (accounts.isEmpty()) {
@@ -139,7 +148,9 @@ public class ResursBank extends Bank {
             BankException, IOException {
         super.updateTransactions(account, urlopen);
         // Only update transactions for the main account
-        if (!account.getId().startsWith("b_")) return;
+        if (!account.getId().startsWith("b_")) {
+            return;
+        }
 
         response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
         Matcher matcher = reTransactions.matcher(response);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
index aae2cf8..df9615f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -15,33 +15,37 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class SJPrio extends SEBKortBase {
-	private static final String TAG = "SJPrio";
-	private static final String NAME = "SJ Prio MasterCard";
-	private static final String NAME_SHORT = "sj_prio";
-	private static final int BANKTYPE_ID = Bank.SJPRIO;
-
-	public SJPrio(Context context) {
-		super(context, "sjse", "0104");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public SJPrio(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "SJPrio";
+
+    private static final String NAME = "SJ Prio MasterCard";
+
+    private static final String NAME_SHORT = "sj_prio";
+
+    private static final int BANKTYPE_ID = Bank.SJPRIO;
+
+    public SJPrio(Context context) {
+        super(context, "sjse", "0104");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public SJPrio(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "sjse", "0104");
-	}
+        super(username, password, context, "sjse", "0104");
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
index 22f11ed..6ba7fcc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Saab extends SEBKortBase {
-	private static final String TAG = "SAAB";
-	private static final String NAME = "SaabKortet";
-	private static final String NAME_SHORT = "saab";
-	private static final int BANKTYPE_ID = Bank.SAAB;
-
-	public Saab(Context context) {
-		super(context, "sbse", "0106");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Saab(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "SAAB";
+
+    private static final String NAME = "SaabKortet";
+
+    private static final String NAME_SHORT = "saab";
+
+    private static final int BANKTYPE_ID = Bank.SAAB;
+
+    public Saab(Context context) {
+        super(context, "sbse", "0106");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Saab(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "sbse", "0106");
-	}
+        super(username, password, context, "sbse", "0106");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
index ec418c9..42435c0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
@@ -15,21 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Seat extends AbsIkanoPartner {
+
     private static final String TAG = "Seat";
+
     private static final String NAME = "Seatkortet";
+
     private static final String NAME_SHORT = "seat";
-    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1301";
+
+    private static final String URL
+            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1301";
+
     private static final int BANKTYPE_ID = Bank.SEAT;
 
     public Seat(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index bc0b52e..9f66217 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -16,105 +16,120 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SevenDay extends Bank {
-	private static final String TAG = "SevenDay";
-	private static final String NAME = "SevenDay";
-	private static final String NAME_SHORT = "sevenday";
-	private static final String URL = "https://www.sevenday.se/mina-sidor/mina-sidor.htm";
-	private static final int BANKTYPE_ID = IBankTypes.SEVENDAY;
+
+    private static final String TAG = "SevenDay";
+
+    private static final String NAME = "SevenDay";
+
+    private static final String NAME_SHORT = "sevenday";
+
+    private static final String URL = "https://www.sevenday.se/mina-sidor/mina-sidor.htm";
+
+    private static final int BANKTYPE_ID = IBankTypes.SEVENDAY;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-	
-    
-	private Pattern reViewState = Pattern.compile("ViewState\"\\s+value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("'depositAccountNum':'([^=]+)=='[^>]+>([^<]+)</a></td>\\s*<td[^>]+>\\s*<span[^>]+>\\s*([0-9,]+)[^<]+</span>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>\\s*([^<]+)<");
-	private String response = null;
-	
-	public SevenDay(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+
+    private Pattern reViewState = Pattern.compile("ViewState\"\\s+value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reAccounts = Pattern.compile(
+            "'depositAccountNum':'([^=]+)=='[^>]+>([^<]+)</a></td>\\s*<td[^>]+>\\s*<span[^>]+>\\s*([0-9,]+)[^<]+</span>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>\\s*([^<]+)<");
+
+    private String response = null;
+
+    public SevenDay(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
+    }
 
-	public SevenDay(String username, String password, Context context) throws BankException,
+    public SevenDay(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sevenday));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_sevenday));
         response = urlopen.open("https://www.sevenday.se/mina-sidor/mina-sidor.htm");
-        
+
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = matcher.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("loginForm", "loginForm"));
         postData.add(new BasicNameValuePair("login", "login"));
         postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
         postData.add(new BasicNameValuePair("ssn", username));
         postData.add(new BasicNameValuePair("password", password));
-        
-        return new LoginPackage(urlopen, postData, response, "https://www.sevenday.se/mina-sidor/mina-sidor.htm");
+
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.sevenday.se/mina-sidor/mina-sidor.htm");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Logga in med personnummer") || response.contains(
+                "kommer automatiskt till startsidan")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (response.contains("Logga in med personnummer") || response.contains("kommer automatiskt till startsidan")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-
-		Matcher matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
@@ -124,15 +139,15 @@ public class SevenDay extends Bank {
              * 4: Amount            10&nbsp;kr
              *
              */
-			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
-			        Helpers.parseBalance(matcher.group(4)),
-			        Html.fromHtml(matcher.group(1)).toString().trim()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-		}
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	    super.updateComplete();
-	}
+            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4)),
+                    Html.fromHtml(matcher.group(1)).toString().trim()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
index 98532df..86d859f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
@@ -15,21 +15,26 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Shell extends AbsIkanoPartner {
+
     private static final String TAG = "Shell";
+
     private static final String NAME = "Shell MasterCard";
+
     private static final String NAME_SHORT = "shell";
+
     private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
+
     private static final int BANKTYPE_ID = Bank.SHELL;
 
     public Shell(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 9fd6b67..a08836c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -1,14 +1,16 @@
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.HttpResponseException;
 import org.apache.http.message.BasicNameValuePair;
 import org.json.JSONArray;
@@ -19,228 +21,252 @@ import android.content.Context;
 import android.provider.Settings.Secure;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Skandiabanken extends Bank {
-	private static final String NAME = "Skandiabanken";
-	private static final String NAME_SHORT = "skandiabanken";
-	private static final int BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
-	private static final String URL = "http://www.skandiabanken.se/hem/";
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-	private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-
-	private static final String BASE_URL = "https://smartrefill.se/BankServices";
-
-	private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_ID = "x-smartrefill-application";
-	private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION = "x-smartrefill-version";
-	private static final String HTTP_HEADER_SMARTREFILL_COUNTRY_CODE = "x-smartrefill-country-code";
-	private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER = "x-smartrefill-customer-owner";
-	private static final String HTTP_HEADER_SMARTREFILL_DEVICE_ID = "x-smartrefill-device";
-	private static final String HTTP_HEADER_SMARTREFILL_INFLOW = "x-smartrefill-inflow";
-
-	private static final String INFLOW_ANDROID = "Android";
-	private final static String customerOwner = "SKANDIABANKEN";
-	private final static String countryCode = "SE";
-	private final static String SERVICE_NAME = "bank";
-
-	private int customerId = 0;
-
-	public Skandiabanken(Context context) {
-		super(context);
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-	}
-
-	public Skandiabanken(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
-
-		HashMap<String, String> headers = urlopen.getHeaders();
-		headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID,
-				"se.skandiabanken.android.wallet");
-		headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION, "9");
-		headers.put(HTTP_HEADER_SMARTREFILL_COUNTRY_CODE, countryCode);
-		headers.put(HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER, customerOwner);
-		headers.put(HTTP_HEADER_SMARTREFILL_DEVICE_ID, getDeviceId());
-		headers.put(HTTP_HEADER_SMARTREFILL_INFLOW, INFLOW_ANDROID);
-		
-		urlopen.setUserAgent(null);
-
-		String loginUrl = getBaseUrlWithCustomerOwner() + "/login";
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("username", username));
-		postData.add(new BasicNameValuePair("password", password));
-
-		try {
-			String loginResponse = urlopen.open(loginUrl, postData);
-			JSONObject obj = new JSONObject(loginResponse);
-			customerId = (int) obj.getLong("id");
-			urlopen.addHeader("x-smartrefill-customer", "" + customerId);
-		} catch (HttpResponseException e) {
-			if (e.getStatusCode() == 401)
-				throw new LoginException(
-						"Inloggning misslyckad fel användarnamn eller lösenord");
-			else
-				throw new BankException("Http fel (" + e.getStatusCode() + ") "
-						+ e.getMessage(), e);
-		} catch (JSONException e) {
-			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
-		}
-
-		return urlopen;
-	}
-
-	private String getBaseUrlWithCustomerOwner() {
-		return BASE_URL + "/rest/" + SERVICE_NAME + "/" + countryCode + "/"
-				+ customerOwner;
-	}
-
-	private void logout() {
-		String logoutUrl = getBaseUrlWithCustomerOwner() + "/customer/"
-				+ customerId + "/logout";
-		try {
-			urlopen.post(logoutUrl);
-		} catch (IOException e) {
-		}
-	}
-
-	@Override
-	public void update() throws BankException, LoginException,
-			BankChoiceException, IOException {
-		super.update();
-
-		if (username == null || password == null || username.length() == 0
-				|| password.length() == 0)
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
-
-		login();
-
-		String accountsUrl = getBaseUrlWithCustomerOwner() + "/customer/"
-				+ customerId + "/accounts";
-		try {
-			String accountsJsonString = urlopen.open(accountsUrl);
-			JSONArray json = new JSONArray(accountsJsonString);
-			for (int i = 0; i< json.length(); i++)
-			{
-				JSONObject acountJsonObj = json.getJSONObject(i);
-				
-				String name = acountJsonObj.optString("alias");
-				
-				if (name.length() != 0)
-					name += " - ";
-				
-				name += acountJsonObj.getString("accountNumber");
-
-				// disposableAmount also exists in JSON
-				String balanceString = acountJsonObj.getString("amount");
-				String id = acountJsonObj.getString("id");
-				int type = Account.REGULAR; // accountType exists in JSON
-				Account account = new Account(name, Helpers.parseBalance(balanceString), id, type);
-				accounts.add(account);
-			}
-		} catch (JSONException e) {
-			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
-		}
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen)
-			throws LoginException, BankException, IOException {
-		super.updateTransactions(account, urlopen);
-
-		if (customerId == 0)
-			login();
-		
-		try {
-	        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-			String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
-					+ "/customer/" + customerId + "/account/" + account.getId();
-
-			String accountJsonString = urlopen.open(accountTransactionsUrl);
-			JSONObject accountJSONObj = new JSONObject(accountJsonString);
-			JSONArray transactionsJSONArray = accountJSONObj.optJSONArray("transactions");
-			if (transactionsJSONArray != null) {
-			for (int i = 0; i< transactionsJSONArray.length(); i++) {
-    				JSONObject transactionJsonObj = transactionsJSONArray.getJSONObject(i);
-    				String date = transactionJsonObj.getString("date"); // time and timestamp also exists in JSON
-    				String ammountString = transactionJsonObj.getString("amount");
-    				String description = transactionJsonObj.getString("merchant");
-    				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
-    				transactions.add(transaction);
-    			}
-
-			    // Sort transactions by date
-    			Collections.sort(transactions, new Comparator<Transaction>() {
-    	            public int compare(Transaction t1, Transaction t2) {
-    	                return t2.compareTo(t1);
-    	            }
-    	        });
-
-    			account.setTransactions(transactions);
-			}
-
-		} catch (JSONException e) {
-			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
-		}
-	}
-
-	@Override
-	public void closeConnection() {
-		logout();
-		super.closeConnection();
-	}
-
-	public String getDeviceId() {
-		// TelephonyManager localTelephonyManager =
-		// (TelephonyManager)context.getSystemService("phone");
-		// if (localTelephonyManager.getDeviceId() != null) // null for emulator
-		// return localTelephonyManager.getDeviceId();
-		// else
-		// return "000000000000000";
-		// We should return the imei of the phone (se code above)
-		// As we would need permission to read imei we use something else that
-		// is unique and constant
-		// Bankdroid should have as less permissions as possible...
-		String test = Secure.getString(context.getContentResolver(),
-				Secure.ANDROID_ID);
-
-		if (test == null) // null for emulator
-			test = "0";
-
-		// convert to decimal string (imei is decimal)
-		try {
-			test = String.valueOf(Integer.parseInt(test, 16));
-		} catch (NumberFormatException e) {
-		}
-
-		while (test.length() < 16)
-			test += "0";
-
-		return test.substring(0, 15);
-	}
+
+    private static final String NAME = "Skandiabanken";
+
+    private static final String NAME_SHORT = "skandiabanken";
+
+    private static final int BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
+
+    private static final String URL = "http://www.skandiabanken.se/hem/";
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
+    private static final String BASE_URL = "https://smartrefill.se/BankServices";
+
+    private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_ID
+            = "x-smartrefill-application";
+
+    private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION
+            = "x-smartrefill-version";
+
+    private static final String HTTP_HEADER_SMARTREFILL_COUNTRY_CODE = "x-smartrefill-country-code";
+
+    private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER
+            = "x-smartrefill-customer-owner";
+
+    private static final String HTTP_HEADER_SMARTREFILL_DEVICE_ID = "x-smartrefill-device";
+
+    private static final String HTTP_HEADER_SMARTREFILL_INFLOW = "x-smartrefill-inflow";
+
+    private static final String INFLOW_ANDROID = "Android";
+
+    private final static String customerOwner = "SKANDIABANKEN";
+
+    private final static String countryCode = "SE";
+
+    private final static String SERVICE_NAME = "bank";
+
+    private int customerId = 0;
+
+    public Skandiabanken(Context context) {
+        super(context);
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+    }
+
+    public Skandiabanken(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
+
+        HashMap<String, String> headers = urlopen.getHeaders();
+        headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID,
+                "se.skandiabanken.android.wallet");
+        headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION, "9");
+        headers.put(HTTP_HEADER_SMARTREFILL_COUNTRY_CODE, countryCode);
+        headers.put(HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER, customerOwner);
+        headers.put(HTTP_HEADER_SMARTREFILL_DEVICE_ID, getDeviceId());
+        headers.put(HTTP_HEADER_SMARTREFILL_INFLOW, INFLOW_ANDROID);
+
+        urlopen.setUserAgent(null);
+
+        String loginUrl = getBaseUrlWithCustomerOwner() + "/login";
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+
+        try {
+            String loginResponse = urlopen.open(loginUrl, postData);
+            JSONObject obj = new JSONObject(loginResponse);
+            customerId = (int) obj.getLong("id");
+            urlopen.addHeader("x-smartrefill-customer", "" + customerId);
+        } catch (HttpResponseException e) {
+            if (e.getStatusCode() == 401) {
+                throw new LoginException(
+                        "Inloggning misslyckad fel användarnamn eller lösenord");
+            } else {
+                throw new BankException("Http fel (" + e.getStatusCode() + ") "
+                        + e.getMessage(), e);
+            }
+        } catch (JSONException e) {
+            throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
+        }
+
+        return urlopen;
+    }
+
+    private String getBaseUrlWithCustomerOwner() {
+        return BASE_URL + "/rest/" + SERVICE_NAME + "/" + countryCode + "/"
+                + customerOwner;
+    }
+
+    private void logout() {
+        String logoutUrl = getBaseUrlWithCustomerOwner() + "/customer/"
+                + customerId + "/logout";
+        try {
+            urlopen.post(logoutUrl);
+        } catch (IOException e) {
+        }
+    }
+
+    @Override
+    public void update() throws BankException, LoginException,
+            BankChoiceException, IOException {
+        super.update();
+
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_username_password).toString());
+        }
+
+        login();
+
+        String accountsUrl = getBaseUrlWithCustomerOwner() + "/customer/"
+                + customerId + "/accounts";
+        try {
+            String accountsJsonString = urlopen.open(accountsUrl);
+            JSONArray json = new JSONArray(accountsJsonString);
+            for (int i = 0; i < json.length(); i++) {
+                JSONObject acountJsonObj = json.getJSONObject(i);
+
+                String name = acountJsonObj.optString("alias");
+
+                if (name.length() != 0) {
+                    name += " - ";
+                }
+
+                name += acountJsonObj.getString("accountNumber");
+
+                // disposableAmount also exists in JSON
+                String balanceString = acountJsonObj.getString("amount");
+                String id = acountJsonObj.getString("id");
+                int type = Account.REGULAR; // accountType exists in JSON
+                Account account = new Account(name, Helpers.parseBalance(balanceString), id, type);
+                accounts.add(account);
+            }
+        } catch (JSONException e) {
+            throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException, IOException {
+        super.updateTransactions(account, urlopen);
+
+        if (customerId == 0) {
+            login();
+        }
+
+        try {
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+            String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
+                    + "/customer/" + customerId + "/account/" + account.getId();
+
+            String accountJsonString = urlopen.open(accountTransactionsUrl);
+            JSONObject accountJSONObj = new JSONObject(accountJsonString);
+            JSONArray transactionsJSONArray = accountJSONObj.optJSONArray("transactions");
+            if (transactionsJSONArray != null) {
+                for (int i = 0; i < transactionsJSONArray.length(); i++) {
+                    JSONObject transactionJsonObj = transactionsJSONArray.getJSONObject(i);
+                    String date = transactionJsonObj
+                            .getString("date"); // time and timestamp also exists in JSON
+                    String ammountString = transactionJsonObj.getString("amount");
+                    String description = transactionJsonObj.getString("merchant");
+                    Transaction transaction = new Transaction(date, description,
+                            Helpers.parseBalance(ammountString));
+                    transactions.add(transaction);
+                }
+
+                // Sort transactions by date
+                Collections.sort(transactions, new Comparator<Transaction>() {
+                    public int compare(Transaction t1, Transaction t2) {
+                        return t2.compareTo(t1);
+                    }
+                });
+
+                account.setTransactions(transactions);
+            }
+
+        } catch (JSONException e) {
+            throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void closeConnection() {
+        logout();
+        super.closeConnection();
+    }
+
+    public String getDeviceId() {
+        // TelephonyManager localTelephonyManager =
+        // (TelephonyManager)context.getSystemService("phone");
+        // if (localTelephonyManager.getDeviceId() != null) // null for emulator
+        // return localTelephonyManager.getDeviceId();
+        // else
+        // return "000000000000000";
+        // We should return the imei of the phone (se code above)
+        // As we would need permission to read imei we use something else that
+        // is unique and constant
+        // Bankdroid should have as less permissions as possible...
+        String test = Secure.getString(context.getContentResolver(),
+                Secure.ANDROID_ID);
+
+        if (test == null) // null for emulator
+        {
+            test = "0";
+        }
+
+        // convert to decimal string (imei is decimal)
+        try {
+            test = String.valueOf(Integer.parseInt(test, 16));
+        } catch (NumberFormatException e) {
+        }
+
+        while (test.length() < 16) {
+            test += "0";
+        }
+
+        return test.substring(0, 15);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
index 90b21c7..97cdab9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
@@ -15,21 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Skoda extends AbsIkanoPartner {
+
     private static final String TAG = "Skoda";
+
     private static final String NAME = "Skodakortet";
+
     private static final String NAME_SHORT = "skoda";
-    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2461";
+
+    private static final String URL
+            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2461";
+
     private static final int BANKTYPE_ID = Bank.SKODA;
 
     public Skoda(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index c775b2f..17bee6d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -15,22 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class SparbankenOresund extends MobilbankenBase {
-	private static final String TAG = "SparbankenOresund";
-	private static final String NAME = "Sparbanken Öresund";
-	private static final String NAME_SHORT = "sparbanken_oresund";
-	private static final String URL = "https://mobil-banken.se/0003/login.html";
-	private static final int BANKTYPE_ID = Bank.SPARBANKEN_ORESUND;
+
+    private static final String TAG = "SparbankenOresund";
+
+    private static final String NAME = "Sparbanken Öresund";
+
+    private static final String NAME_SHORT = "sparbanken_oresund";
+
+    private static final String URL = "https://mobil-banken.se/0003/login.html";
+
+    private static final int BANKTYPE_ID = Bank.SPARBANKEN_ORESUND;
 
     public SparbankenOresund(Context context) {
         super(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index e701b2b..532662d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -15,22 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class SparbankenSyd extends MobilbankenBase {
-	private static final String TAG = "SparbankenSyd";
-	private static final String NAME = "Sparbanken Syd";
-	private static final String NAME_SHORT = "sparbanken_syd";
-	private static final String URL = "https://mobil-banken.se/0004/login.html";
-	private static final int BANKTYPE_ID = Bank.SPARBANKEN_SYD;
+
+    private static final String TAG = "SparbankenSyd";
+
+    private static final String NAME = "Sparbanken Syd";
+
+    private static final String NAME_SHORT = "sparbanken_syd";
+
+    private static final String URL = "https://mobil-banken.se/0004/login.html";
+
+    private static final int BANKTYPE_ID = Bank.SPARBANKEN_SYD;
 
     public SparbankenSyd(Context context) {
         super(context);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
index d07215e..e7dbcbd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Statoil extends SEBKortBase {
-	private static final String TAG = "Statoil";
-	private static final String NAME = "Statoil Mastercard";
-	private static final String NAME_SHORT = "statoil";
-	private static final int BANKTYPE_ID = IBankTypes.STATOIL;
-
-	public Statoil(Context context) {
-		super(context, "stse", "0122");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Statoil(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Statoil";
+
+    private static final String NAME = "Statoil Mastercard";
+
+    private static final String NAME_SHORT = "statoil";
+
+    private static final int BANKTYPE_ID = IBankTypes.STATOIL;
+
+    public Statoil(Context context) {
+        super(context, "stse", "0122");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Statoil(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "stse", "0122");
-	}
+        super(username, password, context, "stse", "0122");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 4420243..688056c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -16,6 +16,23 @@
 
 package com.liato.bankdroid.banking.banks;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.text.ParseException;
@@ -27,60 +44,53 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.util.Log;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Steam extends Bank {
-	private static final String TAG = "Steam";
-	private static final String NAME = "Steam Wallet";
-	private static final String NAME_SHORT = "steam";
-	private static final String URL = "https://store.steampowered.com/login/?redir=account";
-	private static final int BANKTYPE_ID = IBankTypes.STEAM;
-	private static final boolean STATIC_BALANCE = true;
-	
-    private Pattern reBalance = Pattern.compile("accountBalance\">\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("(?:even|odd)\">\\s*<div\\s*class=\"transactionRowDate\">([^<]+)</div>\\s*<div.*?RowPrice\">([^<]+)</div>\\s*<div.*?RowEvent\">([^<]+)</div>.*?RowTitle\">([^<]+)</div>\\s*<span[^>]+>([^<]*)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private String response = null;
-	
-	public Steam(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-	}
-
-	public Steam(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "Steam";
+
+    private static final String NAME = "Steam Wallet";
+
+    private static final String NAME_SHORT = "steam";
+
+    private static final String URL = "https://store.steampowered.com/login/?redir=account";
+
+    private static final int BANKTYPE_ID = IBankTypes.STEAM;
+
+    private static final boolean STATIC_BALANCE = true;
+
+    private Pattern reBalance = Pattern.compile("accountBalance\">\\s*<div[^>]+>([^<]+)</div>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "(?:even|odd)\">\\s*<div\\s*class=\"transactionRowDate\">([^<]+)</div>\\s*<div.*?RowPrice\">([^<]+)</div>\\s*<div.*?RowEvent\">([^<]+)</div>.*?RowTitle\">([^<]+)</div>\\s*<span[^>]+>([^<]*)<",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private String response = null;
+
+    public Steam(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public Steam(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_steam));
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("redir", "account"));
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
@@ -89,42 +99,44 @@ public class Steam extends Bank {
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
         if (response.contains("Enter the characters above")) {
-            throw new LoginException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
+            throw new LoginException(
+                    "You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
+        }
+        if (response.contains("Incorrect login.")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-		if (response.contains("Incorrect login.")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		Matcher matcher = reBalance.matcher(response);
-		if (matcher.find()) {
+        urlopen = login();
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
              * 1: Amount            0,--&#8364;
              * 
              */
-		    String amount = Html.fromHtml(matcher.group(1)).toString().trim().replace("--", "00");
-		    Account account = new Account("Wallet", Helpers.parseBalance(amount), "1");
-		    String currency = Helpers.parseCurrency(amount, "USD");
-		    this.setCurrency(currency);
-		    account.setCurrency(currency);
-		    balance = balance.add(Helpers.parseBalance(amount));
-		    ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		    matcher = reTransactions.matcher(response);
-		    while (matcher.find()) {
-	            /*
+            String amount = Html.fromHtml(matcher.group(1)).toString().trim().replace("--", "00");
+            Account account = new Account("Wallet", Helpers.parseBalance(amount), "1");
+            String currency = Helpers.parseCurrency(amount, "USD");
+            this.setCurrency(currency);
+            account.setCurrency(currency);
+            balance = balance.add(Helpers.parseBalance(amount));
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            matcher = reTransactions.matcher(response);
+            while (matcher.find()) {
+                    /*
 	             * Capture groups:
 	             * GROUP                EXAMPLE DATA
 	             * 1: Date              18 Oct 2007
@@ -136,30 +148,34 @@ public class Steam extends Bank {
 	             */
                 SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
                 SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
-		        Date transactionDate;
+                Date transactionDate;
                 try {
                     transactionDate = sdfFrom.parse(matcher.group(1).trim());
                     String strDate = sdfTo.format(transactionDate);
-                    BigDecimal price = Helpers.parseBalance(Html.fromHtml(matcher.group(2)).toString().trim().replace("--", "00"));
+                    BigDecimal price = Helpers.parseBalance(
+                            Html.fromHtml(matcher.group(2)).toString().trim().replace("--", "00"));
                     if ("Purchase".equalsIgnoreCase(matcher.group(3).trim())) {
                         price = price.negate();
                     }
                     transactions.add(new Transaction(strDate,
-                                                     Html.fromHtml(matcher.group(4)).toString().trim() + (Html.fromHtml(matcher.group(5)).toString().trim().length() > 1 ? " (" + Html.fromHtml(matcher.group(5)).toString().trim() + ")" : ""),
-                                                     price,
-                                                     Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(), "USD")));
-                }
-                catch (ParseException e) {
+                            Html.fromHtml(matcher.group(4)).toString().trim() + (
+                                    Html.fromHtml(matcher.group(5)).toString().trim().length() > 1 ?
+                                            " (" + Html.fromHtml(matcher.group(5)).toString().trim()
+                                                    + ")" : ""),
+                            price,
+                            Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(),
+                                    "USD")));
+                } catch (ParseException e) {
                     Log.e(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
-		    }
-		    Collections.sort(transactions, Collections.reverseOrder());
-		    account.setTransactions(transactions);
-		    accounts.add(account);
-		}
+            }
+            Collections.sort(transactions, Collections.reverseOrder());
+            account.setTransactions(transactions);
+            accounts.add(account);
+        }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }		
+        }
         super.updateComplete();
-	}
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
index b4b3932..35216cd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
@@ -1,13 +1,13 @@
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class SupremeCard extends ResursBank {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 3b76e47..f0df829 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -1,20 +1,15 @@
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.params.ClientPNames;
 import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
@@ -22,6 +17,9 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.InputType;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -31,20 +29,34 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SveaDirekt extends Bank {
+
     private static final String TAG = "SveaDirekt";
+
     private static final String NAME = "Svea Direkt";
+
     private static final String NAME_SHORT = "sveadirekt";
+
     private static final String URL = "https://http://www.sveadirekt.com/sv/swe//";
+
     private static final int BANKTYPE_ID = IBankTypes.SVEADIREKT;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "YYMMDDXXXX";
 
 
     private static final String BASE_URL = "https://services.sveadirekt.se/mypages/sv/";
-    private static final String LOGIN_URL = "https://services.sveadirekt.se/mypages/sv/j_security_check";
-    private static final String ACCOUNTS_URL = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/home.jsp";
-    private static final String TRANSACTIONS_URL = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/balance.jsp";
+
+    private static final String LOGIN_URL
+            = "https://services.sveadirekt.se/mypages/sv/j_security_check";
+
+    private static final String ACCOUNTS_URL
+            = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/home.jsp";
+
+    private static final String TRANSACTIONS_URL
+            = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/balance.jsp";
 
     private String response;
 
@@ -69,8 +81,10 @@ public class SveaDirekt extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
         if (urlopen == null) {
-            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sveadirekt));
-            urlopen.getHttpclient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
+            urlopen = new Urllib(context,
+                    CertificateReader.getCertificates(context, R.raw.cert_sveadirekt));
+            urlopen.getHttpclient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,
+                    true);
         }
         response = urlopen
                 .open(BASE_URL);
@@ -94,7 +108,7 @@ public class SveaDirekt extends Bank {
         response = urlopen.open(LOGIN_URL, lp.getPostData());
         if (response.contains("error-failed-to-login")) {
             throw new LoginException(res.getText(
-                        R.string.invalid_username_password).toString());
+                    R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
@@ -111,9 +125,9 @@ public class SveaDirekt extends Bank {
         urlopen = login();
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("homeForm:balance","Saldo"));
-        postData.add(new BasicNameValuePair("homeForm","homeForm"));
-        response = urlopen.open(ACCOUNTS_URL,postData);
+        postData.add(new BasicNameValuePair("homeForm:balance", "Saldo"));
+        postData.add(new BasicNameValuePair("homeForm", "homeForm"));
+        response = urlopen.open(ACCOUNTS_URL, postData);
         Document doc = Jsoup.parse(response);
         ArrayList<Account> accounts = parseAccounts(doc);
 
@@ -140,8 +154,8 @@ public class SveaDirekt extends Bank {
         ArrayList<Account> accountList = new ArrayList<Account>();
         Element element = pDocument.getElementById("balanceForm:accountsList");
         Elements accounts = element.select("td a[href=#]");
-        for (int i = 0; i<accounts.size(); i++) {
-            Account account = new Account("",BigDecimal.ZERO,Integer.toString(i));
+        for (int i = 0; i < accounts.size(); i++) {
+            Account account = new Account("", BigDecimal.ZERO, Integer.toString(i));
             accountList.add(account);
         }
         return accountList;
@@ -170,23 +184,24 @@ public class SveaDirekt extends Bank {
 
             Elements vTransactionElement = element.select("td");
 
-           BigDecimal amount = new BigDecimal(vTransactionElement.get(1).text()
+            BigDecimal amount = new BigDecimal(vTransactionElement.get(1).text()
                     .replaceAll("[^\\d-]", ""));
             String description = vTransactionElement.get(2).text();
             if (description == null || description.isEmpty()) {
-               description = amount.compareTo(BigDecimal.ZERO) > 0 ? "Insättning"
-                                : "Uttag";
+                description = amount.compareTo(BigDecimal.ZERO) > 0 ? "Insättning"
+                        : "Uttag";
             }
             String date = vTransactionElement.first().text();
-            vTransactions.add(new Transaction(date,description,amount));
+            vTransactions.add(new Transaction(date, description, amount));
         }
         return vTransactions;
     }
 
-    List<NameValuePair>  createTransactionParams(Account pAccount) {
+    List<NameValuePair> createTransactionParams(Account pAccount) {
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("balanceForm", "balanceForm"));
-        postData.add(new BasicNameValuePair("balanceForm:_idcl","balanceForm:accountsList:"+pAccount.getId()+":_id15"));
+        postData.add(new BasicNameValuePair("balanceForm:_idcl",
+                "balanceForm:accountsList:" + pAccount.getId() + ":_id15"));
         return postData;
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 0c3a2b8..6321814 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -16,109 +16,117 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.util.EntityUtils;
 
 import android.content.Context;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SvenskaSpel extends Bank {
 
-	private static final String TAG = "SvenskaSpel";
-	private static final String NAME = "Svenska Spel";
-	private static final String NAME_SHORT = "svenskaspel";
-	private static final String URL = "https://api.www.svenskaspel.se/player/sessions";
-	private static final int BANKTYPE_ID = Bank.SVENSKASPEL;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-	private static final int INPUT_TITLETEXT_USERNAME = R.string.username;
-
-	private Pattern reBalance = Pattern.compile("balance\":\"(.*?)\",", Pattern.CASE_INSENSITIVE);
-	private String response = "";
-
-	public SvenskaSpel(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
-	}
-
-	public SvenskaSpel(String username, String password, Context context) throws BankException,
+    private static final String TAG = "SvenskaSpel";
+
+    private static final String NAME = "Svenska Spel";
+
+    private static final String NAME_SHORT = "svenskaspel";
+
+    private static final String URL = "https://api.www.svenskaspel.se/player/sessions";
+
+    private static final int BANKTYPE_ID = Bank.SVENSKASPEL;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
+    private static final int INPUT_TITLETEXT_USERNAME = R.string.username;
+
+    private Pattern reBalance = Pattern.compile("balance\":\"(.*?)\",", Pattern.CASE_INSENSITIVE);
+
+    private String response = "";
+
+    public SvenskaSpel(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+    }
+
+    public SvenskaSpel(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	protected LoginPackage preLogin() throws BankException, IOException {
-		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
-
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		return new LoginPackage(urlopen, postData, response, URL);
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-
-		StringEntity postdata = new StringEntity(
-				"{\"userName\":\"" + username + "\",\"password\":\"" + password + "\"}");
-		HttpResponse httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), postdata, true);
-
-		if (httpResponse.getStatusLine().getStatusCode() != 200) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		response = EntityUtils.toString(httpResponse.getEntity());
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-
-		Matcher matcher = reBalance.matcher(response);
-		if (matcher.find()) {
-			/*
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        return new LoginPackage(urlopen, postData, response, URL);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+
+        StringEntity postdata = new StringEntity(
+                "{\"userName\":\"" + username + "\",\"password\":\"" + password + "\"}");
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), postdata, true);
+
+        if (httpResponse.getStatusLine().getStatusCode() != 200) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        response = EntityUtils.toString(httpResponse.getEntity());
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
+                        /*
 			 * Capture groups:
 			 * GROUP                    EXAMPLE DATA
 			 * 1: balance               845
 			 *
 			 */
-			Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "1");
-			balance = Helpers.parseBalance(matcher.group(1));
-			balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-			accounts.add(account);
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-		super.updateComplete();
-	}
+            Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "1");
+            balance = Helpers.parseBalance(matcher.group(1));
+            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+            accounts.add(account);
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index 0806fcb..fba7ebe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -16,74 +16,87 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.Urllib;
 
 public class TestBank extends Bank {
-	private static final String TAG = "TestBank";
-	private static final String NAME = "Testbank";
-	private static final String NAME_SHORT = "testbank";
-	private static final String URL = "http://www.nullbyte.eu/";
-	private static final int BANKTYPE_ID = IBankTypes.TESTBANK;
+
+    private static final String TAG = "TestBank";
+
+    private static final String NAME = "Testbank";
+
+    private static final String NAME_SHORT = "testbank";
+
+    private static final String URL = "http://www.nullbyte.eu/";
+
+    private static final int BANKTYPE_ID = IBankTypes.TESTBANK;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-	
-	private Pattern reAccounts = Pattern.compile("<div>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-	public TestBank(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    private Pattern reAccounts = Pattern.compile(
+            "<div>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    public TestBank(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
+    }
 
-	public TestBank(String username, String password, Context context) throws BankException,
+    public TestBank(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(context);
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		String response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/accounts.htm");
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib(context);
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        String response = urlopen.open(
+                "http://www.nullbyte.eu/bankdroid/tests/testbank/accounts.htm");
         Matcher matcher = reAccounts.matcher(response);
         while (matcher.find()) {
             /*
@@ -95,43 +108,50 @@ public class TestBank extends Bank {
              * 4: Type              trans|fund
              *
              */
-            Account acc = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ("fund".equals(matcher.group(4)) ? "f:" : "")+matcher.group(3).trim());
+            Account acc = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(2)),
+                    ("fund".equals(matcher.group(4)) ? "f:" : "") + matcher.group(3).trim());
             if ("fund".equals(matcher.group(4))) {
                 acc.setType(Account.FUNDS);
-            }
-            else {
+            } else {
                 balance = balance.add(Helpers.parseBalance(matcher.group(3)));
             }
             accounts.add(acc);
         }
 
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-		super.updateComplete();
-	}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
-
-		//No transaction history for loans, funds and credit cards.
-		int accType = account.getType();
-		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
-
-		Matcher matcher;
-        String response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
-		matcher = reTransactions.matcher(response);
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		while (matcher.find()) {
-			transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-		}
-		account.setTransactions(transactions);
-	}
+        super.updateTransactions(account, urlopen);
+
+        //No transaction history for loans, funds and credit cards.
+        int accType = account.getType();
+        if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) {
+            return;
+        }
+
+        Matcher matcher;
+        String response = urlopen.open(
+                "http://www.nullbyte.eu/bankdroid/tests/testbank/transactions_" + account.getId()
+                        + ".htm");
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
+        }
+        account.setTransactions(transactions);
+    }
 
     @Override
     public int getImageResource() {
-        return res.getIdentifier("icon_large", "drawable", context.getPackageName()); 
+        return res.getIdentifier("icon_large", "drawable", context.getPackageName());
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index adf4bc0..c58dd43 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -15,12 +15,14 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
@@ -29,33 +31,42 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class TicketRikskortet extends Bank {
 
-	private static final String TAG = "Rikskortet";
-	private static final String NAME = "Ticket Rikskortet";
-	private static final String NAME_SHORT = "rikskortet";
-	private static final String URL = "https://www.edenred.se/sv/System/Logga-in/";
-	private static final int BANKTYPE_ID = Bank.RIKSKORTET;
+    private static final String TAG = "Rikskortet";
+
+    private static final String NAME = "Ticket Rikskortet";
+
+    private static final String NAME_SHORT = "rikskortet";
+
+    private static final String URL = "https://www.edenred.se/sv/System/Logga-in/";
+
+    private static final int BANKTYPE_ID = Bank.RIKSKORTET;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reBalance = Pattern.compile("EmployeeBalanceLabel\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s\\d{2}:\\d{2}:\\d{2}</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reEventValidation = Pattern
+            .compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+
+    private Pattern reBalance = Pattern.compile("EmployeeBalanceLabel\">([^<]+)</span>",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "(\\d{4}-\\d{2}-\\d{2})\\s\\d{2}:\\d{2}:\\d{2}</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>",
+            Pattern.CASE_INSENSITIVE);
 
     private String response = null;
-    
+
     public TicketRikskortet(Context context) {
         super(context);
         super.TAG = TAG;
@@ -71,33 +82,43 @@ public class TicketRikskortet extends Bank {
         this.update(username, password);
     }
 
-    
+
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
         response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = matcher.group(1);
 
         matcher = reEventValidation.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
-        String eventValidation = matcher.group(1);            
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        String eventValidation = matcher.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
         postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("ctl00$CorporateHeaderArea$CorporateHeaderID$QuickSearch$SearchText", "Sök här"));
-        postData.add(new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$UserName", username));
-        postData.add(new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$Password", password));
-        postData.add(new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$LoginButton", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, "https://www.edenred.se/sv/System/Logga-in/");
+        postData.add(new BasicNameValuePair(
+                "ctl00$CorporateHeaderArea$CorporateHeaderID$QuickSearch$SearchText", "Sök här"));
+        postData.add(
+                new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$UserName",
+                        username));
+        postData.add(
+                new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$Password",
+                        password));
+        postData.add(new BasicNameValuePair(
+                "ctl00$StartpageArea$ApplicationArea$LoginControl$LoginButton", "Logga in"));
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.edenred.se/sv/System/Logga-in/");
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
@@ -112,18 +133,18 @@ public class TicketRikskortet extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        if (!"https://www.edenred.se/sv/Apps/Employee/Start/".equalsIgnoreCase(urlopen.getCurrentURI())) {
+        if (!"https://www.edenred.se/sv/Apps/Employee/Start/".equalsIgnoreCase(
+                urlopen.getCurrentURI())) {
             try {
                 response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/");
-            }
-            catch (ClientProtocolException e) {
+            } catch (ClientProtocolException e) {
                 throw new BankException(e.getMessage(), e);
-            }
-            catch (IOException e) {
+            } catch (IOException e) {
                 throw new BankException(e.getMessage(), e);
             }
         }
@@ -152,7 +173,8 @@ public class TicketRikskortet extends Bank {
         super.updateTransactions(account, urlopen);
 
         Matcher matcher;
-        String response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/Transaktioner/");
+        String response = urlopen.open(
+                "https://www.edenred.se/sv/Apps/Employee/Start/Transaktioner/");
         matcher = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 
@@ -166,7 +188,9 @@ public class TicketRikskortet extends Bank {
              *
              */
 
-            transactions.add(new Transaction(matcher.group(1), Html.fromHtml(matcher.group(2).trim()).toString(), Helpers.parseBalance(matcher.group(3))));
+            transactions.add(new Transaction(matcher.group(1),
+                    Html.fromHtml(matcher.group(2).trim()).toString(),
+                    Helpers.parseBalance(matcher.group(3))));
         }
         account.setTransactions(transactions);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 550d32a..41e39c8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -16,119 +16,132 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class TrustBuddy extends Bank {
-	private static final String TAG = "TrustBuddy";
-	private static final String NAME = "TrustBuddy";
-	private static final String NAME_SHORT = "trustbuddy";
-	private static final String URL = "https://www.trustbuddy.com/";
-	private static final int BANKTYPE_ID = IBankTypes.TRUSTBUDDY;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
-	private static final String INPUT_HINT_USERNAME = "Your email";
-	private static final boolean STATIC_BALANCE = true;
-
-	private Pattern reError = Pattern.compile("<h3>error\\s*:\\s*</h3>\\s*<p>\\s*(.*?)\\s*</p>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("<h1>\\s*([^<]+).*?>Balans: ([0-9, ]+) ([A-Z]{3})<",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);	
-
-	public TrustBuddy(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-	}
-
-	public TrustBuddy(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "TrustBuddy";
+
+    private static final String NAME = "TrustBuddy";
+
+    private static final String NAME_SHORT = "trustbuddy";
+
+    private static final String URL = "https://www.trustbuddy.com/";
+
+    private static final int BANKTYPE_ID = IBankTypes.TRUSTBUDDY;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
+    private static final String INPUT_HINT_USERNAME = "Your email";
+
+    private static final boolean STATIC_BALANCE = true;
+
+    private Pattern reError = Pattern.compile("<h3>error\\s*:\\s*</h3>\\s*<p>\\s*(.*?)\\s*</p>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reAccounts = Pattern.compile(
+            "<h1>\\s*([^<]+).*?>Balans: ([0-9, ]+) ([A-Z]{3})<",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    public TrustBuddy(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public TrustBuddy(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
         urlopen.setAllowCircularRedirects(true);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
         postData.add(new BasicNameValuePair("logon", "Logga in"));
         return new LoginPackage(urlopen, postData, null, "https://trustbuddy.com/se/logga_in/");
     }
-    
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		Matcher matcher = reError.matcher(response);
-		if (matcher.find()) {
-		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-		    if (errormsg.contains("Felaktigt")) {
-		        throw new LoginException(errormsg);
-		    }
-		    else {
-	             throw new BankException(errormsg);
-		    }
-		}
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		String response = urlopen.open("https://trustbuddy.com/se/din_sida/");
-		Matcher matcher = reAccounts.matcher(response);
-			
-		while (matcher.find()) {
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        Matcher matcher = reError.matcher(response);
+        if (matcher.find()) {
+            String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+            if (errormsg.contains("Felaktigt")) {
+                throw new LoginException(errormsg);
+            } else {
+                throw new BankException(errormsg);
+            }
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        String response = urlopen.open("https://trustbuddy.com/se/din_sida/");
+        Matcher matcher = reAccounts.matcher(response);
+
+        while (matcher.find()) {
             /*
              * 1: Land
              * 2: Saldo
              * 3: Valuta
              */
-			Account temp = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2).trim()), matcher.group(1).toLowerCase());
-			temp.setCurrency(matcher.group(3));
-			accounts.add(temp);
-
-        	balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-		}
-		if (accounts.isEmpty()) {
-		    throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	}
+            Account temp = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(2).trim()), matcher.group(1).toLowerCase());
+            temp.setCurrency(matcher.group(3));
+            accounts.add(temp);
+
+            balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index cdebeaf..ae6e70d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -16,41 +16,52 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Vasttrafik extends Bank {
+
     private static final String TAG = "Västtrafik";
+
     private static final String NAME = "Västtrafik";
+
     private static final String NAME_SHORT = "vasttrafik";
+
     private static final String URL = "https://www.vasttrafik.se/mina-sidor/";
+
     private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reAccounts = Pattern.compile("<h3 class=\"cardName\">(.*?)</h3>(.*?)<span class=\"isAccount hidden\">", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
-    private Pattern reBalance = Pattern.compile("<span class=\"chargeType\"><span class='col1'>(.*?):</span><span class='col2 boldType'>(.*?)</span></span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+
+    private Pattern reAccounts = Pattern
+            .compile("<h3 class=\"cardName\">(.*?)</h3>(.*?)<span class=\"isAccount hidden\">",
+                    Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+
+    private Pattern reBalance = Pattern.compile(
+            "<span class=\"chargeType\"><span class='col1'>(.*?):</span><span class='col2 boldType'>(.*?)</span></span>",
+            Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+
     private String response = null;
 
     public Vasttrafik(Context context) {
@@ -70,23 +81,34 @@ public class Vasttrafik extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_vasttrafik));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_vasttrafik));
         response = urlopen.open("https://www.vasttrafik.se/mina-sidor/logga-in/");
 
-		Matcher matcher = reViewState.matcher(response);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-		}
-		String strViewState = matcher.group(1);
-
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-		postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxUserName", username));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxPassword", password));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$CheckBoxPersistent", "on"));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$ButtonLogin", "Logga in"));
-
-        return new LoginPackage(urlopen, postData, response, "https://www.vasttrafik.se/mina-sidor/logga-in/?ReturnUrl=/mina-sidor-inloggad/mina-kort/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String strViewState = matcher.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair(
+                "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxUserName",
+                username));
+        postData.add(new BasicNameValuePair(
+                "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxPassword",
+                password));
+        postData.add(new BasicNameValuePair(
+                "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$CheckBoxPersistent",
+                "on"));
+        postData.add(new BasicNameValuePair(
+                "ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$ButtonLogin",
+                "Logga in"));
+
+        return new LoginPackage(urlopen, postData, response,
+                "https://www.vasttrafik.se/mina-sidor/logga-in/?ReturnUrl=/mina-sidor-inloggad/mina-kort/");
     }
 
     @Override
@@ -102,7 +124,8 @@ public class Vasttrafik extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -119,9 +142,9 @@ public class Vasttrafik extends Bank {
              * 2: Balance information
              */
 
-			if ("".equals(matcher.group(1))) {
-				continue;
-			}
+            if ("".equals(matcher.group(1))) {
+                continue;
+            }
 
             matcher_b = reBalance.matcher(matcher.group(2));
             if (matcher_b.find()) {
@@ -132,10 +155,12 @@ public class Vasttrafik extends Bank {
                  * 2: Amount            592,80 kr
                  */
 
-				String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
+                String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>", "")
+                        .replaceAll("\\<[^>]*>", "").trim();
 
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(1)));
-				balance = balance.add(Helpers.parseBalance(balanceString));
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(balanceString), matcher.group(1)));
+                balance = balance.add(Helpers.parseBalance(balanceString));
             }
         }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 873b077..9b17449 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -16,159 +16,189 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Villabanken extends Bank {
-	private static final String TAG = "Villabanken";
-	private static final String NAME = "Villabanken";
-	private static final String NAME_SHORT = "villabanken";
-	private static final String URL = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
-	private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
-
-    private final Pattern reDisposableAmount = Pattern.compile("<[^>]+>((?:Kvar att utnyttja:)+)[^>]+>([^<]+)");
-    private final Pattern reBalance = Pattern.compile("<[^>]+>((?:Utnyttjad kredit:)+)[^>]+>([^<]+)");
-    private final Pattern reCreditLimit = Pattern.compile("<[^>]+>((?:Beviljad kredit:)+)[^>]+>([^<]+)");
-    private final Pattern reTransactions = Pattern.compile("<[^>]+>(\\d{4}-\\d{2}-\\d{2})[^>]+><[^>]*>+([^<]+)<[^>]*><[^>]*>([^<]+) SEK<");
-	private final Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
-	private final Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
-	private final Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
-	private final Pattern reCtl00 = Pattern.compile("\"(ctl00.*?ctl00)\"");
-    private String accountUrl = "https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx";;
+
+    private static final String TAG = "Villabanken";
+
+    private static final String NAME = "Villabanken";
+
+    private static final String NAME_SHORT = "villabanken";
+
+    private static final String URL
+            = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
+
+    private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
+
+    private final Pattern reDisposableAmount = Pattern.compile(
+            "<[^>]+>((?:Kvar att utnyttja:)+)[^>]+>([^<]+)");
+
+    private final Pattern reBalance = Pattern.compile(
+            "<[^>]+>((?:Utnyttjad kredit:)+)[^>]+>([^<]+)");
+
+    private final Pattern reCreditLimit = Pattern.compile(
+            "<[^>]+>((?:Beviljad kredit:)+)[^>]+>([^<]+)");
+
+    private final Pattern reTransactions = Pattern.compile(
+            "<[^>]+>(\\d{4}-\\d{2}-\\d{2})[^>]+><[^>]*>+([^<]+)<[^>]*><[^>]*>([^<]+) SEK<");
+
+    private final Pattern reRequestDigest = Pattern.compile(
+            "__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
+
+    private final Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
+
+    private final Pattern reEventValidation = Pattern.compile(
+            "__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
+
+    private final Pattern reCtl00 = Pattern.compile("\"(ctl00.*?ctl00)\"");
+
+    private String accountUrl
+            = "https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx";
+
+    ;
+
     private String accountResponse = null;
 
     public Villabanken(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public Villabanken(String username, String password, Context context) throws BankException,
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Villabanken(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-	protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_villabanken));
-		String preLoginResponse = urlopen.open(URL);
-		Matcher matcher = reRequestDigest.matcher(preLoginResponse);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString() + " request digest.");
-		}
-		String requestDigest = matcher.group(1);
-
-		matcher = reCtl00.matcher(preLoginResponse);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl00");
-		}
-		String ctl00 = matcher.group(1);
-
-		matcher = reViewState.matcher(preLoginResponse);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString() + " view state.");
-		}
-		String viewState = matcher.group(1);
-
-		matcher = reEventValidation.matcher(preLoginResponse);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString() + " event validation.");
-		}
-		String eventValidation = matcher.group(1);
-
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
-		postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
-		postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
-		postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
-		postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
-		postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
-		postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
-		postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-		postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-		postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
-		postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
-		postData.add(new BasicNameValuePair("MSOSPWebPartManager_ExitingDesignMode", "false"));
-		postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
-		postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
-		postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
-		postData.add(new BasicNameValuePair("_wpSelected", ""));
-		postData.add(new BasicNameValuePair("_wzSelected", ""));
-		postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
-		postData.add(new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
-		postData.add(new BasicNameValuePair("MSOSPWebPartManager_EndWebPartEditing", "false"));
-		postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-		postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-		postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-		postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "accountNumber"), username));
-		postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "password"), password));
-		postData.add(new BasicNameValuePair(ctl00, "Logga in"));
-		postData.add(new BasicNameValuePair("__spDummyText1", ""));
-		postData.add(new BasicNameValuePair("__spDummyText2", ""));
-		postData.add(new BasicNameValuePair("_wpcmWpid", ""));
-		postData.add(new BasicNameValuePair("wpcmVal", ""));
-
-		return new LoginPackage(urlopen, postData, preLoginResponse, URL);
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		String loginResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		if (loginResponse.contains("misslyckades")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_villabanken));
+        String preLoginResponse = urlopen.open(URL);
+        Matcher matcher = reRequestDigest.matcher(preLoginResponse);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " request digest.");
+        }
+        String requestDigest = matcher.group(1);
+
+        matcher = reCtl00.matcher(preLoginResponse);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl00");
+        }
+        String ctl00 = matcher.group(1);
+
+        matcher = reViewState.matcher(preLoginResponse);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " view state.");
+        }
+        String viewState = matcher.group(1);
+
+        matcher = reEventValidation.matcher(preLoginResponse);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " event validation.");
+        }
+        String eventValidation = matcher.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
+        postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
+        postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
+        postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
+        postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
+        postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
+        postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_ExitingDesignMode", "false"));
+        postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
+        postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
+        postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
+        postData.add(new BasicNameValuePair("_wpSelected", ""));
+        postData.add(new BasicNameValuePair("_wzSelected", ""));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
+        postData.add(
+                new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_EndWebPartEditing", "false"));
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "accountNumber"), username));
+        postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "password"), password));
+        postData.add(new BasicNameValuePair(ctl00, "Logga in"));
+        postData.add(new BasicNameValuePair("__spDummyText1", ""));
+        postData.add(new BasicNameValuePair("__spDummyText2", ""));
+        postData.add(new BasicNameValuePair("_wpcmWpid", ""));
+        postData.add(new BasicNameValuePair("wpcmVal", ""));
+
+        return new LoginPackage(urlopen, postData, preLoginResponse, URL);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String loginResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (loginResponse.contains("misslyckades")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
         this.accountResponse = urlopen.open(accountUrl);
 
-		return urlopen;
-	}
+        return urlopen;
+    }
 
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
 
-		Matcher matcher;
+        Matcher matcher;
 
         matcher = reDisposableAmount.matcher(accountResponse);
-        if(matcher.find()) {
-            Account account = new Account("Disponibelt belopp", Helpers.parseBalance(matcher.group(2)), "0");
+        if (matcher.find()) {
+            Account account = new Account("Disponibelt belopp",
+                    Helpers.parseBalance(matcher.group(2)), "0");
             account.setType(Account.CCARD);
             account.setCurrency(currency);
             accounts.add(account);
             balance = balance.add(account.getBalance());
         }
         matcher = reBalance.matcher(accountResponse);
-        if(matcher.find()) {
+        if (matcher.find()) {
             Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
             account.setType(Account.OTHER);
             account.setAliasfor("Saldo alias");
@@ -176,7 +206,7 @@ public class Villabanken extends Bank {
             accounts.add(account);
         }
         matcher = reCreditLimit.matcher(accountResponse);
-        if(matcher.find()) {
+        if (matcher.find()) {
             Account account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
             account.setType(Account.OTHER);
             account.setAliasfor("Köpgräns alias");
@@ -188,18 +218,21 @@ public class Villabanken extends Bank {
         }
 
         super.updateComplete();
-	}
+    }
 
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
-        if (account.getType() != Account.CCARD) return;
+        if (account.getType() != Account.CCARD) {
+            return;
+        }
 
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         Matcher matcher = reTransactions.matcher(accountResponse);
-        while(matcher.find()) {
-            transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate(), account.getCurrency()));
+        while (matcher.find()) {
+            transactions.add(new Transaction(matcher.group(1), matcher.group(2),
+                    Helpers.parseBalance(matcher.group(3)).negate(), account.getCurrency()));
         }
         account.setTransactions(transactions);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
index ed73df3..ca8277d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -15,21 +15,27 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Volkswagen extends AbsIkanoPartner {
+
     private static final String TAG = "Volkswagen";
+
     private static final String NAME = "Volkswagenkortet";
+
     private static final String NAME_SHORT = "volkswagen";
-    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1319";
+
+    private static final String URL
+            = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1319";
+
     private static final int BANKTYPE_ID = Bank.VOLKSWAGEN;
 
     public Volkswagen(Context context) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 9b558ae..ba0453b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -16,17 +16,17 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 import org.json.JSONArray;
@@ -40,107 +40,130 @@ import org.jsoup.nodes.Element;
 import android.content.Context;
 import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Volvofinans extends Bank {
-	private static final String TAG = "Volvofinans";
-	private static final String NAME = "Volvofinans";
-	private static final String NAME_SHORT = "volvofinans";
-	private static final String URL = "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html";
-	private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
+
+    private static final String TAG = "Volvofinans";
+
+    private static final String NAME = "Volvofinans";
+
+    private static final String NAME_SHORT = "volvofinans";
+
+    private static final String URL
+            = "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html";
+
+    private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    private static SimpleDateFormat DATE_PARSER = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy", Locale.UK);
-    private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd", new Locale("sv_SE"));
+
+    private static SimpleDateFormat DATE_PARSER = new SimpleDateFormat(
+            "EEE MMM d HH:mm:ss zzz yyyy", Locale.UK);
+
+    private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd",
+            new Locale("sv_SE"));
+
     private HashMap<String, String> mAccountUrlMappings = new HashMap<String, String>();
-    
-	public Volvofinans(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+
+    public Volvofinans(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
+    }
 
-	public Volvofinans(String username, String password, Context context) throws BankException,
+    public Volvofinans(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
 
-	@Override
+    @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context,
+                R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
-        postData.add(new BasicNameValuePair("TARGET", "https://inloggad.volvofinans.se/privat/inloggning/redirect.html"));
-        postData.add(new BasicNameValuePair("REFERER", "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html"));
-        return new LoginPackage(urlopen, postData, null, "https://secure.volvofinans.se/neas/KodAuth");
+        postData.add(new BasicNameValuePair("TARGET",
+                "https://inloggad.volvofinans.se/privat/inloggning/redirect.html"));
+        postData.add(new BasicNameValuePair("REFERER",
+                "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html"));
+        return new LoginPackage(urlopen, postData, null,
+                "https://secure.volvofinans.se/neas/KodAuth");
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException, IOException {
-	    LoginPackage lp = preLogin();
-	    String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-		if (response.contains("Fel personr/organisationsnr och/eller lösenord.")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		if (response.contains("Internetbanken är stängd för tillfället och beräknas vara tillgänglig")) {
-			throw new LoginException(res.getText(R.string.bank_closed).toString());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		String response = urlopen.open("https://inloggad.volvofinans.se/privat/kund/kortkonto/oversikt/kortkonton.html");
-		try {
-			JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
-			JSONArray data = object.getJSONArray("data");
-
-			int length = data.length();
-			for (int index = 0; index < length; index++) {
-				JSONObject account = data.getJSONObject(index);
-				Document d = Jsoup.parse(account.getString("namnUrl"));
-				Element e = d.getElementsByTag("a").first();
-				if (e != null && e.attr("href") != null) {
-    				mAccountUrlMappings.put(account.getString("kontonummer"), e.attr("href").replace("/info.html", "/info/kontoutdrag.html"));
-				}
-				accounts.add(new Account(String.format("%s (%s)", account.getString("namn"), account.getString("kontonummer")), Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(Helpers.parseBalance(account.getString("limit"))), account.getString("kontonummer")));
-			}
-		}
-		catch (JSONException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+        if (response.contains("Fel personr/organisationsnr och/eller lösenord.")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        if (response.contains(
+                "Internetbanken är stängd för tillfället och beräknas vara tillgänglig")) {
+            throw new LoginException(res.getText(R.string.bank_closed).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        String response = urlopen.open(
+                "https://inloggad.volvofinans.se/privat/kund/kortkonto/oversikt/kortkonton.html");
+        try {
+            JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
+            JSONArray data = object.getJSONArray("data");
+
+            int length = data.length();
+            for (int index = 0; index < length; index++) {
+                JSONObject account = data.getJSONObject(index);
+                Document d = Jsoup.parse(account.getString("namnUrl"));
+                Element e = d.getElementsByTag("a").first();
+                if (e != null && e.attr("href") != null) {
+                    mAccountUrlMappings.put(account.getString("kontonummer"),
+                            e.attr("href").replace("/info.html", "/info/kontoutdrag.html"));
+                }
+                accounts.add(new Account(String.format("%s (%s)", account.getString("namn"),
+                        account.getString("kontonummer")),
+                        Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(
+                                Helpers.parseBalance(account.getString("limit"))),
+                        account.getString("kontonummer")));
+            }
+        } catch (JSONException e) {
+            throw new BankException(e.getMessage(), e);
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-	}
-	
+    }
+
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
@@ -165,7 +188,7 @@ public class Volvofinans extends Bank {
                     } catch (ParseException e) {
                         e.printStackTrace();
                     }
-                    
+
                     transactions.add(new Transaction(date, acc.getString("text"), Helpers
                             .parseBalance(acc.getString("belopp")).negate()));
                 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
index 1501d0a..7243461 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
@@ -15,34 +15,38 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 
 public class Wallet extends SEBKortBase {
-	private static final String TAG = "wallet";
-	private static final String NAME = "wallet MasterCard";
-	private static final String NAME_SHORT = "wallet";
-	private static final int BANKTYPE_ID = Bank.WALLET;
-
-	public Wallet(Context context) {
-		super(context, "wase", "0121");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public Wallet(String username, String password, Context context) throws BankException,
+
+    private static final String TAG = "wallet";
+
+    private static final String NAME = "wallet MasterCard";
+
+    private static final String NAME_SHORT = "wallet";
+
+    private static final int BANKTYPE_ID = Bank.WALLET;
+
+    public Wallet(Context context) {
+        super(context, "wase", "0121");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public Wallet(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		super(username, password, context, "wase", "0121");
-	}
+        super(username, password, context, "wase", "0121");
+    }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 76d5f41..ff3b0ed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -16,133 +16,151 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Zidisha extends Bank {
-	private static final String TAG = "Zidisha";
-	private static final String NAME = "Zidisha";
-	private static final String NAME_SHORT = "zidisha";
-	private static final String URL = "https://www.zidisha.org/";
-	private static final int BANKTYPE_ID = IBankTypes.ZIDISHA;
+
+    private static final String TAG = "Zidisha";
+
+    private static final String NAME = "Zidisha";
+
+    private static final String NAME_SHORT = "zidisha";
+
+    private static final String URL = "https://www.zidisha.org/";
+
+    private static final int BANKTYPE_ID = IBankTypes.ZIDISHA;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+
     private static final String INPUT_HINT_USERNAME = "Username";
+
     private static final boolean STATIC_BALANCE = true;
 
-	private Pattern reUserGuess = Pattern.compile("<input.*?name=\"user_guess\" value=\"([0-9a-f]+)\"", Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("Funds uploaded:</td>.*?USD ([^<]+).*Credit Available:.*?USD ([^<]+).*Amount Lent By Me:.*?USD ([^<]+).*Total Impact:.*?USD ([^<]+)",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	String response;
-	
-	public Zidisha(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+    String response;
+
+    private Pattern reUserGuess = Pattern
+            .compile("<input.*?name=\"user_guess\" value=\"([0-9a-f]+)\"", Pattern.DOTALL);
+
+    private Pattern reAccounts = Pattern.compile(
+            "Funds uploaded:</td>.*?USD ([^<]+).*Credit Available:.*?USD ([^<]+).*Amount Lent By Me:.*?USD ([^<]+).*Total Impact:.*?USD ([^<]+)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    public Zidisha(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
         super.currency = "USD";
-	}
+    }
 
-	public Zidisha(String username, String password, Context context) throws BankException,
+    public Zidisha(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
+
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_zidisha));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_zidisha));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.zidisha.org/");
         Matcher mUserGuess = reUserGuess.matcher(response);
         if (!mUserGuess.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" user_guess.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " user_guess.");
         }
         String user_guess = mUserGuess.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
         postData.add(new BasicNameValuePair("textpassword", username));
         postData.add(new BasicNameValuePair("userlogin", ""));
-        postData.add(new BasicNameValuePair("user_guess",user_guess));
+        postData.add(new BasicNameValuePair("user_guess", user_guess));
         return new LoginPackage(urlopen, postData, response, "https://www.zidisha.org/process.php");
     }
-    
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		Matcher matcher;
-		response = urlopen.open("https://www.zidisha.org/index.php?p=19");
-		matcher = reAccounts.matcher(response);
-
-		while (matcher.find()) {
-			/*
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher;
+        response = urlopen.open("https://www.zidisha.org/index.php?p=19");
+        matcher = reAccounts.matcher(response);
+
+        while (matcher.find()) {
+                        /*
 			 * 1: Funds uploaded
 			 * 2: Available for withdrawal
 			 * 3: Lent by me
 			 * 4: Total Impact
 			 */
-			Account insattningar = new Account("Insättningar", Helpers.parseBalance(matcher.group(1)), "insattningar");
-			Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(2)), "tillgangligt");
-			Account utlanat      = new Account("Utlånat",      Helpers.parseBalance(matcher.group(3)), "utlanat");
-			Account balans       = new Account("Påverkan",     Helpers.parseBalance(matcher.group(4)), "impact");
-
-			insattningar.setCurrency("USD");
-			tillgangligt.setCurrency("USD");
-			utlanat.setCurrency("USD");
-			balans.setCurrency("USD");
-
-			accounts.add(insattningar);
-			accounts.add(tillgangligt);
-			accounts.add(utlanat);
-			accounts.add(balans);
-
-			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-		}
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	}
+            Account insattningar = new Account("Insättningar",
+                    Helpers.parseBalance(matcher.group(1)), "insattningar");
+            Account tillgangligt = new Account("Tillgängligt",
+                    Helpers.parseBalance(matcher.group(2)), "tillgangligt");
+            Account utlanat = new Account("Utlånat", Helpers.parseBalance(matcher.group(3)),
+                    "utlanat");
+            Account balans = new Account("Påverkan", Helpers.parseBalance(matcher.group(4)),
+                    "impact");
+
+            insattningar.setCurrency("USD");
+            tillgangligt.setCurrency("USD");
+            utlanat.setCurrency("USD");
+            balans.setCurrency("USD");
+
+            accounts.add(insattningar);
+            accounts.add(tillgangligt);
+            accounts.add(utlanat);
+            accounts.add(balans);
+
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 8cb1285..e1c537c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -16,14 +16,9 @@
 
 package com.liato.bankdroid.banking.banks.avanza;
 
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Base64;
-
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
@@ -33,15 +28,19 @@ import com.liato.bankdroid.banking.banks.avanza.model.PositionAggregation;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Base64;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -52,6 +51,7 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Avanza extends Bank {
+
     private static final String API_URL = "https://iphone.avanza.se/iphone-ws/";
 
     public Avanza(Context context) {
@@ -71,7 +71,8 @@ public class Avanza extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("Referer", URL + "/start");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("j_username", username));
@@ -83,7 +84,8 @@ public class Avanza extends Bank {
             JSONObject jsonResponse = new JSONObject(response);
             homeUrl = jsonResponse.getString("redirectUrl");
         } catch (JSONException e) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login link.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login link.");
         }
         LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl);
         lp.setIsLoggedIn(true);
@@ -91,28 +93,34 @@ public class Avanza extends Bank {
     }
 
     public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
-        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
+                new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
         balance = new BigDecimal(0);
 
         try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all", new ArrayList<NameValuePair>(), false);
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all",
+                    new ArrayList<NameValuePair>(), false);
             if (httpResponse.getStatusLine().getStatusCode() == 401) {
                 throw new LoginException(context.getText(
                         R.string.invalid_username_password).toString());
             }
             ObjectMapper vObjectMapper = new ObjectMapper();
-            AccountOverview r = vObjectMapper.readValue(httpResponse.getEntity().getContent(), AccountOverview.class);
+            AccountOverview r = vObjectMapper.readValue(httpResponse.getEntity().getContent(),
+                    AccountOverview.class);
             for (com.liato.bankdroid.banking.banks.avanza.model.Account account : r.getAccounts()) {
-                Account a = new Account(account.getAccountName(), new BigDecimal(account.getOwnCapital()), account.getAccountId());
+                Account a = new Account(account.getAccountName(),
+                        new BigDecimal(account.getOwnCapital()), account.getAccountId());
                 if (!account.getCurrencyAccounts().isEmpty()) {
                     a.setCurrency(account.getCurrencyAccounts().get(0).getCurrency());
                 }
                 if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
                     ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account.getCurrencyAccounts()) {
+                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account
+                            .getCurrencyAccounts()) {
                         transactions.add(new Transaction(Helpers.formatDate(now),
                                 "\u2014  " + currencyAccount.getCurrency() + "  \u2014",
                                 BigDecimal.valueOf(currencyAccount.getBalance()),
@@ -143,7 +151,8 @@ public class Avanza extends Bank {
                 // Add subtypes for account as own account.
                 if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
-                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account.getCurrencyAccounts()) {
+                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account
+                            .getCurrencyAccounts()) {
                         Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
                                 currencyAccount.getCurrency(),
                                 new BigDecimal(currencyAccount.getBalance()),
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
index 65116c4..68ecf0a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
@@ -7,45 +7,66 @@ import java.util.Collections;
 import java.util.List;
 
 public class Account implements Serializable {
+
     private static final long serialVersionUID = -5718585872348469144L;
+
     @JsonProperty("balance")
     private double mBalance;
+
     @JsonProperty("totalProfit")
     private double mTotalProfit;
+
     @JsonProperty("accountName")
     private String mAccountName;
+
     @JsonProperty("totalAccruedInterest")
     private double mTotalAccruedInterest;
+
     @JsonProperty("adjustedForwardAmount")
     private double mAdjustedForwardAmount;
+
     @JsonProperty("unUsedCredit")
     private double mUnUsedCredit;
+
     @JsonProperty("superInterest")
     private double mSuperInterest;
+
     @JsonProperty("totalMarginRequirement")
     private double mTotalMarginRequirement;
+
     @JsonProperty("tradingPower")
     private double mTradingPower;
+
     @JsonProperty("resAmount")
     private double mResAmount;
+
     @JsonProperty("loanAmount")
     private double mLoanAmount;
+
     @JsonProperty("accountId")
     private String mAccountId;
+
     @JsonProperty("currencyAccounts")
     private List<CurrencyAccount> mCurrencyAccounts = Collections.emptyList();
+
     @JsonProperty("creditLimit")
     private double mCreditLimit;
+
     @JsonProperty("totalProfitPercent")
     private double mTotalProfitPercent;
+
     @JsonProperty("ownCapital")
     private double mOwnCapital;
+
     @JsonProperty("totalValue")
     private double mTotalValue;
+
     @JsonProperty("interestAmount")
     private double mInterestAmount;
+
     @JsonProperty("secAmount")
     private double mSecAmount;
+
     @JsonProperty("positionAggregations")
     private List<PositionAggregation> mPositionAggregations = Collections.emptyList();
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
index 939ef2b..35a0be0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
@@ -7,9 +7,12 @@ import java.util.Collections;
 import java.util.List;
 
 public class AccountOverview implements Serializable {
+
     private static final long serialVersionUID = -5511775495529857976L;
+
     @JsonProperty("totalOwnCapital")
     private float mTotalOwnCapital;
+
     @JsonProperty("accounts")
     private List<Account> mAccounts = Collections.emptyList();
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
index 61f831f..76cf0b6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
@@ -5,11 +5,15 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.io.Serializable;
 
 public class CurrencyAccount implements Serializable {
+
     private static final long serialVersionUID = 6004713686055778196L;
+
     @JsonProperty("currency")
     private String mCurrency;
+
     @JsonProperty("balance")
     private double mBalance;
+
     @JsonProperty("accountId")
     private String mAccountId;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
index 86a9b1c..0182251 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
@@ -5,33 +5,48 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.io.Serializable;
 
 public class Position implements Serializable {
+
     private static final long serialVersionUID = 4138023852221811457L;
+
     @JsonProperty("instrumentName")
     private String mInstrumentName;
+
     @JsonProperty("averageAcquiredPrice")
     private double mAverageAcquiredPrice;
+
     @JsonProperty("marketValue")
     private double mMarketValue;
+
     @JsonProperty("price")
     private double mPrice;
+
     @JsonProperty("profit")
     private double mProfit;
+
     @JsonProperty("modified")
     private long mModified;
+
     @JsonProperty("expiryDate")
     private long mExpiryDate;
+
     @JsonProperty("volume")
     private int mVolume;
+
     @JsonProperty("tradable")
     private boolean mTradable;
+
     @JsonProperty("orderbookId")
     private long mOrderbookId;
+
     @JsonProperty("profitPercent")
     private double mProfitPercent;
+
     @JsonProperty("type")
     private int mType;
+
     @JsonProperty("instrumentType")
     private String mInstrumentType;
+
     @JsonProperty("change")
     private double mChange;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
index 5c6dab3..3571eca 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
@@ -7,21 +7,30 @@ import java.util.Collections;
 import java.util.List;
 
 public class PositionAggregation implements Serializable {
+
     private static final long serialVersionUID = 5531947007427482418L;
+
     @JsonProperty("totalChange")
     private double mTotalChange;
+
     @JsonProperty("positions")
     private List<Position> mPositions = Collections.emptyList();
+
     @JsonProperty("totalProfit")
     private double mTotalProfit;
+
     @JsonProperty("instrumentTypeName")
     private String mInstrumentTypeName;
+
     @JsonProperty("totalProfitPercent")
     private double mTotalProfitPercent;
+
     @JsonProperty("totalValue")
     private double mTotalValue;
+
     @JsonProperty("instrumentType")
     private int mInstrumentType;
+
     @JsonProperty("totalAverage")
     private double mTotalAverage;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 7ad30c5..f78cfbe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -16,103 +16,112 @@
 
 package com.liato.bankdroid.banking.banks.bitcoin;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.content.Context;
-import android.text.TextUtils;
-
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.bitcoin.model.BlockchainResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+import android.text.TextUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bitcoin extends Bank {
-	private static final String TAG = "Bitcoin";
-	private static final String NAME = "Bitcoin";
-	private static final String NAME_SHORT = "bitcoin";
-	private static final String URL = "http://blockchain.info";
-	private static final int BANKTYPE_ID = IBankTypes.BITCOIN;
-	private static final boolean STATIC_BALANCE = false;
-	private static final boolean INPUT_HIDDEN_PASSWORD = true;
-	private static final int INPUT_TITLETEXT_USERNAME = R.string.bitcoin_address;	
-	
-	private static final String API_URL = "http://blockchain.info/rawaddr/";
-	private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0.00000000 ");
-
-	public Bitcoin(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-		super.currency = "BTC";
-		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
-		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
-	}
-
-	public Bitcoin(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
-
-	public Urllib login() throws LoginException, BankException, IOException {
-		urlopen = new Urllib(context);
-
-		try {
-			String response = urlopen.open(API_URL + username);
-			if(response == null || "".equals(response)) {
-				throw new LoginException(res.getText(
-						R.string.invalid_username_password).toString());
-			}
-			ObjectMapper vObjectMapper = new ObjectMapper();
+
+    private static final String TAG = "Bitcoin";
+
+    private static final String NAME = "Bitcoin";
+
+    private static final String NAME_SHORT = "bitcoin";
+
+    private static final String URL = "http://blockchain.info";
+
+    private static final int BANKTYPE_ID = IBankTypes.BITCOIN;
+
+    private static final boolean STATIC_BALANCE = false;
+
+    private static final boolean INPUT_HIDDEN_PASSWORD = true;
+
+    private static final int INPUT_TITLETEXT_USERNAME = R.string.bitcoin_address;
+
+    private static final String API_URL = "http://blockchain.info/rawaddr/";
+
+    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0.00000000 ");
+
+    public Bitcoin(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.currency = "BTC";
+        super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
+        super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+    }
+
+    public Bitcoin(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
+        this(context);
+        this.update(username, password);
+    }
+
+    public Urllib login() throws LoginException, BankException, IOException {
+        urlopen = new Urllib(context);
+
+        try {
+            String response = urlopen.open(API_URL + username);
+            if (response == null || "".equals(response)) {
+                throw new LoginException(res.getText(
+                        R.string.invalid_username_password).toString());
+            }
+            ObjectMapper vObjectMapper = new ObjectMapper();
             vObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
             vObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
-			BlockchainResponse r = vObjectMapper.readValue(urlopen.open(API_URL + username), BlockchainResponse.class);
-			Account a = new Account("Bitcoin", new BigDecimal(r.getFinalBalance()).divide(BigDecimal.valueOf(100000000)), "1");
-			a.setCurrency("BTC");
-			accounts.add(a);
-			setCurrency("BTC");
-		} catch (JsonParseException e) {
-			throw new BankException(res.getText(
-					R.string.invalid_bitcoin_address).toString());
-		}
-
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException,
-			BankChoiceException, IOException {
-		super.update();
-		if (TextUtils.isEmpty(username)) {
-			throw new LoginException(res.getText(
-					R.string.invalid_bitcoin_address).toString());
-		}
-		login();
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-		super.updateComplete();
-	}
-
-	@Override
-	public DecimalFormat getDecimalFormatter() {
-		return DECIMAL_FORMAT;
-	}
+            BlockchainResponse r = vObjectMapper.readValue(
+                    urlopen.open(API_URL + username), BlockchainResponse.class);
+            Account a = new Account("Bitcoin",
+                    new BigDecimal(r.getFinalBalance()).divide(BigDecimal.valueOf(100000000)), "1");
+            a.setCurrency("BTC");
+            accounts.add(a);
+            setCurrency("BTC");
+        } catch (JsonParseException e) {
+            throw new BankException(res.getText(
+                    R.string.invalid_bitcoin_address).toString());
+        }
+
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException,
+            BankChoiceException, IOException {
+        super.update();
+        if (TextUtils.isEmpty(username)) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_bitcoin_address).toString());
+        }
+        login();
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public DecimalFormat getDecimalFormatter() {
+        return DECIMAL_FORMAT;
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
index 6f51161..17dbff1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
@@ -1,61 +1,69 @@
 package com.liato.bankdroid.banking.banks.bitcoin.model;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.List;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-
 public class BlockchainResponse implements Serializable {
-	private static final long serialVersionUID = -5144109898538621019L;
-	@JsonProperty("total_sent")
-	private long mTotalSent;
-	@JsonProperty("total_received")
-	private long mTotalReceived;
-	@JsonProperty("final_balance")
-	private long mFinalBalance;
-	@JsonProperty("address")
-	private String mAddress;
-	@JsonProperty("hash160")
-	private String mHash160;
-	@JsonProperty("txs")
-	private List<Transfer> mTxs = Collections.emptyList();
-	@JsonProperty("n_tx")
-	private long mNTx;
-
-	@JsonProperty("total_sent")
-	public long getTotalSent() {
-		return mTotalSent;
-	}
-
-	@JsonProperty("total_received")
-	public long getTotalReceived() {
-		return mTotalReceived;
-	}
-
-	@JsonProperty("final_balance")
-	public long getFinalBalance() {
-		return mFinalBalance;
-	}
-
-	@JsonProperty("address")
-	public String getAddress() {
-		return mAddress;
-	}
-
-	@JsonProperty("hash160")
-	public String getHash160() {
-		return mHash160;
-	}
-
-	@JsonProperty("txs")
-	public List<Transfer> getTxs() {
-		return mTxs;
-	}
-
-	@JsonProperty("n_tx")
-	public long getNTx() {
-		return mNTx;
-	}
+
+    private static final long serialVersionUID = -5144109898538621019L;
+
+    @JsonProperty("total_sent")
+    private long mTotalSent;
+
+    @JsonProperty("total_received")
+    private long mTotalReceived;
+
+    @JsonProperty("final_balance")
+    private long mFinalBalance;
+
+    @JsonProperty("address")
+    private String mAddress;
+
+    @JsonProperty("hash160")
+    private String mHash160;
+
+    @JsonProperty("txs")
+    private List<Transfer> mTxs = Collections.emptyList();
+
+    @JsonProperty("n_tx")
+    private long mNTx;
+
+    @JsonProperty("total_sent")
+    public long getTotalSent() {
+        return mTotalSent;
+    }
+
+    @JsonProperty("total_received")
+    public long getTotalReceived() {
+        return mTotalReceived;
+    }
+
+    @JsonProperty("final_balance")
+    public long getFinalBalance() {
+        return mFinalBalance;
+    }
+
+    @JsonProperty("address")
+    public String getAddress() {
+        return mAddress;
+    }
+
+    @JsonProperty("hash160")
+    public String getHash160() {
+        return mHash160;
+    }
+
+    @JsonProperty("txs")
+    public List<Transfer> getTxs() {
+        return mTxs;
+    }
+
+    @JsonProperty("n_tx")
+    public long getNTx() {
+        return mNTx;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
index f202150..6243510 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
@@ -1,17 +1,19 @@
 package com.liato.bankdroid.banking.banks.bitcoin.model;
 
-import java.io.Serializable;
-
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.io.Serializable;
+
 public class Input implements Serializable {
-	private static final long serialVersionUID = 7507419745749485877L;
-	@JsonProperty("prev_out")
-	private PrevOut mPrevOut;
 
-	@JsonProperty("prev_out")
-	public PrevOut getPrevOut() {
-		return mPrevOut;
-	}
+    private static final long serialVersionUID = 7507419745749485877L;
+
+    @JsonProperty("prev_out")
+    private PrevOut mPrevOut;
+
+    @JsonProperty("prev_out")
+    public PrevOut getPrevOut() {
+        return mPrevOut;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
index 99142bc..80ee150 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
@@ -1,45 +1,51 @@
 package com.liato.bankdroid.banking.banks.bitcoin.model;
 
-import java.io.Serializable;
-
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.io.Serializable;
+
 public class Out implements Serializable {
-	private static final long serialVersionUID = 3773393008409837454L;
-	@JsonProperty("tx_index")
-	private long mTxIndex;
-	@JsonProperty("type")
-	private int mType;
-	@JsonProperty("addr")
-	private String mAddr;
-	@JsonProperty("value")
-	private long mValue;
-	@JsonProperty("n")
-	private long mN;
-
-	@JsonProperty("tx_index")
-	public long getTxIndex() {
-		return mTxIndex;
-	}
-
-	@JsonProperty("type")
-	public int getType() {
-		return mType;
-	}
-
-	@JsonProperty("addr")
-	public String getAddr() {
-		return mAddr;
-	}
-
-	@JsonProperty("value")
-	public long getValue() {
-		return mValue;
-	}
-
-	@JsonProperty("n")
-	public long getN() {
-		return mN;
-	}
+
+    private static final long serialVersionUID = 3773393008409837454L;
+
+    @JsonProperty("tx_index")
+    private long mTxIndex;
+
+    @JsonProperty("type")
+    private int mType;
+
+    @JsonProperty("addr")
+    private String mAddr;
+
+    @JsonProperty("value")
+    private long mValue;
+
+    @JsonProperty("n")
+    private long mN;
+
+    @JsonProperty("tx_index")
+    public long getTxIndex() {
+        return mTxIndex;
+    }
+
+    @JsonProperty("type")
+    public int getType() {
+        return mType;
+    }
+
+    @JsonProperty("addr")
+    public String getAddr() {
+        return mAddr;
+    }
+
+    @JsonProperty("value")
+    public long getValue() {
+        return mValue;
+    }
+
+    @JsonProperty("n")
+    public long getN() {
+        return mN;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
index c065b0c..5dafe89 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
@@ -1,45 +1,51 @@
 package com.liato.bankdroid.banking.banks.bitcoin.model;
 
-import java.io.Serializable;
-
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.io.Serializable;
+
 public class PrevOut implements Serializable {
-	private static final long serialVersionUID = 9102767809232718841L;
-	@JsonProperty("tx_index")
-	private long mTxIndex;
-	@JsonProperty("type")
-	private int mType;
-	@JsonProperty("addr")
-	private String mAddr;
-	@JsonProperty("value")
-	private long mValue;
-	@JsonProperty("n")
-	private long mN;
-
-	@JsonProperty("tx_index")
-	public long getTxIndex() {
-		return mTxIndex;
-	}
-
-	@JsonProperty("type")
-	public int getType() {
-		return mType;
-	}
-
-	@JsonProperty("addr")
-	public String getAddr() {
-		return mAddr;
-	}
-
-	@JsonProperty("value")
-	public long getValue() {
-		return mValue;
-	}
-
-	@JsonProperty("n")
-	public long getN() {
-		return mN;
-	}
+
+    private static final long serialVersionUID = 9102767809232718841L;
+
+    @JsonProperty("tx_index")
+    private long mTxIndex;
+
+    @JsonProperty("type")
+    private int mType;
+
+    @JsonProperty("addr")
+    private String mAddr;
+
+    @JsonProperty("value")
+    private long mValue;
+
+    @JsonProperty("n")
+    private long mN;
+
+    @JsonProperty("tx_index")
+    public long getTxIndex() {
+        return mTxIndex;
+    }
+
+    @JsonProperty("type")
+    public int getType() {
+        return mType;
+    }
+
+    @JsonProperty("addr")
+    public String getAddr() {
+        return mAddr;
+    }
+
+    @JsonProperty("value")
+    public long getValue() {
+        return mValue;
+    }
+
+    @JsonProperty("n")
+    public long getN() {
+        return mN;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
index 19bdc54..ec951a9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
@@ -1,100 +1,114 @@
 package com.liato.bankdroid.banking.banks.bitcoin.model;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.List;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
-
 public class Transfer implements Serializable {
-	private static final long serialVersionUID = -2558362412750999606L;
-	@JsonProperty("size")
-	private long mSize;
-	@JsonProperty("inputs")
-	private List<Input> mInputs = Collections.emptyList();
-	@JsonProperty("hash")
-	private String mHash;
-	@JsonProperty("tx_index")
-	private long mTxIndex;
-	@JsonProperty("relayed_by")
-	private String mRelayedBy;
-	@JsonProperty("block_height")
-	private long mBlockHeight;
-	@JsonProperty("vin_sz")
-	private long mVinSz;
-	@JsonProperty("vout_sz")
-	private long mVoutSz;
-	@JsonProperty("time")
-	private long mTime;
-	@JsonProperty("ver")
-	private long mVer;
-	@JsonProperty("out")
-	private List<Out> mOut = Collections.emptyList();
-	@JsonProperty("result")
-	private long mResult;
+
+    private static final long serialVersionUID = -2558362412750999606L;
+
+    @JsonProperty("size")
+    private long mSize;
+
+    @JsonProperty("inputs")
+    private List<Input> mInputs = Collections.emptyList();
+
+    @JsonProperty("hash")
+    private String mHash;
+
+    @JsonProperty("tx_index")
+    private long mTxIndex;
+
+    @JsonProperty("relayed_by")
+    private String mRelayedBy;
+
+    @JsonProperty("block_height")
+    private long mBlockHeight;
+
+    @JsonProperty("vin_sz")
+    private long mVinSz;
+
+    @JsonProperty("vout_sz")
+    private long mVoutSz;
+
+    @JsonProperty("time")
+    private long mTime;
+
+    @JsonProperty("ver")
+    private long mVer;
+
+    @JsonProperty("out")
+    private List<Out> mOut = Collections.emptyList();
+
+    @JsonProperty("result")
+    private long mResult;
+
     @JsonProperty("note")
     private String mNote;
 
 
-	@JsonProperty("size")
-	public long getSize() {
-		return mSize;
-	}
-
-	@JsonProperty("inputs")
-	public List<Input> getInputs() {
-		return mInputs;
-	}
-
-	@JsonProperty("hash")
-	public String getHash() {
-		return mHash;
-	}
-
-	@JsonProperty("tx_index")
-	public long getTxIndex() {
-		return mTxIndex;
-	}
-
-	@JsonProperty("relayed_by")
-	public String getRelayedBy() {
-		return mRelayedBy;
-	}
-
-	@JsonProperty("block_height")
-	public long getBlockHeight() {
-		return mBlockHeight;
-	}
-
-	@JsonProperty("vin_sz")
-	public long getVinSz() {
-		return mVinSz;
-	}
-
-	@JsonProperty("vout_sz")
-	public long getVoutSz() {
-		return mVoutSz;
-	}
-
-	@JsonProperty("time")
-	public long getTime() {
-		return mTime;
-	}
-
-	@JsonProperty("ver")
-	public long getVer() {
-		return mVer;
-	}
-
-	@JsonProperty("out")
-	public List<Out> getOut() {
-		return mOut;
-	}
-
-	@JsonProperty("result")
-	public long getResult() {
-		return mResult;
-	}
+    @JsonProperty("size")
+    public long getSize() {
+        return mSize;
+    }
+
+    @JsonProperty("inputs")
+    public List<Input> getInputs() {
+        return mInputs;
+    }
+
+    @JsonProperty("hash")
+    public String getHash() {
+        return mHash;
+    }
+
+    @JsonProperty("tx_index")
+    public long getTxIndex() {
+        return mTxIndex;
+    }
+
+    @JsonProperty("relayed_by")
+    public String getRelayedBy() {
+        return mRelayedBy;
+    }
+
+    @JsonProperty("block_height")
+    public long getBlockHeight() {
+        return mBlockHeight;
+    }
+
+    @JsonProperty("vin_sz")
+    public long getVinSz() {
+        return mVinSz;
+    }
+
+    @JsonProperty("vout_sz")
+    public long getVoutSz() {
+        return mVoutSz;
+    }
+
+    @JsonProperty("time")
+    public long getTime() {
+        return mTime;
+    }
+
+    @JsonProperty("ver")
+    public long getVer() {
+        return mVer;
+    }
+
+    @JsonProperty("out")
+    public List<Out> getOut() {
+        return mOut;
+    }
+
+    @JsonProperty("result")
+    public long getResult() {
+        return mResult;
+    }
 
     @JsonProperty("note")
     public String getNote() {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index d7a2578..b9fab52 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -16,13 +16,9 @@
 
 package com.liato.bankdroid.banking.banks.coop;
 
-import android.content.Context;
-import android.text.TextUtils;
-
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
@@ -31,6 +27,7 @@ import com.liato.bankdroid.banking.banks.coop.model.web.WebTransactionHistoryRes
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpResponse;
@@ -40,6 +37,9 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
+import android.content.Context;
+import android.text.TextUtils;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
@@ -54,81 +54,35 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Coop extends Bank {
+
     private static final String TAG = "Coop";
+
     private static final String NAME = "Coop";
+
     private static final String NAME_SHORT = "coop";
+
     private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
+
     private static final int BANKTYPE_ID = IBankTypes.COOP;
+
     private static final Map<String, String> MONTHS = new HashMap<>();
+
     static {
-        String[] ms = new String[] {"januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"};
+        String[] ms = new String[]{"januari", "februari", "mars", "april", "maj", "juni", "juli",
+                "augusti", "september", "oktober", "november", "december"};
         for (int i = 0; i < ms.length; i++) {
-            MONTHS.put(ms[i], String.format("%02d", i+1));
+            MONTHS.put(ms[i], String.format("%02d", i + 1));
         }
     }
 
-    enum AccountType {
-        MEDMERA_KONTO("konto_", "https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/"),
-        MEDMERA_EFTER("efter_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter/"),
-        MEDMERA_EFTER1("efter1_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter1/"),
-        MEDMERA_FORE("fore_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Fore/"),
-        MEDMERA_MER("mer_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Mer/"),
-        MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
-
-        final String prefix;
-        final String url;
-        private AccountType(String prefix, String url) {
-            this.prefix = prefix;
-            this.url = url;
-        }
+    private final Pattern rePageGuid = Pattern
+            .compile("pageGuid\"\\s*:\\s*\"([^\"]+)", Pattern.CASE_INSENSITIVE);
 
-        public String getPrefix() {
-            return prefix;
-        }
-
-        public String getUrl() {
-            return url;
-        }
-    }
-
-    class TransactionParams {
-        String pageGuid;
-        String minDate;
-        String maxDate;
-
-        public String getPageGuid() {
-            return pageGuid;
-        }
-
-        public void setPageGuid(String pageGuid) {
-            this.pageGuid = pageGuid;
-        }
-
-        public String getMinDate() {
-            return minDate;
-        }
-
-        public void setMinDate(String minDate) {
-            this.minDate = minDate;
-        }
-
-        public String getMaxDate() {
-            return maxDate;
-        }
-
-        public void setMaxDate(String maxDate) {
-            this.maxDate = maxDate;
-        }
-
-        public boolean isValid() {
-            return pageGuid != null && minDate != null && maxDate != null;
-        }
-    }
+    private final Map<AccountType, TransactionParams> mTransactionParams = new HashMap<>();
 
-    private final Pattern rePageGuid = Pattern.compile("pageGuid\"\\s*:\\s*\"([^\"]+)", Pattern.CASE_INSENSITIVE);
     private ObjectMapper mObjectMapper;
+
     private String response;
-    private final Map<AccountType, TransactionParams> mTransactionParams = new HashMap<>();
 
     public Coop(Context context) {
         super(context);
@@ -151,18 +105,20 @@ public class Coop extends Bank {
             IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
         urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
-        HttpResponse httpResponse = urlopen.openAsHttpResponse("https://www.coop.se/Personliga-Baren/Logga-in/?method=Login",
-                new StringEntity("{\"isBar\":\"true\",\"username\":\"" + username + "\",\"password\":\"" + password + "\"}"),
-                true);
+        HttpResponse httpResponse = urlopen
+                .openAsHttpResponse("https://www.coop.se/Personliga-Baren/Logga-in/?method=Login",
+                        new StringEntity("{\"isBar\":\"true\",\"username\":\"" + username
+                                + "\",\"password\":\"" + password + "\"}"),
+                        true);
         urlopen.removeHeader("X-Requested-With");
-        LoginPackage lp = new LoginPackage(urlopen, null, response, "https://www.coop.se/Mina-sidor/Oversikt/");
+        LoginPackage lp = new LoginPackage(urlopen, null, response,
+                "https://www.coop.se/Mina-sidor/Oversikt/");
         if (httpResponse.getStatusLine().getStatusCode() == 200) {
             lp.setIsLoggedIn(true);
         }
         return lp;
     }
 
-
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
@@ -175,7 +131,8 @@ public class Coop extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -200,9 +157,13 @@ public class Coop extends Bank {
                     transactions.add(new Transaction(
                             formatDate(e.select(".Timeline-header .u-nbfcAlt span").text()),
                             e.select(".u-block").text(),
-                            Helpers.parseBalance(e.select(".Timeline-header .Timeline-title").first().ownText()), ""));
+                            Helpers.parseBalance(
+                                    e.select(".Timeline-header .Timeline-title").first().ownText()),
+                            ""));
                 }
-            } finally { continue; }
+            } finally {
+                continue;
+            }
         }
         accounts.add(poang);
         for (AccountType at : AccountType.values()) {
@@ -234,7 +195,8 @@ public class Coop extends Bank {
                     values.add(e.text().trim());
                 }
                 for (int i = 0; i < Math.min(names.size(), values.size()); i++) {
-                    Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)), String.format("%s%d", at.getPrefix(), i));
+                    Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)),
+                            String.format("%s%d", at.getPrefix(), i));
                     a.setCurrency(Helpers.parseCurrency(values.get(i), "SEK"));
                     if (a.getName().toLowerCase().contains("disponibelt")) {
                         a.setType(Account.REGULAR);
@@ -252,9 +214,9 @@ public class Coop extends Bank {
             }
         }
 
-
         try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
+            response = urlopen
+                    .open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
             dResponse = Jsoup.parse(response);
             Account a = new Account("Återbäring",
                     Helpers.parseBalance(dResponse.select(".Heading--coopNew").text()),
@@ -280,24 +242,34 @@ public class Coop extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException {
         AccountType at = getAccuntType(account.getId());
         TransactionParams tp = mTransactionParams.get(at);
-        if (at == null || tp == null || !tp.isValid() || !isFirstAccountForType(account.getId())) return;
+        if (at == null || tp == null || !tp.isValid() || !isFirstAccountForType(account.getId())) {
+            return;
+        }
         try {
-            String data = URLEncoder.encode(String.format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}", tp.getMinDate(), tp.getMaxDate()), "utf-8");
-            String url = String.format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s", tp.getPageGuid(), data, System.currentTimeMillis());
-            WebTransactionHistoryResponse transactionsResponse = getObjectmapper().readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
+            String data = URLEncoder.encode(String
+                    .format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}",
+                            tp.getMinDate(), tp.getMaxDate()), "utf-8");
+            String url = String
+                    .format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s",
+                            tp.getPageGuid(), data, System.currentTimeMillis());
+            WebTransactionHistoryResponse transactionsResponse = getObjectmapper()
+                    .readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
             if (transactionsResponse != null && transactionsResponse.getModel() != null) {
                 List<Transaction> transactions = new ArrayList<>();
                 account.setTransactions(transactions);
                 for (Result r : transactionsResponse.getModel().getResults()) {
-                    StringBuilder title = new StringBuilder(!TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
+                    StringBuilder title = new StringBuilder(
+                            !TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
                     if (!TextUtils.isEmpty(r.getCardholder())) {
                         title.append(" (").append(r.getCardholder()).append(")");
                     }
                     if (r.getDate() != null) {
-                        transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
+                        transactions.add(new Transaction(formatDate(r.getDate()), title.toString(),
+                                BigDecimal.valueOf(r.getSum())));
                     }
                 }
             }
@@ -308,9 +280,12 @@ public class Coop extends Bank {
 
     private String formatDate(String date) {
         String[] parts = date.split(" ");
-        if( parts.length < 3)
+        if (parts.length < 3) {
             return "";
-        return String.format("%s-%s-%02d", parts[2], MONTHS.containsKey(parts[1].toLowerCase()) ? MONTHS.get(parts[1].toLowerCase()) : "01", Integer.parseInt(parts[0]));
+        }
+        return String.format("%s-%s-%02d", parts[2],
+                MONTHS.containsKey(parts[1].toLowerCase()) ? MONTHS.get(parts[1].toLowerCase())
+                        : "01", Integer.parseInt(parts[0]));
     }
 
     private boolean isFirstAccountForType(String accountId) {
@@ -330,4 +305,69 @@ public class Coop extends Bank {
         }
         return null;
     }
+
+    enum AccountType {
+        MEDMERA_KONTO("konto_", "https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/"),
+        MEDMERA_EFTER("efter_",
+                "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter/"),
+        MEDMERA_EFTER1("efter1_",
+                "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter1/"),
+        MEDMERA_FORE("fore_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Fore/"),
+        MEDMERA_MER("mer_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Mer/"),
+        MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
+
+        final String prefix;
+
+        final String url;
+
+        private AccountType(String prefix, String url) {
+            this.prefix = prefix;
+            this.url = url;
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+    }
+
+    class TransactionParams {
+
+        String pageGuid;
+
+        String minDate;
+
+        String maxDate;
+
+        public String getPageGuid() {
+            return pageGuid;
+        }
+
+        public void setPageGuid(String pageGuid) {
+            this.pageGuid = pageGuid;
+        }
+
+        public String getMinDate() {
+            return minDate;
+        }
+
+        public void setMinDate(String minDate) {
+            this.minDate = minDate;
+        }
+
+        public String getMaxDate() {
+            return maxDate;
+        }
+
+        public void setMaxDate(String maxDate) {
+            this.maxDate = maxDate;
+        }
+
+        public boolean isValid() {
+            return pageGuid != null && minDate != null && maxDate != null;
+        }
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
index 577476c..b12a7f1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
@@ -1,4 +1,3 @@
-
 package com.liato.bankdroid.banking.banks.coop.model.web;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -9,6 +8,7 @@ public class D {
 
     @JsonProperty("template")
     private String template;
+
     @JsonProperty("model")
     private Model model;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
index 17232ad..275e6a4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
@@ -1,4 +1,3 @@
-
 package com.liato.bankdroid.banking.banks.coop.model.web;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -12,16 +11,22 @@ public class Model {
 
     @JsonProperty("results")
     private List<Result> results = new ArrayList<Result>();
+
     @JsonProperty("from")
     private String from;
+
     @JsonProperty("to")
     private String to;
+
     @JsonProperty("id")
     private String id;
+
     @JsonProperty("page")
     private int page;
+
     @JsonProperty("pageCount")
     private int pageCount;
+
     @JsonProperty("pageSize")
     private int pageSize;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
index 9b5dc62..7ef1c7b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
@@ -1,4 +1,3 @@
-
 package com.liato.bankdroid.banking.banks.coop.model.web;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@@ -9,24 +8,34 @@ public class Result {
 
     @JsonProperty("date")
     private String date;
+
     @JsonProperty("icon")
     private boolean icon;
+
     @JsonProperty("title")
     private String title;
+
     @JsonProperty("cardholder")
     private String cardholder;
+
     @JsonProperty("location")
     private String location;
+
     @JsonProperty("sum")
     private double sum;
+
     @JsonProperty("charity")
     private boolean charity;
+
     @JsonProperty("hasdetails")
     private boolean hasdetails;
+
     @JsonProperty("detailsurl")
     private String detailsurl;
+
     @JsonProperty("batchnumber")
     private int batchnumber;
+
     @JsonProperty("sequencenumber")
     private int sequencenumber;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
index ef44524..7c55300 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
@@ -1,4 +1,3 @@
-
 package com.liato.bankdroid.banking.banks.coop.model.web;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index 553e6e1..372e6c2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -16,14 +16,8 @@
 
 package com.liato.bankdroid.banking.banks.ica;
 
-import android.content.Context;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.Base64;
-
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
@@ -32,12 +26,17 @@ import com.liato.bankdroid.banking.banks.ica.model.Overview;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
+
+import android.content.Context;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Base64;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -51,11 +50,17 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICA extends Bank {
+
     private static final String API_URL = "https://api.ica.se/api/";
+
     private static final String AUTHENTICATION_TICKET_HEADER = "AuthenticationTicket";
+
     private static final String SESSION_TICKET_HEADER = "SessionTicket";
+
     private static final String LOGOUT_KEY_HEADER = "LogoutKey";
+
     private ObjectMapper mObjectMapper = new ObjectMapper();
+
     private Map<String, String> mHeaders = new HashMap<String, String>();
 
     public ICA(Context context) {
@@ -83,16 +88,18 @@ public class ICA extends Bank {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ica));
         urlopen.addHeader("Accept", "application/json;charset=UTF-8");
         urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
-        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(
+                new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
 
         try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login", new ArrayList<NameValuePair>(), false);
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login",
+                    new ArrayList<NameValuePair>(), false);
             if (httpResponse.getStatusLine().getStatusCode() == 401) {
                 LoginError le = readJsonValue(httpResponse, LoginError.class);
                 if (le != null && "UsernamePassword".equals(le.getMessageCode())) {
                     if (!TextUtils.isEmpty(le.getMessage())) {
                         throw new LoginException(le.getMessage());
-                    } else  {
+                    } else {
                         throw new LoginException(context.getText(
                                 R.string.invalid_username_password).toString());
                     }
@@ -111,8 +118,10 @@ public class ICA extends Bank {
                 mHeaders.put(entry.getKey(), header.getValue());
             }
 
-            urlopen.addHeader(AUTHENTICATION_TICKET_HEADER, mHeaders.get(AUTHENTICATION_TICKET_HEADER));
-            httpResponse = urlopen.openAsHttpResponse(API_URL + "user/minasidor", new ArrayList<NameValuePair>(), false);
+            urlopen.addHeader(AUTHENTICATION_TICKET_HEADER,
+                    mHeaders.get(AUTHENTICATION_TICKET_HEADER));
+            httpResponse = urlopen.openAsHttpResponse(API_URL + "user/minasidor",
+                    new ArrayList<NameValuePair>(), false);
             Overview overview = readJsonValue(httpResponse, Overview.class);
 
             if (overview == null) {
@@ -120,30 +129,39 @@ public class ICA extends Bank {
             }
 
             if (!TextUtils.isEmpty(overview.getAccountName())) {
-                Account account = new Account(overview.getAccountName(), BigDecimal.valueOf(overview.getAvailableAmount()), overview.getAccountNumber());
+                Account account = new Account(overview.getAccountName(),
+                        BigDecimal.valueOf(overview.getAvailableAmount()),
+                        overview.getAccountNumber());
                 balance = balance.add(account.getBalance());
                 accounts.add(account);
                 List<Transaction> transactions = new ArrayList<Transaction>();
-                for (com.liato.bankdroid.banking.banks.ica.model.Transaction t : overview.getTransactions()) {
-                    transactions.add(new Transaction(t.getTransactionDate(), t.getDescription(), BigDecimal.valueOf(t.getAmount())));
+                for (com.liato.bankdroid.banking.banks.ica.model.Transaction t : overview
+                        .getTransactions()) {
+                    transactions.add(new Transaction(t.getTransactionDate(), t.getDescription(),
+                            BigDecimal.valueOf(t.getAmount())));
                 }
                 account.setTransactions(transactions);
             }
             for (com.liato.bankdroid.banking.banks.ica.model.Account a : overview.getAccounts()) {
-                Account account = new Account(a.getName(), BigDecimal.valueOf(a.getAvailableAmount()), a.getAccountNumber());
+                Account account = new Account(a.getName(),
+                        BigDecimal.valueOf(a.getAvailableAmount()), a.getAccountNumber());
                 balance = balance.add(account.getBalance());
                 accounts.add(account);
                 List<Transaction> transactions = new ArrayList<Transaction>();
-                for (com.liato.bankdroid.banking.banks.ica.model.Transaction t : a.getTransactions()) {
-                    transactions.add(new Transaction(t.getTransactionDate(), t.getDescription(), BigDecimal.valueOf(t.getAmount())));
+                for (com.liato.bankdroid.banking.banks.ica.model.Transaction t : a
+                        .getTransactions()) {
+                    transactions.add(new Transaction(t.getTransactionDate(), t.getDescription(),
+                            BigDecimal.valueOf(t.getAmount())));
                 }
                 account.setTransactions(transactions);
             }
 
-            Account account  = new Account("Erhållen bonus i år", BigDecimal.valueOf(overview.getAcquiredBonus()), "bonus");
+            Account account = new Account("Erhållen bonus i år",
+                    BigDecimal.valueOf(overview.getAcquiredBonus()), "bonus");
             account.setType(Account.OTHER);
             accounts.add(account);
-            account  = new Account("Årets totala inköp på ICA", BigDecimal.valueOf(overview.getYearlyTotalPurchased()), "totalpurchased");
+            account = new Account("Årets totala inköp på ICA",
+                    BigDecimal.valueOf(overview.getYearlyTotalPurchased()), "totalpurchased");
             account.setType(Account.OTHER);
             accounts.add(account);
 
@@ -152,7 +170,8 @@ public class ICA extends Bank {
             }
 
             urlopen.addHeader(LOGOUT_KEY_HEADER, mHeaders.get(LOGOUT_KEY_HEADER));
-            httpResponse = urlopen.openAsHttpResponse(API_URL + "logout", new ArrayList<NameValuePair>(), false);
+            httpResponse = urlopen.openAsHttpResponse(API_URL + "logout",
+                    new ArrayList<NameValuePair>(), false);
             httpResponse.getStatusLine();
         } catch (JsonParseException e) {
             throw new BankException(e.getMessage(), e);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
index 67b85ef..5c943a3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
@@ -13,18 +13,25 @@ public class Account {
 
     @JsonProperty("Name")
     private String name;
+
     @JsonProperty("AccountNumber")
     private String accountNumber;
+
     @JsonProperty("AvailableAmount")
     private double availableAmount;
+
     @JsonProperty("ReservedAmount")
     private double reservedAmount;
+
     @JsonProperty("Saldo")
     private double saldo;
+
     @JsonProperty("CreditLimit")
     private double creditLimit;
+
     @JsonProperty("Transactions")
     private List<Transaction> transactions = new ArrayList<Transaction>();
+
     private Map<String, Object> additionalProperties = new HashMap<String, Object>();
 
     @JsonProperty("Name")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
index 972316a..8dd7007 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
@@ -8,10 +8,13 @@ public class LoginError {
 
     @JsonProperty("Title")
     private String title;
+
     @JsonProperty("MessageCode")
     private String messageCode;
+
     @JsonProperty("PhoneNumber")
     private String phoneNumber;
+
     @JsonProperty("Message")
     private String message;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
index 29d6b1a..8f10d8e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
@@ -11,34 +11,49 @@ public class Overview {
 
     @JsonProperty("Saldo")
     private double saldo;
+
     @JsonProperty("YearlyTotalPurchased")
     private double yearlyTotalPurchased;
+
     @JsonProperty("PurchaseToDate")
     private String purchaseToDate;
+
     @JsonProperty("AcquiredDiscount")
     private double acquiredDiscount;
+
     @JsonProperty("AmountSinceLastBonusCheck")
     private double amountSinceLastBonusCheck;
+
     @JsonProperty("AmountLeftUntilNextBonusCheck")
     private double amountLeftUntilNextBonusCheck;
+
     @JsonProperty("NextBonusCheckValue")
     private double nextBonusCheckValue;
+
     @JsonProperty("AcquiredBonus")
     private double acquiredBonus;
+
     @JsonProperty("BonusToDate")
     private String bonusToDate;
+
     @JsonProperty("IcaBankUrl")
     private String icaBankUrl;
+
     @JsonProperty("AccountNumber")
     private String accountNumber;
+
     @JsonProperty("AccountName")
     private String accountName;
+
     @JsonProperty("AvailableAmount")
     private double availableAmount;
+
     @JsonProperty("CreditLimit")
     private double creditLimit;
+
     @JsonProperty("Accounts")
     private List<Account> accounts = new ArrayList<Account>();
+
     @JsonProperty("Transactions")
     private List<Transaction> transactions = new ArrayList<Transaction>();
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
index 3d90d65..83e3baa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
@@ -8,8 +8,10 @@ public class Transaction {
 
     @JsonProperty("TransactionDate")
     private String transactionDate;
+
     @JsonProperty("Amount")
     private double amount;
+
     @JsonProperty("Description")
     private String description;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
index d1386d9..68ed01a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
@@ -8,8 +8,10 @@ public class User {
 
     @JsonProperty("FirstName")
     private String firstName;
+
     @JsonProperty("LastName")
     private String lastName;
+
     @JsonProperty("Ttl")
     private int ttl;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index b3f310e..d09cd61 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -16,20 +16,7 @@
 
 package com.liato.bankdroid.banking.banks.icabanken;
 
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import org.apache.http.client.ClientProtocolException;
-
-import android.content.Context;
-import android.os.Build;
-import android.text.InputType;
-
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
@@ -40,24 +27,46 @@ import com.liato.bankdroid.banking.banks.icabanken.model.response.LoginResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+import android.os.Build;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Locale;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
+
     private static final String TAG = "ICABanken";
+
     private static final String NAME = "ICA Banken";
+
     private static final String NAME_SHORT = "icabanken";
+
     private static final String URL = "https://mobil.icabanken.se/";
+
     private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
+
     private static final boolean STATIC_BALANCE = false;
 
     private static final String API_KEY = "8987B80B-A708-4C61-B8CF-350D4BA289F0";
+
     private static final String API_URL = "https://appserver.icabanken.se";
+
     private static final String API_VERSION = "1.0";
 
     public ICABanken(Context context) {
@@ -80,7 +89,8 @@ public class ICABanken extends Bank {
     }
 
     public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_icabanken));
         urlopen.addHeader("ApiVersion", API_VERSION);
         urlopen.addHeader("Accept", "application/json");
         urlopen.addHeader("ApiKey", API_KEY);
@@ -89,10 +99,11 @@ public class ICABanken extends Bank {
         urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
         urlopen.addHeader("ClientAppVersion", "777");
 
-        String response = urlopen.open(String.format("%s/login/passwordlogin?customerId=%s&password=%s", API_URL, username, password));
-        if(response == null || "".equals(response)) {
+        String response = urlopen.open(String.format(
+                "%s/login/passwordlogin?customerId=%s&password=%s", API_URL, username, password));
+        if (response == null || "".equals(response)) {
             throw new LoginException(res.getText(
-                        R.string.invalid_username_password).toString());
+                    R.string.invalid_username_password).toString());
         }
         ObjectMapper vObjectMapper = new ObjectMapper();
         vObjectMapper.setDateFormat(new SimpleDateFormat(
@@ -132,7 +143,7 @@ public class ICABanken extends Bank {
             account.setTransactions(mapTransactions(icaAccount));
             Account alias = new Account(icaAccount.getName() + " (Saldo)",
                     icaAccount.getCurrentAmount(), "a:"
-                            + icaAccount.getAccountId());
+                    + icaAccount.getAccountId());
             alias.setAliasfor(icaAccount.getAccountId());
             accounts.add(account);
             accounts.add(alias);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
index 69ff542..0b20126 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
@@ -1,13 +1,14 @@
 package com.liato.bankdroid.banking.banks.icabanken.model;
 
-import java.math.BigDecimal;
-import java.util.List;
-
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.math.BigDecimal;
+import java.util.List;
+
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class IcaBankenAccount {
+
     private String mAccountId;
 
     private String mAccountNumber;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
index 2eb03e7..cfb4dd4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
@@ -1,25 +1,32 @@
 package com.liato.bankdroid.banking.banks.icabanken.model;
 
-import java.math.BigDecimal;
-import java.util.List;
-
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.math.BigDecimal;
+import java.util.List;
+
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class IcaBankenAccountList {
 
     private List<IcaBankenAccount> mAccounts;
 
     private String mDefaultAccountIdForEgiros;
+
     private String mDefaultAccountIdForPayments;
+
     private String mDefaultAccountIdForTransfers;
+
     private BigDecimal mJointAccountsTotalAvailableAmount;
 
     private BigDecimal mJointAccountsTotalCurrentAmount;
+
     private BigDecimal mMinorsAccountsTotalAvailableAmount;
+
     private BigDecimal mMinorsAccountsTotalCurrentAmount;
+
     private BigDecimal mOwnAccountsTotalAvailableAmount;
+
     private BigDecimal mOwnAccountsTotalCurrentAmount;
 
     @JsonProperty("Accounts")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
index e405c9d..c356b91 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
@@ -1,11 +1,11 @@
 package com.liato.bankdroid.banking.banks.icabanken.model;
 
-import java.math.BigDecimal;
-import java.util.Date;
-
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class IcaBankenTransaction {
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
index a7e578a..e6ec565 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
@@ -7,36 +7,36 @@ import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccountList;
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class LoginResponse {
 
-	private String mABCustomerId;
+    private String mABCustomerId;
 
-	private IcaBankenAccountList mAccountList;
+    private IcaBankenAccountList mAccountList;
 
-	private String mSessionId;
+    private String mSessionId;
 
-	@JsonProperty("ABCustomerId")
-	public String getABCustomerId() {
-		return mABCustomerId;
-	}
+    @JsonProperty("ABCustomerId")
+    public String getABCustomerId() {
+        return mABCustomerId;
+    }
 
-	public void setABCustomerId(String pABCustomerId) {
-		this.mABCustomerId = pABCustomerId;
-	}
+    public void setABCustomerId(String pABCustomerId) {
+        this.mABCustomerId = pABCustomerId;
+    }
 
-	@JsonProperty("AccountList")
-	public IcaBankenAccountList getAccountList() {
-		return mAccountList;
-	}
+    @JsonProperty("AccountList")
+    public IcaBankenAccountList getAccountList() {
+        return mAccountList;
+    }
 
-	public void setAccountList(IcaBankenAccountList pAccountList) {
-		this.mAccountList = pAccountList;
-	}
+    public void setAccountList(IcaBankenAccountList pAccountList) {
+        this.mAccountList = pAccountList;
+    }
 
-	@JsonProperty("SessionId")
-	public String getSessionId() {
-		return mSessionId;
-	}
+    @JsonProperty("SessionId")
+    public String getSessionId() {
+        return mSessionId;
+    }
 
-	public void setSessionId(String pSessionId) {
-		this.mSessionId = pSessionId;
-	}
+    public void setSessionId(String pSessionId) {
+        this.mSessionId = pSessionId;
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index d98b94a..adc88c0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -16,32 +16,10 @@
 
 package com.liato.bankdroid.banking.banks.lansforsakringar;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.InputType;
-
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
@@ -57,26 +35,62 @@ import com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transac
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Lansforsakringar extends Bank {
+
     private static final String TAG = "Lansforsakringar";
+
     private static final String NAME = "Länsförsäkringar";
+
     private static final String NAME_SHORT = "lansforsakringar";
-    private static final String URL = "https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces";
+
+    private static final String URL
+            = "https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces";
+
     private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    
+
     private static final String API_BASEURL = "https://mobil.lansforsakringar.se/appoutlet/";
 
-    private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reLoginToken = Pattern.compile("login:loginToken\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reViewState = Pattern.compile(
+            "(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reLoginToken = Pattern.compile("login:loginToken\"\\s+.*?value=\"([^\"]+)\"",
+            Pattern.CASE_INSENSITIVE);
+
     private ObjectMapper mObjectMapper = new ObjectMapper();
+
     private HashMap<String, String> mAccountLedger = new HashMap<String, String>();
 
     public Lansforsakringar(Context context) {
@@ -102,122 +116,144 @@ public class Lansforsakringar extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        Urllib weblogin = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
+        Urllib weblogin = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         weblogin.setAllowCircularRedirects(true);
 
-        String response = weblogin.open("https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces");
+        String response = weblogin.open(
+                "https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = matcher.group(1);
         matcher = reLoginToken.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" LoginToken.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " LoginToken.");
         }
         String loginToken = matcher.group(1);
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("login:userId", username));
         postData.add(new BasicNameValuePair("login:pin", password));
         postData.add(new BasicNameValuePair("login", "login"));
         postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
-        postData.add(new BasicNameValuePair("login:time", Long.toString(System.currentTimeMillis())));
+        postData.add(
+                new BasicNameValuePair("login:time", Long.toString(System.currentTimeMillis())));
         postData.add(new BasicNameValuePair("login:loginToken", loginToken));
         postData.add(new BasicNameValuePair("login:loginButton", "login:loginButton"));
         return new LoginPackage(weblogin, postData, response, weblogin.getCurrentURI());
     }
 
     public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
         urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
         urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
         //TODO: Change user-agent to "lf-android-app" if they block Bankdroid
         //urlopen.setUserAgent("lf-android-app");
 
-        NumberResponse nr = readJsonValue(API_BASEURL + "security/client", null, NumberResponse.class);
-        ChallengeResponse cr = readJsonValue(API_BASEURL + "security/client", objectAsJson(new ChallengeRequest(nr.getNumber(), nr.getNumberPair(), generateChallenge(nr.getNumber()))), ChallengeResponse.class);
+        NumberResponse nr = readJsonValue(API_BASEURL + "security/client", null,
+                NumberResponse.class);
+        ChallengeResponse cr = readJsonValue(API_BASEURL + "security/client", objectAsJson(
+                new ChallengeRequest(nr.getNumber(), nr.getNumberPair(),
+                        generateChallenge(nr.getNumber()))), ChallengeResponse.class);
         urlopen.addHeader("Ctoken", cr.getToken());
         try {
-        	LoginResponse lr = readJsonValue(API_BASEURL + "security/user", objectAsJson(new LoginRequest(username, password)), LoginResponse.class);
-        	urlopen.addHeader("Utoken", lr.getTicket());
-		} catch (Exception e) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+            LoginResponse lr = readJsonValue(API_BASEURL + "security/user",
+                    objectAsJson(new LoginRequest(username, password)), LoginResponse.class);
+            urlopen.addHeader("Utoken", lr.getTicket());
+        } catch (Exception e) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
         return urlopen;
     }
-    
-    
+
+
     private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
         try {
-			return mObjectMapper.readValue(is, valueType);
-		} catch (Exception e) {
-			throw new BankException(e.getMessage(), e);
-		}
+            return mObjectMapper.readValue(is, valueType);
+        } catch (Exception e) {
+            throw new BankException(e.getMessage(), e);
+        }
     }
 
-    private <T> T readJsonValue(String url, String postData, Class<T> valueType) throws BankException {
-    	try {
-			return readJsonValue(urlopen.openStream(url, postData, false), valueType);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw new BankException(e.getMessage(), e);
-		}
+    private <T> T readJsonValue(String url, String postData, Class<T> valueType)
+            throws BankException {
+        try {
+            return readJsonValue(urlopen.openStream(url, postData, false), valueType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
+        }
     }
-    
+
     public String objectAsJson(Object value) {
-    	try {
-			return mObjectMapper.writeValueAsString(value);
-		} catch (JsonProcessingException e) {
-			e.printStackTrace();
-		}
-    	return null;
+        try {
+            return mObjectMapper.writeValueAsString(value);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
     }
-    
+
     private String generateChallenge(int originalChallenge) {
-		try {
-			String h = Integer.toHexString(originalChallenge + (1000 * 20 / 4) + 100 * (18 / 3) + 10 * (2 / 2) + 6);
-			MessageDigest md = MessageDigest.getInstance("SHA-1");
-			byte[] messageDigest = md.digest(h.getBytes());
-			BigInteger number = new BigInteger(1,messageDigest);
-			String md5 = number.toString(16);
-			while(md5.length() < 40)
-				md5 = "0" + md5;        
-			return md5;
-		} catch (NoSuchAlgorithmException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		return "";
-    		
+        try {
+            String h = Integer.toHexString(
+                    originalChallenge + (1000 * 20 / 4) + 100 * (18 / 3) + 10 * (2 / 2) + 6);
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            byte[] messageDigest = md.digest(h.getBytes());
+            BigInteger number = new BigInteger(1, messageDigest);
+            String md5 = number.toString(16);
+            while (md5.length() < 40) {
+                md5 = "0" + md5;
+            }
+            return md5;
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return "";
+
     }
-    
+
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
         urlopen = login();
 
         mAccountLedger.clear();
-        AccountsResponse ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)), AccountsResponse.class);
-        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
-        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()), a.getAccountNumber()));
-        	//a.getLedger() should be saved to database, used when fetching transactions
-        	mAccountLedger.put(a.getAccountNumber(), a.getLedger());
-        	balance = balance.add(new BigDecimal(a.getBalance()));
+        AccountsResponse ar = readJsonValue(API_BASEURL + "account/bytype",
+                objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)),
+                AccountsResponse.class);
+        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar
+                .getAccounts()) {
+            accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()),
+                    a.getAccountNumber()));
+            //a.getLedger() should be saved to database, used when fetching transactions
+            mAccountLedger.put(a.getAccountNumber(), a.getLedger());
+            balance = balance.add(new BigDecimal(a.getBalance()));
         }
-        ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)), AccountsResponse.class);
-        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
-        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()), a.getAccountNumber()));
+        ar = readJsonValue(API_BASEURL + "account/bytype",
+                objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)),
+                AccountsResponse.class);
+        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar
+                .getAccounts()) {
+            accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()),
+                    a.getAccountNumber()));
             mAccountLedger.put(a.getAccountNumber(), a.getLedger());
-        	balance = balance.add(new BigDecimal(a.getBalance()));
-        }        
+            balance = balance.add(new BigDecimal(a.getBalance()));
+        }
         if (accounts.isEmpty()) {
-        	throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         super.updateComplete();
     }
@@ -227,25 +263,33 @@ public class Lansforsakringar extends Bank {
             BankException, IOException {
         super.updateTransactions(account, urlopen);
         // No transaction history for funds and loans
-        if (account.getType() != Account.REGULAR) return;
-        
+        if (account.getType() != Account.REGULAR) {
+            return;
+        }
+
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         //TODO: Get upcoming transactions?
         //TransactionsResponse tr = readJsonValue(API_BASEURL + "account/upcoming", objectAsJson(new UpcomingTransactionsRequest(account.getId())), TransactionsResponse.class);
-        
+
         try {
-            TransactionsResponse tr = readJsonValue(API_BASEURL + "account/transaction", objectAsJson(new TransactionsRequest(0, mAccountLedger.containsKey(account.getId()) ? mAccountLedger.get(account.getId()) : "DEPIOSIT", account.getId())), TransactionsResponse.class);
-            for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transaction t : tr.getTransactions()) {
+            TransactionsResponse tr = readJsonValue(API_BASEURL + "account/transaction",
+                    objectAsJson(new TransactionsRequest(0,
+                            mAccountLedger.containsKey(account.getId()) ? mAccountLedger
+                                    .get(account.getId()) : "DEPIOSIT", account.getId())),
+                    TransactionsResponse.class);
+            for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transaction t : tr
+                    .getTransactions()) {
                 //TODO: Set locale to Europe/Stockholm on date?
-                transactions.add(new Transaction(Helpers.formatDate(new Date(t.getTransactiondate())), t.getText(), new BigDecimal(t.getAmmount())));
+                transactions
+                        .add(new Transaction(Helpers.formatDate(new Date(t.getTransactiondate())),
+                                t.getText(), new BigDecimal(t.getAmmount())));
             }
-            account.setTransactions(transactions);        
+            account.setTransactions(transactions);
         } catch (BankException e) {
             // No transactions for account if this fails.
             // readJsonValue will print the stack trace
         }
-        
-        
+
         super.updateComplete();
-    }       	
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
index 54b0de9..3d90c33 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
@@ -1,32 +1,40 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class AccountsRequest {
-	public enum Type {
-		CHECKING("CHECKING"),
-		SAVING("SAVING");
-		
-		private String name;
-		private Type(String name) {
-			this.name = name;
-		}
-		
-		@Override
-		public String toString() {
-			return this.name;
-		}
-	}
-    private String mAccountType;
 
+    private String mAccountType;
 
-    public AccountsRequest (Type accountType) {
+    public AccountsRequest(Type accountType) {
         mAccountType = accountType.toString();
     }
 
-    @JsonSetter("accountType")
-    public void setAccountType(String a) { mAccountType = a; }
     @JsonProperty("accountType")
-    public String getAccountType() { return mAccountType; }
+    public String getAccountType() {
+        return mAccountType;
+    }
+
+    @JsonSetter("accountType")
+    public void setAccountType(String a) {
+        mAccountType = a;
+    }
+
+    public enum Type {
+        CHECKING("CHECKING"),
+        SAVING("SAVING");
+
+        private String name;
+
+        private Type(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String toString() {
+            return this.name;
+        }
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
index 0a24a38..48ef553 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
@@ -1,32 +1,51 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class ChallengeRequest {
+
     private int mOriginalChallenge;
+
     private String mChallengePair;
+
     private String mHash;
 
 
-    public ChallengeRequest (int originalChallenge, String challengePair, String hash) {
+    public ChallengeRequest(int originalChallenge, String challengePair, String hash) {
         mOriginalChallenge = originalChallenge;
         mChallengePair = challengePair;
         mHash = hash;
     }
 
-    @JsonSetter("originalChallenge")
-    public void setOriginalChallenge(int o) { mOriginalChallenge = o; }
     @JsonProperty("originalChallenge")
-    public int getOriginalChallenge() { return mOriginalChallenge; }
+    public int getOriginalChallenge() {
+        return mOriginalChallenge;
+    }
+
+    @JsonSetter("originalChallenge")
+    public void setOriginalChallenge(int o) {
+        mOriginalChallenge = o;
+    }
 
-    @JsonSetter("challengePair")
-    public void setChallengePair(String c) { mChallengePair = c; }
     @JsonProperty("challengePair")
-    public String getChallengePair() { return mChallengePair; }
+    public String getChallengePair() {
+        return mChallengePair;
+    }
+
+    @JsonSetter("challengePair")
+    public void setChallengePair(String c) {
+        mChallengePair = c;
+    }
 
-    @JsonSetter("hash")
-    public void setHash(String h) { mHash = h; }
     @JsonProperty("hash")
-    public String getHash() { return mHash; }
+    public String getHash() {
+        return mHash;
+    }
+
+    @JsonSetter("hash")
+    public void setHash(String h) {
+        mHash = h;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
index c1ccade..87fe6fd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
@@ -1,25 +1,38 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class LoginRequest {
+
     private String mSsn;
+
     private String mPin;
 
 
-    public LoginRequest (String ssn, String pin) {
+    public LoginRequest(String ssn, String pin) {
         mSsn = ssn;
         mPin = pin;
     }
 
-    @JsonSetter("ssn")
-    public void setSsn(String s) { mSsn = s; }
     @JsonProperty("ssn")
-    public String getSsn() { return mSsn; }
+    public String getSsn() {
+        return mSsn;
+    }
+
+    @JsonSetter("ssn")
+    public void setSsn(String s) {
+        mSsn = s;
+    }
 
-    @JsonSetter("pin")
-    public void setPin(String p) { mPin = p; }
     @JsonProperty("pin")
-    public String getPin() { return mPin; }
+    public String getPin() {
+        return mPin;
+    }
+
+    @JsonSetter("pin")
+    public void setPin(String p) {
+        mPin = p;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
index e684069..ba948b9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
@@ -1,32 +1,51 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class TransactionsRequest {
+
     private int mRequestedPage;
+
     private String mLedger;
+
     private String mAccountNumber;
 
 
-    public TransactionsRequest (int requestedPage, String ledger, String accountNumber) {
+    public TransactionsRequest(int requestedPage, String ledger, String accountNumber) {
         mRequestedPage = requestedPage;
         mLedger = ledger;
         mAccountNumber = accountNumber;
     }
 
-    @JsonSetter("requestedPage")
-    public void setRequestedPage(int r) { mRequestedPage = r; }
     @JsonProperty("requestedPage")
-    public int getRequestedPage() { return mRequestedPage; }
+    public int getRequestedPage() {
+        return mRequestedPage;
+    }
+
+    @JsonSetter("requestedPage")
+    public void setRequestedPage(int r) {
+        mRequestedPage = r;
+    }
 
-    @JsonSetter("ledger")
-    public void setLedger(String l) { mLedger = l; }
     @JsonProperty("ledger")
-    public String getLedger() { return mLedger; }
+    public String getLedger() {
+        return mLedger;
+    }
+
+    @JsonSetter("ledger")
+    public void setLedger(String l) {
+        mLedger = l;
+    }
 
-    @JsonSetter("accountNumber")
-    public void setAccountNumber(String a) { mAccountNumber = a; }
     @JsonProperty("accountNumber")
-    public String getAccountNumber() { return mAccountNumber; }
+    public String getAccountNumber() {
+        return mAccountNumber;
+    }
+
+    @JsonSetter("accountNumber")
+    public void setAccountNumber(String a) {
+        mAccountNumber = a;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
index a31b757..78c525f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
@@ -1,18 +1,25 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class UpcomingTransactionsRequest {
+
     private String mAccountNumber;
 
 
-    public UpcomingTransactionsRequest (String accountNumber) {
+    public UpcomingTransactionsRequest(String accountNumber) {
         mAccountNumber = accountNumber;
     }
 
-    @JsonSetter("accountNumber")
-    public void setAccountNumber(String a) { mAccountNumber = a; }
     @JsonProperty("accountNumber")
-    public String getAccountNumber() { return mAccountNumber; }
+    public String getAccountNumber() {
+        return mAccountNumber;
+    }
+
+    @JsonSetter("accountNumber")
+    public void setAccountNumber(String a) {
+        mAccountNumber = a;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
index a2a09e2..494312a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
@@ -4,66 +4,125 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class Account {
-	private boolean mTransferTo;
-	private String mProductCode;
-	private boolean mYouthAccount;
-	private String mAccountNumber;
-	private String mClearingNumber;
-	private boolean mTransferFrom;
-	private String mLedger;
-	private String mAccountName;
-	private float mDispoibleAmount;
-	private float mBalance;
-
-
-	@JsonSetter("transferTo")
-	public void setTransferTo(boolean t) { mTransferTo = t; }
-	@JsonProperty("transferTo")
-	public boolean getTransferTo() { return mTransferTo; }
-
-	@JsonSetter("productCode")
-	public void setProductCode(String p) { mProductCode = p; }
-	@JsonProperty("productCode")
-	public String getProductCode() { return mProductCode; }
-
-	@JsonSetter("youthAccount")
-	public void setYouthAccount(boolean y) { mYouthAccount = y; }
-	@JsonProperty("youthAccount")
-	public boolean getYouthAccount() { return mYouthAccount; }
-
-	@JsonSetter("accountNumber")
-	public void setAccountNumber(String a) { mAccountNumber = a; }
-	@JsonProperty("accountNumber")
-	public String getAccountNumber() { return mAccountNumber; }
-
-	@JsonSetter("clearingNumber")
-	public void setClearingNumber(String c) { mClearingNumber = c; }
-	@JsonProperty("clearingNumber")
-	public String getClearingNumber() { return mClearingNumber; }
-
-	@JsonSetter("transferFrom")
-	public void setTransferFrom(boolean t) { mTransferFrom = t; }
-	@JsonProperty("transferFrom")
-	public boolean getTransferFrom() { return mTransferFrom; }
-
-	@JsonSetter("ledger")
-	public void setLedger(String l) { mLedger = l; }
-	@JsonProperty("ledger")
-	public String getLedger() { return mLedger; }
-
-	@JsonSetter("accountName")
-	public void setAccountName(String a) { mAccountName = a; }
-	@JsonProperty("accountName")
-	public String getAccountName() { return mAccountName; }
-
-	@JsonSetter("dispoibleAmount")
-	public void setDispoibleAmount(float d) { mDispoibleAmount = d; }
-	@JsonProperty("dispoibleAmount")
-	public float getDispoibleAmount() { return mDispoibleAmount; }
-
-	@JsonSetter("balance")
-	public void setBalance(float b) { mBalance = b; }
-	@JsonProperty("balance")
-	public float getBalance() { return mBalance; }
+
+    private boolean mTransferTo;
+
+    private String mProductCode;
+
+    private boolean mYouthAccount;
+
+    private String mAccountNumber;
+
+    private String mClearingNumber;
+
+    private boolean mTransferFrom;
+
+    private String mLedger;
+
+    private String mAccountName;
+
+    private float mDispoibleAmount;
+
+    private float mBalance;
+
+    @JsonProperty("transferTo")
+    public boolean getTransferTo() {
+        return mTransferTo;
+    }
+
+    @JsonSetter("transferTo")
+    public void setTransferTo(boolean t) {
+        mTransferTo = t;
+    }
+
+    @JsonProperty("productCode")
+    public String getProductCode() {
+        return mProductCode;
+    }
+
+    @JsonSetter("productCode")
+    public void setProductCode(String p) {
+        mProductCode = p;
+    }
+
+    @JsonProperty("youthAccount")
+    public boolean getYouthAccount() {
+        return mYouthAccount;
+    }
+
+    @JsonSetter("youthAccount")
+    public void setYouthAccount(boolean y) {
+        mYouthAccount = y;
+    }
+
+    @JsonProperty("accountNumber")
+    public String getAccountNumber() {
+        return mAccountNumber;
+    }
+
+    @JsonSetter("accountNumber")
+    public void setAccountNumber(String a) {
+        mAccountNumber = a;
+    }
+
+    @JsonProperty("clearingNumber")
+    public String getClearingNumber() {
+        return mClearingNumber;
+    }
+
+    @JsonSetter("clearingNumber")
+    public void setClearingNumber(String c) {
+        mClearingNumber = c;
+    }
+
+    @JsonProperty("transferFrom")
+    public boolean getTransferFrom() {
+        return mTransferFrom;
+    }
+
+    @JsonSetter("transferFrom")
+    public void setTransferFrom(boolean t) {
+        mTransferFrom = t;
+    }
+
+    @JsonProperty("ledger")
+    public String getLedger() {
+        return mLedger;
+    }
+
+    @JsonSetter("ledger")
+    public void setLedger(String l) {
+        mLedger = l;
+    }
+
+    @JsonProperty("accountName")
+    public String getAccountName() {
+        return mAccountName;
+    }
+
+    @JsonSetter("accountName")
+    public void setAccountName(String a) {
+        mAccountName = a;
+    }
+
+    @JsonProperty("dispoibleAmount")
+    public float getDispoibleAmount() {
+        return mDispoibleAmount;
+    }
+
+    @JsonSetter("dispoibleAmount")
+    public void setDispoibleAmount(float d) {
+        mDispoibleAmount = d;
+    }
+
+    @JsonProperty("balance")
+    public float getBalance() {
+        return mBalance;
+    }
+
+    @JsonSetter("balance")
+    public void setBalance(float b) {
+        mBalance = b;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
index c77a851..fd9132e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
@@ -1,17 +1,22 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
-import java.util.ArrayList;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
+import java.util.ArrayList;
+
 public class AccountsResponse {
 
-	private ArrayList<Account> mAccounts = new ArrayList<Account>();
+    private ArrayList<Account> mAccounts = new ArrayList<Account>();
 
+    @JsonProperty("accounts")
+    public ArrayList<Account> getAccounts() {
+        return mAccounts;
+    }
 
-	@JsonSetter("accounts")
-	public void setAccounts(ArrayList<Account> a) { mAccounts = a; }
-	@JsonProperty("accounts")
-	public ArrayList<Account> getAccounts() { return mAccounts; }
+    @JsonSetter("accounts")
+    public void setAccounts(ArrayList<Account> a) {
+        mAccounts = a;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
index 98b0507..ef86227 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
@@ -1,20 +1,32 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class ChallengeResponse {
+
     private int mLifetime;
+
     private String mToken;
 
+    @JsonProperty("lifetime")
+    public int getLifetime() {
+        return mLifetime;
+    }
 
     @JsonSetter("lifetime")
-    public void setLifetime(int l) { mLifetime = l; }
-    @JsonProperty("lifetime")
-    public int getLifetime() { return mLifetime; }
+    public void setLifetime(int l) {
+        mLifetime = l;
+    }
 
-    @JsonSetter("token")
-    public void setToken(String t) { mToken = t; }
     @JsonProperty("token")
-    public String getToken() { return mToken; }
+    public String getToken() {
+        return mToken;
+    }
+
+    @JsonSetter("token")
+    public void setToken(String t) {
+        mToken = t;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
index 41c6b82..4753489 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
@@ -1,44 +1,80 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class LoginResponse {
+
     private String mName;
+
     private String mLfCompanyBelonging;
+
     private String mSsn;
+
     private int mTicketLifetime;
+
     private boolean mPinPadAvailable;
+
     private String mTicket;
 
+    @JsonProperty("name")
+    public String getName() {
+        return mName;
+    }
 
     @JsonSetter("name")
-    public void setName(String n) { mName = n; }
-    @JsonProperty("name")
-    public String getName() { return mName; }
+    public void setName(String n) {
+        mName = n;
+    }
 
-    @JsonSetter("lfCompanyBelonging")
-    public void setLfCompanyBelonging(String l) { mLfCompanyBelonging = l; }
     @JsonProperty("lfCompanyBelonging")
-    public String getLfCompanyBelonging() { return mLfCompanyBelonging; }
+    public String getLfCompanyBelonging() {
+        return mLfCompanyBelonging;
+    }
+
+    @JsonSetter("lfCompanyBelonging")
+    public void setLfCompanyBelonging(String l) {
+        mLfCompanyBelonging = l;
+    }
 
-    @JsonSetter("ssn")
-    public void setSsn(String s) { mSsn = s; }
     @JsonProperty("ssn")
-    public String getSsn() { return mSsn; }
+    public String getSsn() {
+        return mSsn;
+    }
+
+    @JsonSetter("ssn")
+    public void setSsn(String s) {
+        mSsn = s;
+    }
 
-    @JsonSetter("ticketLifetime")
-    public void setTicketLifetime(int t) { mTicketLifetime = t; }
     @JsonProperty("ticketLifetime")
-    public int getTicketLifetime() { return mTicketLifetime; }
+    public int getTicketLifetime() {
+        return mTicketLifetime;
+    }
+
+    @JsonSetter("ticketLifetime")
+    public void setTicketLifetime(int t) {
+        mTicketLifetime = t;
+    }
 
-    @JsonSetter("pinPadAvailable")
-    public void setPinPadAvailable(boolean p) { mPinPadAvailable = p; }
     @JsonProperty("pinPadAvailable")
-    public boolean getPinPadAvailable() { return mPinPadAvailable; }
+    public boolean getPinPadAvailable() {
+        return mPinPadAvailable;
+    }
+
+    @JsonSetter("pinPadAvailable")
+    public void setPinPadAvailable(boolean p) {
+        mPinPadAvailable = p;
+    }
 
-    @JsonSetter("ticket")
-    public void setTicket(String t) { mTicket = t; }
     @JsonProperty("ticket")
-    public String getTicket() { return mTicket; }
+    public String getTicket() {
+        return mTicket;
+    }
+
+    @JsonSetter("ticket")
+    public void setTicket(String t) {
+        mTicket = t;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
index d22a6c8..39574a2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
@@ -1,20 +1,32 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class NumberResponse {
+
     private int mNumber;
+
     private String mNumberPair;
 
+    @JsonProperty("number")
+    public int getNumber() {
+        return mNumber;
+    }
 
     @JsonSetter("number")
-    public void setNumber(int n) { mNumber = n; }
-    @JsonProperty("number")
-    public int getNumber() { return mNumber; }
+    public void setNumber(int n) {
+        mNumber = n;
+    }
 
-    @JsonSetter("numberPair")
-    public void setNumberPair(String n) { mNumberPair = n; }
     @JsonProperty("numberPair")
-    public String getNumberPair() { return mNumberPair; }
+    public String getNumberPair() {
+        return mNumberPair;
+    }
+
+    @JsonSetter("numberPair")
+    public void setNumberPair(String n) {
+        mNumberPair = n;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
index 63b0e98..7b2a288 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
@@ -4,24 +4,41 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
 public class Transaction {
-	private String mText;
-	private long mTransactiondate;
-	private float mAmmount;
 
+    private String mText;
 
-	@JsonSetter("text")
-	public void setText(String t) { mText = t; }
-	@JsonProperty("text")
-	public String getText() { return mText; }
+    private long mTransactiondate;
 
-	@JsonSetter("transactiondate")
-	public void setTransactiondate(long t) { mTransactiondate = t; }
-	@JsonProperty("transactiondate")
-	public long getTransactiondate() { return mTransactiondate; }
+    private float mAmmount;
 
-	@JsonSetter("ammount")
-	public void setAmmount(float a) { mAmmount = a; }
-	@JsonProperty("ammount")
-	public float getAmmount() { return mAmmount; }
+    @JsonProperty("text")
+    public String getText() {
+        return mText;
+    }
+
+    @JsonSetter("text")
+    public void setText(String t) {
+        mText = t;
+    }
+
+    @JsonProperty("transactiondate")
+    public long getTransactiondate() {
+        return mTransactiondate;
+    }
+
+    @JsonSetter("transactiondate")
+    public void setTransactiondate(long t) {
+        mTransactiondate = t;
+    }
+
+    @JsonProperty("ammount")
+    public float getAmmount() {
+        return mAmmount;
+    }
+
+    @JsonSetter("ammount")
+    public void setAmmount(float a) {
+        mAmmount = a;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
index 7170ec0..0c3a29b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
@@ -1,28 +1,46 @@
 package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
-import java.util.ArrayList;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonSetter;
 
+import java.util.ArrayList;
+
 public class TransactionsResponse {
-	private boolean mHasMore;
-	private int mNextSequenceNumber;
-	private ArrayList<Transaction> mTransactions = new ArrayList<Transaction>();
 
+    private boolean mHasMore;
+
+    private int mNextSequenceNumber;
+
+    private ArrayList<Transaction> mTransactions = new ArrayList<Transaction>();
+
+    @JsonProperty("hasMore")
+    public boolean getHasMore() {
+        return mHasMore;
+    }
+
+    @JsonSetter("hasMore")
+    public void setHasMore(boolean h) {
+        mHasMore = h;
+    }
+
+    @JsonProperty("nextSequenceNumber")
+    public int getNextSequenceNumber() {
+        return mNextSequenceNumber;
+    }
 
-	@JsonSetter("hasMore")
-	public void setHasMore(boolean h) { mHasMore = h; }
-	@JsonProperty("hasMore")
-	public boolean getHasMore() { return mHasMore; }
+    @JsonSetter("nextSequenceNumber")
+    public void setNextSequenceNumber(int n) {
+        mNextSequenceNumber = n;
+    }
 
-	@JsonSetter("nextSequenceNumber")
-	public void setNextSequenceNumber(int n) { mNextSequenceNumber = n; }
-	@JsonProperty("nextSequenceNumber")
-	public int getNextSequenceNumber() { return mNextSequenceNumber; }
+    @JsonProperty("transactions")
+    public ArrayList<Transaction> getTransactions() {
+        return mTransactions;
+    }
 
-	@JsonSetter("transactions")
-	public void setTransactions(ArrayList<Transaction> t) { mTransactions = t; }
-	@JsonProperty("transactions")
-	public ArrayList<Transaction> getTransactions() { return mTransactions; }
+    @JsonSetter("transactions")
+    public void setTransactions(ArrayList<Transaction> t) {
+        mTransactions = t;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
index 41a3db9..a3e9212 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
@@ -1,16 +1,17 @@
 package com.liato.bankdroid.banking.banks.nordea;
 
-import java.util.ArrayList;
-
 import android.graphics.Bitmap;
 
+import java.util.ArrayList;
+
 public class CaptchaBreaker {
+
     private final static int[][][] NUMBERS = CaptchaBreakerNumbers.NUMBERS;
-    
+
     public static String iMustBreakYou(Bitmap bitmap) {
         int width = bitmap.getWidth();
         int height = bitmap.getHeight();
-        
+
         ArrayList<Segment> segments = new ArrayList<Segment>();
 
         boolean numberpart = false;
@@ -27,20 +28,20 @@ public class CaptchaBreaker {
                     break;
                 }
             }
-            if (numberpart && !numberpartcol) {            
+            if (numberpart && !numberpartcol) {
                 numberpart = false;
-                segment.end = x-1;
+                segment.end = x - 1;
                 segments.add(segment);
                 segment = new Segment();
             }
         }
         if (segment.end == -1 && segment.start >= 0) {
-            segment.end = width-1;
+            segment.end = width - 1;
             segments.add(segment);
         }
         StringBuilder sb = new StringBuilder(segments.size());
         for (Segment s : segments) {
-            Bitmap numberSegment = Bitmap.createBitmap(bitmap, s.start, 0, s.end-s.start, height);
+            Bitmap numberSegment = Bitmap.createBitmap(bitmap, s.start, 0, s.end - s.start, height);
             sb.append(extractNumber(numberSegment));
             numberSegment.recycle();
             numberSegment = null;
@@ -48,7 +49,7 @@ public class CaptchaBreaker {
         return sb.toString();
 
     }
-    
+
     private final static String extractNumber(Bitmap bitmap) {
         int width = bitmap.getWidth();
         for (int i = 0; i < NUMBERS.length; i++) {
@@ -60,8 +61,9 @@ public class CaptchaBreaker {
                     break;
                 }
                 int color = bitmap.getPixel(point[0], point[1]);
-                if ((color == 0xffffffff && point[2] == 0) || (color != 0xffffffff && point[2] == 1)) {
-                    matches ++;
+                if ((color == 0xffffffff && point[2] == 0) || (color != 0xffffffff
+                        && point[2] == 1)) {
+                    matches++;
                 }
             }
             if (matches == number.length) {
@@ -70,14 +72,16 @@ public class CaptchaBreaker {
         }
         return "?";
     }
-    
+
 
 }
-    
+
 class Segment {
+
     public int start = -1;
+
     public int end = -1;
-    
+
     @Override
     public String toString() {
         return String.format("Segment {start=%d, end=%d}", start, end);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
index b169406..9a503f2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
@@ -2,89 +2,90 @@ package com.liato.bankdroid.banking.banks.nordea;
 
 /**
  * Autogenerated captcha numbers for Nordea.
- * 
+ *
  * @since 2012-07-08 05:51:25
  */
 public class CaptchaBreakerNumbers {
+
     public final static int[][][] NUMBERS = {
-            { { 7, 12, 0 }, { 6, 22, 1 }, { 11, 18, 0 }, { 4, 9, 1 },
-                    { 0, 14, 1 }, { 5, 27, 0 }, { 2, 27, 0 }, { 5, 17, 1 },
-                    { 9, 17, 0 }, { 17, 1, 0 }, { 8, 9, 0 }, { 11, 15, 0 },
-                    { 1, 15, 1 }, { 15, 1, 0 }, { 15, 3, 1 }, { 8, 0, 1 },
-                    { 4, 0, 0 }, { 9, 3, 0 }, { 14, 1, 1 }, { 16, 20, 1 },
-                    { 9, 6, 0 }, { 9, 18, 0 }, { 15, 5, 1 }, { 0, 13, 1 },
-                    { 5, 18, 1 }, { 15, 17, 1 }, { 12, 25, 1 }, { 6, 16, 0 },
-                    { 11, 16, 0 }, { 16, 28, 0 }, { 16, 27, 0 }, { 6, 1, 1 } },
-            { { 7, 27, 0 }, { 8, 4, 1 }, { 5, 5, 1 }, { 12, 25, 1 },
-                    { 0, 25, 1 }, { 11, 16, 0 }, { 8, 26, 0 }, { 3, 27, 0 },
-                    { 2, 27, 0 }, { 9, 4, 1 }, { 5, 0, 0 }, { 7, 7, 1 },
-                    { 10, 20, 0 }, { 12, 11, 0 }, { 1, 11, 0 }, { 3, 1, 1 },
-                    { 4, 18, 0 }, { 0, 24, 1 }, { 1, 16, 0 }, { 9, 27, 0 },
-                    { 3, 22, 0 }, { 7, 21, 1 }, { 11, 18, 0 }, { 6, 24, 1 },
-                    { 0, 20, 0 }, { 13, 16, 0 }, { 7, 11, 1 }, { 8, 12, 1 },
-                    { 10, 22, 0 }, { 3, 24, 1 }, { 3, 12, 0 }, { 8, 27, 0 } },
-            { { 3, 10, 0 }, { 12, 18, 0 }, { 14, 25, 1 }, { 13, 10, 1 },
-                    { 10, 19, 0 }, { 11, 21, 0 }, { 1, 15, 0 }, { 1, 27, 0 },
-                    { 10, 10, 1 }, { 0, 14, 0 }, { 10, 21, 0 }, { 12, 1, 1 },
-                    { 5, 9, 0 }, { 9, 27, 0 }, { 7, 18, 1 }, { 12, 0, 1 },
-                    { 11, 18, 0 }, { 2, 10, 0 }, { 1, 7, 0 }, { 6, 27, 0 },
-                    { 3, 25, 1 }, { 9, 25, 1 }, { 12, 23, 1 }, { 2, 1, 1 },
-                    { 8, 25, 1 }, { 0, 20, 1 }, { 12, 16, 0 }, { 8, 8, 0 },
-                    { 11, 5, 1 }, { 11, 17, 0 }, { 0, 3, 0 }, { 1, 18, 0 } },
-            { { 10, 9, 1 }, { 3, 11, 1 }, { 2, 2, 1 }, { 7, 20, 0 },
-                    { 8, 24, 1 }, { 5, 14, 1 }, { 12, 25, 1 }, { 1, 17, 0 },
-                    { 0, 15, 0 }, { 2, 18, 0 }, { 6, 27, 0 }, { 0, 22, 1 },
-                    { 13, 8, 1 }, { 2, 21, 0 }, { 13, 23, 1 }, { 11, 7, 1 },
-                    { 13, 26, 0 }, { 2, 18, 0 }, { 5, 27, 0 }, { 2, 27, 0 },
-                    { 0, 1, 1 }, { 4, 18, 0 }, { 4, 7, 0 }, { 13, 27, 0 },
-                    { 10, 17, 0 }, { 9, 2, 1 }, { 7, 1, 1 }, { 8, 20, 0 },
-                    { 13, 25, 0 }, { 13, 26, 0 }, { 6, 0, 1 }, { 2, 0, 1 } },
-            { { 10, 5, 1 }, { 18, 3, 0 }, { 6, 16, 1 }, { 16, 6, 1 },
-                    { 17, 20, 0 }, { 16, 22, 1 }, { 3, 19, 0 }, { 15, 28, 0 },
-                    { 10, 7, 1 }, { 16, 23, 1 }, { 11, 9, 0 }, { 13, 24, 1 },
-                    { 15, 7, 1 }, { 3, 19, 0 }, { 9, 12, 0 }, { 3, 8, 0 },
-                    { 10, 10, 0 }, { 13, 0, 1 }, { 15, 3, 1 }, { 12, 2, 1 },
-                    { 13, 8, 1 }, { 16, 3, 1 }, { 2, 14, 1 }, { 9, 9, 0 },
-                    { 8, 23, 0 }, { 6, 27, 0 }, { 8, 0, 0 }, { 0, 16, 1 },
-                    { 10, 2, 1 }, { 13, 13, 1 }, { 13, 10, 1 }, { 8, 5, 1 } },
-            { { 2, 14, 0 }, { 3, 20, 0 }, { 3, 4, 0 }, { 13, 13, 1 },
-                    { 1, 15, 0 }, { 2, 13, 0 }, { 6, 21, 0 }, { 3, 20, 0 },
-                    { 11, 0, 1 }, { 4, 16, 0 }, { 13, 14, 1 }, { 11, 2, 1 },
-                    { 2, 23, 1 }, { 0, 22, 1 }, { 7, 20, 0 }, { 11, 9, 0 },
-                    { 0, 23, 1 }, { 14, 7, 0 }, { 9, 8, 0 }, { 8, 22, 1 },
-                    { 6, 2, 1 }, { 1, 0, 1 }, { 13, 19, 1 }, { 7, 20, 0 },
-                    { 9, 14, 1 }, { 4, 5, 0 }, { 8, 25, 1 }, { 0, 26, 0 },
-                    { 3, 5, 0 }, { 11, 17, 1 }, { 4, 18, 0 }, { 4, 3, 1 } },
-            { { 0, 5, 0 }, { 2, 3, 1 }, { 10, 0, 1 }, { 4, 8, 1 }, { 3, 6, 1 },
-                    { 12, 10, 1 }, { 13, 1, 1 }, { 7, 12, 1 }, { 5, 7, 1 },
-                    { 9, 21, 0 }, { 0, 4, 0 }, { 3, 28, 0 }, { 13, 9, 1 },
-                    { 10, 12, 1 }, { 4, 4, 1 }, { 13, 22, 1 }, { 13, 10, 1 },
-                    { 7, 1, 1 }, { 6, 22, 1 }, { 11, 16, 0 }, { 4, 9, 1 },
-                    { 15, 14, 1 }, { 12, 18, 0 }, { 13, 1, 1 }, { 4, 27, 0 },
-                    { 9, 0, 1 }, { 12, 13, 1 }, { 4, 13, 1 }, { 17, 4, 0 },
-                    { 16, 6, 0 }, { 14, 12, 1 }, { 7, 23, 1 } },
-            { { 12, 3, 1 }, { 0, 22, 0 }, { 8, 27, 0 }, { 15, 19, 0 },
-                    { 12, 3, 1 }, { 9, 7, 0 }, { 4, 6, 0 }, { 7, 4, 0 },
-                    { 9, 23, 0 }, { 14, 0, 1 }, { 2, 15, 0 }, { 7, 0, 1 },
-                    { 6, 18, 1 }, { 11, 11, 1 }, { 6, 10, 0 }, { 11, 20, 0 },
-                    { 13, 10, 0 }, { 13, 2, 1 }, { 15, 5, 1 }, { 5, 13, 0 },
-                    { 10, 8, 1 }, { 10, 16, 0 }, { 4, 19, 1 }, { 8, 28, 0 },
-                    { 8, 16, 1 }, { 13, 4, 1 }, { 15, 22, 0 }, { 15, 10, 0 },
-                    { 3, 12, 0 }, { 13, 6, 1 }, { 3, 5, 0 }, { 12, 23, 0 } },
-            { { 5, 27, 0 }, { 5, 3, 1 }, { 5, 24, 1 }, { 17, 18, 1 },
-                    { 8, 13, 1 }, { 1, 14, 1 }, { 9, 19, 0 }, { 2, 26, 0 },
-                    { 3, 13, 1 }, { 4, 19, 1 }, { 12, 15, 1 }, { 7, 28, 0 },
-                    { 13, 0, 1 }, { 8, 22, 1 }, { 11, 25, 1 }, { 11, 5, 0 },
-                    { 6, 23, 1 }, { 0, 16, 1 }, { 4, 0, 0 }, { 17, 25, 0 },
-                    { 12, 22, 1 }, { 6, 13, 1 }, { 7, 19, 0 }, { 9, 19, 0 },
-                    { 11, 23, 1 }, { 11, 8, 0 }, { 17, 11, 0 }, { 12, 25, 1 },
-                    { 1, 26, 0 }, { 15, 5, 1 }, { 0, 18, 1 }, { 7, 11, 1 } },
-            { { 6, 24, 1 }, { 14, 13, 1 }, { 0, 3, 0 }, { 8, 6, 0 },
-                    { 3, 12, 1 }, { 7, 21, 0 }, { 7, 26, 0 }, { 10, 28, 0 },
-                    { 3, 23, 1 }, { 7, 1, 1 }, { 6, 0, 1 }, { 13, 0, 1 },
-                    { 12, 28, 0 }, { 15, 15, 1 }, { 6, 24, 1 }, { 11, 5, 0 },
-                    { 3, 20, 0 }, { 9, 12, 0 }, { 2, 15, 1 }, { 4, 21, 0 },
-                    { 13, 11, 1 }, { 3, 8, 1 }, { 17, 16, 1 }, { 13, 9, 0 },
-                    { 3, 1, 1 }, { 14, 10, 1 }, { 3, 19, 0 }, { 14, 7, 1 },
-                    { 15, 19, 1 }, { 3, 1, 1 }, { 8, 19, 0 }, { 11, 13, 1 } } };
+            {{7, 12, 0}, {6, 22, 1}, {11, 18, 0}, {4, 9, 1},
+                    {0, 14, 1}, {5, 27, 0}, {2, 27, 0}, {5, 17, 1},
+                    {9, 17, 0}, {17, 1, 0}, {8, 9, 0}, {11, 15, 0},
+                    {1, 15, 1}, {15, 1, 0}, {15, 3, 1}, {8, 0, 1},
+                    {4, 0, 0}, {9, 3, 0}, {14, 1, 1}, {16, 20, 1},
+                    {9, 6, 0}, {9, 18, 0}, {15, 5, 1}, {0, 13, 1},
+                    {5, 18, 1}, {15, 17, 1}, {12, 25, 1}, {6, 16, 0},
+                    {11, 16, 0}, {16, 28, 0}, {16, 27, 0}, {6, 1, 1}},
+            {{7, 27, 0}, {8, 4, 1}, {5, 5, 1}, {12, 25, 1},
+                    {0, 25, 1}, {11, 16, 0}, {8, 26, 0}, {3, 27, 0},
+                    {2, 27, 0}, {9, 4, 1}, {5, 0, 0}, {7, 7, 1},
+                    {10, 20, 0}, {12, 11, 0}, {1, 11, 0}, {3, 1, 1},
+                    {4, 18, 0}, {0, 24, 1}, {1, 16, 0}, {9, 27, 0},
+                    {3, 22, 0}, {7, 21, 1}, {11, 18, 0}, {6, 24, 1},
+                    {0, 20, 0}, {13, 16, 0}, {7, 11, 1}, {8, 12, 1},
+                    {10, 22, 0}, {3, 24, 1}, {3, 12, 0}, {8, 27, 0}},
+            {{3, 10, 0}, {12, 18, 0}, {14, 25, 1}, {13, 10, 1},
+                    {10, 19, 0}, {11, 21, 0}, {1, 15, 0}, {1, 27, 0},
+                    {10, 10, 1}, {0, 14, 0}, {10, 21, 0}, {12, 1, 1},
+                    {5, 9, 0}, {9, 27, 0}, {7, 18, 1}, {12, 0, 1},
+                    {11, 18, 0}, {2, 10, 0}, {1, 7, 0}, {6, 27, 0},
+                    {3, 25, 1}, {9, 25, 1}, {12, 23, 1}, {2, 1, 1},
+                    {8, 25, 1}, {0, 20, 1}, {12, 16, 0}, {8, 8, 0},
+                    {11, 5, 1}, {11, 17, 0}, {0, 3, 0}, {1, 18, 0}},
+            {{10, 9, 1}, {3, 11, 1}, {2, 2, 1}, {7, 20, 0},
+                    {8, 24, 1}, {5, 14, 1}, {12, 25, 1}, {1, 17, 0},
+                    {0, 15, 0}, {2, 18, 0}, {6, 27, 0}, {0, 22, 1},
+                    {13, 8, 1}, {2, 21, 0}, {13, 23, 1}, {11, 7, 1},
+                    {13, 26, 0}, {2, 18, 0}, {5, 27, 0}, {2, 27, 0},
+                    {0, 1, 1}, {4, 18, 0}, {4, 7, 0}, {13, 27, 0},
+                    {10, 17, 0}, {9, 2, 1}, {7, 1, 1}, {8, 20, 0},
+                    {13, 25, 0}, {13, 26, 0}, {6, 0, 1}, {2, 0, 1}},
+            {{10, 5, 1}, {18, 3, 0}, {6, 16, 1}, {16, 6, 1},
+                    {17, 20, 0}, {16, 22, 1}, {3, 19, 0}, {15, 28, 0},
+                    {10, 7, 1}, {16, 23, 1}, {11, 9, 0}, {13, 24, 1},
+                    {15, 7, 1}, {3, 19, 0}, {9, 12, 0}, {3, 8, 0},
+                    {10, 10, 0}, {13, 0, 1}, {15, 3, 1}, {12, 2, 1},
+                    {13, 8, 1}, {16, 3, 1}, {2, 14, 1}, {9, 9, 0},
+                    {8, 23, 0}, {6, 27, 0}, {8, 0, 0}, {0, 16, 1},
+                    {10, 2, 1}, {13, 13, 1}, {13, 10, 1}, {8, 5, 1}},
+            {{2, 14, 0}, {3, 20, 0}, {3, 4, 0}, {13, 13, 1},
+                    {1, 15, 0}, {2, 13, 0}, {6, 21, 0}, {3, 20, 0},
+                    {11, 0, 1}, {4, 16, 0}, {13, 14, 1}, {11, 2, 1},
+                    {2, 23, 1}, {0, 22, 1}, {7, 20, 0}, {11, 9, 0},
+                    {0, 23, 1}, {14, 7, 0}, {9, 8, 0}, {8, 22, 1},
+                    {6, 2, 1}, {1, 0, 1}, {13, 19, 1}, {7, 20, 0},
+                    {9, 14, 1}, {4, 5, 0}, {8, 25, 1}, {0, 26, 0},
+                    {3, 5, 0}, {11, 17, 1}, {4, 18, 0}, {4, 3, 1}},
+            {{0, 5, 0}, {2, 3, 1}, {10, 0, 1}, {4, 8, 1}, {3, 6, 1},
+                    {12, 10, 1}, {13, 1, 1}, {7, 12, 1}, {5, 7, 1},
+                    {9, 21, 0}, {0, 4, 0}, {3, 28, 0}, {13, 9, 1},
+                    {10, 12, 1}, {4, 4, 1}, {13, 22, 1}, {13, 10, 1},
+                    {7, 1, 1}, {6, 22, 1}, {11, 16, 0}, {4, 9, 1},
+                    {15, 14, 1}, {12, 18, 0}, {13, 1, 1}, {4, 27, 0},
+                    {9, 0, 1}, {12, 13, 1}, {4, 13, 1}, {17, 4, 0},
+                    {16, 6, 0}, {14, 12, 1}, {7, 23, 1}},
+            {{12, 3, 1}, {0, 22, 0}, {8, 27, 0}, {15, 19, 0},
+                    {12, 3, 1}, {9, 7, 0}, {4, 6, 0}, {7, 4, 0},
+                    {9, 23, 0}, {14, 0, 1}, {2, 15, 0}, {7, 0, 1},
+                    {6, 18, 1}, {11, 11, 1}, {6, 10, 0}, {11, 20, 0},
+                    {13, 10, 0}, {13, 2, 1}, {15, 5, 1}, {5, 13, 0},
+                    {10, 8, 1}, {10, 16, 0}, {4, 19, 1}, {8, 28, 0},
+                    {8, 16, 1}, {13, 4, 1}, {15, 22, 0}, {15, 10, 0},
+                    {3, 12, 0}, {13, 6, 1}, {3, 5, 0}, {12, 23, 0}},
+            {{5, 27, 0}, {5, 3, 1}, {5, 24, 1}, {17, 18, 1},
+                    {8, 13, 1}, {1, 14, 1}, {9, 19, 0}, {2, 26, 0},
+                    {3, 13, 1}, {4, 19, 1}, {12, 15, 1}, {7, 28, 0},
+                    {13, 0, 1}, {8, 22, 1}, {11, 25, 1}, {11, 5, 0},
+                    {6, 23, 1}, {0, 16, 1}, {4, 0, 0}, {17, 25, 0},
+                    {12, 22, 1}, {6, 13, 1}, {7, 19, 0}, {9, 19, 0},
+                    {11, 23, 1}, {11, 8, 0}, {17, 11, 0}, {12, 25, 1},
+                    {1, 26, 0}, {15, 5, 1}, {0, 18, 1}, {7, 11, 1}},
+            {{6, 24, 1}, {14, 13, 1}, {0, 3, 0}, {8, 6, 0},
+                    {3, 12, 1}, {7, 21, 0}, {7, 26, 0}, {10, 28, 0},
+                    {3, 23, 1}, {7, 1, 1}, {6, 0, 1}, {13, 0, 1},
+                    {12, 28, 0}, {15, 15, 1}, {6, 24, 1}, {11, 5, 0},
+                    {3, 20, 0}, {9, 12, 0}, {2, 15, 1}, {4, 21, 0},
+                    {13, 11, 1}, {3, 8, 1}, {17, 16, 1}, {13, 9, 0},
+                    {3, 1, 1}, {14, 10, 1}, {3, 19, 0}, {14, 7, 1},
+                    {15, 19, 1}, {3, 1, 1}, {8, 19, 0}, {11, 13, 1}}};
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index e004d12..37eb265 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -16,257 +16,299 @@
 
 package com.liato.bankdroid.banking.banks.nordea;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpResponseException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordea extends Bank {
-	private static final String TAG = "Nordea";
-	private static final String NAME = "Nordea";
-	private static final String NAME_SHORT = "nordea";
-	private static final String BASE_URL = "https://internetbanken.privat.nordea.se/nsp/";
-	private static final String LOGIN_URL = BASE_URL + "login";
-	private static final int BANKTYPE_ID = IBankTypes.NORDEA;
+
+    private static final String TAG = "Nordea";
+
+    private static final String NAME = "Nordea";
+
+    private static final String NAME_SHORT = "nordea";
+
+    private static final String BASE_URL = "https://internetbanken.privat.nordea.se/nsp/";
+
+    private static final String LOGIN_URL = BASE_URL + "login";
+
+    private static final int BANKTYPE_ID = IBankTypes.NORDEA;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    
+
     private static final int MAX_TRANSACTIONS = 50;
 
     private Pattern reSimpleLoginLink = Pattern.compile(
             "href=\"(login\\?" +
-            "(?=[^\"]*usecase=commonlogin)" +
-            "(?=[^\"]*command=commonlogintabcommand)" +
-            "(?=[^\"]*guid=([\\w]*))" +
-            "(?=[^\"]*fpid=([\\w]*))" +
-            "(?=[^\"]*commonlogintab=2)" +
-            "(?=[^\"]*hash=([\\w]*))" +
-            "[^\"]*)",
+                    "(?=[^\"]*usecase=commonlogin)" +
+                    "(?=[^\"]*command=commonlogintabcommand)" +
+                    "(?=[^\"]*guid=([\\w]*))" +
+                    "(?=[^\"]*fpid=([\\w]*))" +
+                    "(?=[^\"]*commonlogintab=2)" +
+                    "(?=[^\"]*hash=([\\w]*))" +
+                    "[^\"]*)",
             Pattern.CASE_INSENSITIVE
     );
-    private Pattern reLoginFormContents = Pattern.compile("<form[^>]+id=\"commonlogin\"[^>]*>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reNonTextInputField = Pattern.compile("<input(?=[^>]+type=\"((?!text)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
-    private Pattern reNonTelInputField = Pattern.compile("<input(?=[^>]+type=\"((?!tel)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reLoginFormContents = Pattern.compile(
+            "<form[^>]+id=\"commonlogin\"[^>]*>(.*?)</form>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reNonTextInputField = Pattern.compile(
+            "<input(?=[^>]+type=\"((?!text)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reNonTelInputField = Pattern.compile(
+            "<input(?=[^>]+type=\"((?!tel)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")",
+            Pattern.CASE_INSENSITIVE);
 
     // Link to home/overview - PageType.ENTRY
     private Pattern reHomeLink = Pattern.compile(
             "href=\"(core[^\"#]*)#?\"" + // The actual url (trim the '#')
-            "[^>]*>" +
-            "[^<]*" +
-            "<img[^>]+id=\"home\"" // Identificator
-            );
+                    "[^>]*>" +
+                    "[^<]*" +
+                    "<img[^>]+id=\"home\"" // Identificator
+    );
+
+    private Pattern reTransactionFormContents = Pattern.compile(
+            "<form(?=[^>]+id=\"accountTransactions\")(?=[^>]+action=\"([^\"]*)\").*?>(.*?)</form>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
-    private Pattern reTransactionFormContents = Pattern.compile("<form(?=[^>]+id=\"accountTransactions\")(?=[^>]+action=\"([^\"]*)\").*?>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountLink = Pattern.compile(
             "href=\"(core\\?" +
-            "(?=[^\"]*usecase=accountsoverview)" +
-            "(?=[^\"]*command=getcurrenttransactions)" +
-            "(?=[^\"]*currentaccountsoverviewtable=([\\d]+))" +
-            "[^\"]*)[^>]*>" + // End of link attributes
-            "(.*?)" + // Link contents - account name
-            "</a>" +
-            ".*?" + // fast forward
-            "([*\\d]+)" + // censured account number (account identifier)
-            ".*?" + // fast forward
-            "<td.*?>(.*?)</td>", // account balance
+                    "(?=[^\"]*usecase=accountsoverview)" +
+                    "(?=[^\"]*command=getcurrenttransactions)" +
+                    "(?=[^\"]*currentaccountsoverviewtable=([\\d]+))" +
+                    "[^\"]*)[^>]*>" + // End of link attributes
+                    "(.*?)" + // Link contents - account name
+                    "</a>" +
+                    ".*?" + // fast forward
+                    "([*\\d]+)" + // censured account number (account identifier)
+                    ".*?" + // fast forward
+                    "<td.*?>(.*?)</td>", // account balance
             Pattern.DOTALL
     );
-    private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d+,.-]*)", Pattern.DOTALL);
-    private Pattern reCurrency = Pattern.compile("Saldo:.*?[\\d\\.,-]+[\\s]*</td>[\\s]*<td[^>]*>([^<]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reTransaction = Pattern.compile(
+            "(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d+,.-]*)",
+            Pattern.DOTALL);
+
+    private Pattern reCurrency = Pattern.compile(
+            "Saldo:.*?[\\d\\.,-]+[\\s]*</td>[\\s]*<td[^>]*>([^<]*)",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
     // The link to go to the credit cards overview page
     private Pattern reCreditCardsLink = Pattern.compile("<a href=\"([^\"#]*)#?\">Kort<");
+
     // Link to specific credit card
     private Pattern reCreditCardLink = Pattern.compile(
             "href=\"" +
-            "(" + // Start group 1: link url
-            "engine\\?" +
-            "(?=[^\"]*usecase=viewallcards)" +
-            "(?=[^\"]*command=gettransactionscredit)" + // debit cards have "debit" - but we don't need those
-            "[^\"#]*" + // Rest of link url
-            ")" + // End group 1
-            "[^>]*>" + // Rest of link attributes
-            "(.*?)" + // Group 2: Link contents - Credit card type (Eg. "Nordea Gold")
-            "</a>" +
-            ".*?" + // Fast forward
-            "\\*+(\\d+)"+ // Group 3: Censured credit card number (account identifier)
-            ".*?" + // Fast forward
-            "<td.*?>([^<]*)</td>" + // Group 4: Expire date **/**
-            ".*?" + // Fast forward
-            "<td.*?>([^<]*)</td>", // Group 5: Account balance
+                    "(" + // Start group 1: link url
+                    "engine\\?" +
+                    "(?=[^\"]*usecase=viewallcards)" +
+                    "(?=[^\"]*command=gettransactionscredit)" +
+                    // debit cards have "debit" - but we don't need those
+                    "[^\"#]*" + // Rest of link url
+                    ")" + // End group 1
+                    "[^>]*>" + // Rest of link attributes
+                    "(.*?)" + // Group 2: Link contents - Credit card type (Eg. "Nordea Gold")
+                    "</a>" +
+                    ".*?" + // Fast forward
+                    "\\*+(\\d+)" + // Group 3: Censured credit card number (account identifier)
+                    ".*?" + // Fast forward
+                    "<td.*?>([^<]*)</td>" + // Group 4: Expire date **/**
+                    ".*?" + // Fast forward
+                    "<td.*?>([^<]*)</td>", // Group 5: Account balance
             Pattern.DOTALL
     );
+
     // Credit card transaction entry
     private Pattern reCreditCardTransaction = Pattern.compile(
             "(\\d{4}-\\d{2}-\\d{2})</a>" + // Group 1: Transaction date
-            "[^<]*</td>" + // End date col
-            "[^<]*<td[^>]*>" + // Start transaction name col
-            "\\s*([^<]*)\\s*</td>" + // Group 2: (trimmed) Transaction name
-            "[^<]*<td[^>]*>" + // Start recipient name col (same as transaction name?)
-            "[^<]*</td>" + // Transaction name
-            "[^<]*<td[^>]*>" + // Start transaction native amount/currency col
-            "\\s*([^<]*)\\s*</td>" + // Group 3: Transaction native amount/currency (Empty when SEK)
-            "[^<]*<td[^>]*>" + // Start amount col
-            "\\s*([\\d,.-]+)", // Group 4: Transaction amount
+                    "[^<]*</td>" + // End date col
+                    "[^<]*<td[^>]*>" + // Start transaction name col
+                    "\\s*([^<]*)\\s*</td>" + // Group 2: (trimmed) Transaction name
+                    "[^<]*<td[^>]*>" + // Start recipient name col (same as transaction name?)
+                    "[^<]*</td>" + // Transaction name
+                    "[^<]*<td[^>]*>" + // Start transaction native amount/currency col
+                    "\\s*([^<]*)\\s*</td>" +
+                    // Group 3: Transaction native amount/currency (Empty when SEK)
+                    "[^<]*<td[^>]*>" + // Start amount col
+                    "\\s*([\\d,.-]+)", // Group 4: Transaction amount
             Pattern.DOTALL
     );
+
     // Credit card currency
     private Pattern reCreditCardCurrency = Pattern.compile(
-      "<th[^>]*>Belopp\\s([^<]+)</th>"
+            "<th[^>]*>Belopp\\s([^<]+)</th>"
     );
 
     // The link to go to the loans overview page
     private Pattern reLoansLink = Pattern.compile("<a href=\"([^\"#]*)#?\">Lån<");
+
     // Link to specific loan
     private Pattern reLoanLink = Pattern.compile(
             "href=\"" +
-            "(" + // Start group 1: link url
-            "engine\\?" +
-            "(?=[^\"]*usecase=loansoverview)" +
-            "(?=[^\"]*command=get_loan_details_command)" +
-            "[^\"#]*" + // Rest of link url
-            ")" + // End group 1
-            "#?" + // Trim off a padded #
-            "[^>]*>" + // Rest of link attributes
-            "(.*?)" + // Group 2: Link contents - Loan type (Eg. "Bolån")
-            "</a>" +
-            ".*?" + // Fast forward
-            "\\*+(\\d+)" + // Group 3: Censured loan number (account identifier)
-            ".*?" + // Fast forward
-            "(\\d{4}-\\d{2}-\\d{2})" + // Group 4: "Transaction date" - Latest interest payment date
-            ".*?" + // Fast forward
-            "([\\d\\.,]+)", // Group 5: Loan amount
+                    "(" + // Start group 1: link url
+                    "engine\\?" +
+                    "(?=[^\"]*usecase=loansoverview)" +
+                    "(?=[^\"]*command=get_loan_details_command)" +
+                    "[^\"#]*" + // Rest of link url
+                    ")" + // End group 1
+                    "#?" + // Trim off a padded #
+                    "[^>]*>" + // Rest of link attributes
+                    "(.*?)" + // Group 2: Link contents - Loan type (Eg. "Bolån")
+                    "</a>" +
+                    ".*?" + // Fast forward
+                    "\\*+(\\d+)" + // Group 3: Censured loan number (account identifier)
+                    ".*?" + // Fast forward
+                    "(\\d{4}-\\d{2}-\\d{2})" +
+                    // Group 4: "Transaction date" - Latest interest payment date
+                    ".*?" + // Fast forward
+                    "([\\d\\.,]+)", // Group 5: Loan amount
             Pattern.DOTALL
     );
-    
-    private Pattern reAccountSelect = Pattern.compile("<select[^>]+name=\"transactionaccount\"[^>]*>(.*?)</select>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountOption = Pattern.compile("<option[^>]+value=\"([\\d]+)\"[^>]*>.*?(\\*{12}\\d{4})", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    
+
+    private Pattern reAccountSelect = Pattern.compile(
+            "<select[^>]+name=\"transactionaccount\"[^>]*>(.*?)</select>",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private Pattern reAccountOption = Pattern.compile(
+            "<option[^>]+value=\"([\\d]+)\"[^>]*>.*?(\\*{12}\\d{4})",
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
     // Nordea generates unique urls on each page load and serves content from session info,
     // so we need to find new links in lastResponse after each page load.
     private String lastResponse;
+
     private int currentPageType;
-    
-	public Nordea(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = BASE_URL;
+
+    public Nordea(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = BASE_URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
+    }
 
-	public Nordea(String username, String password, Context context) throws BankException,
+    public Nordea(String username, String password, Context context) throws BankException,
             LoginException, BankChoiceException, IOException {
-		this(context);
-		this.update(username, password);
-	}
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-		urlopen = new Urllib(context);
-		Matcher matcher;
-		// Find "simple login" link
-		this.lastResponse = urlopen.open(LOGIN_URL);
-		this.currentPageType = PageType.LOGIN;
-		matcher = reSimpleLoginLink.matcher(this.lastResponse);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login link.");
-		}
-		// Visit login link
-		String link = BASE_URL + matcher.group(1);
-		this.lastResponse = urlopen.open(link);
-		this.currentPageType = PageType.SIMPLE_LOGIN;
-		matcher = reLoginFormContents.matcher(this.lastResponse);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login form.");
-		}
-		// Extract hidden fields
-		String formContents = matcher.group(1);
-		matcher = reNonTelInputField.matcher(formContents);
-		if (!matcher.find()) {
-			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login fields.");
-		}
-		matcher.reset();
-		List <NameValuePair> postData = new ArrayList <NameValuePair>();
-		while (matcher.find()) {
-			String name  = matcher.group(2);
-			String value = matcher.group(3);
-			// The non-mobile page requires javascript, so we'd best pretend we have it
-			if ("JAVASCRIPT_DETECTED".equals(name)) {
-				value = "true";
-			}
-			postData.add(new BasicNameValuePair(name, value));
-		}
-		// Login information
-		postData.add(new BasicNameValuePair("userid", username));
-		postData.add(new BasicNameValuePair("pin", password));
-		// Submit button is not contained within the form and thus cannot (should not) be found with the InputField matcher
-		postData.add(new BasicNameValuePair("commonlogin$loginLight", "Logga in"));
-		return new LoginPackage(urlopen, postData, this.lastResponse, LOGIN_URL);
+        urlopen = new Urllib(context);
+        Matcher matcher;
+        // Find "simple login" link
+        this.lastResponse = urlopen.open(LOGIN_URL);
+        this.currentPageType = PageType.LOGIN;
+        matcher = reSimpleLoginLink.matcher(this.lastResponse);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login link.");
+        }
+        // Visit login link
+        String link = BASE_URL + matcher.group(1);
+        this.lastResponse = urlopen.open(link);
+        this.currentPageType = PageType.SIMPLE_LOGIN;
+        matcher = reLoginFormContents.matcher(this.lastResponse);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login form.");
+        }
+        // Extract hidden fields
+        String formContents = matcher.group(1);
+        matcher = reNonTelInputField.matcher(formContents);
+        if (!matcher.find()) {
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " login fields.");
+        }
+        matcher.reset();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        while (matcher.find()) {
+            String name = matcher.group(2);
+            String value = matcher.group(3);
+            // The non-mobile page requires javascript, so we'd best pretend we have it
+            if ("JAVASCRIPT_DETECTED".equals(name)) {
+                value = "true";
+            }
+            postData.add(new BasicNameValuePair(name, value));
+        }
+        // Login information
+        postData.add(new BasicNameValuePair("userid", username));
+        postData.add(new BasicNameValuePair("pin", password));
+        // Submit button is not contained within the form and thus cannot (should not) be found with the InputField matcher
+        postData.add(new BasicNameValuePair("commonlogin$loginLight", "Logga in"));
+        return new LoginPackage(urlopen, postData, this.lastResponse, LOGIN_URL);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        this.lastResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        this.currentPageType = PageType.ENTRY;
+        if (this.lastResponse.contains("fel uppgifter")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException, IOException {
-		LoginPackage lp = preLogin();
-		this.lastResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		this.currentPageType = PageType.ENTRY;
-		if (this.lastResponse.contains("fel uppgifter")) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException, IOException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		// This puts us at PageType.ENTRY
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        // This puts us at PageType.ENTRY
         urlopen = login();
         String loanName;
 
-		// Add regular accounts
+        // Add regular accounts
         Matcher matcher = reAccountLink.matcher(this.lastResponse);
-		while (matcher.find()) {
-			accounts.add(new Account(
+        while (matcher.find()) {
+            accounts.add(new Account(
                     // Account name
-					Html.fromHtml(matcher.group(3)).toString().trim(),
-					// Balance
+                    Html.fromHtml(matcher.group(3)).toString().trim(),
+                    // Balance
                     Helpers.parseBalance(Html.fromHtml(matcher.group(5)).toString()),
                     // Account identifier - half censured account number: "************1234"
-					Html.fromHtml(matcher.group(4)).toString().trim()
-					));
-		}
+                    Html.fromHtml(matcher.group(4)).toString().trim()
+            ));
+        }
 
         // TODO: Code for funds
 
@@ -283,7 +325,7 @@ public class Nordea extends Bank {
                     "c:" + matcher.group(3),
                     -1L,
                     Account.CCARD
-                    ));
+            ));
         }
 
         goToPage(PageType.LOANS);
@@ -300,21 +342,21 @@ public class Nordea extends Bank {
             ));
         }
 
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
         super.updateComplete();
-		
+
         // Demo account to use with screenshots
         //accounts.add(new Account("Personkonto", Helpers.parseBalance("7953.37"), "1"));
         //accounts.add(new Account("Kapitalkonto", Helpers.parseBalance("28936.08"), "0"));
 
-	}
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
-		super.updateTransactions(account, urlopen);
+        super.updateTransactions(account, urlopen);
 
         int accType = account.getType();
         switch (accType) {
@@ -327,7 +369,7 @@ public class Nordea extends Bank {
             default:
                 break;
         }
-	}
+    }
 
     private void goToPage(int pageType) throws IOException {
         // Convenience method for going to an overview page
@@ -368,10 +410,11 @@ public class Nordea extends Bank {
         String link = null;
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
 
-        if(this.currentPageType != PageType.ENTRY && this.currentPageType != PageType.TRANSACTIONS) {
+        if (this.currentPageType != PageType.ENTRY
+                && this.currentPageType != PageType.TRANSACTIONS) {
             goToPage(PageType.ENTRY);
         }
-        if(currentPageType == PageType.ENTRY) {
+        if (currentPageType == PageType.ENTRY) {
             // Find the link to the transaction page for this account
             matcher = reAccountLink.matcher(this.lastResponse);
             while (matcher.find()) {
@@ -381,19 +424,21 @@ public class Nordea extends Bank {
                 }
             }
             if (link == null) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions link.");
+                throw new BankException(
+                        res.getText(R.string.unable_to_find).toString() + " transactions link.");
             }
-        }
-        else if(currentPageType == PageType.TRANSACTIONS) {
+        } else if (currentPageType == PageType.TRANSACTIONS) {
             // Find the account dropdown form
             matcher = reTransactionFormContents.matcher(this.lastResponse);
             if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" account form.");
+                throw new BankException(
+                        res.getText(R.string.unable_to_find).toString() + " account form.");
             }
             link = matcher.group(1);
             matcher = reNonTextInputField.matcher(matcher.group(2));
             if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" input fields.");
+                throw new BankException(
+                        res.getText(R.string.unable_to_find).toString() + " input fields.");
             }
             matcher.reset();
             // Input fields
@@ -407,23 +452,24 @@ public class Nordea extends Bank {
             // Account id
             matcher = reAccountSelect.matcher(this.lastResponse);
             if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" account selection.");
+                throw new BankException(
+                        res.getText(R.string.unable_to_find).toString() + " account selection.");
             }
             // Find account to switch to in dropdown
             matcher = reAccountOption.matcher(matcher.group(1));
             String id = null;
             while (matcher.find()) {
-                if(matcher.group(2).equals(account.getId())) {
+                if (matcher.group(2).equals(account.getId())) {
                     id = matcher.group(1);
                     break;
                 }
             }
             if (id == null) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" account id.");
+                throw new BankException(
+                        res.getText(R.string.unable_to_find).toString() + " account id.");
             }
             postData.add(new BasicNameValuePair("transactionaccount", id));
-        }
-        else {
+        } else {
             throw new BankException("This should never happen. If it does: Grats, you broke it.");
         }
 
@@ -470,7 +516,8 @@ public class Nordea extends Bank {
             }
         }
         if (link == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " transactions link.");
+            throw new BankException(
+                    res.getText(R.string.unable_to_find).toString() + " transactions link.");
         }
 
         this.lastResponse = urlopen.open(BASE_URL + link);
@@ -492,14 +539,21 @@ public class Nordea extends Bank {
             account.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
         }
     }
-	
-	private static class PageType {
-		public static final int LOGIN = 0;
-		public static final int SIMPLE_LOGIN = 1;
-		public static final int ENTRY = 2;
-		public static final int TRANSACTIONS = 3;
-		public static final int LOANS = 4;
-		public static final int CREDIT_CARDS = 5;
-		public static final int CREDIT_CARD_TRANSACTIONS = 6;
-	}
+
+    private static class PageType {
+
+        public static final int LOGIN = 0;
+
+        public static final int SIMPLE_LOGIN = 1;
+
+        public static final int ENTRY = 2;
+
+        public static final int TRANSACTIONS = 3;
+
+        public static final int LOANS = 4;
+
+        public static final int CREDIT_CARDS = 5;
+
+        public static final int CREDIT_CARD_TRANSACTIONS = 6;
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index d1702fe..ff94126 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -16,24 +16,23 @@
  */
 package com.liato.bankdroid.banking.banks.rikslunchen;
 
-import android.content.Context;
-import android.text.InputType;
-import android.text.TextUtils;
-
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.rikslunchen.model.Envelope;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
 import org.simpleframework.xml.Serializer;
 import org.simpleframework.xml.core.Persister;
 
+import android.content.Context;
+import android.text.InputType;
+import android.text.TextUtils;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -45,9 +44,13 @@ import eu.nullbyte.android.urllib.Urllib;
 public class Rikslunchen extends Bank {
 
     private static final String TAG = "Rikslunchen";
+
     private static final String NAME = "Rikslunchen";
+
     private static final String NAME_SHORT = "rikslunchen";
+
     private static final String URL = "http://www.rikslunchen.se/index.html";
+
     private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
 
     private String myResponse = "";
@@ -82,12 +85,16 @@ public class Rikslunchen extends Bank {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         try {
-            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
+            urlopen = new Urllib(context,
+                    CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
             urlopen.addHeader("Authorization", "basic Q0g6ODlAUHFqJGw4NyMjTVM=");
             urlopen.addHeader("SOAPAction", "");
             urlopen.addHeader("Content-Type", "text/xml;charset=UTF-8");
-            StringEntity body = new StringEntity(String.format("<v:Envelope xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:v=\"http://schemas.xmlsoap.org/soap/envelope/\"><v:Header /><v:Body><n0:getBalance id=\"o0\" c:root=\"1\" xmlns:n0=\"urn:PhoneService\"><cardNo i:type=\"d:string\">%s</cardNo></n0:getBalance></v:Body></v:Envelope>", username), "UTF-8");
-            InputStream is = urlopen.openStream("https://www.rikslunchen.se/rkchws/PhoneService", body, true);
+            StringEntity body = new StringEntity(String.format(
+                    "<v:Envelope xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:v=\"http://schemas.xmlsoap.org/soap/envelope/\"><v:Header /><v:Body><n0:getBalance id=\"o0\" c:root=\"1\" xmlns:n0=\"urn:PhoneService\"><cardNo i:type=\"d:string\">%s</cardNo></n0:getBalance></v:Body></v:Envelope>",
+                    username), "UTF-8");
+            InputStream is = urlopen.openStream("https://www.rikslunchen.se/rkchws/PhoneService",
+                    body, true);
 
             Serializer serializer = new Persister();
             Envelope resp = null;
@@ -97,14 +104,18 @@ public class Rikslunchen extends Bank {
                 throw new BankException(e.getMessage(), e);
             }
 
-            if (resp != null && resp.body != null && resp.body.fault != null && !TextUtils.isEmpty(resp.body.fault.faultstring)) {
+            if (resp != null && resp.body != null && resp.body.fault != null && !TextUtils.isEmpty(
+                    resp.body.fault.faultstring)) {
                 throw new LoginException(context.getString(R.string.invalid_card_number));
                 //faultString isn't always very descriptive
                 //throw new BankException(resp.body.fault.faultstring);
-            } else if (resp == null || resp.body == null || resp.body.getBalanceResponse == null || resp.body.getBalanceResponse.responseReturn == null || resp.body.getBalanceResponse.responseReturn.amount == null) {
+            } else if (resp == null || resp.body == null || resp.body.getBalanceResponse == null
+                    || resp.body.getBalanceResponse.responseReturn == null
+                    || resp.body.getBalanceResponse.responseReturn.amount == null) {
                 throw new LoginException(context.getString(R.string.invalid_card_number));
             }
-            BigDecimal balance = Helpers.parseBalance(resp.body.getBalanceResponse.responseReturn.amount);
+            BigDecimal balance = Helpers.parseBalance(
+                    resp.body.getBalanceResponse.responseReturn.amount);
             accounts.add(new Account("Rikslunchen", balance, "1"));
         } catch (UnsupportedEncodingException e) {
             throw new BankException(e.getMessage(), e);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
index 205bb92..36dc047 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
@@ -22,35 +22,40 @@ import org.simpleframework.xml.Root;
 
 @Root
 public class Envelope {
+
+    @Element(name = "Body")
+    public Body body;
+
     public static class Body {
+
+        @Element(required = false)
+        public GetBalanceResponse getBalanceResponse;
+
+        @Element(name = "Fault", required = false)
+        public Fault fault;
+
         public static class GetBalanceResponse {
+
+            @Element(name = "return")
+            public Return responseReturn;
+
             public static class Return {
+
                 @Element
                 public String amount;
 
                 @Element
                 public String lastTopUpDate;
             }
-
-            @Element(name="return")
-            public Return responseReturn;
         }
 
         public static class Fault {
+
             @Element
             public String faultcode;
 
             @Element
             public String faultstring;
         }
-
-        @Element(required=false)
-        public GetBalanceResponse getBalanceResponse;
-
-        @Element(name="Fault", required=false)
-        public Fault fault;
     }
-
-    @Element(name="Body")
-    public Body body;
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index 723f7c5..ae8d957 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -16,14 +16,9 @@
 
 package com.liato.bankdroid.banking.banks.seb;
 
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.seb.model.DEVID;
@@ -36,16 +31,20 @@ import com.liato.bankdroid.banking.banks.seb.model.VODB;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
 
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -57,18 +56,31 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SEB extends Bank {
+
     private static final String TAG = "SEB";
+
     private static final String NAME = "SEB";
+
     private static final String NAME_SHORT = "seb";
+
     private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx";
+
     private static final int BANKTYPE_ID = IBankTypes.SEB;
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
-    private Pattern reAccounts = Pattern.compile("/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile(
+            "/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*",
+            Pattern.CASE_INSENSITIVE);
+
+    private Pattern reTransactions = Pattern.compile(
+            "(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>",
+            Pattern.CASE_INSENSITIVE);
 
     private String response = null;
+
     private ObjectMapper mObjectMapper;
 
     public SEB(Context context) {
@@ -90,26 +102,32 @@ public class SEB extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_seb_web));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_seb_web));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://m.seb.se/");
         urlopen.setKeepAliveTimeout(5);
         //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
         postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
+        return new LoginPackage(urlopen, postData, response,
+                "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
     }
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getClientCertificate(context, R.raw.cert_client_seb, "openbankdata"), CertificateReader.getCertificates(context, R.raw.cert_seb));
+        urlopen = new Urllib(context, CertificateReader
+                .getClientCertificate(context, R.raw.cert_client_seb, "openbankdata"),
+                CertificateReader.getCertificates(context, R.raw.cert_seb));
         urlopen.setFollowRedirects(false);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
-        HttpResponse hr = urlopen.openAsHttpResponse("https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw", postData, true);
+        HttpResponse hr = urlopen.openAsHttpResponse(
+                "https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw",
+                postData, true);
         if (hr.getStatusLine().getStatusCode() == 200) {
             throw new LoginException(res.getString(R.string.invalid_username_password));
         } else if (hr.getStatusLine().getStatusCode() != 302) {
@@ -123,7 +141,8 @@ public class SEB extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
@@ -147,7 +166,9 @@ public class SEB extends Bank {
 
         try {
             HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(sessionRequest));
-            HttpResponse hr = urlopen.openAsHttpResponse("https://mP.seb.se/1000/ServiceFactory/PC_BANK/PC_BankAktivera01Session01.asmx/Execute", e, true);
+            HttpResponse hr = urlopen.openAsHttpResponse(
+                    "https://mP.seb.se/1000/ServiceFactory/PC_BANK/PC_BankAktivera01Session01.asmx/Execute",
+                    e, true);
             hr.getEntity().getContent();
 
         } catch (UnsupportedEncodingException e1) {
@@ -156,7 +177,6 @@ public class SEB extends Bank {
             e1.printStackTrace();
         }
 
-
 //        {
 //            "request": {
 //            "ResultInfo": null,
@@ -238,7 +258,9 @@ public class SEB extends Bank {
 
         //No transaction history for loans, funds and credit cards.
         int accType = account.getType();
-        if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
+        if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) {
+            return;
+        }
 
 //        Matcher matcher;
 //        try {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
index 084bdc8..fb070a8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
@@ -5,18 +5,24 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.io.Serializable;
 
 public class DEVID implements Serializable {
+
     private static final long serialVersionUID = -8706994448508325149L;
 
     @JsonProperty("APPLICATION_VERSION")
     private String applicationVersion;
+
     @JsonProperty("OS_NAME")
     private String osName;
+
     @JsonProperty("MODEL")
     private String model;
+
     @JsonProperty("MANUFACTURER")
     private String manufacturer;
+
     @JsonProperty("OS_VERSION")
     private String osVersion;
+
     @JsonProperty("APPLICATION_NAME")
     private String applicationName;
 
@@ -25,7 +31,8 @@ public class DEVID implements Serializable {
 
     }
 
-    public DEVID(String model, String applicationName, String applicationVersion, String osName, String osVersion, String manufacturer) {
+    public DEVID(String model, String applicationName, String applicationVersion, String osName,
+            String osVersion, String manufacturer) {
         this.model = model;
         this.applicationName = applicationName;
         this.osVersion = osVersion;
@@ -99,5 +106,4 @@ public class DEVID implements Serializable {
     }
 
 
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
index 018e5ae..38a42f4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
@@ -8,8 +8,10 @@ public class HWINFO implements Serializable {
 
     @JsonProperty("LONGITUDE_DECIMAL")
     private String longitudeDecimal;
+
     @JsonProperty("LATITUDE_DECIMAL")
     private String latitudeDecimal;
+
     @JsonProperty("COUNTRY_PREFIX")
     private long countryPrefix;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
index aee3ad3..4294369 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
@@ -1,7 +1,5 @@
 package com.liato.bankdroid.banking.banks.seb.model;
 
-import com.fasterxml.jackson.annotation.JsonAnyGetter;
-import com.fasterxml.jackson.annotation.JsonAnySetter;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import java.io.Serializable;
@@ -12,12 +10,16 @@ public class Request implements Serializable {
 
     @JsonProperty("ResultInfo")
     private Object resultInfo;
+
     @JsonProperty("VODB")
     private VODB vODB;
+
     @JsonProperty("ServiceInput")
     private List<ServiceInput> serviceInput = new ArrayList<ServiceInput>();
+
     @JsonProperty("UserCredentials")
     private UserCredentials userCredentials;
+
     @JsonProperty("ServiceInfo")
     private Object serviceInfo;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
index 819d30a..6516f9f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
@@ -10,10 +10,13 @@ public class ServiceInput implements Serializable {
 
     @JsonProperty("Condition")
     private String condition;
+
     @JsonProperty("VariableNamePossibleValues")
     private List<Object> variableNamePossibleValues = new ArrayList<Object>();
+
     @JsonProperty("VariableName")
     private String variableName;
+
     @JsonProperty("VariableValue")
     private String variableValue;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
index f9d629f..8a03e66 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
@@ -6,14 +6,19 @@ public class UserCredentials {
 
     @JsonProperty("ApplicationName")
     private String applicationName;
+
     @JsonProperty("WorkstationID")
     private String workstationID;
+
     @JsonProperty("LoggedOnUser")
     private String loggedOnUser;
+
     @JsonProperty("AuthMethod")
     private String authMethod;
+
     @JsonProperty("UserId")
     private String userId;
+
     @JsonProperty("Password")
     private String password;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
index 7e0df07..2ddceff 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
@@ -7,20 +7,27 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class VODB implements Serializable {
+
     private static final long serialVersionUID = 6084093222386932965L;
 
     @JsonProperty("USRINF01")
     private Object usrinf01;
+
     @JsonProperty("DBZV160")
     private List<Object> dbzv160 = new ArrayList<Object>();
+
     @JsonProperty("DEVID01")
     private DEVID devid01;
+
     @JsonProperty("HWINFO01")
     private HWINFO hWINFO01;
+
     @JsonProperty("CBEW501")
     private List<Object> cbew501 = new ArrayList<Object>();
+
     @JsonProperty("DBZV170")
     private List<Object> dbzv170 = new ArrayList<Object>();
+
     @JsonProperty("CBEW502")
     private List<Object> cbew502 = new ArrayList<Object>();
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index adbe42c..0f45e00 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -16,15 +16,9 @@
 
 package com.liato.bankdroid.banking.banks.sebkort;
 
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.text.TextUtils;
-
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
@@ -38,11 +32,16 @@ import com.liato.bankdroid.banking.banks.sebkort.model.response.UserResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.text.TextUtils;
+
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -55,17 +54,29 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class SEBKortBase extends Bank {
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
     private static final boolean STATIC_BALANCE = true;
+
     private ObjectMapper mObjectMapper = new ObjectMapper();
+
     private String response = null;
+
     private String mProviderPart;
+
     private String mProdgroup;
+
     private String mApiBase;
+
     private int[] mCertificates;
+
     private BasicNameValuePair mParamsTarget;
+
     private BasicNameValuePair mParamsErrorTarget;
+
     private Map<Account, String> mBillingUnitIds = new HashMap<Account, String>();
 
 
@@ -73,12 +84,14 @@ public abstract class SEBKortBase extends Bank {
         this(context, providerPart, prodgroup, "secure.sebkort.com", new int[]{R.raw.cert_sebkort});
     }
 
-    public SEBKortBase(Context context, String providerPart, String prodgroup, String apiBase, int[] certificates) {
+    public SEBKortBase(Context context, String providerPart, String prodgroup, String apiBase,
+            int[] certificates) {
         super(context);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
-        super.URL = String.format("https://%s/nis/m/%s/external/t/login/index", apiBase, providerPart);
+        super.URL = String
+                .format("https://%s/nis/m/%s/external/t/login/index", apiBase, providerPart);
         mProviderPart = providerPart;
         mProdgroup = prodgroup;
         mApiBase = apiBase;
@@ -89,13 +102,15 @@ public abstract class SEBKortBase extends Bank {
         mParamsErrorTarget = new BasicNameValuePair("errorTarget", URL);
     }
 
-    public SEBKortBase(String username, String password, Context context, String url, String prodgroup)
+    public SEBKortBase(String username, String password, Context context, String url,
+            String prodgroup)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context, url, prodgroup);
         this.update(username, password);
     }
 
-    public SEBKortBase(String username, String password, Context context, String url, String prodgroup, String apiBase, int[] certificates)
+    public SEBKortBase(String username, String password, Context context, String url,
+            String prodgroup, String apiBase, int[] certificates)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context, url, prodgroup, apiBase, certificates);
         this.update(username, password);
@@ -105,7 +120,8 @@ public abstract class SEBKortBase extends Bank {
     protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, mCertificates));
         //Get required cookies
-        response = urlopen.open(String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
+        response = urlopen.open(String
+                .format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.clear();
         postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
@@ -117,25 +133,33 @@ public abstract class SEBKortBase extends Bank {
         postData.add(new BasicNameValuePair("mProdgroup", mProdgroup));
         postData.add(mParamsTarget);
         postData.add(mParamsErrorTarget);
-        return new LoginPackage(urlopen, postData, response, String.format("https://%s/auth4/Authentication/select.jsp", mApiBase));
+        return new LoginPackage(urlopen, postData, response,
+                String.format("https://%s/auth4/Authentication/select.jsp", mApiBase));
     }
 
     @Override
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         urlopen.addHeader("Origin", String.format("https://%s", mApiBase));
-        urlopen.addHeader("Referer", String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
+        urlopen.addHeader("Referer",
+                String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase,
+                        mProviderPart));
         urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
         List<NameValuePair> postData = lp.getPostData();
         postData.remove(mParamsTarget);
         postData.remove(mParamsErrorTarget);
-        postData.add(new BasicNameValuePair("target", String.format("/nis/m/%s/login/loginSuccess", mProviderPart)));
-        postData.add(new BasicNameValuePair("errorTarget", String.format("/nis/m/%s/external/login/loginError", mProviderPart)));
-
-        LoginResponse r = mObjectMapper.readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
-                LoginResponse.class);
+        postData.add(new BasicNameValuePair("target",
+                String.format("/nis/m/%s/login/loginSuccess", mProviderPart)));
+        postData.add(new BasicNameValuePair("errorTarget",
+                String.format("/nis/m/%s/external/login/loginError", mProviderPart)));
+
+        LoginResponse r = mObjectMapper
+                .readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
+                        LoginResponse.class);
         if ("Failure".equalsIgnoreCase(r.getReturnCode())) {
-            throw new LoginException(!TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString() : res.getText(R.string.invalid_username_password).toString());
+            throw new LoginException(
+                    !TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString()
+                            : res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
@@ -143,27 +167,40 @@ public abstract class SEBKortBase extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)), UserResponse.class);
-        BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)), BillingUnitsResponse.class);
+        UserResponse ur = mObjectMapper.readValue(urlopen.openStream(
+                String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)),
+                UserResponse.class);
+        BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(
+                String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)),
+                BillingUnitsResponse.class);
 
         boolean multipleAccounts = br.getBody().size() > 1;
         for (BillingUnit bu : br.getBody()) {
-            Account account = new Account(formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp", multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
+            Account account = new Account(
+                    formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp",
+                            multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()),
+                    bu.getArrangementNumber());
             account.setType(Account.CCARD);
             account.setCurrency(currency);
             mBillingUnitIds.put(account, bu.getBillingUnitId());
             accounts.add(account);
             balance = balance.add(account.getBalance());
-            account = new Account(formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts), Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
+            account = new Account(
+                    formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts),
+                    Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
             account.setType(Account.OTHER);
             account.setAliasfor(bu.getArrangementNumber());
             account.setCurrency(currency);
             accounts.add(account);
-            account = new Account(formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts), Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
+            account = new Account(
+                    formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts),
+                    Helpers.parseBalance(bu.getCreditAmountNumber()),
+                    bu.getArrangementNumber() + "_3");
             account.setType(Account.OTHER);
             account.setAliasfor(bu.getArrangementNumber());
             account.setCurrency(currency);
@@ -176,7 +213,8 @@ public abstract class SEBKortBase extends Bank {
         super.updateComplete();
     }
 
-    private String formatAccountName(String accountNumber, String name, boolean includeAccountNnumber) {
+    private String formatAccountName(String accountNumber, String name,
+            boolean includeAccountNnumber) {
         return includeAccountNnumber ? String.format("%s (%s)", accountNumber, name) : name;
     }
 
@@ -184,14 +222,23 @@ public abstract class SEBKortBase extends Bank {
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
-        if (account.getType() != Account.CCARD) return;
+        if (account.getType() != Account.CCARD) {
+            return;
+        }
 
-        PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/pendingTransactions/%s", mApiBase, mProviderPart, mBillingUnitIds.get(account))), PendingTransactionsResponse.class);
+        PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(
+                String.format("https://%s/nis/m/%s/a/pendingTransactions/%s", mApiBase,
+                        mProviderPart, mBillingUnitIds.get(account))),
+                PendingTransactionsResponse.class);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         for (CardGroup cg : r.getBody().getCardGroups()) {
             for (TransactionGroup tg : cg.getTransactionGroups()) {
-                for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg.getTransactions()) {
-                    transactions.add(new Transaction(Helpers.formatDate(new Date(t.getOriginalAmountDateDate())), t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate(), account.getCurrency()));
+                for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg
+                        .getTransactions()) {
+                    transactions.add(new Transaction(
+                            Helpers.formatDate(new Date(t.getOriginalAmountDateDate())),
+                            t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate(),
+                            account.getCurrency()));
                 }
             }
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
index 9ad2aa5..31568d7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
@@ -7,24 +7,43 @@ import java.io.Serializable;
 import java.util.ArrayList;
 
 public class BillingUnit implements Serializable {
+
     private static final long serialVersionUID = 335801680600207389L;
+
     private String mUnInvoicedAmount;
+
     private boolean mShowCreditAmount;
+
     private String mArrangementId;
+
     private ArrayList<Contract> mContracts = new ArrayList<Contract>();
+
     private String mCutOffDate;
+
     private String mInterestPercentage;
+
     private String mCreditAmount;
+
     private String mLatestPaymentDate;
+
     private boolean mShowInvoices;
+
     private String mCreditAmountNumber;
+
     private String mBillingUnitName;
+
     private String mBillingUnitId;
+
     private String mDisposableAmount;
+
     private String mBalance;
+
     private boolean mFinanceServiceAllowed;
+
     private String mLatestPaymentAmount;
+
     private String mArrangementNumber;
+
     private String mNextInvoiceDate;
 
     @JsonProperty("unInvoicedAmount")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
index bdb0a1d..0f9edfc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
@@ -8,12 +8,17 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class CardGroup implements Serializable {
+
     private static final long serialVersionUID = 4603347903479018508L;
 
     private List<TransactionGroup> mTransactionGroups = new ArrayList<TransactionGroup>();
+
     private double mTotalNumber;
+
     private String mTotal;
+
     private String mMaskedCardNumber;
+
     private String mNameOnCard;
 
     @JsonProperty("transactionGroups")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
index 31658ce..ab4fcf4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
@@ -6,10 +6,15 @@ import com.fasterxml.jackson.annotation.JsonSetter;
 import java.io.Serializable;
 
 public class Contract implements Serializable {
+
     private static final long serialVersionUID = 9210413430068677151L;
+
     private String mUnInvoicedAmount;
+
     private String mContractName;
+
     private String mCreditAmount;
+
     private String mContractId;
 
     @JsonProperty("unInvoicedAmount")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
index 04c031c..2f71e1d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
@@ -8,14 +8,23 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class PendingTransactions implements Serializable {
+
     private static final long serialVersionUID = 8675073239578979403L;
+
     private double mTotalNumber;
+
     private boolean mMoreDataExists;
+
     private List<CardGroup> mCobrandCardGroups = new ArrayList<CardGroup>();
+
     private String mReservedAmount;
+
     private String mReservedAmountNumber;
+
     private List<CardGroup> mCardGroups = new ArrayList<CardGroup>();
+
     private List<TransactionGroup> mTransactionGroups = new ArrayList<TransactionGroup>();
+
     private String mTotal;
 
     @JsonProperty("totalNumber")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
index 7e89bf5..a9da3af 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
@@ -6,21 +6,35 @@ import com.fasterxml.jackson.annotation.JsonSetter;
 import java.io.Serializable;
 
 public class Transaction implements Serializable {
+
     private static final long serialVersionUID = 2810644466680342679L;
 
     private String mCity;
+
     private String mRefTransactionId;
+
     private String mDescription;
+
     private String mExchangeRateDescription;
+
     private String mOriginalAmountDate;
+
     private String mOriginalAmountOrVat;
+
     private String mPostingDate;
+
     private long mPostingDateDate;
+
     private String mCurrency;
+
     private String mAmount;
+
     private double mAmountNumber;
+
     private long mTransactionId;
+
     private String mOriginalAmountOrVatNumber;
+
     private long mOriginalAmountDateDate;
 
     @JsonProperty("city")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
index a22f47e..73a9a2a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
@@ -8,11 +8,17 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class TransactionGroup implements Serializable {
+
     private static final long serialVersionUID = 5011424262690542196L;
+
     private String mTotal;
+
     private String mType;
+
     private double mTotalNumber;
+
     private List<Transaction> mTransactions = new ArrayList<Transaction>();
+
     private String mTitle;
 
     @JsonProperty("total")
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
index 969fe4c..e433d55 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
@@ -6,27 +6,40 @@ import com.fasterxml.jackson.annotation.JsonSetter;
 import java.io.Serializable;
 
 public class User implements Serializable {
+
     private static final long serialVersionUID = -6588506336066035322L;
 
     private String mSurName;
+
     private String mFirstName;
+
     private boolean mPasswordAuthentication;
+
     private boolean mCoBrowse;
+
     private int mAuthenticationTypeId;
+
     private String mPhone;
+
     private boolean mHsu;
+
     private String mEmail;
+
     private boolean mOtpAuthentication;
 
+    @JsonProperty("surName")
+    public String getSurName() {
+        return mSurName;
+    }
 
     @JsonSetter("surName")
     public void setSurName(String s) {
         mSurName = s;
     }
 
-    @JsonProperty("surName")
-    public String getSurName() {
-        return mSurName;
+    @JsonProperty("firstName")
+    public String getFirstName() {
+        return mFirstName;
     }
 
     @JsonSetter("firstName")
@@ -34,9 +47,9 @@ public class User implements Serializable {
         mFirstName = f;
     }
 
-    @JsonProperty("firstName")
-    public String getFirstName() {
-        return mFirstName;
+    @JsonProperty("passwordAuthentication")
+    public boolean getPasswordAuthentication() {
+        return mPasswordAuthentication;
     }
 
     @JsonSetter("passwordAuthentication")
@@ -44,9 +57,9 @@ public class User implements Serializable {
         mPasswordAuthentication = p;
     }
 
-    @JsonProperty("passwordAuthentication")
-    public boolean getPasswordAuthentication() {
-        return mPasswordAuthentication;
+    @JsonProperty("coBrowse")
+    public boolean getCoBrowse() {
+        return mCoBrowse;
     }
 
     @JsonSetter("coBrowse")
@@ -54,9 +67,9 @@ public class User implements Serializable {
         mCoBrowse = c;
     }
 
-    @JsonProperty("coBrowse")
-    public boolean getCoBrowse() {
-        return mCoBrowse;
+    @JsonProperty("authenticationTypeId")
+    public int getAuthenticationTypeId() {
+        return mAuthenticationTypeId;
     }
 
     @JsonSetter("authenticationTypeId")
@@ -64,9 +77,9 @@ public class User implements Serializable {
         mAuthenticationTypeId = a;
     }
 
-    @JsonProperty("authenticationTypeId")
-    public int getAuthenticationTypeId() {
-        return mAuthenticationTypeId;
+    @JsonProperty("phone")
+    public String getPhone() {
+        return mPhone;
     }
 
     @JsonSetter("phone")
@@ -74,9 +87,9 @@ public class User implements Serializable {
         mPhone = p;
     }
 
-    @JsonProperty("phone")
-    public String getPhone() {
-        return mPhone;
+    @JsonProperty("hsu")
+    public boolean getHsu() {
+        return mHsu;
     }
 
     @JsonSetter("hsu")
@@ -84,9 +97,9 @@ public class User implements Serializable {
         mHsu = h;
     }
 
-    @JsonProperty("hsu")
-    public boolean getHsu() {
-        return mHsu;
+    @JsonProperty("email")
+    public String getEmail() {
+        return mEmail;
     }
 
     @JsonSetter("email")
@@ -94,9 +107,9 @@ public class User implements Serializable {
         mEmail = e;
     }
 
-    @JsonProperty("email")
-    public String getEmail() {
-        return mEmail;
+    @JsonProperty("otpAuthentication")
+    public boolean getOtpAuthentication() {
+        return mOtpAuthentication;
     }
 
     @JsonSetter("otpAuthentication")
@@ -104,9 +117,4 @@ public class User implements Serializable {
         mOtpAuthentication = o;
     }
 
-    @JsonProperty("otpAuthentication")
-    public boolean getOtpAuthentication() {
-        return mOtpAuthentication;
-    }
-
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
index e6eb465..95a074f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
@@ -6,32 +6,55 @@ import com.fasterxml.jackson.annotation.JsonSetter;
 import java.io.Serializable;
 
 public abstract class BaseResponse<T> implements Serializable {
+
     private static final long serialVersionUID = 2771913870986291964L;
 
     private String mErrorCode;
+
     private String mMessage;
+
     private String mReturnCode;
+
     private T mBody;
 
+    @JsonProperty("errorCode")
+    public String getErrorCode() {
+        return mErrorCode;
+    }
 
     @JsonSetter("errorCode")
-    public void setErrorCode(String e) { mErrorCode = e; }
-    @JsonProperty("errorCode")
-    public String getErrorCode() { return mErrorCode; }
+    public void setErrorCode(String e) {
+        mErrorCode = e;
+    }
 
-    @JsonSetter("body")
-    public void setBody(T b) { mBody = b; }
     @JsonProperty("body")
-    public T getBody() { return mBody; }
+    public T getBody() {
+        return mBody;
+    }
+
+    @JsonSetter("body")
+    public void setBody(T b) {
+        mBody = b;
+    }
 
-    @JsonSetter("message")
-    public void setMessage(String m) { mMessage = m; }
     @JsonProperty("message")
-    public String getMessage() { return mMessage; }
+    public String getMessage() {
+        return mMessage;
+    }
+
+    @JsonSetter("message")
+    public void setMessage(String m) {
+        mMessage = m;
+    }
 
-    @JsonSetter("returnCode")
-    public void setReturnCode(String r) { mReturnCode = r; }
     @JsonProperty("returnCode")
-    public String getReturnCode() { return mReturnCode; }
+    public String getReturnCode() {
+        return mReturnCode;
+    }
+
+    @JsonSetter("returnCode")
+    public void setReturnCode(String r) {
+        mReturnCode = r;
+    }
 
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
index a09b7a3..5e14eb1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
@@ -5,5 +5,6 @@ import com.liato.bankdroid.banking.banks.sebkort.model.BillingUnit;
 import java.util.ArrayList;
 
 public class BillingUnitsResponse extends BaseResponse<ArrayList<BillingUnit>> {
+
     private static final long serialVersionUID = 2004033024178420458L;
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
index 2759db9..f3d6977 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
@@ -1,5 +1,6 @@
 package com.liato.bankdroid.banking.banks.sebkort.model.response;
 
 public class LoginResponse extends BaseResponse<Object> {
+
     private static final long serialVersionUID = -5831397352860729105L;
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
index 93df752..ed9b9e7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
@@ -3,5 +3,6 @@ package com.liato.bankdroid.banking.banks.sebkort.model.response;
 import com.liato.bankdroid.banking.banks.sebkort.model.PendingTransactions;
 
 public class PendingTransactionsResponse extends BaseResponse<PendingTransactions> {
+
     private static final long serialVersionUID = 3753708966368822328L;
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
index 6308f42..705c27c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
@@ -4,5 +4,6 @@ import com.liato.bankdroid.banking.banks.sebkort.model.User;
 
 
 public class UserResponse extends BaseResponse<User> {
+
     private static final long serialVersionUID = -7005608413740529742L;
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index d4befe8..148edc8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -1,16 +1,8 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Log;
-
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankChoice;
@@ -27,14 +19,21 @@ import com.liato.bankdroid.banking.banks.swedbank.model.profile.ProfileResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.utils.Installation;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.protocol.HTTP;
 
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -51,13 +50,18 @@ import eu.nullbyte.android.urllib.HttpMethod;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class AbstractSwedbank extends Bank {
+
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+
     private static final boolean WEB_VIEW_ENABLED = false;
 
-    private static final String API_BASE = "https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/";
+    private static final String API_BASE
+            = "https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/";
 
     private ObjectMapper mObjectMapper = new ObjectMapper();
+
     private Map<String, String> mIdMap = new HashMap<String, String>();
 
     public AbstractSwedbank(Context context) {
@@ -79,11 +83,12 @@ public abstract class AbstractSwedbank extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_swedbank));
-        urlopen.addHeader("Authorization",getAuthenticationHeader());
-        urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
-        urlopen.addHeader("Accept","application/json");
-        return new LoginPackage(urlopen,null,null,getResourceUri("identification/personalcode"));
+        urlopen = new Urllib(context,
+                CertificateReader.getCertificates(context, R.raw.cert_swedbank));
+        urlopen.addHeader("Authorization", getAuthenticationHeader());
+        urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
+        urlopen.addHeader("Accept", "application/json");
+        return new LoginPackage(urlopen, null, null, getResourceUri("identification/personalcode"));
     }
 
     @Override
@@ -91,17 +96,20 @@ public abstract class AbstractSwedbank extends Bank {
         HttpResponse httpResponse = null;
         try {
             LoginPackage lp = preLogin();
-            httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), new StringEntity(objectAsJson(new PersonalCodeRequest(username, password)), HTTP.UTF_8), true);
+            httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(),
+                    new StringEntity(objectAsJson(new PersonalCodeRequest(username, password)),
+                            HTTP.UTF_8), true);
             int responseCode = httpResponse.getStatusLine().getStatusCode();
-            if(responseCode == 201) {
+            if (responseCode == 201) {
                 return urlopen;
-            } else if(responseCode == 401 || responseCode == 400) {
+            } else if (responseCode == 401 || responseCode == 400) {
                 throw new LoginException(res.getText(
                         R.string.invalid_username_password).toString());
             } else if (responseCode == 503) {
                 String errorMessage = null;
                 try {
-                    ErrorResponse er = readJsonValue(httpResponse.getEntity().getContent(), ErrorResponse.class);
+                    ErrorResponse er = readJsonValue(httpResponse.getEntity().getContent(),
+                            ErrorResponse.class);
                     StringBuilder sb = new StringBuilder();
                     for (List<ErrorMessage> ems : er.getErrorMessages().values()) {
                         for (ErrorMessage em : ems) {
@@ -112,12 +120,13 @@ public abstract class AbstractSwedbank extends Bank {
                 } catch (BankException e) {
                     //Ignore json parse errors and show generic server error message
                 }
-                throw new BankException(TextUtils.isEmpty(errorMessage) ? context.getString(R.string.server_error_try_again) : errorMessage);
+                throw new BankException(TextUtils.isEmpty(errorMessage) ? context
+                        .getString(R.string.server_error_try_again) : errorMessage);
             } else {
                 throw new BankException("");
             }
         } finally {
-            if(httpResponse != null) {
+            if (httpResponse != null) {
                 HttpEntity httpEntity = httpResponse.getEntity();
                 if (httpEntity != null) {
                     try {
@@ -133,7 +142,8 @@ public abstract class AbstractSwedbank extends Bank {
     @Override
     public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
@@ -141,18 +151,20 @@ public abstract class AbstractSwedbank extends Bank {
         ProfileResponse profileResponse = getAvailableProfiles();
         setDefaultProfile(getBankId(profileResponse.getBanks()));
 
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/overview"), false);
-        if(httpResponse.getStatusLine().getStatusCode() != 200) {
+        HttpResponse httpResponse = urlopen
+                .openAsHttpResponse(getResourceUri("engagement/overview"), false);
+        if (httpResponse.getStatusLine().getStatusCode() != 200) {
             throw new BankException(httpResponse.getStatusLine().toString());
         }
 
-        OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),OverviewResponse.class);
-        addAccounts(overviewResponse.getTransactionAccounts(),Account.REGULAR);
-        addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
-        addAccounts(overviewResponse.getTransactionDisposalAccounts(),Account.REGULAR);
-        addAccounts(overviewResponse.getSavingDisposalAccounts(),Account.REGULAR);
+        OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),
+                OverviewResponse.class);
+        addAccounts(overviewResponse.getTransactionAccounts(), Account.REGULAR);
+        addAccounts(overviewResponse.getSavingAccounts(), Account.REGULAR);
+        addAccounts(overviewResponse.getTransactionDisposalAccounts(), Account.REGULAR);
+        addAccounts(overviewResponse.getSavingDisposalAccounts(), Account.REGULAR);
         addCardAccounts(overviewResponse.getCardAccounts());
-        addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
+        addAccounts(overviewResponse.getLoanAccounts(), Account.LOANS);
         if (this.accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
@@ -163,20 +175,20 @@ public abstract class AbstractSwedbank extends Bank {
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
             BankException, IOException {
         super.updateTransactions(account, urlopen);
-        if(account.getType() == Account.CCARD) {
+        if (account.getType() == Account.CCARD) {
             updateCreditCardTransactions(account, urlopen);
             return;
-        }
-        else if(account.getType() != Account.REGULAR) {
+        } else if (account.getType() != Account.REGULAR) {
             return;
-        }
-        else if(mIdMap.get(account.getId()) == null) {
+        } else if (mIdMap.get(account.getId()) == null) {
             return;
         }
 
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+mIdMap.get(account.getId())),false);
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(
+                getResourceUri("engagement/transactions/" + mIdMap.get(account.getId())), false);
 
-        TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(), TransactionsResponse.class);
+        TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(),
+                TransactionsResponse.class);
         List<Transaction> transactions = new ArrayList<Transaction>();
         transactions.addAll(transformTransactions(response.getTransactions()));
         transactions.addAll(transformTransactions(response.getReservedTransactions()));
@@ -186,8 +198,9 @@ public abstract class AbstractSwedbank extends Bank {
     @Override
     public void closeConnection() {
         try {
-            HttpResponse response = urlopen.openAsHttpResponse(getResourceUri("identification/logout"), HttpMethod.PUT);
-        } catch(IOException e) {
+            HttpResponse response = urlopen
+                    .openAsHttpResponse(getResourceUri("identification/logout"), HttpMethod.PUT);
+        } catch (IOException e) {
             //Ignore logout exceptions
         } finally {
             super.closeConnection();
@@ -196,30 +209,34 @@ public abstract class AbstractSwedbank extends Bank {
 
     private void updateCreditCardTransactions(Account account, Urllib urlopen) throws BankException,
             IOException {
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/cardaccount/"+mIdMap.get(account.getId())),false);
-        if(httpResponse.getStatusLine().getStatusCode() != 200) {
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(
+                getResourceUri("engagement/cardaccount/" + mIdMap.get(account.getId())), false);
+        if (httpResponse.getStatusLine().getStatusCode() != 200) {
             Log.i(TAG, "Couldn't find transactions for creditcard");
             account.setTransactions(Collections.<Transaction>emptyList());
             return;
         }
-        CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),CardAccountResponse.class);
+        CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),
+                CardAccountResponse.class);
         List<Transaction> transactions = new ArrayList<Transaction>();
         transactions.addAll(transformCardTransactions(response.getTransactions()));
         transactions.addAll(transformCardTransactions(response.getReservedTransactions()));
         account.setTransactions(transactions);
     }
 
-    private List<Transaction> transformTransactions(List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {
+    private List<Transaction> transformTransactions(
+            List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {
         List<Transaction> transactionList = new ArrayList<Transaction>();
-        for(com.liato.bankdroid.banking.banks.swedbank.model.Transaction transaction : transactions) {
-            transactionList.add(new Transaction(transaction.getDate(),transaction.getDescription(),transaction.getAmount(),transaction.getCurrency()));
+        for (com.liato.bankdroid.banking.banks.swedbank.model.Transaction transaction : transactions) {
+            transactionList.add(new Transaction(transaction.getDate(), transaction.getDescription(),
+                    transaction.getAmount(), transaction.getCurrency()));
         }
         return transactionList;
     }
 
     private List<Transaction> transformCardTransactions(List<CardTransaction> transactions) {
         List<Transaction> transactionList = new ArrayList<Transaction>();
-        for(CardTransaction transaction : transactions) {
+        for (CardTransaction transaction : transactions) {
             transactionList.add(new Transaction(transaction.getDate(),
                     transaction.getDescription(),
                     transaction.getLocalAmount().getAmount(),
@@ -228,14 +245,20 @@ public abstract class AbstractSwedbank extends Bank {
         return transactionList;
     }
 
-    private ProfileResponse getAvailableProfiles() throws IOException, BankException, LoginException {
+    private ProfileResponse getAvailableProfiles()
+            throws IOException, BankException, LoginException {
         HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/"), false);
         if (httpResponse.getStatusLine().getStatusCode() == 200) {
-            ProfileResponse response = readJsonValue(httpResponse.getEntity().getContent(), ProfileResponse.class);
-            if(response.getBanks().isEmpty()) {
-                String provider = response.isSwedbankProfile() ? "Swedbank" : response.isSavingbankProfile() ? "Sparbankerna" : null;
-                if(provider != null) {
-                    throw new LoginException("You are trying to connect an account from " + provider + " to the " + NAME + " bank. Please use the " + provider + " bank instead.");
+            ProfileResponse response = readJsonValue(httpResponse.getEntity().getContent(),
+                    ProfileResponse.class);
+            if (response.getBanks().isEmpty()) {
+                String provider = response.isSwedbankProfile() ? "Swedbank"
+                        : response.isSavingbankProfile() ? "Sparbankerna" : null;
+                if (provider != null) {
+                    throw new LoginException(
+                            "You are trying to connect an account from " + provider + " to the "
+                                    + NAME + " bank. Please use the " + provider
+                                    + " bank instead.");
                 } else {
                     throw new BankException("No profiles available.");
                 }
@@ -246,40 +269,46 @@ public abstract class AbstractSwedbank extends Bank {
     }
 
     private void setDefaultProfile(String bankId) throws IOException, BankException {
-        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/private/" + bankId), true);
+        HttpResponse httpResponse = urlopen
+                .openAsHttpResponse(getResourceUri("profile/private/" + bankId), true);
         httpResponse.getEntity().consumeContent();
         if (httpResponse.getStatusLine().getStatusCode() != 201) {
             throw new BankException("Could not set the default profile.");
         }
     }
 
-    private String getBankId(List<com.liato.bankdroid.banking.banks.swedbank.model.Bank> bankList) throws BankChoiceException {
+    private String getBankId(List<com.liato.bankdroid.banking.banks.swedbank.model.Bank> bankList)
+            throws BankChoiceException {
         String bankId = getExtras();
-        if(bankId != null && !bankId.isEmpty()) {
+        if (bankId != null && !bankId.isEmpty()) {
             return bankId;
         }
-        if(bankList.size() > 1) {
+        if (bankList.size() > 1) {
             ArrayList<BankChoice> banks = new ArrayList<BankChoice>();
-            for(com.liato.bankdroid.banking.banks.swedbank.model.Bank bank : bankList) {
+            for (com.liato.bankdroid.banking.banks.swedbank.model.Bank bank : bankList) {
                 banks.add(new BankChoice(bank.getName(), bank.getBankId()));
             }
-            throw new BankChoiceException("Select a bank.",banks);
+            throw new BankChoiceException("Select a bank.", banks);
         }
         return bankList.get(0).getBankId();
     }
 
-    private void addAccounts(List<com.liato.bankdroid.banking.banks.swedbank.model.Account> accountList, int accountType) {
-        for(com.liato.bankdroid.banking.banks.swedbank.model.Account account : accountList) {
-            Account bankdroidAccount = new Account(account.getName(), account.getBalance(), account.getFullyFormattedNumber(), accountType,account.getCurrency());
+    private void addAccounts(
+            List<com.liato.bankdroid.banking.banks.swedbank.model.Account> accountList,
+            int accountType) {
+        for (com.liato.bankdroid.banking.banks.swedbank.model.Account account : accountList) {
+            Account bankdroidAccount = new Account(account.getName(), account.getBalance(),
+                    account.getFullyFormattedNumber(), accountType, account.getCurrency());
             mIdMap.put(bankdroidAccount.getId(), account.getId());
             this.accounts.add(bankdroidAccount);
         }
     }
 
     private void addCardAccounts(List<CardAccount> accountList) {
-        for(CardAccount account : accountList) {
+        for (CardAccount account : accountList) {
             String currency = account.getCurrency() == null ? "SEK" : account.getCurrency();
-            Account bankdroidAccount = new Account(account.getName(),account.getAvailableAmount(),account.getCardNumber(), Account.CCARD,currency);
+            Account bankdroidAccount = new Account(account.getName(), account.getAvailableAmount(),
+                    account.getCardNumber(), Account.CCARD, currency);
             mIdMap.put(bankdroidAccount.getId(), account.getId());
             this.accounts.add(bankdroidAccount);
         }
@@ -291,7 +320,7 @@ public abstract class AbstractSwedbank extends Bank {
                     .append(':')
                     .append(Installation.id(context))
                     .toString().getBytes("UTF-8");
-            return Base64.encodeToString(data,Base64.NO_WRAP);
+            return Base64.encodeToString(data, Base64.NO_WRAP);
         } catch (UnsupportedEncodingException e) {
             // Ignore
         }
@@ -299,9 +328,9 @@ public abstract class AbstractSwedbank extends Bank {
     }
 
     private String getResourceUri(String resource) {
-        String dsid = "dsid="+UUID.randomUUID().toString();
-        urlopen.addHeader("Cookie",dsid);
-        return API_BASE + resource + '?'+dsid;
+        String dsid = "dsid=" + UUID.randomUUID().toString();
+        urlopen.addHeader("Cookie", dsid);
+        return API_BASE + resource + '?' + dsid;
     }
 
     private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
index 7a84be9..c8bbb5d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
@@ -11,8 +11,10 @@ import java.math.BigDecimal;
 
 
 public class BalanceDeserializer extends JsonDeserializer<BigDecimal> {
+
     @Override
-    public BigDecimal deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+    public BigDecimal deserialize(JsonParser jp, DeserializationContext ctxt)
+            throws IOException, JsonProcessingException {
         return Helpers.parseBalance(jp.getValueAsString());
 
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
index eefb1ba..155c399 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -1,19 +1,22 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class Sparbankerna extends AbstractSwedbank {
 
+    protected static final String NAME_SHORT = "sparbankerna";
+
     private static final String TAG = "Sparbankerna";
+
     private static final String NAME = "Sparbankerna";
-    protected static final String NAME_SHORT = "sparbankerna";
+
     private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
 
     private static final String APP_ID = "qdorTi1mqZ09Zcyc";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
index ae2fe9e..17818fc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
@@ -1,19 +1,22 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class SparbankernaCorporate extends AbstractSwedbank {
 
     private static final String TAG = "Sparbankerna Företag";
+
     private static final String NAME = "Sparbankerna Företag";
+
     private static final String NAME_SHORT = "sparbankerna-corporate";
+
     private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA_CORPORATE;
 
     private static final String APP_ID = "qdorTi1mqZ09Zcyc";
@@ -40,6 +43,7 @@ public class SparbankernaCorporate extends AbstractSwedbank {
 
     @Override
     public int getImageResource() {
-        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable", context.getPackageName());
+        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable",
+                context.getPackageName());
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
index 96f7eb1..55f89ee 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
@@ -1,19 +1,22 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class SparbankernaYouth extends AbstractSwedbank {
 
     private static final String TAG = "Sparbankerna Ung";
+
     private static final String NAME = "Sparbankerna Ung";
+
     private static final String NAME_SHORT = "sparbankerna-youth";
+
     private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA_YOUTH;
 
     private static final String APP_ID = "QtDHyRnJvEuET2vU";
@@ -40,6 +43,7 @@ public class SparbankernaYouth extends AbstractSwedbank {
 
     @Override
     public int getImageResource() {
-        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable", context.getPackageName());
+        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable",
+                context.getPackageName());
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
index 9c77788..dcaf3bc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -1,20 +1,23 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class Swedbank extends AbstractSwedbank {
 
+    protected static final String NAME_SHORT = "swedbank";
+
     private static final String TAG = "Swedbank";
+
     private static final String NAME = "Swedbank";
+
     private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
-    protected static final String NAME_SHORT = "swedbank";
 
     private static final String APP_ID = "vgmYRMelBJ0Yzujs";
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
index a1305ac..1a8fe17 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
@@ -1,19 +1,22 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class SwedbankCorporate extends AbstractSwedbank {
 
     private static final String TAG = "Swedbank Företag";
+
     private static final String NAME = "Swedbank Företag";
+
     private static final String NAME_SHORT = "swedbank-corporate";
+
     private static final int BANKTYPE_ID = IBankTypes.SWEDBANK_CORPORATE;
 
     private static final String APP_ID = "Our91qzclXdNmpdE";
@@ -40,6 +43,7 @@ public class SwedbankCorporate extends AbstractSwedbank {
 
     @Override
     public int getImageResource() {
-        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable", context.getPackageName());
+        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable",
+                context.getPackageName());
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
index 9d9e0e4..158f77e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
@@ -1,19 +1,22 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
-import android.content.Context;
-
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import android.content.Context;
+
 import java.io.IOException;
 
 public class SwedbankYouth extends AbstractSwedbank {
 
     private static final String TAG = "Swedbank Ung";
+
     private static final String NAME = "Swedbank Ung";
+
     private static final String NAME_SHORT = "swedbank-youth";
+
     private static final int BANKTYPE_ID = IBankTypes.SWEDBANK_YOUTH;
 
     private static final String APP_ID = "19AaEzp0jQJDt3vO";
@@ -40,6 +43,7 @@ public class SwedbankYouth extends AbstractSwedbank {
 
     @Override
     public int getImageResource() {
-        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable", context.getPackageName());
+        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable",
+                context.getPackageName());
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
index 05f5b7e..8c6408e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
@@ -46,9 +46,9 @@ public class Bank {
     }
 
     public List<CorporateProfile> getCorporateProfiles() {
-       if(corporateProfiles == null) {
-           corporateProfiles = new ArrayList<CorporateProfile>();
-       }
+        if (corporateProfiles == null) {
+            corporateProfiles = new ArrayList<CorporateProfile>();
+        }
         return corporateProfiles;
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
index 7b13cbe..0fa5982 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
@@ -13,7 +13,7 @@ public class CardAccount {
 
     @JsonProperty
     private String name;
-    
+
     @JsonProperty
     private BigDecimal creditLimit;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
index 7f79127..68e5c8e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
@@ -46,7 +46,7 @@ public class CreditCard {
     }
 
     public List<String> getCardNumbers() {
-        if(cardNumbers == null) {
+        if (cardNumbers == null) {
             cardNumbers = new ArrayList<String>();
         }
         return cardNumbers;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
index ed419dc..95c5a3d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
@@ -20,7 +20,9 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.io.Serializable;
 
 public class ErrorMessage implements Serializable {
+
     private static final long serialVersionUID = 7228754028321179052L;
+
     @JsonProperty
     String title;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
index bebcc6f..fac0869 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
@@ -35,6 +35,7 @@ import java.util.Map;
  */
 //@JsonIgnoreProperties(ignoreUnknown = true)
 public class ErrorResponse implements Serializable {
+
     private static final long serialVersionUID = 1971937841087070779L;
 
     @JsonProperty
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
index 9ed2edc..7396285 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
 import com.liato.bankdroid.banking.banks.swedbank.model.CardTransaction;
-import com.liato.bankdroid.banking.banks.swedbank.model.Transaction;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -30,7 +29,7 @@ public class CardAccountResponse {
     }
 
     public List<CardTransaction> getTransactions() {
-        if(transactions == null) {
+        if (transactions == null) {
             transactions = new ArrayList<CardTransaction>();
         }
         return transactions;
@@ -41,7 +40,7 @@ public class CardAccountResponse {
     }
 
     public List<CardTransaction> getReservedTransactions() {
-        if(reservedTransactions == null) {
+        if (reservedTransactions == null) {
             reservedTransactions = new ArrayList<CardTransaction>();
         }
         return reservedTransactions;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
index 7ae62f3..c5133d9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
@@ -42,7 +42,7 @@ public class OverviewResponse {
     }
 
     public List<Account> getTransactionAccounts() {
-        if(transactionAccounts == null) {
+        if (transactionAccounts == null) {
             transactionAccounts = new ArrayList<Account>();
         }
         return transactionAccounts;
@@ -53,7 +53,7 @@ public class OverviewResponse {
     }
 
     public List<Account> getSavingAccounts() {
-        if(savingAccounts == null) {
+        if (savingAccounts == null) {
             savingAccounts = new ArrayList<Account>();
         }
         return savingAccounts;
@@ -64,7 +64,7 @@ public class OverviewResponse {
     }
 
     public List<Account> getLoanAccounts() {
-        if(loanAccounts == null) {
+        if (loanAccounts == null) {
             loanAccounts = new ArrayList<Account>();
         }
         return loanAccounts;
@@ -75,7 +75,7 @@ public class OverviewResponse {
     }
 
     public List<Account> getTransactionDisposalAccounts() {
-        if(transactionDisposalAccounts == null) {
+        if (transactionDisposalAccounts == null) {
             transactionDisposalAccounts = new ArrayList<Account>();
         }
         return transactionDisposalAccounts;
@@ -86,7 +86,7 @@ public class OverviewResponse {
     }
 
     public List<Account> getSavingDisposalAccounts() {
-        if(savingDisposalAccounts == null) {
+        if (savingDisposalAccounts == null) {
             savingDisposalAccounts = new ArrayList<Account>();
         }
         return savingDisposalAccounts;
@@ -97,7 +97,7 @@ public class OverviewResponse {
     }
 
     public List<CardAccount> getCardAccounts() {
-        if(cardAccounts == null) {
+        if (cardAccounts == null) {
             cardAccounts = new ArrayList<CardAccount>();
         }
         return cardAccounts;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
index 40a1be4..ce7c84f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
@@ -17,7 +17,7 @@ public class TransactionsResponse {
     private List<Transaction> reservedTransactions;
 
     public List<Transaction> getTransactions() {
-        if(transactions == null) {
+        if (transactions == null) {
             transactions = new ArrayList<Transaction>();
         }
         return transactions;
@@ -28,7 +28,7 @@ public class TransactionsResponse {
     }
 
     public List<Transaction> getReservedTransactions() {
-        if(reservedTransactions == null) {
+        if (reservedTransactions == null) {
             reservedTransactions = new ArrayList<Transaction>();
         }
         return reservedTransactions;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
index a862234..e20c3ce 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
@@ -25,7 +25,7 @@ public class PersonalCodeResponse {
     }
 
     public List<OperationalMessages> getOperationalMessages() {
-        if(operationalMessages == null) {
+        if (operationalMessages == null) {
             operationalMessages = new ArrayList<OperationalMessages>();
         }
         return operationalMessages;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
index 432bca0..6900058 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
@@ -36,7 +36,7 @@ public class ProfileResponse {
     }
 
     public List<Bank> getBanks() {
-        if(banks == null) {
+        if (banks == null) {
             banks = new ArrayList<Bank>();
         }
         return banks;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
index 67d92f7..8f6abbb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
@@ -16,18 +16,21 @@
 
 package com.liato.bankdroid.banking.exceptions;
 
-import java.util.ArrayList;
-
 import com.liato.bankdroid.banking.BankChoice;
 
+import java.util.ArrayList;
+
 public class BankChoiceException extends Exception {
-	private static final long serialVersionUID = 1L;
-	private ArrayList<BankChoice> banks;
-	public BankChoiceException(String message) {
-		super(message);
-	}
 
-	public BankChoiceException(String message,  ArrayList<BankChoice> banks) {
+    private static final long serialVersionUID = 1L;
+
+    private ArrayList<BankChoice> banks;
+
+    public BankChoiceException(String message) {
+        super(message);
+    }
+
+    public BankChoiceException(String message, ArrayList<BankChoice> banks) {
         super(message);
         this.banks = banks;
     }
@@ -37,5 +40,5 @@ public class BankChoiceException extends Exception {
      */
     public ArrayList<BankChoice> getBanks() {
         return banks;
-    }	
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
index 57280fc..9b3532c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
@@ -17,10 +17,13 @@
 package com.liato.bankdroid.banking.exceptions;
 
 public class BankException extends Exception {
-	private static final long serialVersionUID = 1L;
-	public BankException(String message) {
-		super(message);
-	}
+
+    private static final long serialVersionUID = 1L;
+
+    public BankException(String message) {
+        super(message);
+    }
+
     public BankException(String message, Throwable throwable) {
         super(message, throwable);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
index df810ef..65446a9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
@@ -17,8 +17,10 @@
 package com.liato.bankdroid.banking.exceptions;
 
 public class LoginException extends Exception {
-	private static final long serialVersionUID = 1L;
-	public LoginException(String message) {
-		super(message);
-	}
+
+    private static final long serialVersionUID = 1L;
+
+    public LoginException(String message) {
+        super(message);
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
index 92f1e5d..1dfdaac 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
@@ -17,13 +17,14 @@ package com.liato.bankdroid.provider;
 
 /**
  * Defines what types of accounts are supported.
- * 
+ *
  * @since 8 jan 2011
  */
 public interface IAccountTypes {
-	public final static int REGULAR = 1;
-	public final static int FUNDS = 2;
-	public final static int LOANS = 3;
-	public final static int CCARD = 4;
-	public final static int OTHER = 5;
+
+    public final static int REGULAR = 1;
+    public final static int FUNDS = 2;
+    public final static int LOANS = 3;
+    public final static int CCARD = 4;
+    public final static int OTHER = 5;
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index a79c958..3e824e1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -26,253 +26,244 @@ import java.math.BigDecimal;
  * <p>
  * Uri format for querying for all transaction of a given bank/account
  * combination:<br/>
- * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}/{{@link #API_KEY}}={yourkey}</code>
+ * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}/{{@link
+ * #API_KEY}}={yourkey}</code>
  * <br>
  * <code><b>Would result in: content://com.liato.bankdroid.provider.BankTransactionsProvider/transactions/API_KEY=AAABBBCCC111222</code>
  * </b>
  * </p>
- * 
+ *
  * <p>
  * <b>Example of reading transactions from a View that implements this
  * interface:</b>
- * 
+ *
  * <pre>
  * final Uri uri = Uri.parse(&quot;content://&quot; + AUTHORITY + &quot;/&quot; + TRANSACTIONS_CAT
  * 		+ &quot;/&quot; + API_KEY + apiKey);
- * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION, ACCOUNT_SELECTION_FILTER, new String[] { currentAccountId }, null);
+ * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION, ACCOUNT_SELECTION_FILTER, new
+ * String[] { currentAccountId }, null);
  * startManagingCursor(cur);
  * </pre>
- * 
+ *
  * Where <code>currentAccountId</code> is the account ID you wish to filter on.
  * </p>
- * 
+ *
  * @author Magnus Andersson
- * @since 8 jan 2011
  * @version 1.0-RC2
  * @see BankTransactionsProvider
+ * @since 8 jan 2011
  */
 public interface IBankTransactionsProvider {
-	/**
-	 * <p>
-	 * The authority part of the URI.
-	 * </p>
-	 */
-	String AUTHORITY = "com.liato.bankdroid.provider.BankTransactionsProvider";
-
-	/**
-	 * <p>
-	 * The API Key part of the URI.
-	 * </p>
-	 */
-	String API_KEY = "API_KEY=";
-
-	// ====================================MIME-TYPES======================================
-	/**
-	 * <p>
-	 * MIME-type for Transactions. Not use today (no inserts) added for clarity.
-	 * </p>
-	 */
-	String TRANSACTIONS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.transactions";
-
-	/**
-	 * <p>
-	 * MIME-type for Bank/Account. Not use today (no inserts) added for clarity.
-	 * </p>
-	 */
-	String BANK_ACCOUNTS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.bankaccounts";
-
-	// ===================================CATEGORIES=======================================
-	/**
-	 * <p>
-	 * A category part of the URI.
-	 * </p>
-	 */
-	String BANK_ACCOUNTS_CAT = "bankaccounts";
-
-	/**
-	 * <p>
-	 * A category part of the URI.
-	 * </p>
-	 */
-	String TRANSACTIONS_CAT = "transactions";
-
-	// ===================================BANK/ACCOUNT_FIELDS==============================
-	/**
-	 * <p>
-	 * ID for Bank.
-	 * </p>
-	 * <b>PLEASE NOTE</b><br>
-	 * This is an BankDroid internal id, do not depend on this id for keeping
-	 * track between sessions.</p>
-	 */
-	String BANK_ID = "_id";
-
-	/**
-	 * <p>
-	 * User defined custom name for the Bank
-	 * </p>
-	 */
-	String BANK_NAME = "custname";
-
-	/**
-	 * <p>
-	 * Type of Bank.
-	 * </p>
-	 * 
-	 * @see IBankTypes
-	 */
-	String BANK_TYPE = "banktype";
-
-	/**
-	 * <p>
-	 * Last time the bank and the bank accounts were synchronized.
-	 * </p>
-	 */
-	String BANK_LAST_UPDATED = "updated";
-
-	/**
-	 * <p>
-	 * Account id, this is a composite key that
-	 * </p>
-	 * <b>PLEASE NOTE</b><br>
-	 * This is an BankDroid internal id, do not depend on this id for keeping
-	 * track between sessions.</p>
-	 * 
-	 * @See {@link #TRANS_ACCNT}, {@link #ACCOUNT_SELECTION_FILTER}
-	 * 
-	 */
-	String ACC_ID = "id";
 
-	/**
-	 * <p>
-	 * Name of the account.
-	 * </p>
-	 */
-	String ACC_NAME = "name";
+    /**
+     * <p>
+     * The authority part of the URI.
+     * </p>
+     */
+    String AUTHORITY = "com.liato.bankdroid.provider.BankTransactionsProvider";
 
-	/**
-	 * <p>
-	 * The account Type.
-	 * </p>
-	 * 
-	 * @See {@link IAccountTypes}
-	 */
-	String ACC_TYPE = "acctype";
+    /**
+     * <p>
+     * The API Key part of the URI.
+     * </p>
+     */
+    String API_KEY = "API_KEY=";
 
-	/**
-	 * <p>
-	 * The account balance.
-	 * </p>
-	 * <p>
-	 * <i>Note! This will most likely differ from the total amount that can be
-	 * calculated from transactions.</i>
-	 * </p>
-	 */
-	String ACC_BALANCE = "balance";
+    // ====================================MIME-TYPES======================================
+    /**
+     * <p>
+     * MIME-type for Transactions. Not use today (no inserts) added for clarity.
+     * </p>
+     */
+    String TRANSACTIONS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.transactions";
 
-	/**
-	 * Defines if an account is hidden.
-	 */
-	String ACC_HIDDEN = "hidden";
+    /**
+     * <p>
+     * MIME-type for Bank/Account. Not use today (no inserts) added for clarity.
+     * </p>
+     */
+    String BANK_ACCOUNTS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.bankaccounts";
 
-	/**
-	 * <p>
-	 * The projection (ie. db view) that works with the
-	 * {@link #BANK_ACCOUNTS_CAT} category.
-	 * </p>
-	 */
-	String[] BANK_ACCOUNT_PROJECTION = { BANK_ID, BANK_NAME, BANK_TYPE,
-			BANK_LAST_UPDATED, ACC_ID, ACC_BALANCE, ACC_NAME, ACC_TYPE };
+    // ===================================CATEGORIES=======================================
+    /**
+     * <p>
+     * A category part of the URI.
+     * </p>
+     */
+    String BANK_ACCOUNTS_CAT = "bankaccounts";
 
-	/**
-	 * <p>
-	 * Use this filter to ignore hidden accounts (Hidden accounts only used for
-	 * debug purposes). Always use this filter or incorporate it into your own
-	 * filters.
-	 * </p>
-	 */
-	String NO_HIDDEN_ACCOUNTS_FILTER = ACC_HIDDEN + " = 0";
+    /**
+     * <p>
+     * A category part of the URI.
+     * </p>
+     */
+    String TRANSACTIONS_CAT = "transactions";
 
-	/**
-	 * <p>
-	 * Use this order by to make sure that all account belonging to one Bank
-	 * comes clustered.
-	 * </p>
-	 */
-	String ORDER_BY_BANK_ACCOUNT = BANK_ID + " DESC";
+    // ===================================BANK/ACCOUNT_FIELDS==============================
+    /**
+     * <p>
+     * ID for Bank.
+     * </p>
+     * <b>PLEASE NOTE</b><br>
+     * This is an BankDroid internal id, do not depend on this id for keeping
+     * track between sessions.</p>
+     */
+    String BANK_ID = "_id";
+    /**
+     * <p>
+     * Use this order by to make sure that all account belonging to one Bank
+     * comes clustered.
+     * </p>
+     */
+    String ORDER_BY_BANK_ACCOUNT = BANK_ID + " DESC";
+    /**
+     * <p>
+     * User defined custom name for the Bank
+     * </p>
+     */
+    String BANK_NAME = "custname";
+    /**
+     * <p>
+     * Type of Bank.
+     * </p>
+     *
+     * @see IBankTypes
+     */
+    String BANK_TYPE = "banktype";
+    /**
+     * <p>
+     * Last time the bank and the bank accounts were synchronized.
+     * </p>
+     */
+    String BANK_LAST_UPDATED = "updated";
+    /**
+     * <p>
+     * Account id, this is a composite key that
+     * </p>
+     * <b>PLEASE NOTE</b><br>
+     * This is an BankDroid internal id, do not depend on this id for keeping
+     * track between sessions.</p>
+     *
+     * @See {@link #TRANS_ACCNT}, {@link #ACCOUNT_SELECTION_FILTER}
+     */
+    String ACC_ID = "id";
+    /**
+     * <p>
+     * Name of the account.
+     * </p>
+     */
+    String ACC_NAME = "name";
+    /**
+     * <p>
+     * The account Type.
+     * </p>
+     *
+     * @See {@link IAccountTypes}
+     */
+    String ACC_TYPE = "acctype";
+    /**
+     * <p>
+     * The account balance.
+     * </p>
+     * <p>
+     * <i>Note! This will most likely differ from the total amount that can be
+     * calculated from transactions.</i>
+     * </p>
+     */
+    String ACC_BALANCE = "balance";
+    /**
+     * <p>
+     * The projection (ie. db view) that works with the
+     * {@link #BANK_ACCOUNTS_CAT} category.
+     * </p>
+     */
+    String[] BANK_ACCOUNT_PROJECTION = {BANK_ID, BANK_NAME, BANK_TYPE,
+            BANK_LAST_UPDATED, ACC_ID, ACC_BALANCE, ACC_NAME, ACC_TYPE};
+    /**
+     * Defines if an account is hidden.
+     */
+    String ACC_HIDDEN = "hidden";
+    /**
+     * <p>
+     * Use this filter to ignore hidden accounts (Hidden accounts only used for
+     * debug purposes). Always use this filter or incorporate it into your own
+     * filters.
+     * </p>
+     */
+    String NO_HIDDEN_ACCOUNTS_FILTER = ACC_HIDDEN + " = 0";
 
-	// ===================================TRANSACTION_FIELDS===============================
-	/**
-	 * <p>
-	 * Transaction ID.
-	 * </p>
-	 * <p>
-	 * <b>PLEASE NOTE</b><br>
-	 * This is an BankDroid internal id, not the actual bank transaction id.
-	 * </p>
-	 */
-	String TRANS_ID = "_id";
+    // ===================================TRANSACTION_FIELDS===============================
+    /**
+     * <p>
+     * Transaction ID.
+     * </p>
+     * <p>
+     * <b>PLEASE NOTE</b><br>
+     * This is an BankDroid internal id, not the actual bank transaction id.
+     * </p>
+     */
+    String TRANS_ID = "_id";
 
-	/**
-	 * <p>
-	 * Date of Transaction.
-	 * </p>
-	 */
-	String TRANS_DATE = "transdate";
+    /**
+     * <p>
+     * Date of Transaction.
+     * </p>
+     */
+    String TRANS_DATE = "transdate";
 
-	/**
-	 * <p>
-	 * Description text of Transaction.
-	 * </p>
-	 */
-	String TRANS_DESC = "btransaction";
+    /**
+     * <p>
+     * Description text of Transaction.
+     * </p>
+     */
+    String TRANS_DESC = "btransaction";
 
-	/**
-	 * <p>
-	 * Amount of Transaction.
-	 * </p>
-	 * <p>
-	 * String representation of a {@link BigDecimal}. Positive for <i>Income</i>
-	 * and negative for <i>Expenses</i>.
-	 * </p>
-	 */
-	String TRANS_AMT = "amount";
+    /**
+     * <p>
+     * Amount of Transaction.
+     * </p>
+     * <p>
+     * String representation of a {@link BigDecimal}. Positive for <i>Income</i>
+     * and negative for <i>Expenses</i>.
+     * </p>
+     */
+    String TRANS_AMT = "amount";
 
-	/**
-	 * <p>
-	 * Currency of the Transaction. (Currently Only SEK)
-	 * </p>
-	 */
-	String TRANS_CUR = "currency";
+    /**
+     * <p>
+     * Currency of the Transaction. (Currently Only SEK)
+     * </p>
+     */
+    String TRANS_CUR = "currency";
 
-	/**
-	 * <p>
-	 * The account a transaction belongs to.
-	 * </p>
-	 */
-	String TRANS_ACCNT = "account";
+    /**
+     * <p>
+     * The account a transaction belongs to.
+     * </p>
+     */
+    String TRANS_ACCNT = "account";
 
-	/**
-	 * <p>
-	 * The projection (ie. db view) that works with the
-	 * {@link #TRANSACTIONS_CAT} category.
-	 * </p>
-	 */
-	String[] TRANSACTIONS_PROJECTION = { TRANS_ID, TRANS_DATE, TRANS_DESC,
-			TRANS_AMT, TRANS_CUR, TRANS_ACCNT };
+    /**
+     * <p>
+     * The projection (ie. db view) that works with the
+     * {@link #TRANSACTIONS_CAT} category.
+     * </p>
+     */
+    String[] TRANSACTIONS_PROJECTION = {TRANS_ID, TRANS_DATE, TRANS_DESC,
+            TRANS_AMT, TRANS_CUR, TRANS_ACCNT};
 
-	/**
-	 * <p>
-	 * Use this filter to only return transactions belonging to a certain
-	 * account.
-	 * </p>
-	 * 
-	 * <p>
-	 * The format for the composite bank/account ID is {BANK_ID}_{ACCOUNT_ID}.<br>
-	 * <b>Example IDs:</b> 1_1 or 1_0
-	 * </p>
-	 * 
-	 * @See {@link #ACC_ID}
-	 */
-	String ACCOUNT_SELECTION_FILTER = TRANS_ACCNT + " = ?";
+    /**
+     * <p>
+     * Use this filter to only return transactions belonging to a certain
+     * account.
+     * </p>
+     *
+     * <p>
+     * The format for the composite bank/account ID is {BANK_ID}_{ACCOUNT_ID}.<br>
+     * <b>Example IDs:</b> 1_1 or 1_0
+     * </p>
+     *
+     * @See {@link #ACC_ID}
+     */
+    String ACCOUNT_SELECTION_FILTER = TRANS_ACCNT + " = ?";
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 38c6db6..df6a882 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -17,31 +17,32 @@ package com.liato.bankdroid.provider;
 
 /**
  * Defines what types banks are supported.
- * 
+ *
  * @since 8 jan 2011
  */
 public interface IBankTypes {
-	public final static int TESTBANK = 0;
-	public final static int SWEDBANK = 1;
-	public final static int NORDEA = 2;
-	public final static int ICABANKEN = 3;
-	public final static int LANSFORSAKRINGAR = 4;
-	public final static int HANDELSBANKEN = 5;
-	public final static int COOP = 6;
-	public final static int ICA = 7;
-	public final static int STATOIL = 8;
-	public final static int AVANZA = 9;
-	public final static int VILLABANKEN = 10;
-	public final static int AVANZAMINI = 11;
-	public final static int OKQ8 = 12;
-	public final static int EUROCARD = 13;
-	public final static int FIRSTCARD = 14;
-	public final static int PAYPAL = 15;
-	public final static int PAYSON = 16;
-	public final static int JOJO = 17;
-	public final static int IKANOBANK = 18;
-	public final static int STEAM = 19;
-	public final static int DINERSCLUB = 20;
+
+    public final static int TESTBANK = 0;
+    public final static int SWEDBANK = 1;
+    public final static int NORDEA = 2;
+    public final static int ICABANKEN = 3;
+    public final static int LANSFORSAKRINGAR = 4;
+    public final static int HANDELSBANKEN = 5;
+    public final static int COOP = 6;
+    public final static int ICA = 7;
+    public final static int STATOIL = 8;
+    public final static int AVANZA = 9;
+    public final static int VILLABANKEN = 10;
+    public final static int AVANZAMINI = 11;
+    public final static int OKQ8 = 12;
+    public final static int EUROCARD = 13;
+    public final static int FIRSTCARD = 14;
+    public final static int PAYPAL = 15;
+    public final static int PAYSON = 16;
+    public final static int JOJO = 17;
+    public final static int IKANOBANK = 18;
+    public final static int STEAM = 19;
+    public final static int DINERSCLUB = 20;
     public final static int SASEUROBONUSMASTERCARD = 21;
     public final static int RIKSLUNCHEN = 22;
     public final static int HEMKOP = 23;
@@ -77,7 +78,7 @@ public interface IBankTypes {
     public final static int NORDEA_DK = 53;
     public final static int VASTTRAFIK = 54;
     public final static int EVERYDAYCARD = 55;
-	public static final int AKELIUSINVEST = 56;
+    public static final int AKELIUSINVEST = 56;
     public static final int MENIGA = 57;
     public static final int RIKSKORTET = 58;
     public static final int BIOKLUBBEN = 59;
@@ -87,7 +88,7 @@ public interface IBankTypes {
     public static final int SVENSKASPEL = 63;
     public static final int EASYCARD = 64;
     public static final int APPEAKPOKER = 65;
-    public static final int TRUSTBUDDY = 66;    
+    public static final int TRUSTBUDDY = 66;
     public static final int BRUMMER_KF = 67;
     public static final int ZIDISHA = 68;
     public static final int BETTERGLOBE = 69;
@@ -95,8 +96,8 @@ public interface IBankTypes {
     public final static int SASEUROBONUSMASTERCARD_NO = 71;
     public final static int BITCOIN = 72;
     public final static int SASEUROBONUSMASTERCARD_DK = 73;
-    public final static int SVEADIREKT  = 74;
-    public final static int SUPREMECARD  = 75;
+    public final static int SVEADIREKT = 74;
+    public final static int SUPREMECARD = 75;
     public final static int SPARBANKERNA = 76;
     public final static int BLEKINGETRAFIKEN = 77;
     public final static int OSTGOTATRAFIKEN = 78;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
index 748ed4b..761b52e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
@@ -14,26 +14,29 @@ import java.util.UUID;
  * The id is generated the first time the {@link #id(android.content.Context)} is called
  * and are then persisted until the application is uninstalled.
  *
- * @see <a href="http://android-developers.blogspot.se/2011/03/identifying-app-installations.html">Identifying App Installations</a>.
+ * @see <a href="http://android-developers.blogspot.se/2011/03/identifying-app-installations.html">Identifying
+ * App Installations</a>.
  */
 public class Installation {
 
-    private static String sID = null;
-
     private static final String INSTALLATION = "INSTALLATION";
 
+    private static String sID = null;
+
     /**
      * Get the unique identification for the installation.
      * A new id will be generated the first time the method is called and are then
      * persisted until the application is uninstalled.
+     *
      * @return The unique identification for the installed application.
      */
     public synchronized static String id(Context context) {
         if (sID == null) {
             File installation = new File(context.getFilesDir(), INSTALLATION);
             try {
-                if (!installation.exists())
+                if (!installation.exists()) {
                     writeInstallationFile(installation);
+                }
                 sID = readInstallationFile(installation);
             } catch (Exception e) {
                 throw new RuntimeException(e);
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index 7b856eb..9b26a38 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -19,20 +19,19 @@ package eu.nullbyte.android.urllib;
  * under the License.
  */
 
-import android.os.Build;
-
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 
+import android.os.Build;
+
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import java.security.KeyManagementException;
-import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
@@ -48,14 +47,23 @@ import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 
 public class CertPinningSSLSocketFactory extends SSLSocketFactory {
+
     private final static String TAG = CertPinningSSLSocketFactory.class.getSimpleName();
+
     private SSLContext sslcontext = null;
+
     private Certificate[] certificates;
+
     private String lastHost;
+
     private CertPinningTrustManager mTrustManager;
+
     private ClientCertificate mClientCertificate;
 
-    public CertPinningSSLSocketFactory(ClientCertificate clientCertificate, Certificate[] certificates) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+    public CertPinningSSLSocketFactory(ClientCertificate clientCertificate,
+            Certificate[] certificates)
+            throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException,
+            KeyManagementException {
         super(null);
         this.certificates = certificates;
         this.mClientCertificate = clientCertificate;
@@ -68,12 +76,14 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
             SSLContext context = SSLContext.getInstance("TLS");
             mTrustManager = new CertPinningTrustManager(certificates, lastHost);
             KeyManager[] keyManagers = null;
-            if  (mClientCertificate != null) {
-                KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-                kmf.init(mClientCertificate.getKeyStore(), mClientCertificate.getPassword().toCharArray());
+            if (mClientCertificate != null) {
+                KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+                        KeyManagerFactory.getDefaultAlgorithm());
+                kmf.init(mClientCertificate.getKeyStore(),
+                        mClientCertificate.getPassword().toCharArray());
                 keyManagers = kmf.getKeyManagers();
             }
-            context.init(keyManagers, new TrustManager[] { mTrustManager }, null);
+            context.init(keyManagers, new TrustManager[]{mTrustManager}, null);
             return context;
         } catch (Exception e) {
             throw new IOException(e.getMessage());
@@ -92,8 +102,8 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
 
     /**
      * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
-     *      String, int, java.net.InetAddress, int,
-     *      org.apache.http.params.HttpParams)
+     * String, int, java.net.InetAddress, int,
+     * org.apache.http.params.HttpParams)
      */
     @Override
     public Socket connectSocket(Socket sock, String host, int port,
@@ -143,14 +153,15 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
 
     /**
      * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
-     *      String, int, boolean)
+     * String, int, boolean)
      */
     @Override
     public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
             throws IOException, UnknownHostException {
         //Log.v(TAG, "createSocket(socket: " + socket + ", host: " + host + ", port: " + port + ", autoClose: " + autoClose);
         lastHost = host;
-        return secureSocket(getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose));
+        return secureSocket(
+                getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose));
     }
 
     public void setHost(String host) {
@@ -161,22 +172,25 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
     }
 
     private Socket secureSocket(Socket socket) {
-        if(!(socket instanceof SSLSocket)) {
+        if (!(socket instanceof SSLSocket)) {
             return socket;
         }
-        
+
         SSLSocket vSocket = (SSLSocket) socket;
 
         // Remove SSLv3 support.
         // See https://code.google.com/p/android/issues/detail?id=78187
-        List<String> supportedProtocols = new ArrayList<String>(Arrays.asList(vSocket.getSupportedProtocols()));
+        List<String> supportedProtocols = new ArrayList<String>(
+                Arrays.asList(vSocket.getSupportedProtocols()));
         supportedProtocols.remove("SSLv3");
-        vSocket.setEnabledProtocols(supportedProtocols.toArray(new String[supportedProtocols.size()]));
+        vSocket.setEnabledProtocols(
+                supportedProtocols.toArray(new String[supportedProtocols.size()]));
 
         // Fix for supporting old servers.
         // See https://code.google.com/p/android-developer-preview/issues/detail?id=1200#c23
-        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
-            List<String> ciphers = new ArrayList<String>(Arrays.asList(vSocket.getEnabledCipherSuites()));
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
+            List<String> ciphers = new ArrayList<String>(
+                    Arrays.asList(vSocket.getEnabledCipherSuites()));
             ciphers.remove("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
             ciphers.remove("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
             vSocket.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
index 9fdf215..92302c6 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -8,7 +8,9 @@ import java.util.Arrays;
 import javax.net.ssl.X509TrustManager;
 
 public class CertPinningTrustManager implements X509TrustManager {
+
     private Certificate[] certificates;
+
     private String host;
 
     public CertPinningTrustManager(Certificate[] certificates, String host) {
@@ -37,7 +39,8 @@ public class CertPinningTrustManager implements X509TrustManager {
                 }
             }
         }
-        throw new CertificateException(host == null ? "Server certificate not trusted." : String.format("Server certificate not trusted for host: %s.", host));
+        throw new CertificateException(host == null ? "Server certificate not trusted."
+                : String.format("Server certificate not trusted for host: %s.", host));
     }
 
     public void setHost(String host) {
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
index d5c2f2c..5c1ceb4 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
@@ -43,7 +43,8 @@ public class CertificateReader {
         return certificates.toArray(new Certificate[certificates.size()]);
     }
 
-    public static ClientCertificate getClientCertificate(Context context, int rawResCert, String password) {
+    public static ClientCertificate getClientCertificate(Context context, int rawResCert,
+            String password) {
         InputStream is = null;
         try {
             KeyStore keyStore = KeyStore.getInstance("PKCS12");
@@ -97,7 +98,7 @@ public class CertificateReader {
         int len = b.length;
         String data = new String();
 
-        for (int i = 0; i < len; i++){
+        for (int i = 0; i < len; i++) {
             data += Integer.toHexString((b[i] >> 4) & 0xf);
             data += Integer.toHexString(b[i] & 0xf);
         }
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
index 4d3dc16..8dd1a99 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
@@ -3,7 +3,9 @@ package eu.nullbyte.android.urllib;
 import java.security.KeyStore;
 
 public class ClientCertificate {
+
     private String mPassword;
+
     private KeyStore mKeyStore;
 
     public ClientCertificate(KeyStore keyStore, String password) {
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 60feb01..3ee068d 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -16,14 +16,6 @@
 
 package eu.nullbyte.android.urllib;
 
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.preference.PreferenceManager;
-
 import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.ConnectionReuseStrategy;
@@ -54,7 +46,6 @@ 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.ssl.SSLSocketFactory;
-import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
@@ -71,6 +62,14 @@ import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestExecutor;
 import org.apache.http.util.EntityUtils;
 
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.os.Build;
+import android.preference.PreferenceManager;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -86,14 +85,24 @@ import java.util.HashMap;
 import java.util.List;
 
 public class Urllib {
-    public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+
+    public static String DEFAULT_USER_AGENT
+            = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+
     private String userAgent = null;
+
     private DefaultHttpClient httpclient;
+
     private HttpContext mHttpContext;
+
     private String currentURI;
+
     private String charset = HTTP.UTF_8;
+
     private HashMap<String, String> headers;
+
     private Context mContext;
+
     private CertPinningSSLSocketFactory mSSLSocketFactory;
 
 
@@ -116,10 +125,13 @@ public class Urllib {
         SchemeRegistry registry = new SchemeRegistry();
         registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-        boolean trustSystemKeystore = prefs.getBoolean("debug_mode", false) && prefs.getBoolean("no_cert_pinning", false);
+        boolean trustSystemKeystore = prefs.getBoolean("debug_mode", false) && prefs
+                .getBoolean("no_cert_pinning", false);
         try {
             mSSLSocketFactory = new CertPinningSSLSocketFactory(clientCert, pins);
-            registry.register(new Scheme("https", pins != null && !trustSystemKeystore ? mSSLSocketFactory : SSLSocketFactory.getSocketFactory(), 443));
+            registry.register(new Scheme("https",
+                    pins != null && !trustSystemKeystore ? mSSLSocketFactory
+                            : SSLSocketFactory.getSocketFactory(), 443));
         } catch (UnrecoverableKeyException e) {
             e.printStackTrace();
         } catch (KeyManagementException e) {
@@ -134,72 +146,81 @@ public class Urllib {
         mHttpContext = new BasicHttpContext();
 
     }
-    
+
     public String open(String url) throws ClientProtocolException, IOException {
-        return this.open(url, new ArrayList <NameValuePair>());
+        return this.open(url, new ArrayList<NameValuePair>());
     }
-    
+
     public String post(String url) throws ClientProtocolException, IOException {
-        return this.open(url, new ArrayList <NameValuePair>(), true);
+        return this.open(url, new ArrayList<NameValuePair>(), true);
     }
-    
-    public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
+
+    public String open(String url, List<NameValuePair> postData)
+            throws ClientProtocolException, IOException {
         return open(url, postData, false);
     }
-    public String open(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+
+    public String open(String url, List<NameValuePair> postData, boolean forcePost)
+            throws ClientProtocolException, IOException {
         HttpEntity entity = openAsHttpResponse(url, postData, forcePost).getEntity();
-        if(entity == null) {
+        if (entity == null) {
             return "";
         }
         return EntityUtils.toString(entity);
     }
 
-    public HttpResponse openAsHttpResponse(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
-        HttpEntity entity = (postData == null || postData.isEmpty()) && !forcePost ? null : new UrlEncodedFormEntity(postData, this.charset);
+    public HttpResponse openAsHttpResponse(String url, List<NameValuePair> postData,
+            boolean forcePost) throws ClientProtocolException, IOException {
+        HttpEntity entity = (postData == null || postData.isEmpty()) && !forcePost ? null
+                : new UrlEncodedFormEntity(postData, this.charset);
         return openAsHttpResponse(url, entity, forcePost);
     }
 
-    public HttpResponse openAsHttpResponse(String url, boolean forcePost) throws ClientProtocolException, IOException {
-        return openAsHttpResponse(url, Collections.<NameValuePair>emptyList(),forcePost);
+    public HttpResponse openAsHttpResponse(String url, boolean forcePost)
+            throws ClientProtocolException, IOException {
+        return openAsHttpResponse(url, Collections.<NameValuePair>emptyList(), forcePost);
     }
 
-    public HttpResponse openAsHttpResponse(String url, HttpEntity entity, boolean forcePost) throws ClientProtocolException, IOException {
+    public HttpResponse openAsHttpResponse(String url, HttpEntity entity, boolean forcePost)
+            throws ClientProtocolException, IOException {
         if ((entity == null) && !forcePost) {
-           return openAsHttpResponse(url,entity,HttpMethod.GET);
-        }
-        else {
-           return openAsHttpResponse(url,entity,HttpMethod.POST);
+            return openAsHttpResponse(url, entity, HttpMethod.GET);
+        } else {
+            return openAsHttpResponse(url, entity, HttpMethod.POST);
         }
     }
 
-    public HttpResponse openAsHttpResponse(String url, HttpMethod method) throws ClientProtocolException, IOException {
+    public HttpResponse openAsHttpResponse(String url, HttpMethod method)
+            throws ClientProtocolException, IOException {
         return openAsHttpResponse(url, null, method);
     }
 
-    public HttpResponse openAsHttpResponse(String url, HttpEntity entity, HttpMethod method) throws ClientProtocolException, IOException {
+    public HttpResponse openAsHttpResponse(String url, HttpEntity entity, HttpMethod method)
+            throws ClientProtocolException, IOException {
         this.currentURI = url;
         HttpResponse response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         ResponseHandler<String> responseHandler = new BasicResponseHandler();
         HttpUriRequest request;
-        switch(method) {
+        switch (method) {
             case GET:
                 request = new HttpGet(url);
                 break;
             case POST:
                 request = new HttpPost(url);
-                ((HttpPost)request).setEntity(entity);
+                ((HttpPost) request).setEntity(entity);
                 break;
             case PUT:
                 request = new HttpPut(url);
-                ((HttpPut)request).setEntity(entity);
+                ((HttpPut) request).setEntity(entity);
                 break;
             default:
                 request = new HttpGet(url);
         }
-        if (userAgent != null)
+        if (userAgent != null) {
             request.addHeader("User-Agent", userAgent);
+        }
 
         for (int i = 0; i < headerKeys.length; i++) {
             request.addHeader(headerKeys[i], headerVals[i]);
@@ -216,9 +237,9 @@ public class Urllib {
     }
 
     public InputStream openStream(String url) throws ClientProtocolException, IOException {
-        return openStream(url, (HttpEntity)null, false);
+        return openStream(url, (HttpEntity) null, false);
     }
-    
+
     public HttpEntity toEntity(List<NameValuePair> postData) {
         if (postData != null && !postData.isEmpty()) {
             try {
@@ -229,31 +250,34 @@ public class Urllib {
         }
         return null;
     }
-    
-    public InputStream openStream(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+
+    public InputStream openStream(String url, List<NameValuePair> postData, boolean forcePost)
+            throws ClientProtocolException, IOException {
         return openStream(url, toEntity(postData), forcePost);
     }
-    
-    public InputStream openStream(String url, String postData, boolean forcePost) throws ClientProtocolException, IOException {
-        return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, forcePost);
+
+    public InputStream openStream(String url, String postData, boolean forcePost)
+            throws ClientProtocolException, IOException {
+        return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null,
+                forcePost);
     }
-    
-    public InputStream openStream(String url, HttpEntity postData, boolean forcePost) throws ClientProtocolException, IOException {
+
+    public InputStream openStream(String url, HttpEntity postData, boolean forcePost)
+            throws ClientProtocolException, IOException {
         this.currentURI = url;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         HttpUriRequest request;
         if (!forcePost && postData == null) {
             request = new HttpGet(url);
-        }
-        else {
+        } else {
             request = new HttpPost(url);
-            ((HttpPost)request).setEntity(postData);
+            ((HttpPost) request).setEntity(postData);
         }
         if (userAgent != null) {
             request.addHeader("User-Agent", userAgent);
         }
-        
+
         for (int i = 0; i < headerKeys.length; i++) {
             request.addHeader(headerKeys[i], headerVals[i]);
         }
@@ -261,20 +285,20 @@ public class Urllib {
         HttpResponse response = httpclient.execute(request);
         HttpEntity entity = response.getEntity();
         return entity.getContent();
-    }      
-    
+    }
+
     public void close() {
         httpclient.getConnectionManager().shutdown();
     }
-    
+
     public HttpContext getHttpContext() {
         return mHttpContext;
     }
-    
+
     public String getCurrentURI() {
         return currentURI;
     }
-    
+
     public DefaultHttpClient getHttpclient() {
         return httpclient;
     }
@@ -292,42 +316,44 @@ public class Urllib {
     public void addHeader(String key, String value) {
         this.headers.put(key, value);
     }
-    
+
     public void setKeepAliveTimeout(final int seconds) {
-        httpclient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { 
+        httpclient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
             @Override
             public long getKeepAliveDuration(HttpResponse response, HttpContext arg1) {
                 return seconds;
-            }});
+            }
+        });
     }
 
     public String removeHeader(String key) {
         return this.headers.remove(key);
-    }  
-    
+    }
+
     public void clearHeaders() {
         this.headers.clear();
     }
-    
+
     public HashMap<String, String> getHeaders() {
         return this.headers;
     }
 
     public void setFollowRedirects(boolean follow) {
-        httpclient.setRedirectHandler(follow ? new DefaultRedirectHandler() : new RedirectHandler() {
-            public URI getLocationURI(HttpResponse response,
-                                      HttpContext context) throws ProtocolException {
-                return null;
-            }
+        httpclient
+                .setRedirectHandler(follow ? new DefaultRedirectHandler() : new RedirectHandler() {
+                    public URI getLocationURI(HttpResponse response,
+                            HttpContext context) throws ProtocolException {
+                        return null;
+                    }
 
-            public boolean isRedirectRequested(HttpResponse response,
-                                               HttpContext context) {
-                return false;
-            }
-        });
+                    public boolean isRedirectRequested(HttpResponse response,
+                            HttpContext context) {
+                        return false;
+                    }
+                });
     }
 
-    
+
     public void setUserAgent(String userAgent) {
         this.userAgent = userAgent;
     }
@@ -338,24 +364,32 @@ public class Urllib {
         String appVersion = "";
 
         try {
-            PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS);
+            PackageInfo packageInfo = mContext.getPackageManager()
+                    .getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS);
             packageName = packageInfo.packageName;
             appVersion = packageInfo.versionName;
         } catch (PackageManager.NameNotFoundException ignore) {
         }
 
         Configuration config = mContext.getResources().getConfiguration();
-        return String.format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %10$s Build/%7$s; %8$s) %9$s %10$s"
-                , appName
-                , appVersion
-                , System.getProperty("os.name", "Linux")
-                , Build.VERSION.RELEASE
-                , config.locale.getLanguage().toLowerCase()
-                , config.locale.getCountry().toLowerCase()
-                , Build.ID
-                , Build.BRAND
-                , Build.MANUFACTURER
-                , Build.MODEL);
+        return String
+                .format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %10$s Build/%7$s; %8$s) %9$s %10$s"
+                        , appName
+                        , appVersion
+                        , System.getProperty("os.name", "Linux")
+                        , Build.VERSION.RELEASE
+                        , config.locale.getLanguage().toLowerCase()
+                        , config.locale.getCountry().toLowerCase()
+                        , Build.ID
+                        , Build.BRAND
+                        , Build.MANUFACTURER
+                        , Build.MODEL);
+    }
+
+    private void updateSocketFactoryHost(HttpHost host) {
+        if (mSSLSocketFactory != null && host != null) {
+            mSSLSocketFactory.setHost(host.getHostName());
+        }
     }
 
     class BankdroidHttpClient extends DefaultHttpClient {
@@ -365,41 +399,54 @@ public class Urllib {
         }
 
         @Override
-        public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
+        public <T> T execute(HttpHost target, HttpRequest request,
+                ResponseHandler<? extends T> responseHandler)
+                throws IOException, ClientProtocolException {
             updateSocketFactoryHost(target);
             return super.execute(target, request, responseHandler);
         }
 
         @Override
-        public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
+        public <T> T execute(HttpHost target, HttpRequest request,
+                ResponseHandler<? extends T> responseHandler, HttpContext context)
+                throws IOException, ClientProtocolException {
             updateSocketFactoryHost(target);
             return super.execute(target, request, responseHandler, context);
         }
 
         @Override
-        protected RequestDirector createClientRequestDirector(HttpRequestExecutor requestExec, ClientConnectionManager conman, ConnectionReuseStrategy reustrat, ConnectionKeepAliveStrategy kastrat, HttpRoutePlanner rouplan, HttpProcessor httpProcessor, HttpRequestRetryHandler retryHandler, RedirectHandler redirectHandler, AuthenticationHandler targetAuthHandler, AuthenticationHandler proxyAuthHandler, UserTokenHandler stateHandler, HttpParams params) {
-            return new DefaultishRequestDirector(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, stateHandler, params);
+        protected RequestDirector createClientRequestDirector(HttpRequestExecutor requestExec,
+                ClientConnectionManager conman, ConnectionReuseStrategy reustrat,
+                ConnectionKeepAliveStrategy kastrat, HttpRoutePlanner rouplan,
+                HttpProcessor httpProcessor, HttpRequestRetryHandler retryHandler,
+                RedirectHandler redirectHandler, AuthenticationHandler targetAuthHandler,
+                AuthenticationHandler proxyAuthHandler, UserTokenHandler stateHandler,
+                HttpParams params) {
+            return new DefaultishRequestDirector(requestExec, conman, reustrat, kastrat, rouplan,
+                    httpProcessor, retryHandler, redirectHandler, targetAuthHandler,
+                    proxyAuthHandler, stateHandler, params);
         }
     }
 
     class DefaultishRequestDirector extends DefaultRequestDirector {
 
-        public DefaultishRequestDirector(HttpRequestExecutor requestExec, ClientConnectionManager conman, ConnectionReuseStrategy reustrat, ConnectionKeepAliveStrategy kastrat, HttpRoutePlanner rouplan, HttpProcessor httpProcessor, HttpRequestRetryHandler retryHandler, RedirectHandler redirectHandler, AuthenticationHandler targetAuthHandler, AuthenticationHandler proxyAuthHandler, UserTokenHandler userTokenHandler, HttpParams params) {
-            super(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params);
+        public DefaultishRequestDirector(HttpRequestExecutor requestExec,
+                ClientConnectionManager conman, ConnectionReuseStrategy reustrat,
+                ConnectionKeepAliveStrategy kastrat, HttpRoutePlanner rouplan,
+                HttpProcessor httpProcessor, HttpRequestRetryHandler retryHandler,
+                RedirectHandler redirectHandler, AuthenticationHandler targetAuthHandler,
+                AuthenticationHandler proxyAuthHandler, UserTokenHandler userTokenHandler,
+                HttpParams params) {
+            super(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler,
+                    redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params);
         }
 
         @Override
-        public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException, IOException {
+        public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context)
+                throws HttpException, IOException {
             updateSocketFactoryHost(target);
             return super.execute(target, request, context);
         }
     }
 
-
-    private void updateSocketFactoryHost(HttpHost host) {
-        if (mSSLSocketFactory != null && host != null) {
-            mSSLSocketFactory.setHost(host.getHostName());
-        }
-    }
-
 }
\ No newline at end of file

commit cfdad6ed41555badb9372334edb78e853895ff4b
Merge: 310e5de 362ae7c
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Mar 14 07:40:49 2015 +0100

    Merge pull request #503 from liato/feature/adds-checkstyle
    
    Adds checkstyle to project.

commit 310e5dedac3e3f696c9aa57db1d7257d24405ed6
Merge: 84acb73 a39099e
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Mar 14 07:39:45 2015 +0100

    Merge pull request #500 from liato/feature/contributing
    
    Adds contributing guidelines

commit 84acb73e1c6054eb7918ada197663f1e02b1e70a
Merge: 075d147 f097e41
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Mar 14 07:38:32 2015 +0100

    Merge pull request #502 from liato/feature/changelog
    
    Rename CHANGELOG to conform to naming standard.

commit 362ae7cceadc0ee44fca57fbb9be4f90162fa964
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 23:54:42 2015 +0100

    Adds checkstyle to project.

diff --git app/build.gradle app/build.gradle
index 03d802d..da2e810 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,6 +8,7 @@ buildscript {
     }
 }
 apply plugin: 'com.android.application'
+apply from: '../config/quality/quality.gradle'
 
 if(new File('app/crashlytics.properties').exists()) {
     apply plugin: 'io.fabric'
@@ -74,11 +75,6 @@ android {
             ext.enableCrashlytics = false
         }
     }
-
-    lintOptions {
-        abortOnError false
-    }
-
 }
 
 dependencies {
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index ea7ac52..344cb77 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -1,4 +1,5 @@
 apply plugin: 'com.android.library'
+apply from: '../config/quality/quality.gradle'
 
 android {
     compileSdkVersion 22
@@ -16,15 +17,10 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
-
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_7
         targetCompatibility JavaVersion.VERSION_1_7
     }
-
-    lintOptions {
-        abortOnError false
-    }
 }
 
 dependencies {
diff --git config/quality/checkstyle/checkstyle.xml config/quality/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..0fc6033
--- /dev/null
+++ config/quality/checkstyle/checkstyle.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+   "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+<module name="Checker">
+    <property name="charset" value="UTF-8"/>
+    
+    <property name="severity" value="error" />
+
+    <module name="SuppressionFilter">
+      <property name="file" value="${checkstyleSuppressionsPath}"/>
+    </module>
+    <module name="FileTabCharacter">
+        <property name="eachLine" value="true"/>
+    </module>
+    <module name="NewlineAtEndOfFile" />
+    <module name="Translation" />
+    <module name="RegexpSingleline">
+        <property name="format" value="\s+$" />
+        <property name="minimum" value="0" />
+        <property name="maximum" value="0" />
+        <property name="message" value="Line has trailing spaces." />
+        <property name="severity" value="info" />
+    </module>
+
+    <module name="TreeWalker">
+        <property name="tabWidth" value="4" />
+        <module name="ConstantName" />
+        <module name="LocalFinalVariableName" />
+        <module name="LocalVariableName" />
+        <module name="MethodName" />
+        <module name="PackageName" />
+        <module name="ParameterName" />
+        <module name="TypeName" />
+        <module name="MemberName">
+            <property name="format" value="^m[A-Z][a-zA-Z0-9]*$" />
+        </module>
+        <module name="StaticVariableName">
+            <property name="format" value="^s[A-Z][a-zA-Z0-9]*$" />
+        </module>
+        <module name="AvoidStarImport" />
+        <module name="IllegalImport" />
+        <module name="RedundantImport" />
+        <module name="UnusedImports" />
+        <module name="MethodLength" />
+        <module name="ParameterNumber" />
+        <module name="EmptyForIteratorPad" />
+        <module name="MethodParamPad" />
+        <module name="NoWhitespaceAfter">
+            <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS" />
+        </module>
+        <module name="NoWhitespaceBefore" />
+        <module name="OperatorWrap" />
+        <module name="ParenPad" />
+        <module name="TypecastParenPad" />
+        <module name="WhitespaceAfter" />
+        <module name="WhitespaceAround">
+           <property name="allowEmptyMethods" value="true" />
+        </module>
+        <module name="ModifierOrder" />
+        <module name="RedundantModifier" />
+        <module name="AvoidNestedBlocks" />
+        <module name="EmptyBlock" />
+        <module name="LeftCurly" />
+        <module name="NeedBraces" />
+        <module name="RightCurly" />
+        <module name="EmptyStatement" />
+        <module name="EqualsHashCode" />
+        <module name="IllegalInstantiation" />
+        <module name="InnerAssignment" />
+        <module name="MagicNumber" />
+        <module name="MissingSwitchDefault" />
+        <module name="SimplifyBooleanExpression" />
+        <module name="SimplifyBooleanReturn" />
+        <module name="FinalClass" />
+        <module name="HideUtilityClassConstructor" />
+        <module name="InterfaceIsType" />
+        <module name="ArrayTypeStyle" />
+
+        <module name="UpperEll" />
+        <module name="MethodLength">
+            <property name="max" value="40" />
+        </module>
+        <module name="LineLength">
+            <property name="max" value="100" />
+             <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
+        </module>
+        <module name="InnerTypeLast" />
+    </module>
+</module>
diff --git config/quality/checkstyle/suppressions.xml config/quality/checkstyle/suppressions.xml
new file mode 100644
index 0000000..d8776f0
--- /dev/null
+++ config/quality/checkstyle/suppressions.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE suppressions PUBLIC
+    "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+    "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+
+<suppressions>
+    <suppress files="R.java" checks="[a-zA-Z0-9]*"/>
+    <suppress files="BuildConfig.java" checks="[a-zA-Z0-9]*"/>
+    <suppress files="Test" checks="[a-zA-Z0-9]*"/>
+    <suppress files="generated" checks="[a-zA-Z0-9]*"/>
+</suppressions>
diff --git config/quality/quality.gradle config/quality/quality.gradle
new file mode 100644
index 0000000..e6a9c47
--- /dev/null
+++ config/quality/quality.gradle
@@ -0,0 +1,24 @@
+apply plugin: 'checkstyle'
+
+// Add checkstyle and lint to the check task.
+check.dependsOn 'checkstyle', 'lint'
+
+task checkstyle(type: Checkstyle) {
+    configFile file("${project.rootDir}/config/quality/checkstyle/checkstyle.xml")
+    configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
+    
+    source 'src'
+    include '**/*.java'
+    classpath = files()
+}
+
+checkstyle {
+    toolVersion '6.1.1' // TODO https://github.com/jshiell/checkstyle-idea/blob/dbe595028c3488400790e6caed2f122fba0bded1/README#L13-19
+    ignoreFailures true // TODO Remove when project has been cleaned.
+}
+
+android {
+    lintOptions {
+        abortOnError false // TODO Set to true when project has been cleaned.
+    }
+}

commit f097e416f2c4b671fed781441f39f4d553c17c48
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 22:54:10 2015 +0100

    Rename CHANGELOG to conform to naming standard.
    
    Adds union merge strategy for CHANGELOG

diff --git .gitattributes .gitattributes
new file mode 100644
index 0000000..89e130e
--- /dev/null
+++ .gitattributes
@@ -0,0 +1 @@
+CHANGELOG merge=union
diff --git CHANGES.txt CHANGELOG
similarity index 100%
rename from CHANGES.txt
rename to CHANGELOG

commit a39099e0465b81b22d87a3d52f42cf8ade1d4395
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 22:20:59 2015 +0100

    Adds contribution guidelines.

diff --git CONTRIBUTING.md CONTRIBUTING.md
new file mode 100644
index 0000000..d050540
--- /dev/null
+++ CONTRIBUTING.md
@@ -0,0 +1,73 @@
+# Contribute to Bankdroid
+
+This guide details how to use issues and pull requests (for new code) to improve Bankdroid.
+
+## Code Style and Template
+
+We use the [Android Open-Source Project (AOSP) Code Style Guidelines](http://source.android.com/source/code-style.html).
+
+We strongly suggest that you use the [`AndroidStyle.xml`](/config/ide/androidstudio/AndroidStyle.xml) template file, included in this repository, in Android Studio to format your code:
+
+1. Place `AndroidStyle.xml` in your Android Studio `/codestyles` directory (e.g., `%userprofile%\.AndroidStudio\config\codestyles`, or `~/Library/Preferences/AndroidStudio/codestyles/` on OS X)
+2. Restart Android Studio.
+3. Go to "File->Settings->Code Style", and under "Scheme" select "AndroidStyle" and click "Ok".
+4. Right-click on the files that contain your contributions and select "Reformat Code", check "Optimize imports", and select "Run".
+
+## Closing policy for issues and pull requests
+
+Bankdroid is a popular project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice.
+
+Please treat our volunteers with courtesy and respect, it will go a long way towards getting your issue resolved.
+
+Issues and pull requests should be in English and contain appropriate language for audiences of all ages.
+
+## Issue tracker
+
+The [issue tracker](https://github.com/liato/android-bankdroid/issues) is only for obvious bugs, misbehavior, & feature requests in the latest stable or development release of Bankdroid. When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a pull request which partially or fully addresses the issue.
+
+### Issue tracker guidelines
+
+**[Search](https://github.com/liato/android-bankdroid/search?q=&ref=cmdform&type=Issues)** for similar entries before submitting your own, there's a good chance somebody else had the same issue or feature request. Show your support with `:+1:` and/or join the discussion. Please submit issues in the following format (as the first post) and feature requests in a similar format:
+
+1. **Summary:** Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
+2. **Steps to reproduce:** How can we reproduce the issue?
+3. **Expected behavior:** What did you expect the app to do?
+4. **Observed behavior:** What did you see instead?  Describe your issue in detail here.
+5. **Device and Android version:** What make and model device (e.g., Samsung Galaxy S3) did you encounter this on?  What Android version (e.g., Android 4.0 Ice Cream Sandwich) are you running?  Is it the stock version from the manufacturer or a custom ROM?
+5. **Screenshots:** Can be created by pressing the Volume Down and Power Button at the same time on Android 4.0 and higher.
+6. **Possible fixes**: If you can, link to the line of code that might be responsible for the problem.
+
+## Pull requests
+
+We welcome pull requests with fixes and improvements to Bankdroid code, tests, and/or documentation. The features we would really like a pull request for are open issues with the [feature](https://github.com/liato/android-bankdroid/issues?labels=feature&page=1&state=open), [broken](https://github.com/liato/android-bankdroid/issues?labels=broken&page=1&state=open) or [improvement](https://github.com/liato/android-bankdroid/issues?labels=improvement&page=1&state=open) labels.
+
+### Pull request guidelines
+
+If you can, please submit a pull request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a pull request is as follows:
+
+1. Fork the project on GitHub
+2. Create a feature branch
+3. Write tests and code
+4. Apply the `AndroidStyle.xml` style template to your code in Android Studio.
+5. Add your changes to the [CHANGELOG](/CHANGELOG)
+6. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
+7. Push the commit to your fork
+8. Submit a pull request with a motive for your change and the method you used to achieve it
+9. [Search for issues](https://github.com/liato/android-bankdroid/search?q=&ref=cmdform&type=Issues) related to your pull request and mention them in the pull request description or comments
+
+We will accept pull requests if:
+
+* The code has proper tests and all tests pass (or it is a test exposing a failure in existing code)
+* It can be merged without problems (if not please use: `git rebase master`)
+* It doesn't break any existing functionality
+* It's quality code that conforms to standard style guides and best practices
+* The description includes a motive for your change and the method you used to achieve it
+* It is not a catch all pull request but rather fixes a specific issue or implements a specific feature
+* It keeps the Bankdroid code base clean and well structured
+* We think other users will benefit from the same functionality
+* If it makes changes to the UI the pull request should include screenshots
+* It is a single commit (please use `git rebase -i` to squash commits)
+
+## License
+
+By contributing code to this project via pull requests, patches, or any other process, you are agreeing to license your contributions under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).

commit 075d147c369741f35df30fe135aa2484dd68e7c3
Merge: 39d71a9 1e7e87c
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Mar 13 22:48:00 2015 +0100

    Merge pull request #501 from liato/feature/add-formatting-styles
    
    Adds Android codestyle template for AndroidStudio.

commit 1e7e87cd0b9196a2e382c9643ec78db8a8fc21e6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 22:23:38 2015 +0100

    Adds Android codestyle template for AndroidStudio.

diff --git config/ide/androidstudio/AndroidStyle.xml config/ide/androidstudio/AndroidStyle.xml
new file mode 100644
index 0000000..6ba5033
--- /dev/null
+++ config/ide/androidstudio/AndroidStyle.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<code_scheme name="AndroidStyle">
+    <option name="JAVA_INDENT_OPTIONS">
+        <value>
+            <option name="INDENT_SIZE" value="4"/>
+            <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+            <option name="TAB_SIZE" value="8"/>
+            <option name="USE_TAB_CHARACTER" value="false"/>
+            <option name="SMART_TABS" value="false"/>
+            <option name="LABEL_INDENT_SIZE" value="0"/>
+            <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+            <option name="USE_RELATIVE_INDENTS" value="false"/>
+        </value>
+    </option>
+    <option name="FIELD_NAME_PREFIX" value="m"/>
+    <option name="STATIC_FIELD_NAME_PREFIX" value="m"/>
+    <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999"/>
+    <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="9999"/>
+    <option name="IMPORT_LAYOUT_TABLE">
+        <value>
+            <package name="com.google" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="com" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="junit" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="net" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="org" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="android" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="java" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="javax" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="false"/>
+            <emptyLine/>
+            <package name="" withSubpackages="true" static="true"/>
+        </value>
+    </option>
+    <option name="RIGHT_MARGIN" value="100"/>
+    <option name="JD_P_AT_EMPTY_LINES" value="false"/>
+    <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true"/>
+    <option name="JD_KEEP_EMPTY_PARAMETER" value="false"/>
+    <option name="JD_KEEP_EMPTY_EXCEPTION" value="false"/>
+    <option name="JD_KEEP_EMPTY_RETURN" value="false"/>
+    <option name="JD_PRESERVE_LINE_FEEDS" value="true"/>
+    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+    <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+    <option name="BLANK_LINES_AROUND_FIELD" value="1"/>
+    <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
+    <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+    <option name="ALIGN_MULTILINE_FOR" value="false"/>
+    <option name="CALL_PARAMETERS_WRAP" value="1"/>
+    <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+    <option name="EXTENDS_LIST_WRAP" value="1"/>
+    <option name="THROWS_LIST_WRAP" value="1"/>
+    <option name="EXTENDS_KEYWORD_WRAP" value="1"/>
+    <option name="THROWS_KEYWORD_WRAP" value="1"/>
+    <option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
+    <option name="BINARY_OPERATION_WRAP" value="1"/>
+    <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
+    <option name="TERNARY_OPERATION_WRAP" value="1"/>
+    <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
+    <option name="FOR_STATEMENT_WRAP" value="1"/>
+    <option name="ARRAY_INITIALIZER_WRAP" value="1"/>
+    <option name="ASSIGNMENT_WRAP" value="1"/>
+    <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true"/>
+    <option name="WRAP_COMMENTS" value="true"/>
+    <option name="IF_BRACE_FORCE" value="3"/>
+    <option name="DOWHILE_BRACE_FORCE" value="3"/>
+    <option name="WHILE_BRACE_FORCE" value="3"/>
+    <option name="FOR_BRACE_FORCE" value="3"/>
+    <ADDITIONAL_INDENT_OPTIONS fileType="css">
+        <option name="INDENT_SIZE" value="4"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+        <option name="TAB_SIZE" value="4"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <ADDITIONAL_INDENT_OPTIONS fileType="java">
+        <option name="INDENT_SIZE" value="4"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+        <option name="TAB_SIZE" value="8"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <ADDITIONAL_INDENT_OPTIONS fileType="js">
+        <option name="INDENT_SIZE" value="4"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="4"/>
+        <option name="TAB_SIZE" value="4"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <ADDITIONAL_INDENT_OPTIONS fileType="jsp">
+        <option name="INDENT_SIZE" value="4"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+        <option name="TAB_SIZE" value="4"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <ADDITIONAL_INDENT_OPTIONS fileType="sql">
+        <option name="INDENT_SIZE" value="2"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+        <option name="TAB_SIZE" value="4"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <ADDITIONAL_INDENT_OPTIONS fileType="xml">
+        <option name="INDENT_SIZE" value="4"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+        <option name="TAB_SIZE" value="4"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <ADDITIONAL_INDENT_OPTIONS fileType="yml">
+        <option name="INDENT_SIZE" value="2"/>
+        <option name="CONTINUATION_INDENT_SIZE" value="8"/>
+        <option name="TAB_SIZE" value="4"/>
+        <option name="USE_TAB_CHARACTER" value="false"/>
+        <option name="SMART_TABS" value="false"/>
+        <option name="LABEL_INDENT_SIZE" value="0"/>
+        <option name="LABEL_INDENT_ABSOLUTE" value="false"/>
+        <option name="USE_RELATIVE_INDENTS" value="false"/>
+    </ADDITIONAL_INDENT_OPTIONS>
+    <codeStyleSettings language="JavaScript">
+        <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
+        <option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
+        <option name="BLANK_LINES_AROUND_FIELD" value="1"/>
+        <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
+        <option name="ALIGN_MULTILINE_FOR" value="false"/>
+        <option name="CALL_PARAMETERS_WRAP" value="1"/>
+        <option name="METHOD_PARAMETERS_WRAP" value="1"/>
+        <option name="EXTENDS_LIST_WRAP" value="1"/>
+        <option name="THROWS_LIST_WRAP" value="1"/>
+        <option name="EXTENDS_KEYWORD_WRAP" value="1"/>
+        <option name="THROWS_KEYWORD_WRAP" value="1"/>
+        <option name="METHOD_CALL_CHAIN_WRAP" value="1"/>
+        <option name="BINARY_OPERATION_WRAP" value="1"/>
+        <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
+        <option name="TERNARY_OPERATION_WRAP" value="1"/>
+        <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true"/>
+        <option name="FOR_STATEMENT_WRAP" value="1"/>
+        <option name="ARRAY_INITIALIZER_WRAP" value="1"/>
+        <option name="ASSIGNMENT_WRAP" value="1"/>
+        <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true"/>
+        <option name="WRAP_COMMENTS" value="true"/>
+        <option name="IF_BRACE_FORCE" value="3"/>
+        <option name="DOWHILE_BRACE_FORCE" value="3"/>
+        <option name="WHILE_BRACE_FORCE" value="3"/>
+        <option name="FOR_BRACE_FORCE" value="3"/>
+        <option name="PARENT_SETTINGS_INSTALLED" value="true"/>
+    </codeStyleSettings>
+</code_scheme>

commit 39d71a96d46fab9d862eeb95698f00238839c25b
Merge: aade758 cf7b51c
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Mar 13 22:26:29 2015 +0100

    Merge pull request #499 from liato/feature/android-22
    
    Upgrade Android SDK to version 22.

commit aade758c74549450918b21866584b24d0ac90b79
Merge: ffb3fcd b045a6a
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Mar 13 22:25:52 2015 +0100

    Merge pull request #498 from liato/feature/upgrade-dependencies
    
    Upgrade Gradle to 2.3

commit cf7b51c23321f22632edfd2c7492bc0560e333b0
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 21:08:13 2015 +0100

    Upgrade Android SDK to version 22.

diff --git .travis.yml .travis.yml
index 7a16044..3f1cc66 100644
--- .travis.yml
+++ .travis.yml
@@ -2,12 +2,13 @@ language: android
 jdk: oraclejdk7
 env:
   matrix:
-    - ANDROID_TARGET=android-21  ANDROID_ABI=armeabi-v7a
+    - ANDROID_TARGET=android-22  ANDROID_ABI=armeabi-v7a
 
 android:
   components:
-    - build-tools-21.1.1
+    - build-tools-22.0.0
     - extra-android-m2repository
+    - android-22
 
 script: ./gradlew check
 
diff --git app/build.gradle app/build.gradle
index 1c781bc..03d802d 100644
--- app/build.gradle
+++ app/build.gradle
@@ -19,13 +19,13 @@ repositories {
 
 
 android {
-    compileSdkVersion 21
-    buildToolsVersion "21.1.1"
+    compileSdkVersion 22
+    buildToolsVersion "22.0.0"
 
     defaultConfig {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
-        targetSdkVersion 21
+        targetSdkVersion 22
         versionCode 202
         versionName "1.9.8.0"
     }
@@ -39,6 +39,11 @@ android {
         }
     }
 
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+
     // Get signing keys for release
     gradle.taskGraph.whenReady { taskGraph ->
         if(taskGraph.hasTask(':app:assembleRelease')) {
@@ -79,7 +84,7 @@ android {
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-legacy')
-    compile "com.android.support:appcompat-v7:21.0.+"
+    compile "com.android.support:appcompat-v7:22.0.+"
     compile 'com.google.collections:google-collections:1.0'
     compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
         transitive = true;
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index b6057de..ea7ac52 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -1,12 +1,12 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 21
-    buildToolsVersion "21.1.2"
+    compileSdkVersion 22
+    buildToolsVersion "22.0.0"
 
     defaultConfig {
         minSdkVersion 9
-        targetSdkVersion 21
+        targetSdkVersion 22
         versionCode 1
         versionName "1.0"
     }
@@ -17,6 +17,11 @@ android {
         }
     }
 
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+
     lintOptions {
         abortOnError false
     }
@@ -24,7 +29,7 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:21.0.+'
+    compile 'com.android.support:appcompat-v7:22.0.+'
     compile 'org.apache.commons:commons-io:1.3.2'
     compile 'org.jsoup:jsoup:1.7.3'
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'

commit b045a6abea0d5958122d98e42cb7b4376877d49a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 20:48:53 2015 +0100

    Upgrades Gradle Wrapper to version 22

diff --git build.gradle build.gradle
index 15ff55d..5fdb7f6 100644
--- build.gradle
+++ build.gradle
@@ -17,3 +17,7 @@ allprojects {
         mavenCentral()
     }
 }
+
+task wrapper(type: Wrapper) {
+    gradleVersion = '2.3'
+}
diff --git gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
index 8c0fb64..c97a8bd 100644
Binary files gradle/wrapper/gradle-wrapper.jar and gradle/wrapper/gradle-wrapper.jar differ
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index bac4113..fa82012 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Nov 25 00:35:41 CET 2014
+#Fri Mar 13 20:47:51 CET 2015
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
diff --git gradlew.bat gradlew.bat
index 8a0b282..aec9973 100644
--- gradlew.bat
+++ gradlew.bat
@@ -1,90 +1,90 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem  Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

commit ffb3fcdb39261cd75fc9a43b3a313eae921ef063
Merge: 9162501 89fd36b
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Mar 13 06:32:50 2015 +0100

    Merge pull request #497 from liato/feature/skandiabanken
    
    Disable Skandiabanken due to requirement of BankId.

commit 89fd36b612d5dd6076d56c245bd1e377bfed9c44
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Mar 13 00:29:07 2015 +0100

    Disable Skandiabanken due to requirement of BankId.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index d376bec..4c6d61e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -46,7 +46,6 @@ import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
-import com.liato.bankdroid.banking.banks.Skandiabanken;
 import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
@@ -194,8 +193,8 @@ public class LegacyBankFactory {
                 return new SparbankenOresund(context);
             case IBankTypes.NORDNETDIREKT:
                 return new Nordnetdirekt(context);
-            case IBankTypes.SKANDIABANKEN:
-                return new Skandiabanken(context);
+            // case IBankTypes.SKANDIABANKEN:
+            //    return new Skandiabanken(context);
             case IBankTypes.DANSKEBANK:
                 return new DanskeBank(context);
             case IBankTypes.NORDEA_DK:
@@ -302,7 +301,7 @@ public class LegacyBankFactory {
         banks.add(new SparbankenSyd(context));
         // banks.add(new SparbankenOresund(context));
         // banks.add(new Opel(context));
-        banks.add(new Skandiabanken(context));
+        // banks.add(new Skandiabanken(context));
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));

commit 91625011f6bbe4f21d4bdb9f5e158d319cb05eef
Merge: 53e5a0c 5951175
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 12 23:06:21 2015 +0100

    Merge pull request #496 from liato/feature/exception
    
    Login fixes, throw right Exception and handle unsuccessful logins

commit 5951175ed35b3eb5c8fcacea5abc382c7d48f768
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Mar 11 09:54:11 2015 +0100

    Login fixes, throw right Exception and handle unsuccessful logins

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 424ca8d..1783c19 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -80,7 +80,7 @@ public class BlekingeTrafiken extends Bank {
         HttpResponse httpResponse = urlopen.openAsHttpResponse(URL + "/webshop/card/balance/",
                 new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
         if(httpResponse.getStatusLine().getStatusCode() != 200) {
-            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+            throw new BankException(res.getText(R.string.invalid_card_number).toString());
         }
         response = EntityUtils.toString(httpResponse.getEntity());
         return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index e41d1fc..7b3dba1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -70,8 +70,7 @@ public class Bredband2VoIP extends Bank {
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bredband2));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("cUsername", username));
@@ -79,25 +78,18 @@ public class Bredband2VoIP extends Bank {
         postData.add(new BasicNameValuePair("bIsCompany", "0"));
         postData.add(new BasicNameValuePair("submit", "Logga in"));
         response = urlopen.open(API_URL + "index/", postData, true);
-        if (!response.contains("Logga ut")) {
-            throw new BankException(res.getText(R.string.invalid_username_password).toString());
-        }
         LoginPackage lp = new LoginPackage(urlopen, postData, response, API_URL + "index/");
-        lp.setIsLoggedIn(true);
+        if (response.contains("Logga ut")) {
+            lp.setIsLoggedIn(true);
+        }
         return lp;
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            if (!lp.isLoggedIn()) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        if (!lp.isLoggedIn()) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index c69ed3e..8bfc5dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -70,7 +70,9 @@ public class MinPension extends Bank {
         String response = urlopen.open("https://www.minpension.se/AjaxifyContent/795");
         Document jDoc = Jsoup.parse(response);
         Element el = jDoc.select("input[name=__RequestVerificationToken]").first();
-        if (el == null) return null;
+        if (el == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " token.");
+        }
         postData.add(new BasicNameValuePair("__RequestVerificationToken", el.val()));
         postData.add(new BasicNameValuePair("viewModel.Personnummer", username));
         postData.add(new BasicNameValuePair("viewModel.Kod", password));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 2a23823..8cb1285 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -83,7 +83,7 @@ public class Avanza extends Bank {
             JSONObject jsonResponse = new JSONObject(response);
             homeUrl = jsonResponse.getString("redirectUrl");
         } catch (JSONException e) {
-            throw new BankException(res.getString(R.string.invalid_username_password));
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login link.");
         }
         LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl);
         lp.setIsLoggedIn(true);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 0c99eca..d7a2578 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -154,12 +154,11 @@ public class Coop extends Bank {
         HttpResponse httpResponse = urlopen.openAsHttpResponse("https://www.coop.se/Personliga-Baren/Logga-in/?method=Login",
                 new StringEntity("{\"isBar\":\"true\",\"username\":\"" + username + "\",\"password\":\"" + password + "\"}"),
                 true);
-        if (httpResponse.getStatusLine().getStatusCode() != 200) {
-            throw new BankException(res.getString(R.string.invalid_username_password));
-        }
         urlopen.removeHeader("X-Requested-With");
         LoginPackage lp = new LoginPackage(urlopen, null, response, "https://www.coop.se/Mina-sidor/Oversikt/");
-        lp.setIsLoggedIn(true);
+        if (httpResponse.getStatusLine().getStatusCode() == 200) {
+            lp.setIsLoggedIn(true);
+        }
         return lp;
     }
 
@@ -168,7 +167,7 @@ public class Coop extends Bank {
     public Urllib login() throws LoginException, BankException, IOException {
         LoginPackage lp = preLogin();
         if (!lp.isLoggedIn()) {
-            throw new BankException(res.getString(R.string.invalid_username_password));
+            throw new LoginException(res.getString(R.string.invalid_username_password));
         }
         return urlopen;
     }

commit 53e5a0c144083cfab43517edd2a8966207800431
Merge: 4fed56d f9458e6
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 8 13:27:55 2015 +0100

    Merge pull request #493 from liato/feature/316-swedbank-corporate-and-youth
    
    Adds support for Swedbank and Sparbankerna Youth and Corporate profiles.

commit 4fed56d12e94725f5e6cd109fcd7730b7b94adb6
Merge: 88a88bb 5a32d97
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 8 06:46:39 2015 +0100

    Merge pull request #494 from jonasgroth/master
    
    Fixes issues with Nordnet, fixes #104

commit 5a32d97e6dfb894cbd9fac2200a78da7d0422cea
Author: Jonas Groth <jonas@groth.im>
Date:   Sat Mar 7 16:27:02 2015 +0100

    Fixes issues with Nordnet

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index bd2400c..ff32ff6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -52,8 +52,9 @@ public class Nordnet extends Bank {
     private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
     private static final int BANKTYPE_ID = IBankTypes.NORDNET;
 
-    
-    private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)([0-9 ]{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
+    private Pattern reAccounts =
+            Pattern.compile("<span class=\"bullet\">·<\\/span>\\n\\t\\t\\t\\t\\t\\t<span>(.*?)<\\/span>");
+    private Pattern reBalance = Pattern.compile("<div class=\\\"value\\\">\\n(.*?)\\n\\t\\t<\\/div>");
     private String response = null;
 
     public Nordnet(Context context) {
@@ -117,28 +118,33 @@ public class Nordnet extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        Matcher matcher = reBalance.matcher(response);
+        Matcher matcher = reAccounts.matcher(response);
+        Matcher matcher_b = reBalance.matcher(response);
         while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                EXAMPLE DATA
-             * 1: Name              Efternamnet Förnamnet | Sparkonto
-             * 2: Account name      Aktie- och fonddepå   | Sparkonto
-             * 3: Account number    1234567               | 1234 567890 1
-             * 4: Amount            31 337                | 123
+             * 1: Account name and number      Investeringssparkonto 1234567   | Sparkonto 1234 567890 1
              *
              */
-            Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
-                    + Html.fromHtml(matcher.group(3)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(4)),
-                    Html.fromHtml(matcher.group(3)).toString().trim().replaceAll(" ", ""));
-
-            // Saving accounts contain white space characters in the account number
-            if (!matcher.group(3).trim().contains(" ")) {
-                account.setType(Account.FUNDS);
+            if(matcher_b.find()) {
+                /*
+                * Capture groups:
+                * GROUP                EXAMPLE DATA
+                * 1: Account balance     62 356 | 0
+                *
+                */
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(matcher_b.group(1)),
+                        Html.fromHtml(matcher.group(1)).toString().trim().replaceAll(" ", ""));
+
+                // Saving accounts contain white space characters in the account number
+                if (!matcher.group(1).trim().contains(" ")) {
+                    account.setType(Account.FUNDS);
+                }
+                accounts.add(account);
+                balance = balance.add(Helpers.parseBalance(matcher_b.group(1)));
             }
-            accounts.add(account);
-            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
         }
 
         if (accounts.isEmpty()) {

commit f9458e691a3cbfb465bf34f14856ba174f0a5e8f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 5 19:08:58 2015 +0100

    Adds support for Swedbank and Sparbankerna Youth and Corporate profiles.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index c78d92b..d376bec 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -70,7 +70,11 @@ import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
+import com.liato.bankdroid.banking.banks.swedbank.SparbankernaCorporate;
+import com.liato.bankdroid.banking.banks.swedbank.SparbankernaYouth;
 import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
+import com.liato.bankdroid.banking.banks.swedbank.SwedbankCorporate;
+import com.liato.bankdroid.banking.banks.swedbank.SwedbankYouth;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.provider.IBankTypes;
 
@@ -244,6 +248,14 @@ public class LegacyBankFactory {
                 return new EspressoHouse(context);
             case IBankTypes.MINPENSION:
                 return new MinPension(context);
+            case IBankTypes.SPARBANKERNA_CORPORATE:
+                return new SparbankernaCorporate(context);
+            case IBankTypes.SPARBANKERNA_YOUTH:
+                return new SparbankernaYouth(context);
+            case IBankTypes.SWEDBANK_CORPORATE:
+                return new SwedbankCorporate(context);
+            case IBankTypes.SWEDBANK_YOUTH:
+                return new SwedbankYouth(context);
             default:
                 throw new BankException("BankType id not found.");
         }
@@ -332,6 +344,10 @@ public class LegacyBankFactory {
         banks.add(new Bredband2VoIP(context));
         banks.add(new EspressoHouse(context));
         banks.add(new MinPension(context));
+        banks.add(new SparbankernaCorporate(context));
+        banks.add(new SparbankernaYouth(context));
+        banks.add(new SwedbankCorporate(context));
+        banks.add(new SwedbankYouth(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
index 8eb1a88..eefb1ba 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -13,7 +13,7 @@ public class Sparbankerna extends AbstractSwedbank {
 
     private static final String TAG = "Sparbankerna";
     private static final String NAME = "Sparbankerna";
-    private static final String NAME_SHORT = "sparbankerna";
+    protected static final String NAME_SHORT = "sparbankerna";
     private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
 
     private static final String APP_ID = "qdorTi1mqZ09Zcyc";
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
similarity index 60%
copy from bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
copy to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
index 8eb1a88..ae2fe9e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaCorporate.java
@@ -9,16 +9,16 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import java.io.IOException;
 
-public class Sparbankerna extends AbstractSwedbank {
+public class SparbankernaCorporate extends AbstractSwedbank {
 
-    private static final String TAG = "Sparbankerna";
-    private static final String NAME = "Sparbankerna";
-    private static final String NAME_SHORT = "sparbankerna";
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
+    private static final String TAG = "Sparbankerna Företag";
+    private static final String NAME = "Sparbankerna Företag";
+    private static final String NAME_SHORT = "sparbankerna-corporate";
+    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA_CORPORATE;
 
     private static final String APP_ID = "qdorTi1mqZ09Zcyc";
 
-    public Sparbankerna(Context context) {
+    public SparbankernaCorporate(Context context) {
         super(context);
         super.TAG = TAG;
         super.NAME = NAME;
@@ -27,7 +27,7 @@ public class Sparbankerna extends AbstractSwedbank {
 
     }
 
-    public Sparbankerna(String username, String password, Context context)
+    public SparbankernaCorporate(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
@@ -37,4 +37,9 @@ public class Sparbankerna extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
+
+    @Override
+    public int getImageResource() {
+        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable", context.getPackageName());
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
similarity index 57%
copy from bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
copy to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
index 8eb1a88..96f7eb1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SparbankernaYouth.java
@@ -9,16 +9,16 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import java.io.IOException;
 
-public class Sparbankerna extends AbstractSwedbank {
+public class SparbankernaYouth extends AbstractSwedbank {
 
-    private static final String TAG = "Sparbankerna";
-    private static final String NAME = "Sparbankerna";
-    private static final String NAME_SHORT = "sparbankerna";
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
+    private static final String TAG = "Sparbankerna Ung";
+    private static final String NAME = "Sparbankerna Ung";
+    private static final String NAME_SHORT = "sparbankerna-youth";
+    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA_YOUTH;
 
-    private static final String APP_ID = "qdorTi1mqZ09Zcyc";
+    private static final String APP_ID = "QtDHyRnJvEuET2vU";
 
-    public Sparbankerna(Context context) {
+    public SparbankernaYouth(Context context) {
         super(context);
         super.TAG = TAG;
         super.NAME = NAME;
@@ -27,7 +27,7 @@ public class Sparbankerna extends AbstractSwedbank {
 
     }
 
-    public Sparbankerna(String username, String password, Context context)
+    public SparbankernaYouth(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
@@ -37,4 +37,9 @@ public class Sparbankerna extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
+
+    @Override
+    public int getImageResource() {
+        return res.getIdentifier("logo_" + Sparbankerna.NAME_SHORT, "drawable", context.getPackageName());
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
index a671d2f..9c77788 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -13,8 +13,8 @@ public class Swedbank extends AbstractSwedbank {
 
     private static final String TAG = "Swedbank";
     private static final String NAME = "Swedbank";
-    private static final String NAME_SHORT = "swedbank";
     private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
+    protected static final String NAME_SHORT = "swedbank";
 
     private static final String APP_ID = "vgmYRMelBJ0Yzujs";
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
similarity index 53%
copy from bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
copy to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
index 8eb1a88..a1305ac 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankCorporate.java
@@ -9,16 +9,16 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import java.io.IOException;
 
-public class Sparbankerna extends AbstractSwedbank {
+public class SwedbankCorporate extends AbstractSwedbank {
 
-    private static final String TAG = "Sparbankerna";
-    private static final String NAME = "Sparbankerna";
-    private static final String NAME_SHORT = "sparbankerna";
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
+    private static final String TAG = "Swedbank Företag";
+    private static final String NAME = "Swedbank Företag";
+    private static final String NAME_SHORT = "swedbank-corporate";
+    private static final int BANKTYPE_ID = IBankTypes.SWEDBANK_CORPORATE;
 
-    private static final String APP_ID = "qdorTi1mqZ09Zcyc";
+    private static final String APP_ID = "Our91qzclXdNmpdE";
 
-    public Sparbankerna(Context context) {
+    public SwedbankCorporate(Context context) {
         super(context);
         super.TAG = TAG;
         super.NAME = NAME;
@@ -27,7 +27,7 @@ public class Sparbankerna extends AbstractSwedbank {
 
     }
 
-    public Sparbankerna(String username, String password, Context context)
+    public SwedbankCorporate(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
@@ -37,4 +37,9 @@ public class Sparbankerna extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
+
+    @Override
+    public int getImageResource() {
+        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable", context.getPackageName());
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
similarity index 54%
copy from bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
copy to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
index 8eb1a88..9d9e0e4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/SwedbankYouth.java
@@ -9,16 +9,16 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import java.io.IOException;
 
-public class Sparbankerna extends AbstractSwedbank {
+public class SwedbankYouth extends AbstractSwedbank {
 
-    private static final String TAG = "Sparbankerna";
-    private static final String NAME = "Sparbankerna";
-    private static final String NAME_SHORT = "sparbankerna";
-    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
+    private static final String TAG = "Swedbank Ung";
+    private static final String NAME = "Swedbank Ung";
+    private static final String NAME_SHORT = "swedbank-youth";
+    private static final int BANKTYPE_ID = IBankTypes.SWEDBANK_YOUTH;
 
-    private static final String APP_ID = "qdorTi1mqZ09Zcyc";
+    private static final String APP_ID = "19AaEzp0jQJDt3vO";
 
-    public Sparbankerna(Context context) {
+    public SwedbankYouth(Context context) {
         super(context);
         super.TAG = TAG;
         super.NAME = NAME;
@@ -27,7 +27,7 @@ public class Sparbankerna extends AbstractSwedbank {
 
     }
 
-    public Sparbankerna(String username, String password, Context context)
+    public SwedbankYouth(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
@@ -37,4 +37,9 @@ public class Sparbankerna extends AbstractSwedbank {
     protected String getAppId() {
         return APP_ID;
     }
+
+    @Override
+    public int getImageResource() {
+        return res.getIdentifier("logo_" + Swedbank.NAME_SHORT, "drawable", context.getPackageName());
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index ea599d4..38c6db6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -103,4 +103,8 @@ public interface IBankTypes {
     public final static int BREDBAND2VOIP = 79;
     public final static int ESPRESSOHOUSE = 80;
     public final static int MINPENSION = 81;
+    public final static int SWEDBANK_YOUTH = 82;
+    public final static int SWEDBANK_CORPORATE = 83;
+    public final static int SPARBANKERNA_YOUTH = 84;
+    public final static int SPARBANKERNA_CORPORATE = 85;
 }

commit 88a88bb10957ada51da353703f090bba2fded24e
Merge: 026a63e aa16248
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Mar 5 17:46:17 2015 +0100

    Merge pull request #489 from liato/feature/466-handle-connectivity-loss
    
    Only log IOExceptions to Crashlytics if there is an internet connection

commit aa16248340a9a409ad1ebc577c66cb775c93861c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 5 16:24:32 2015 +0100

    Removes all calls to updateComplete from the finally clause

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 39a00f1..060a3f6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -130,44 +130,39 @@ public class AkeliusInvest extends Bank {
 		}
 
 		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://online.akeliusinvest.com/AccountPortfolio.mws");
-			matcher = reAccounts.matcher(response);
-            int accId = 0;
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                ICA					AKELIUSINVEST
-                 * 1: ID                0000000000			Kontonamn
-                 * 2: Name              ICA KONTO			KontoID
-                 * 3: Disponibelt       00.000,00			Kontonummer
-                 * 4: Saldo             1.655,71			Valuta
-                 * 5: 										Tillgängligt belopp
-                 * 6: 										Saldo
-                 */			    
-//				Försök att lösa problemet med för långa, icke radbrytande kontonamn:
-//					if (matcher.group(1).length() > 24)  {
-//						matcher.group(1).replaceFirst("(", "(\n");
-//					}
-               
-                mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());           
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
-                account.setAliasfor(matcher.group(1).trim());
-                
-                accounts.add(account);      
-	                
-                balance = balance.add(Helpers.parseBalance(matcher.group(5)));
-                accId++;
-			}
-						if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-		    super.updateComplete();
+
+        String response = urlopen.open("https://online.akeliusinvest.com/AccountPortfolio.mws");
+        Matcher	matcher = reAccounts.matcher(response);
+        int accId = 0;
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                ICA					AKELIUSINVEST
+             * 1: ID                0000000000			Kontonamn
+             * 2: Name              ICA KONTO			KontoID
+             * 3: Disponibelt       00.000,00			Kontonummer
+             * 4: Saldo             1.655,71			Valuta
+             * 5: 										Tillgängligt belopp
+             * 6: 										Saldo
+             */
+//			Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//				if (matcher.group(1).length() > 24)  {
+//					matcher.group(1).replaceFirst("(", "(\n");
+//				}
+
+            mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());
+			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
+            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
+            account.setAliasfor(matcher.group(1).trim());
+            accounts.add(account);
+
+            balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+            accId++;
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
+        super.updateComplete();
 	}
 
 	@Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 83d6ef4..58e3baa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -132,43 +132,39 @@ public class AkeliusSpar extends Bank {
 		}
 
 		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
-			matcher = reAccounts.matcher(response);
-			int accId = 0;
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                ICA					AKELIUSINVEST
-                 * 1: ID                0000000000			Kontonamn
-                 * 2: Name              ICA KONTO			KontoID
-                 * 3: Disponibelt       00.000,00			Kontonummer
-                 * 4: Saldo             1.655,71			Valuta
-                 * 5: 										Tillgängligt belopp
-                 * 6: 										Saldo
-                 */			    
-//				Försök att lösa problemet med för långa, icke radbrytande kontonamn:
-//					if (matcher.group(1).length() > 24)  {
-//						matcher.group(1).replaceFirst("(", "(\n");
-//					}
-               
-                mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());           
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
-                account.setAliasfor(matcher.group(1).trim());
-                
-                accounts.add(account);      
-                balance = balance.add(Helpers.parseBalance(matcher.group(5)));
-                accId++;
-			}
-						if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-            super.updateComplete();
-        }
+
+		String response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
+		Matcher	matcher = reAccounts.matcher(response);
+		int accId = 0;
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                ICA					AKELIUSINVEST
+             * 1: ID                0000000000			Kontonamn
+             * 2: Name              ICA KONTO			KontoID
+             * 3: Disponibelt       00.000,00			Kontonummer
+             * 4: Saldo             1.655,71			Valuta
+             * 5: 										Tillgängligt belopp
+             * 6: 										Saldo
+             */
+//			Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//				if (matcher.group(1).length() > 24)  {
+//					matcher.group(1).replaceFirst("(", "(\n");
+//				}
+
+            mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());
+			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
+            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
+            account.setAliasfor(matcher.group(1).trim());
+
+            accounts.add(account);
+            balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+            accId++;
+		}
+    	if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+        super.updateComplete();
 	}
 
 	@Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index e2cf936..c8d3e61 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -124,41 +124,38 @@ public class CSN extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		try {
-		    response = urlopen.open("https://www.csn.se/aterbetalning/hurStorArMinSkuld/aktuellStudieskuld.do?javascript=off");
-			Matcher matcher;
-			matcher = reBalance.matcher(response);
-			int i = 0;
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: ID                0
-                 * 2: Name              Lån efter 30 juni 2001 (annuitetslån)
-                 * 3: Amount            123,456
-                 *  
-                 */
-			    BigDecimal amount = Helpers.parseBalance(matcher.group(3).replace(",", "")).negate();
-			    Account account = new Account(
-                        Html.fromHtml(matcher.group(2)).toString().trim(),
-                        amount,
-                        matcher.group(1).trim(),
-                        Account.LOANS);
-			    if (i > 0) {
-			        account.setAliasfor("0");
-			    }
-				accounts.add(account);
-				balance = balance.add(amount);
-				i++;
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
+
+		response = urlopen.open("https://www.csn.se/aterbetalning/hurStorArMinSkuld/aktuellStudieskuld.do?javascript=off");
+		Matcher matcher;
+		matcher = reBalance.matcher(response);
+		int i = 0;
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: ID                0
+             * 2: Name              Lån efter 30 juni 2001 (annuitetslån)
+             * 3: Amount            123,456
+             *
+             */
+		    BigDecimal amount = Helpers.parseBalance(matcher.group(3).replace(",", "")).negate();
+		    Account account = new Account(
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    amount,
+                    matcher.group(1).trim(),
+                    Account.LOANS);
+		    if (i > 0) {
+		        account.setAliasfor("0");
+		    }
+			accounts.add(account);
+			balance = balance.add(amount);
+			i++;
 		}
-        finally {
-            super.updateComplete();
-        }
+			
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+	    }
+        super.updateComplete();
 	}
 	
     @Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 71eb3fb..47b4da7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -96,8 +96,6 @@ public class Chalmrest extends Bank {
 		{
 			throw new BankException(e.getMessage(), e);
 		}
-		finally {
-			super.updateComplete();
-		}
+		super.updateComplete();
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index 4901308..b890d75 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -150,38 +150,35 @@ public class DanskeBank extends Bank {
         else {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " personnummer.");
         }
-		
-		try {
-			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s", mSessionId, mPersonnr));
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Internal acc number?  0123456789
-                 * 2: Account name          Danske Direkt Bas
-                 * 3: Account number        01234567890
-                 * 4: Balance               1.124,56
-                 * 5: Balance (disp.)       1.124,56
-                 * 
-                 */   		
-			    String name = Html.fromHtml(matcher.group(2)).toString().trim();
-			    Account account = new Account(name, Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim());
-			    if (name.contains("lån") || name.contains("Lån")) {
-			        account.setType(Account.LOANS);
-			    }
-			    else {
-		             balance = balance.add(Helpers.parseBalance(matcher.group(5)));
-			    }
-				accounts.add(account);
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-		    super.updateComplete();
+
+		response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s", mSessionId, mPersonnr));
+		matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Internal acc number?  0123456789
+             * 2: Account name          Danske Direkt Bas
+             * 3: Account number        01234567890
+             * 4: Balance               1.124,56
+             * 5: Balance (disp.)       1.124,56
+             *
+             */
+		    String name = Html.fromHtml(matcher.group(2)).toString().trim();
+		    Account account = new Account(name, Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim());
+		    if (name.contains("lån") || name.contains("Lån")) {
+		        account.setType(Account.LOANS);
+		    }
+		    else {
+	             balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+		    }
+			accounts.add(account);
+		}
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
+		super.updateComplete();
 	}
 
 	@Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index d85f00f..95ace26 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -102,28 +102,27 @@ public class FirstCard extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		try {
-			response = urlopen.open("https://www.firstcard.se/mkol/index.jsp");
-			Matcher matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-				/*
-				 * Capture groups:
-				 * GROUP				EXAMPLE DATA
-				 * 1: id				kdKPq4ghlcy9wpXymSzzS46wWQcS_0OT
-				 * 2: account number	1111 3333 7777 9999
-				 * 3: amount 			9 824,08
-				 * 
-				 */				
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
 
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}			
-		} finally {
-            super.updateComplete();
-        }
+		response = urlopen.open("https://www.firstcard.se/mkol/index.jsp");
+		Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+			/*
+			 * Capture groups:
+			 * GROUP				EXAMPLE DATA
+			 * 1: id				kdKPq4ghlcy9wpXymSzzS46wWQcS_0OT
+			 * 2: account number	1111 3333 7777 9999
+			 * 3: amount 			9 824,08
+			 *
+			 */
+			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+		}
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+
+        super.updateComplete();
 	}
 
 	@Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 43af2bb..2dc3b34 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -117,28 +117,25 @@ public class Handelsbanken extends Bank {
 		}
 
 		urlopen = login();
-		Matcher matcher;
-		try {
-			matcher = reAccountsUrl.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
-			}
-			String strAccountsUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);			
-			response = urlopen.open(strAccountsUrl);
-			matcher = reBalance.matcher(response);
-			Integer accountId = 0;
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-				accountIds.add(matcher.group(1));
-				accountId += 1;
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-            super.updateComplete();
-        }
+
+        Matcher matcher = reAccountsUrl.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
+		}
+		String strAccountsUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);
+		response = urlopen.open(strAccountsUrl);
+		matcher = reBalance.matcher(response);
+		Integer accountId = 0;
+		while (matcher.find()) {
+			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			accountIds.add(matcher.group(1));
+			accountId += 1;
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+        super.updateComplete();
 	}
 	
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index e5d5177..2b8f392 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -127,32 +127,26 @@ public class Marginalen extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		Matcher matcher;
-		
-		try {
-	        response = urlopen.open(accountUrl);
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Name              Högräntekonto
-                 * 2: URL               engine?usecase=account&amp;command=transactions&amp;guid=mCmupGvnAAJuC76MGuuRnwCC&amp;commandorigin=0.account_private_viewhandler&amp;account_table=0&amp;hash=Be2HxFargpk2m0BI2tShAACC
-                 * 3: ID                92351124972
-                 * 4: Amount            100.000,00
-                 *  
-                 */
-				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2), Long.parseLong(matcher.group(3)));
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-				accounts.add(account);
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-	      super.updateComplete();
+	    response = urlopen.open(accountUrl);
+        Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Name              Högräntekonto
+             * 2: URL               engine?usecase=account&amp;command=transactions&amp;guid=mCmupGvnAAJuC76MGuuRnwCC&amp;commandorigin=0.account_private_viewhandler&amp;account_table=0&amp;hash=Be2HxFargpk2m0BI2tShAACC
+             * 3: ID                92351124972
+             * 4: Amount            100.000,00
+             *
+             */
+			Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2), Long.parseLong(matcher.group(3)));
+			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+			accounts.add(account);
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
-		
+	    super.updateComplete();
     }
     
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index 51619b5..a258223 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -91,35 +91,30 @@ public class Meniga extends Bank{
         }
         urlopen = login();
 
-        Matcher matcher;
-        try {
-            response = urlopen.open("https://www.meniga.is/Mobile/Accounts");
-            matcher = reAccounts.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Type              id
-                 * 2: Name              accont
-                 * 3: ----              plus or minus
-                 * 4: Balance            5 678
-                 *
-                 */
-                String balanceString ;
-                balanceString = matcher.group(4) + ".00";
-                Account account = new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(balanceString), matcher.group(1).trim());
-                account.setCurrency("ISK");
-                balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-                accounts.add(account);
-            }
-
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
+        response = urlopen.open("https://www.meniga.is/Mobile/Accounts");
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Type              id
+             * 2: Name              accont
+             * 3: ----              plus or minus
+             * 4: Balance            5 678
+             *
+             */
+            String balanceString ;
+            balanceString = matcher.group(4) + ".00";
+            Account account = new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(balanceString), matcher.group(1).trim());
+            account.setCurrency("ISK");
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+            accounts.add(account);
         }
-        finally {
-            super.updateComplete();
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        super.updateComplete();
     }
 
     @Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index ad3cebd..a990c6d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -134,41 +134,37 @@ public class NordeaDK extends Bank {
 		}
 
 		urlopen = login();
-		Matcher matcher;
-		try {
-			matcher = reAccounts.matcher(response);
-
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find)
-						.toString() + " accounts url.");
-			}
-			matcher.reset();
-			while (matcher.find()) {
-				/*
-				 * Capture groups: 
-				 * GROUP 		EXAMPLE DATA 
-				 * 1: Link		https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
-				 * 2: ID 		0 
-				 * 3: Name 		Check-in-konto 
-				 * 4: Amount	1.234,56
-				 */
-				String name = Html.fromHtml(matcher.group(3)).toString().trim();
-				String id = matcher.group(2).toString().trim();
-				BigDecimal amount = Helpers.parseBalance(matcher.group(4));
-
-				accounts.add(new Account(name, amount, id, Account.REGULAR,
-						this.currency));
-				balance = balance.add(amount);
-
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found)
-						.toString());
-			}
-			this.updatePrefix();
-		} finally {
-			super.updateComplete();
+		Matcher matcher = reAccounts.matcher(response);
+
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find)
+					.toString() + " accounts url.");
+		}
+		matcher.reset();
+		while (matcher.find()) {
+			/*
+			 * Capture groups:
+			 * GROUP 		EXAMPLE DATA
+			 * 1: Link		https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
+			 * 2: ID 		0
+			 * 3: Name 		Check-in-konto
+			 * 4: Amount	1.234,56
+			 */
+			String name = Html.fromHtml(matcher.group(3)).toString().trim();
+			String id = matcher.group(2).toString().trim();
+			BigDecimal amount = Helpers.parseBalance(matcher.group(4));
+
+			accounts.add(new Account(name, amount, id, Account.REGULAR,
+					this.currency));
+			balance = balance.add(amount);
+
 		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found)
+					.toString());
+		}
+		this.updatePrefix();
+		super.updateComplete();
 	}
 
 	@Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index fb73b72..bd2400c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -117,38 +117,33 @@ public class Nordnet extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            Matcher matcher;
-            matcher = reBalance.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Name              Efternamnet Förnamnet | Sparkonto
-                 * 2: Account name      Aktie- och fonddepå   | Sparkonto
-                 * 3: Account number    1234567               | 1234 567890 1
-                 * 4: Amount            31 337                | 123
-                 *  
-                 */
-                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
-                        + Html.fromHtml(matcher.group(3)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(4)),
-                        Html.fromHtml(matcher.group(3)).toString().trim().replaceAll(" ", ""));
-
-                // Saving accounts contain white space characters in the account number
-                if (!matcher.group(3).trim().contains(" ")) {
-                    account.setType(Account.FUNDS);
-                }
-                accounts.add(account);
-                balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-            }
-
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        Matcher matcher = reBalance.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Name              Efternamnet Förnamnet | Sparkonto
+             * 2: Account name      Aktie- och fonddepå   | Sparkonto
+             * 3: Account number    1234567               | 1234 567890 1
+             * 4: Amount            31 337                | 123
+             *
+             */
+            Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
+                    + Html.fromHtml(matcher.group(3)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4)),
+                    Html.fromHtml(matcher.group(3)).toString().trim().replaceAll(" ", ""));
+
+            // Saving accounts contain white space characters in the account number
+            if (!matcher.group(3).trim().contains(" ")) {
+                account.setType(Account.FUNDS);
             }
+            accounts.add(account);
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
         }
-        finally {
-            super.updateComplete();
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        super.updateComplete();
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index ea61d33..d484c9d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -109,36 +109,30 @@ public class Nordnetdirekt extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		try {
-			Matcher matcher;
-			matcher = reBalance.matcher(response);
-			if (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Currency          Dep&aring;v&auml;rde - SEK
-                 * 2: Kontantsaldo      13 264,53
-                 * 3: Värdepapper       111 909,05
-                 *  
-                 */
-                accounts.add(new Account(
-                        "Kontosaldo",
-                        Helpers.parseBalance(matcher.group(2)),
-                        "1"));
-                accounts.add(new Account(
-                        "Värdepapper",
-                        Helpers.parseBalance(matcher.group(3)),
-                        "2"));
-				balance = balance.add(Helpers.parseBalance(matcher.group(2)));				
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}		
-        finally {
-            super.updateComplete();
-        }
+		Matcher matcher = reBalance.matcher(response);
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Currency          Dep&aring;v&auml;rde - SEK
+             * 2: Kontantsaldo      13 264,53
+             * 3: Värdepapper       111 909,05
+             *
+             */
+            accounts.add(new Account(
+                    "Kontosaldo",
+                    Helpers.parseBalance(matcher.group(2)),
+                    "1"));
+            accounts.add(new Account(
+                    "Värdepapper",
+                    Helpers.parseBalance(matcher.group(3)),
+                    "2"));
+			balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+        super.updateComplete();
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index e9e2d84..989842a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -162,61 +162,51 @@ public class OKQ8 extends Bank {
 		if (response == null) {
 			urlopen = login();
 		}
-		try {
-			/*
-			 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
-			 * The balance is the first value (of three) that are matched by reBalance expression.
-			 */
-			Matcher matcher;
-			matcher = reBalance.matcher(response);
-			
-			/*
-			 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
-			 * The balance is the first value (of three) that are matched by reBalance expression.
-			 */
-			matcher = reBalance.matcher(response);
-			if(matcher.find())
-			{
-			    accounts.add(new Account("Kvar att utnyttja" , Helpers.parseBalance(matcher.group(1)), "1"));
-			    balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-			}
-			/*
-			 * Find the next value that is "Saldo". Add a new account but don't add to the balance.
-			 */
-			if(matcher.find())
-			{
-			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2"));
-			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)).negate(), "4"));
-			}
+		/*
+		 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
+		 * The balance is the first value (of three) that are matched by reBalance expression.
+		 */
+		Matcher matcher = reBalance.matcher(response);
+		if(matcher.find())
+		{
+		    accounts.add(new Account("Kvar att utnyttja" , Helpers.parseBalance(matcher.group(1)), "1"));
+		    balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+		}
+		/*
+		 * Find the next value that is "Saldo". Add a new account but don't add to the balance.
+		 */
+		if(matcher.find())
+		{
+		    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2"));
+		    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)).negate(), "4"));
+		}
+		/*
+		 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.
+		 */
+		if(matcher.find())
+		{
+		    accounts.add(new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3"));
+		}
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+
+
+		response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
+
+		matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
 			/*
-			 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.
+			 * Capture group 1 = date
+			 * Capture group 2 = text
+			 * Capture group 3 = amount
+			 * Negate the amount since buys are reported as positive.
 			 */
-			if(matcher.find())
-			{
-			    accounts.add(new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3"));
-			}			
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-	
-	
-			response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
-	
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				/*
-				 * Capture group 1 = date
-				 * Capture group 2 = text
-				 * Capture group 3 = amount
-				 * Negate the amount since buys are reported as positive.
-				 */
-				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)).negate()));
-			}
-			accounts.get(0).setTransactions(transactions);
-		} finally {
-            super.updateComplete();
-        }
+			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)).negate()));
+		}
+		accounts.get(0).setTransactions(transactions);
+        super.updateComplete();
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 0bc9502..46ef3da 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -98,67 +98,63 @@ public class Ostgotatrafiken extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
+		String cardOverviewUrl = "https://webtick.ostgotatrafiken.se/webtick/user/pages/CardOverview.iface";
+		response = urlopen.open(cardOverviewUrl);
+		parseTravelCardBalanceFromServerResponse(response);
 
-		try {
-			String cardOverviewUrl = "https://webtick.ostgotatrafiken.se/webtick/user/pages/CardOverview.iface";
-			response = urlopen.open(cardOverviewUrl);
+		Matcher viewStateMatcher = reViewState.matcher(response);
+		if (!viewStateMatcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState");
+		}
+		Matcher moreCardsMatcher = reMoreCards.matcher(response);
+		while (moreCardsMatcher.find()) {
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("form1cardOverviewTabs:j_idcl", moreCardsMatcher.group(1)));
+			postData.add(new BasicNameValuePair("ice.focus", moreCardsMatcher.group(1)));
+			postData.add(new BasicNameValuePair(moreCardsMatcher.group(1), moreCardsMatcher.group(1)));
+			postData.add(new BasicNameValuePair("form1cardOverviewTabs", "form1cardOverviewTabs"));
+			postData.add(new BasicNameValuePair("ice.event.captured", moreCardsMatcher.group(1)));
+			postData.add(new BasicNameValuePair("javax.faces.source", moreCardsMatcher.group(1)));
+			postData.add(new BasicNameValuePair("javax.faces.ViewState", viewStateMatcher.group(1)));
+
+			postData.add(new BasicNameValuePair("icefacesCssUpdates", ""));
+			postData.add(new BasicNameValuePair("javax.faces.partial.event", "click"));
+			postData.add(new BasicNameValuePair("javax.faces.partial.execute", "@all"));
+			postData.add(new BasicNameValuePair("javax.faces.partial.render", "@all"));
+			postData.add(new BasicNameValuePair("ice.event.type", "onclick"));
+			postData.add(new BasicNameValuePair("ice.event.alt", "false"));
+			postData.add(new BasicNameValuePair("ice.event.ctrl", "false"));
+			postData.add(new BasicNameValuePair("ice.event.shift", "false"));
+			postData.add(new BasicNameValuePair("ice.event.meta", "false"));
+			postData.add(new BasicNameValuePair("ice.event.x", "606"));
+			postData.add(new BasicNameValuePair("ice.event.y", "362"));
+			postData.add(new BasicNameValuePair("ice.event.left", "true"));
+			postData.add(new BasicNameValuePair("ice.event.right", "false"));
+			postData.add(new BasicNameValuePair("ice.submit.type", "ice.s"));
+			postData.add(new BasicNameValuePair("ice.submit.serialization", "form"));
+			postData.add(new BasicNameValuePair("javax.faces.partial.ajax", "true"));
+
+			// ice.event.target is sent by browser, but not needed by
+			// server so don't bother parsing response for its correct value
+			//postData.add(new BasicNameValuePair("ice.event.target", "form1cardOverviewTabs:j_idt240:1:j_idt243"));
+
+			// ice.window and ice.view are sent by browser, but by not sending
+			// these to server we get an HTML response which can be parsed
+			// just like the initial response. If including ice.window and
+			// ice.view in POST the server will give us XML data back which
+			// would need separate parsing.
+			//postData.add(new BasicNameValuePair("ice.window", "p7htbwx9t8"));
+			//postData.add(new BasicNameValuePair("ice.view", "vcuag6esom"));
+
+			urlopen.addHeader("Faces-Request", "partial/ajax");
+			response = urlopen.open(cardOverviewUrl, postData);
 			parseTravelCardBalanceFromServerResponse(response);
+		}
 
-			Matcher viewStateMatcher = reViewState.matcher(response);
-			if (!viewStateMatcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState");
-			}
-			Matcher moreCardsMatcher = reMoreCards.matcher(response);
-			while (moreCardsMatcher.find()) {
-				List <NameValuePair> postData = new ArrayList <NameValuePair>();
-				postData.add(new BasicNameValuePair("form1cardOverviewTabs:j_idcl", moreCardsMatcher.group(1)));
-				postData.add(new BasicNameValuePair("ice.focus", moreCardsMatcher.group(1)));
-				postData.add(new BasicNameValuePair(moreCardsMatcher.group(1), moreCardsMatcher.group(1)));
-				postData.add(new BasicNameValuePair("form1cardOverviewTabs", "form1cardOverviewTabs"));
-				postData.add(new BasicNameValuePair("ice.event.captured", moreCardsMatcher.group(1)));
-				postData.add(new BasicNameValuePair("javax.faces.source", moreCardsMatcher.group(1)));
-				postData.add(new BasicNameValuePair("javax.faces.ViewState", viewStateMatcher.group(1)));
-
-				postData.add(new BasicNameValuePair("icefacesCssUpdates", ""));
-				postData.add(new BasicNameValuePair("javax.faces.partial.event", "click"));
-				postData.add(new BasicNameValuePair("javax.faces.partial.execute", "@all"));
-				postData.add(new BasicNameValuePair("javax.faces.partial.render", "@all"));
-				postData.add(new BasicNameValuePair("ice.event.type", "onclick"));
-				postData.add(new BasicNameValuePair("ice.event.alt", "false"));
-				postData.add(new BasicNameValuePair("ice.event.ctrl", "false"));
-				postData.add(new BasicNameValuePair("ice.event.shift", "false"));
-				postData.add(new BasicNameValuePair("ice.event.meta", "false"));
-				postData.add(new BasicNameValuePair("ice.event.x", "606"));
-				postData.add(new BasicNameValuePair("ice.event.y", "362"));
-				postData.add(new BasicNameValuePair("ice.event.left", "true"));
-				postData.add(new BasicNameValuePair("ice.event.right", "false"));
-				postData.add(new BasicNameValuePair("ice.submit.type", "ice.s"));
-				postData.add(new BasicNameValuePair("ice.submit.serialization", "form"));
-				postData.add(new BasicNameValuePair("javax.faces.partial.ajax", "true"));
-
-				// ice.event.target is sent by browser, but not needed by
-				// server so don't bother parsing response for its correct value
-				//postData.add(new BasicNameValuePair("ice.event.target", "form1cardOverviewTabs:j_idt240:1:j_idt243"));
-
-				// ice.window and ice.view are sent by browser, but by not sending
-				// these to server we get an HTML response which can be parsed
-				// just like the initial response. If including ice.window and
-				// ice.view in POST the server will give us XML data back which
-				// would need separate parsing.
-				//postData.add(new BasicNameValuePair("ice.window", "p7htbwx9t8"));
-				//postData.add(new BasicNameValuePair("ice.view", "vcuag6esom"));
-
-				urlopen.addHeader("Faces-Request", "partial/ajax");
-				response = urlopen.open(cardOverviewUrl, postData);
-				parseTravelCardBalanceFromServerResponse(response);
-			}
-
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-			super.updateComplete();
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
+		super.updateComplete();
 	}
 
 	private void parseTravelCardBalanceFromServerResponse(String response) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 6c7f682..fbd6f26 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -131,47 +131,46 @@ public class PayPal extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
-            Matcher matcher = reAccounts.matcher(response);
-            int accId = 1;
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: name              SEK (Primary)
-                 * 2: amount            554.70
-                 * 3: currency          SEK
-                 * 
-                 */
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ""+accId);
-                account.setCurrency(matcher.group(3).trim());
-                accounts.add(account);
-                accId++;
-            }
-            matcher = reBalance.matcher(response);
-            if (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: balance           554.70
-                 * 2: currency          SEK
-                 * 
-                 */
-                balance = Helpers.parseBalance(matcher.group(1));
-                currency = matcher.group(2).trim();
-                if (accounts.isEmpty()) {
-                    // Probably a premier account.
-                    Account account = new Account(currency, balance, "1");
-                    account.setCurrency(currency);
-                    accounts.add(account);                }
-            }
 
+        response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
+        Matcher matcher = reAccounts.matcher(response);
+        int accId = 1;
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: name              SEK (Primary)
+             * 2: amount            554.70
+             * 3: currency          SEK
+             *
+             */
+            Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ""+accId);
+            account.setCurrency(matcher.group(3).trim());
+            accounts.add(account);
+            accId++;
+        }
+        matcher = reBalance.matcher(response);
+        if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: balance           554.70
+             * 2: currency          SEK
+             *
+             */
+            balance = Helpers.parseBalance(matcher.group(1));
+            currency = matcher.group(2).trim();
             if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+                // Probably a premier account.
+                Account account = new Account(currency, balance, "1");
+                account.setCurrency(currency);
+                accounts.add(account);
             }
-        } finally {
-            super.updateComplete();
         }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index e130542..8a23d9a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -98,52 +98,48 @@ public class PlusGirot extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		try {
-			Matcher matcher;
-			matcher = reAccounts.matcher(response);
-			if (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Account holder    Efternamn,Fornamn
-                 * 2: PG account        456 12 34-5
-                 * 3: Amount            123,45
-                 * 4: Credit            24,68
-                 *  
-                 */
-			    Account account = new Account(matcher.group(2).trim() + " (" + Html.fromHtml(matcher.group(1)).toString().trim() + ")",
-			                                    Helpers.parseBalance(matcher.group(3)),
-			                                    matcher.group(2).trim().replaceAll("[^0-9]*", ""));
-				accounts.add(account);
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-	
-	
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Date              2011-04-04
-                 * 2: Specification     UTTAG
-                 * 3: Payment code      Inr.
-                 * 4: Amount            -100,00
-                 *   
-                 */     
-				transactions.add(
-				        new Transaction(matcher.group(1).trim(),
-				        Html.fromHtml(matcher.group(2)).toString().trim() + " " + Html.fromHtml(matcher.group(3)).toString().trim(),
-				        Helpers.parseBalance(matcher.group(4))));
-			}
-			accounts.get(0).setTransactions(transactions);
-		}		
-        finally {
-            super.updateComplete();
-        }
+
+        Matcher matcher = reAccounts.matcher(response);
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Account holder    Efternamn,Fornamn
+             * 2: PG account        456 12 34-5
+             * 3: Amount            123,45
+             * 4: Credit            24,68
+             *
+             */
+		    Account account = new Account(matcher.group(2).trim() + " (" + Html.fromHtml(matcher.group(1)).toString().trim() + ")",
+		                                    Helpers.parseBalance(matcher.group(3)),
+		                                    matcher.group(2).trim().replaceAll("[^0-9]*", ""));
+			accounts.add(account);
+			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+		}
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+
+
+		matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Date              2011-04-04
+             * 2: Specification     UTTAG
+             * 3: Payment code      Inr.
+             * 4: Amount            -100,00
+             *
+             */
+			transactions.add(
+			        new Transaction(matcher.group(1).trim(),
+			        Html.fromHtml(matcher.group(2)).toString().trim() + " " + Html.fromHtml(matcher.group(3)).toString().trim(),
+			        Helpers.parseBalance(matcher.group(4))));
+		}
+		accounts.get(0).setTransactions(transactions);
+        super.updateComplete();
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 9a9abbf..bc0b52e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -112,31 +112,27 @@ public class SevenDay extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		try {
-			Matcher matcher;
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Account id        JigBFAUETrrqVKY+V4Dm3tcoY1n6Usa21IuHxa1BV7MnJT3T6rrGChDcDK0RSuM731uAeB/f9rvPRXRFYCCBcQ
-                 * 2: Account name      Sparkonto: XXX
-                 * 3: Interest          2,55
-                 * 4: Amount            10&nbsp;kr
-                 *  
-                 */			    
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
-				        Helpers.parseBalance(matcher.group(4)),
-				        Html.fromHtml(matcher.group(1)).toString().trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}		
-        finally {
-            super.updateComplete();
-        }
+
+		Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Account id        JigBFAUETrrqVKY+V4Dm3tcoY1n6Usa21IuHxa1BV7MnJT3T6rrGChDcDK0RSuM731uAeB/f9rvPRXRFYCCBcQ
+             * 2: Account name      Sparkonto: XXX
+             * 3: Interest          2,55
+             * 4: Amount            10&nbsp;kr
+             *
+             */
+			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
+			        Helpers.parseBalance(matcher.group(4)),
+			        Html.fromHtml(matcher.group(1)).toString().trim()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+		}
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	    super.updateComplete();
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 7101ccf..3b76e47 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -109,33 +109,31 @@ public class SveaDirekt extends Bank {
         }
 
         urlopen = login();
-        try {
-            List<NameValuePair> postData = new ArrayList<NameValuePair>();
-            postData.add(new BasicNameValuePair("homeForm:balance","Saldo"));
-            postData.add(new BasicNameValuePair("homeForm","homeForm"));
-            response = urlopen.open(ACCOUNTS_URL,postData);
-            Document doc = Jsoup.parse(response);
-            ArrayList<Account> accounts = parseAccounts(doc);
-
-            if (!accounts.isEmpty()) {
-                Account firstAccount = accounts.get(0);
-                // Get account details for first account
-                addAccountDetails(firstAccount, doc);
-                firstAccount.setTransactions(parseTransactions(response));
 
-            }
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("homeForm:balance","Saldo"));
+        postData.add(new BasicNameValuePair("homeForm","homeForm"));
+        response = urlopen.open(ACCOUNTS_URL,postData);
+        Document doc = Jsoup.parse(response);
+        ArrayList<Account> accounts = parseAccounts(doc);
 
-            // Fetch additional accounts transaction pages to get their balance.
-            for (int i = 1; i < accounts.size(); i++) {
-                Account account = accounts.get(i);
-                response = urlopen.open(TRANSACTIONS_URL, createTransactionParams(account));
-                addAccountDetails(account, Jsoup.parse(response));
-                account.setTransactions(parseTransactions(response));
-            }
-            this.setAccounts(accounts);
-        } finally {
-          super.updateComplete();
+        if (!accounts.isEmpty()) {
+            Account firstAccount = accounts.get(0);
+            // Get account details for first account
+            addAccountDetails(firstAccount, doc);
+            firstAccount.setTransactions(parseTransactions(response));
+
+        }
+
+        // Fetch additional accounts transaction pages to get their balance.
+        for (int i = 1; i < accounts.size(); i++) {
+            Account account = accounts.get(i);
+            response = urlopen.open(TRANSACTIONS_URL, createTransactionParams(account));
+            addAccountDetails(account, Jsoup.parse(response));
+            account.setTransactions(parseTransactions(response));
         }
+        this.setAccounts(accounts);
+        super.updateComplete();
     }
 
     private ArrayList<Account> parseAccounts(Document pDocument) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index ec4fd36..0806fcb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -83,38 +83,32 @@ public class TestBank extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-		    
-            response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/accounts.htm");
-            matcher = reAccounts.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Name              Sparkonto
-                 * 2: Amount            83553,70
-                 * 3: ID                1
-                 * 4: Type              trans|fund
-                 *  
-                 */
-                Account acc = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ("fund".equals(matcher.group(4)) ? "f:" : "")+matcher.group(3).trim());
-                if ("fund".equals(matcher.group(4))) {
-                    acc.setType(Account.FUNDS);
-                }
-                else {
-                    balance = balance.add(Helpers.parseBalance(matcher.group(3)));    
-                }
-                accounts.add(acc);
-            }		        
+		String response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/accounts.htm");
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Name              Sparkonto
+             * 2: Amount            83553,70
+             * 3: ID                1
+             * 4: Type              trans|fund
+             *
+             */
+            Account acc = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ("fund".equals(matcher.group(4)) ? "f:" : "")+matcher.group(3).trim());
+            if ("fund".equals(matcher.group(4))) {
+                acc.setType(Account.FUNDS);
+            }
+            else {
+                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+            }
+            accounts.add(acc);
+        }
 
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-		    super.updateComplete();
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
+		super.updateComplete();
 	}
 
 	@Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 142ecf4..cdebeaf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -106,45 +106,42 @@ public class Vasttrafik extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            response = urlopen.open("https://www.vasttrafik.se/mina-sidor-inloggad/mina-kort/");
-            Matcher matcher;
-            Matcher matcher_b;
-
-            matcher = reAccounts.matcher(response);
-            while (matcher.find()) {
+        response = urlopen.open("https://www.vasttrafik.se/mina-sidor-inloggad/mina-kort/");
+        Matcher matcher;
+        Matcher matcher_b;
+
+        matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Name              Nytt
+             * 2: Balance information
+             */
+
+			if ("".equals(matcher.group(1))) {
+				continue;
+			}
+
+            matcher_b = reBalance.matcher(matcher.group(2));
+            if (matcher_b.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
-                 * 1: Name              Nytt
-                 * 2: Balance information
+                 * 1: Type              Kontoladdning
+                 * 2: Amount            592,80 kr
                  */
 
-				if ("".equals(matcher.group(1))) {
-					continue;
-				}
-
-                matcher_b = reBalance.matcher(matcher.group(2));
-                if (matcher_b.find()) {
-                    /*
-                     * Capture groups:
-                     * GROUP                EXAMPLE DATA
-                     * 1: Type              Kontoladdning
-                     * 2: Amount            592,80 kr
-                     */
-
-					String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
+				String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
 
-					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(1)));
-					balance = balance.add(Helpers.parseBalance(balanceString));
-                }
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(1)));
+				balance = balance.add(Helpers.parseBalance(balanceString));
             }
+        }
 
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        } finally {
-            super.updateComplete();
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        super.updateComplete();
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index b819a21..9b558ae 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -116,33 +116,29 @@ public class Volvofinans extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		String response = null;
+		String response = urlopen.open("https://inloggad.volvofinans.se/privat/kund/kortkonto/oversikt/kortkonton.html");
 		try {
-			response = urlopen.open("https://inloggad.volvofinans.se/privat/kund/kortkonto/oversikt/kortkonton.html");
-			try {
-				JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
-				JSONArray data = object.getJSONArray("data");
-
-				int length = data.length();
-				for (int index = 0; index < length; index++) {
-					JSONObject account = data.getJSONObject(index);
-					Document d = Jsoup.parse(account.getString("namnUrl"));
-					Element e = d.getElementsByTag("a").first();
-					if (e != null && e.attr("href") != null) {
-    					mAccountUrlMappings.put(account.getString("kontonummer"), e.attr("href").replace("/info.html", "/info/kontoutdrag.html"));
-					}
-					accounts.add(new Account(String.format("%s (%s)", account.getString("namn"), account.getString("kontonummer")), Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(Helpers.parseBalance(account.getString("limit"))), account.getString("kontonummer")));
+			JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
+			JSONArray data = object.getJSONArray("data");
+
+			int length = data.length();
+			for (int index = 0; index < length; index++) {
+				JSONObject account = data.getJSONObject(index);
+				Document d = Jsoup.parse(account.getString("namnUrl"));
+				Element e = d.getElementsByTag("a").first();
+				if (e != null && e.attr("href") != null) {
+    				mAccountUrlMappings.put(account.getString("kontonummer"), e.attr("href").replace("/info.html", "/info/kontoutdrag.html"));
 				}
+				accounts.add(new Account(String.format("%s (%s)", account.getString("namn"), account.getString("kontonummer")), Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(Helpers.parseBalance(account.getString("limit"))), account.getString("kontonummer")));
 			}
-			catch (JSONException e) {
-				throw new BankException(e.getMessage(), e);
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-	      super.updateComplete();
 		}
+		catch (JSONException e) {
+			throw new BankException(e.getMessage(), e);
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+        super.updateComplete();
 	}
 	
     @Override
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 3407020..e004d12 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -254,59 +254,56 @@ public class Nordea extends Bank {
 		// This puts us at PageType.ENTRY
         urlopen = login();
         String loanName;
-		Matcher matcher;
-		try {
-			// Add regular accounts
-            matcher = reAccountLink.matcher(this.lastResponse);
-			while (matcher.find()) {
-				accounts.add(new Account(
-                        // Account name
-						Html.fromHtml(matcher.group(3)).toString().trim(), 
-						// Balance
-                        Helpers.parseBalance(Html.fromHtml(matcher.group(5)).toString()),
-                        // Account identifier - half censured account number: "************1234"
-						Html.fromHtml(matcher.group(4)).toString().trim()
-						));
-			}
 
-            // TODO: Code for funds
+		// Add regular accounts
+        Matcher matcher = reAccountLink.matcher(this.lastResponse);
+		while (matcher.find()) {
+			accounts.add(new Account(
+                    // Account name
+					Html.fromHtml(matcher.group(3)).toString().trim(),
+					// Balance
+                    Helpers.parseBalance(Html.fromHtml(matcher.group(5)).toString()),
+                    // Account identifier - half censured account number: "************1234"
+					Html.fromHtml(matcher.group(4)).toString().trim()
+					));
+		}
 
-            goToPage(PageType.CREDIT_CARDS);
-            matcher = reCreditCardLink.matcher(this.lastResponse);
-            // Add credit cards
-            while (matcher.find()) {
-                accounts.add(new Account(
-                        // Account/Credit card name
-                        matcher.group(2),
-                        // Balance (not available through simple login)
-                        Helpers.parseBalance(matcher.group(5)),
-                        // Account/Credit card identifier
-                        "c:" + matcher.group(3),
-                        -1L,
-                        Account.CCARD
-                        ));
-            }
+        // TODO: Code for funds
 
-            goToPage(PageType.LOANS);
-            matcher = reLoanLink.matcher(this.lastResponse);
-            // Add loans
-            while (matcher.find()) {
-                loanName = matcher.group(2) + ' ' + matcher.group(3);
-                accounts.add(new Account(
-                        loanName,
-                        Helpers.parseBalance(matcher.group(5)),
-                        "l:" + matcher.group(3).trim(),
-                        -1L,
-                        Account.LOANS
-                ));
-            }
+        goToPage(PageType.CREDIT_CARDS);
+        matcher = reCreditCardLink.matcher(this.lastResponse);
+        // Add credit cards
+        while (matcher.find()) {
+            accounts.add(new Account(
+                    // Account/Credit card name
+                    matcher.group(2),
+                    // Balance (not available through simple login)
+                    Helpers.parseBalance(matcher.group(5)),
+                    // Account/Credit card identifier
+                    "c:" + matcher.group(3),
+                    -1L,
+                    Account.CCARD
+                    ));
+        }
 
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		} finally {
-		    super.updateComplete();
+        goToPage(PageType.LOANS);
+        matcher = reLoanLink.matcher(this.lastResponse);
+        // Add loans
+        while (matcher.find()) {
+            loanName = matcher.group(2) + ' ' + matcher.group(3);
+            accounts.add(new Account(
+                    loanName,
+                    Helpers.parseBalance(matcher.group(5)),
+                    "l:" + matcher.group(3).trim(),
+                    -1L,
+                    Account.LOANS
+            ));
+        }
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
+        super.updateComplete();
 		
         // Demo account to use with screenshots
         //accounts.add(new Account("Personkonto", Helpers.parseBalance("7953.37"), "1"));
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index c3544cc..adbe42c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -147,36 +147,33 @@ public abstract class SEBKortBase extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)), UserResponse.class);
-            BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)), BillingUnitsResponse.class);
-
-            boolean multipleAccounts = br.getBody().size() > 1;
-            for (BillingUnit bu : br.getBody()) {
-                Account account = new Account(formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp", multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
-                account.setType(Account.CCARD);
-                account.setCurrency(currency);
-                mBillingUnitIds.put(account, bu.getBillingUnitId());
-                accounts.add(account);
-                balance = balance.add(account.getBalance());
-                account = new Account(formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts), Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
-                account.setType(Account.OTHER);
-                account.setAliasfor(bu.getArrangementNumber());
-                account.setCurrency(currency);
-                accounts.add(account);
-                account = new Account(formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts), Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
-                account.setType(Account.OTHER);
-                account.setAliasfor(bu.getArrangementNumber());
-                account.setCurrency(currency);
-                accounts.add(account);
-            }
+        UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)), UserResponse.class);
+        BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)), BillingUnitsResponse.class);
+
+        boolean multipleAccounts = br.getBody().size() > 1;
+        for (BillingUnit bu : br.getBody()) {
+            Account account = new Account(formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp", multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
+            account.setType(Account.CCARD);
+            account.setCurrency(currency);
+            mBillingUnitIds.put(account, bu.getBillingUnitId());
+            accounts.add(account);
+            balance = balance.add(account.getBalance());
+            account = new Account(formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts), Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
+            account.setType(Account.OTHER);
+            account.setAliasfor(bu.getArrangementNumber());
+            account.setCurrency(currency);
+            accounts.add(account);
+            account = new Account(formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts), Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
+            account.setType(Account.OTHER);
+            account.setAliasfor(bu.getArrangementNumber());
+            account.setCurrency(currency);
+            accounts.add(account);
+        }
 
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        } finally {
-            super.updateComplete();
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        super.updateComplete();
     }
 
     private String formatAccountName(String accountNumber, String name, boolean includeAccountNnumber) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index eb55fbc..d4befe8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -138,28 +138,25 @@ public abstract class AbstractSwedbank extends Bank {
         }
         urlopen = login();
 
-        try {
-            ProfileResponse profileResponse = getAvailableProfiles();
-            setDefaultProfile(getBankId(profileResponse.getBanks()));
+        ProfileResponse profileResponse = getAvailableProfiles();
+        setDefaultProfile(getBankId(profileResponse.getBanks()));
 
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/overview"), false);
-            if(httpResponse.getStatusLine().getStatusCode() != 200) {
-                throw new BankException(httpResponse.getStatusLine().toString());
-            }
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/overview"), false);
+        if(httpResponse.getStatusLine().getStatusCode() != 200) {
+            throw new BankException(httpResponse.getStatusLine().toString());
+        }
 
-            OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),OverviewResponse.class);
-            addAccounts(overviewResponse.getTransactionAccounts(),Account.REGULAR);
-            addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
-            addAccounts(overviewResponse.getTransactionDisposalAccounts(),Account.REGULAR);
-            addAccounts(overviewResponse.getSavingDisposalAccounts(),Account.REGULAR);
-            addCardAccounts(overviewResponse.getCardAccounts());
-            addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
-            if (this.accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        } finally {
-            updateComplete();
+        OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),OverviewResponse.class);
+        addAccounts(overviewResponse.getTransactionAccounts(),Account.REGULAR);
+        addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
+        addAccounts(overviewResponse.getTransactionDisposalAccounts(),Account.REGULAR);
+        addAccounts(overviewResponse.getSavingDisposalAccounts(),Account.REGULAR);
+        addCardAccounts(overviewResponse.getCardAccounts());
+        addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
+        if (this.accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        updateComplete();
     }
 
     @Override

commit 5ca95735d542bd7b55b51651bb5dd75695d12810
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 5 02:18:13 2015 +0100

    Only log IOExceptions to Crashlytics if there was an internet connection when the exception was thrown.

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index c12a6c2..adcdd22 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -16,6 +16,7 @@
 
 package com.liato.bankdroid;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -55,6 +56,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.NetworkUtils;
 
 public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private final static String TAG = "BankEditActivity";
@@ -256,6 +258,11 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 			}
             catch (BankChoiceException e) {
                 this.exc = e;
+            } catch (IOException e) {
+                this.exc = e;
+                if(NetworkUtils.isInternetAvailable()) {
+                    Crashlytics.logException(e);
+                }
             }
 			return null;
 		}
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index be51536..b0a9aea 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -16,6 +16,7 @@
 
 package com.liato.bankdroid;
 
+import java.io.IOException;
 import java.util.ArrayList;
 
 import android.app.AlertDialog;
@@ -36,6 +37,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.NetworkUtils;
 
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
     private final static String TAG = "DataRetrieverTask";
@@ -100,11 +102,16 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
 						+ ")");
 				DBAdapter.disable(bank, parent);
-			}
-            catch (BankChoiceException e) {
+			} catch (BankChoiceException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
                 Log.e(TAG, "BankChoiceError: " + e.getMessage());
+            } catch(IOException e) {
+                this.errors.add(bank.getName() + " (" + bank.getUsername()
+                        + ")");
+                if(NetworkUtils.isInternetAvailable()) {
+                    Crashlytics.logException(e);
+                }
             }
 
 			final SharedPreferences prefs = PreferenceManager
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 8bc2cdc..118e305 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -45,6 +45,9 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.utils.NetworkUtils;
+
+import java.io.IOException;
 
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 	private final static String TAG = "BankdroidWidgetProvider";
@@ -379,7 +382,12 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
                 catch (BankChoiceException e) {
                     Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
                 }
-
+                catch(IOException e) {
+                    Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+                    if(NetworkUtils.isInternetAvailable()) {
+                        Crashlytics.logException(e);
+                    }
+                }
 				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
 				return null;
 			}

commit b0aa9dd2764a92715e8e918cc211389e287b0842
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 5 02:16:37 2015 +0100

    Adds NetworkUtils class for common network related helper methods.

diff --git app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
new file mode 100644
index 0000000..159bd26
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/utils/NetworkUtils.java
@@ -0,0 +1,35 @@
+package com.liato.bankdroid.utils;
+
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+public class NetworkUtils {
+
+    private NetworkUtils() {}
+
+    public static boolean isInternetAvailable() {
+        return ping(new byte[]{8,8,8,8}, 500);
+    }
+
+
+    public static boolean ping(byte[] ipAddress, int timeout) {
+        DatagramSocket datagramSocket= null;
+        try {
+            datagramSocket = new DatagramSocket();
+            datagramSocket.setSoTimeout(timeout);
+            datagramSocket.connect(InetAddress.getByAddress(ipAddress), 7);
+            if (datagramSocket.isConnected()) {
+                return true;
+            }
+        } catch (SocketException | UnknownHostException e) {
+            return false;
+        } finally {
+            if(datagramSocket != null) {
+                datagramSocket.close();
+            }
+        }
+        return false;
+    }
+}

commit 7a975968bb619c1e92c88dbae5130a8283ac5795
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Mar 5 01:55:42 2015 +0100

    Throws IOException from bank update methods.
    
    Removes all IOException catches where it was just re-thrown as a BankException.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 874a210..f3bfed5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -100,13 +100,14 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.res = this.context.getResources();
     }
 
-    public void update(String username, String password) throws BankException, LoginException, BankChoiceException {
+    public void update(String username, String password) throws BankException, LoginException,
+            BankChoiceException, IOException {
         this.username = username;
         this.password = password;
         this.update();
     }
 
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         balance = new BigDecimal(0);
         oldAccounts = new HashMap<String, Account>();
         for(Account account: accounts) {
@@ -115,10 +116,11 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         accounts = new ArrayList<Account>();
     }
 
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
     }
 
-    public void updateAllTransactions() throws LoginException, BankException {
+    public void updateAllTransactions() throws LoginException, BankException, IOException {
         if (urlopen == null) {
             urlopen = login();
         }
@@ -127,7 +129,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         }
     }
 
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         return null;
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 45888eb..d2653ec 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -61,13 +61,13 @@ public abstract class AbsIkanoPartner extends Bank {
     }
 
     public AbsIkanoPartner(String username, String password, Context context) throws BankException, LoginException,
-            BankChoiceException {
+            BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
 
@@ -100,26 +100,19 @@ public abstract class AbsIkanoPartner extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
                     || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")
                     || response.contains("elaktig självbetjäningskod")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
-
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -130,54 +123,47 @@ public abstract class AbsIkanoPartner extends Bank {
         Element element = d.select("#primary-nav > li:eq(1) > a").first();
         if (element != null && element.attr("href") != null) {
             String myAccountUrl = element.attr("href");
-            try {
-                response = urlopen.open("https://partner.ikanobank.se/" + myAccountUrl);
-                d = Jsoup.parse(response);
-                Elements es = d.select("#CustomerAccountInformationSpan > span > span");
-                int accId = 0;
-                for (Element el : es) {
-                    Element name = el.select("> span > span:eq(0)").first();
-                    Element balance = el.select("> span:eq(1)").first();
-                    Element currency = el.select("> span:eq(2)").first();
-                    if (name != null && balance != null && currency != null) {
-                        Account account = new Account(name.text().trim(), Helpers.parseBalance(balance.text()),
-                                Integer.toString(accId));
-                        account.setCurrency(Helpers.parseCurrency(currency.text(), "SEK"));
-                        if (accId > 0) {
-                            account.setAliasfor("0");
-                        }
-                        accounts.add(account);
-                        accId++;
-                    }
-                }
-                if (accounts.isEmpty()) {
-                    throw new BankException(res.getText(R.string.no_accounts_found).toString());
-                }
-                // Use the amount from "Kvar att handla för" which should be the
-                // last account in the list.
-                this.balance = accounts.get(accounts.size() - 1).getBalance();
-                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                es = d.select("#ShowCustomerTransactionPurchasesInformationDiv table tr:has(td)");
-                for (Element el : es) {
-                    if (el.childNodeSize() == 6) {
-                        Transaction transaction = new Transaction(el.child(0).text().trim(), el.child(1).text().trim(),
-                                Helpers.parseBalance(el.child(2).text()));
-                        transaction.setCurrency(Helpers.parseCurrency(el.child(3).text().trim(), "SEK"));
-                        transactions.add(transaction);
+
+            response = urlopen.open("https://partner.ikanobank.se/" + myAccountUrl);
+            d = Jsoup.parse(response);
+            Elements es = d.select("#CustomerAccountInformationSpan > span > span");
+            int accId = 0;
+            for (Element el : es) {
+                Element name = el.select("> span > span:eq(0)").first();
+                Element currency = el.select("> span:eq(2)").first();
+                Element balance = el.select("> span:eq(1)").first();
+                if (name != null && balance != null && currency != null) {
+                    Account account = new Account(name.text().trim(), Helpers.parseBalance(balance.text()),
+                            Integer.toString(accId));
+                    account.setCurrency(Helpers.parseCurrency(currency.text(), "SEK"));
+                    if (accId > 0) {
+                        account.setAliasfor("0");
                     }
+                    accounts.add(account);
+                    accId++;
                 }
-                accounts.get(0).setTransactions(transactions);
             }
-
-            catch (ClientProtocolException e) {
-                throw new BankException(e.getMessage(), e);
-            } catch (IOException e) {
-                throw new BankException(e.getMessage(), e);
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+            // Use the amount from "Kvar att handla för" which should be the
+            // last account in the list.
+            this.balance = accounts.get(accounts.size() - 1).getBalance();
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            es = d.select("#ShowCustomerTransactionPurchasesInformationDiv table tr:has(td)");
+            for (Element el : es) {
+                if (el.childNodeSize() == 6) {
+                    Transaction transaction = new Transaction(el.child(0).text().trim(), el.child(1).text().trim(),
+                            Helpers.parseBalance(el.child(2).text()));
+                    transaction.setCurrency(Helpers.parseCurrency(el.child(3).text().trim(), "SEK"));
+                    transactions.add(transaction);
+                }
             }
+            accounts.get(0).setTransactions(transactions);
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         super.updateComplete();
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 80f03e4..39a00f1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -77,15 +77,15 @@ public class AkeliusInvest extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public AkeliusInvest(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public AkeliusInvest(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_akeliusinvest));
         String response = urlopen.open("https://online.akeliusinvest.com/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
@@ -106,32 +106,24 @@ public class AkeliusInvest extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://online.akeliusinvest.com/login.mws");
     }
     
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Matcher matcher = reError.matcher(response);
-			if (matcher.find()) {
-			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
-			        throw new LoginException(errormsg);    
-			    }
-			    else {
-	                 throw new BankException(errormsg);    
-			    }
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		Matcher matcher = reError.matcher(response);
+		if (matcher.find()) {
+		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+		    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+		        throw new LoginException(errormsg);
+		    }
+		    else {
+	            throw new BankException(errormsg);
 			}
 		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
 		return urlopen;
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -173,43 +165,32 @@ public class AkeliusInvest extends Bank {
 						if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
 		} finally {
 		    super.updateComplete();
 		}
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
         if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
         String accountId = mIdMappings.get(account.getId());
 		String response = null;
 		Matcher matcher;
-		try {
-			response = urlopen.open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="+accountId);
-			matcher = reTransactions.matcher(response);
-			/* 				ICA-banken	Akelius Invest
-			 * Beskrivning	1			2
-			 * Datum		2			1
-			 * Belopp		3			3
-			 */
+		response = urlopen.open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="+accountId);
+		matcher = reTransactions.matcher(response);
+		/* 				ICA-banken	Akelius Invest
+		 * Beskrivning	1			2
+		 * Datum		2			1
+		 * Belopp		3			3
+		 */
 			
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+		}
+
+		account.setTransactions(transactions);
 	}		
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 079f2e1..83d6ef4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -78,15 +78,15 @@ public class AkeliusSpar extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public AkeliusSpar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public AkeliusSpar(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_akeliusspar));
         String response = urlopen.open("https://www.online.akeliusspar.se/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
@@ -107,32 +107,25 @@ public class AkeliusSpar extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://www.online.akeliusspar.se/login.mws");
     }
     
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Matcher matcher = reError.matcher(response);
-			if (matcher.find()) {
-			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
-			        throw new LoginException(errormsg);    
-			    }
-			    else {
-	                 throw new BankException(errormsg);    
-			    }
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+
+		LoginPackage lp = preLogin();
+		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		Matcher matcher = reError.matcher(response);
+		if (matcher.find()) {
+		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+		    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+		        throw new LoginException(errormsg);
+		    }
+		    else {
+	             throw new BankException(errormsg);
+		    }
 		}
 		return urlopen;
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -173,43 +166,33 @@ public class AkeliusSpar extends Bank {
 						if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
 		} finally {
             super.updateComplete();
         }
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
         if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
         String accountId = mIdMappings.get(account.getId());
 		String response = null;
 		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+accountId);
-			matcher = reTransactions.matcher(response);
-			/* 				ICA-banken	Akelius Invest
-			 * Beskrivning	1			2
-			 * Datum		2			1
-			 * Belopp		3			3
-			 */
-			
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
+
+		response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+accountId);
+		matcher = reTransactions.matcher(response);
+		/* 				ICA-banken	Akelius Invest
+		 * Beskrivning	1			2
+		 * Datum		2			1
+		 * Belopp		3			3
+		 */
 			
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 		}
+
+		account.setTransactions(transactions);
 	}		
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index eac29ba..10aba12 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -69,14 +69,14 @@ public class AmericanExpress extends Bank {
         super.URL = URL;
     }
 
-    public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public AmericanExpress(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress_global));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
@@ -102,24 +102,18 @@ public class AmericanExpress extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
-            if (!response.contains("Your Personal Cards")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        if (!response.contains("Your Personal Cards")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException,IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -151,43 +145,38 @@ public class AmericanExpress extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
 
-        try {
-            response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
-            Matcher matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-            SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
-            SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
-            Date transactionDate;
-
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Date                  17 jan 2011
-                 * 2: Specification         xx
-                 * 3: Amount                1.582,00&nbsp;kr
-                 * 
-                 */
-                try {
-                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
-                    String strDate = sdfTo.format(transactionDate);
-                    transactions.add(new Transaction(strDate,
-                                                     Html.fromHtml(matcher.group(2)).toString().trim(),
-                                                     Helpers.parseBalance(matcher.group(3).trim()).negate()));
-                }
-                catch (ParseException e) {
-                    Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
-                }
+        response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
+        Matcher matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+        SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
+        SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
+        Date transactionDate;
+
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Date                  17 jan 2011
+             * 2: Specification         xx
+             * 3: Amount                1.582,00&nbsp;kr
+             *
+             */
+            try {
+                transactionDate = sdfFrom.parse(matcher.group(1).trim());
+                String strDate = sdfTo.format(transactionDate);
+                transactions.add(new Transaction(strDate,
+                                                 Html.fromHtml(matcher.group(2)).toString().trim(),
+                                                 Helpers.parseBalance(matcher.group(3).trim()).negate()));
+            }
+            catch (ParseException e) {
+                Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
             }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
+        account.setTransactions(transactions);
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 10ea936..1eb93d2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -63,42 +63,35 @@ public class AppeakPoker extends Bank {
         currency = "chips";
 	}
 
-	public AppeakPoker(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public AppeakPoker(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+	protected LoginPackage preLogin() throws BankException, IOException {
 		urlopen = new Urllib(context);
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
 		return new LoginPackage(urlopen, postData, "", String.format("http://poker.appeak.se/playerInfo/?username=%s", username));
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            String response = urlopen.open(lp.getLoginTarget());
-            Document d = Jsoup.parse(response);
-            Element e = d.select("#content > table tr:eq(2) td:eq(1)").first();
-            if (e == null) {
-                throw new LoginException(res.getText(R.string.invalid_username).toString());
-            } else {
-            	mChips = e.html();
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        String response = urlopen.open(lp.getLoginTarget());
+        Document d = Jsoup.parse(response);
+        Element e = d.select("#content > table tr:eq(2) td:eq(1)").first();
+        if (e == null) {
+            throw new LoginException(res.getText(R.string.invalid_username).toString());
+        } else {
+        	mChips = e.html();
         }
         return urlopen;		
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null) {
 			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
@@ -115,4 +108,4 @@ public class AppeakPoker extends Bank {
         }
         super.updateComplete();
 	}
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
index dcae4ce..5c6ef98 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Audi extends AbsIkanoPartner {
     private static final String TAG = "Audi";
@@ -40,7 +42,8 @@ public class Audi extends AbsIkanoPartner {
         this.structId = "2177";
     }
 
-    public Audi(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Audi(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 69db5c5..f4652a0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -71,15 +71,15 @@ public class BetterGlobe extends Bank {
 		super.currency = "EUR";
 	}
 
-	public BetterGlobe(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public BetterGlobe(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context);
         urlopen.setAllowCircularRedirects(true);
 		HashMap<String, String> headers = urlopen.getHeaders();
@@ -91,22 +91,15 @@ public class BetterGlobe extends Bank {
         return new LoginPackage(urlopen, postData, "", "http://betterglobe.com/Login.aspx?rememberMe=False");
     }
     
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
 		return urlopen;
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -114,53 +107,43 @@ public class BetterGlobe extends Bank {
 
 		urlopen = login();
 		Matcher matcher;
-		String response;
-		try {
-			response = urlopen.open("http://betterglobe.com/bgaccount.aspx/report");
-			matcher = reBalance.matcher(response);
-			
-			while (matcher.find()) {
-				Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(1)), "tillgangligt");
-				tillgangligt.setCurrency("EUR");
-				accounts.add(tillgangligt);
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-			}
-			
-			response = urlopen.open("http://betterglobe.com/mytrees.aspx/Valueforecast");
-			matcher = reForecast.matcher(response);
-
-			while (matcher.find()) {
-				Account inkop  = new Account("Inköp",              Helpers.parseBalance(matcher.group(2)), "inkop");
-				Account netto  = new Account("Beräknad vinst",     Helpers.parseBalance(matcher.group(3)), "netto");
-				Account brutto = new Account("Beräknat slutvärde", Helpers.parseBalance(matcher.group(1)), "brutto");
-				inkop.setCurrency("EUR");
-				brutto.setCurrency("EUR");
-				netto.setCurrency("EUR");
-				accounts.add(inkop);
-				accounts.add(brutto);
-				accounts.add(netto);
-				balance = balance.add(Helpers.parseBalance(matcher.group(2)));;
-			}
-
-			response = urlopen.open("http://betterglobe.com/mytrees.aspx");
-			matcher = reTrees.matcher(response);
-
-			while (matcher.find()) {
-				Account trees = new Account("Innehav", Helpers.parseBalance(matcher.group(1)), "trees");
-				trees.setCurrency("träd");
-				accounts.add(trees);
-			}
-				
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
+		String response = urlopen.open("http://betterglobe.com/bgaccount.aspx/report");
+		matcher = reBalance.matcher(response);
+
+		while (matcher.find()) {
+			Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(1)), "tillgangligt");
+			tillgangligt.setCurrency("EUR");
+			accounts.add(tillgangligt);
+			balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+		}
+
+		response = urlopen.open("http://betterglobe.com/mytrees.aspx/Valueforecast");
+		matcher = reForecast.matcher(response);
+
+		while (matcher.find()) {
+			Account inkop  = new Account("Inköp",              Helpers.parseBalance(matcher.group(2)), "inkop");
+			Account netto  = new Account("Beräknad vinst",     Helpers.parseBalance(matcher.group(3)), "netto");
+			Account brutto = new Account("Beräknat slutvärde", Helpers.parseBalance(matcher.group(1)), "brutto");
+			inkop.setCurrency("EUR");
+			brutto.setCurrency("EUR");
+			netto.setCurrency("EUR");
+			accounts.add(inkop);
+			accounts.add(brutto);
+			accounts.add(netto);
+			balance = balance.add(Helpers.parseBalance(matcher.group(2)));;
 		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
+
+		response = urlopen.open("http://betterglobe.com/mytrees.aspx");
+		matcher = reTrees.matcher(response);
+
+		while (matcher.find()) {
+			Account trees = new Account("Innehav", Helpers.parseBalance(matcher.group(1)), "trees");
+			trees.setCurrency("träd");
+			accounts.add(trees);
 		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+
+	    if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
 	}
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index 467c10a..6c63336 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -64,14 +64,14 @@ public class Bioklubben extends Bank {
         currency = context.getString(R.string.points);
     }
 
-    public Bioklubben(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Bioklubben(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context);
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("http://bioklubben.sf.se/Start.aspx");
@@ -102,52 +102,42 @@ public class Bioklubben extends Bank {
         return new LoginPackage(urlopen, postData, response, "http://bioklubben.sf.se/Start.aspx");
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Felaktigt anv")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Felaktigt anv")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            Document d = Jsoup.parse(urlopen.open("http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
-            Element e = d.getElementById("ctl00_ContentPlaceHolder1_BonusPointsLabel");
-            if (e == null) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString() + " points element.");
-            }
-            BigDecimal b = Helpers.parseBalance(e.text());
-            Account a = new Account("Poäng", b, "1");
-            a.setCurrency(context.getString(R.string.points));
-            accounts.add(a);
-            balance = balance.add(a.getBalance());
-
-            Elements es = d.select(".GridViewStd_Item,.GridViewStd_ItemAlt");
-            List<Transaction> transactions = new ArrayList<Transaction>();
-            if (es != null) {
-                for (Element el : es) {
-                    transactions.add(new Transaction(el.child(0).text().trim(), el.child(1).text().trim(), Helpers.parseBalance(el.child(2).text())));
-                }
+        Document d = Jsoup.parse(urlopen.open("http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
+        Element e = d.getElementById("ctl00_ContentPlaceHolder1_BonusPointsLabel");
+        if (e == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " points element.");
+        }
+        BigDecimal b = Helpers.parseBalance(e.text());
+        Account a = new Account("Poäng", b, "1");
+        a.setCurrency(context.getString(R.string.points));
+        accounts.add(a);
+        balance = balance.add(a.getBalance());
+
+        Elements es = d.select(".GridViewStd_Item,.GridViewStd_ItemAlt");
+        List<Transaction> transactions = new ArrayList<Transaction>();
+        if (es != null) {
+            for (Element el : es) {
+                transactions.add(new Transaction(el.child(0).text().trim(), el.child(1).text().trim(), Helpers.parseBalance(el.child(2).text())));
             }
-            a.setTransactions(transactions);
-
-        } catch (IOException e) {
-                throw new BankException(e.getMessage(), e);
         }
+        a.setTransactions(transactions);
+
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 99f07aa..424ca8d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -59,7 +59,7 @@ public class BlekingeTrafiken extends Bank {
     }
 
     public BlekingeTrafiken(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -73,27 +73,21 @@ public class BlekingeTrafiken extends Bank {
         return lp;
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
-            urlopen.addHeader("Accept","application/json");
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(URL + "/webshop/card/balance/",
-                    new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
-            if(httpResponse.getStatusLine().getStatusCode() != 200) {
-                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-            }
-            response = EntityUtils.toString(httpResponse.getEntity());
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
+        urlopen.addHeader("Accept","application/json");
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(URL + "/webshop/card/balance/",
+                new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
+        if(httpResponse.getStatusLine().getStatusCode() != 200) {
+            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
+        response = EntityUtils.toString(httpResponse.getEntity());
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || username.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index a421789..e41d1fc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -64,7 +64,7 @@ public class Bredband2VoIP extends Bank {
     }
 
     public Bredband2VoIP(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -103,7 +103,7 @@ public class Bredband2VoIP extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -129,31 +129,28 @@ public class Bredband2VoIP extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
 
-        try {
-            response = urlopen.open(API_URL + "voip/invoicelist/iPhoneProviderID/" + account.getId());
-            Matcher mInvoiceUrl = reInvoiceUrl.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            int i = 1;
-            while (mInvoiceUrl.find() && i++ <= 2) {
-                try {
-                    String url = mInvoiceUrl.group(1);
-                    String sInvoice = urlopen.open(API_URL + url);
-                    Matcher mTransaction = reTransactions.matcher(sInvoice);
-                    while (mTransaction.find()) {
-                        transactions.add(new Transaction(mTransaction.group(2),
-                                mTransaction.group(1) + "  —  " + mTransaction.group(4),
-                                Helpers.parseBalance(mTransaction.group(5)).negate()));
-                    }
-                } catch (Exception e) {
-                    Log.w(TAG, "Unable to parse: " + mInvoiceUrl.group(1));
+        response = urlopen.open(API_URL + "voip/invoicelist/iPhoneProviderID/" + account.getId());
+        Matcher mInvoiceUrl = reInvoiceUrl.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        int i = 1;
+        while (mInvoiceUrl.find() && i++ <= 2) {
+            try {
+                String url = mInvoiceUrl.group(1);
+                String sInvoice = urlopen.open(API_URL + url);
+                Matcher mTransaction = reTransactions.matcher(sInvoice);
+                while (mTransaction.find()) {
+                    transactions.add(new Transaction(mTransaction.group(2),
+                            mTransaction.group(1) + "  —  " + mTransaction.group(4),
+                            Helpers.parseBalance(mTransaction.group(5)).negate()));
                 }
+            } catch (Exception e) {
+                Log.w(TAG, "Unable to parse: " + mInvoiceUrl.group(1));
             }
-            account.setTransactions(transactions);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
+        account.setTransactions(transactions);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index ca4653b..e28b6dd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -75,15 +75,15 @@ public class BrummerKF extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public BrummerKF(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public BrummerKF(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_brummer));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.brummer.se/sv/online/privat/Login/");
@@ -111,33 +111,25 @@ public class BrummerKF extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://www.brummer.se/sv/online/privat/Login/");
     }
     
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
-			Matcher matcher = reError.matcher(response);
-			if (matcher.find()) {
-			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-			    if (errormsg.contains("Personnummer")) {
-			        throw new LoginException(errormsg);    
-			    }
-			    else {
-	                 throw new BankException(errormsg);    
-			    }
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+		Matcher matcher = reError.matcher(response);
+		if (matcher.find()) {
+		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+		    if (errormsg.contains("Personnummer")) {
+		        throw new LoginException(errormsg);
+		    }
+		    else {
+                 throw new BankException(errormsg);
+		    }
 		}
 		return urlopen;
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -145,34 +137,26 @@ public class BrummerKF extends Bank {
 
 		urlopen = login();
 		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.brummer.se/sv/online/privat/");
-			matcher = reAccounts.matcher(response);
+
+        response = urlopen.open("https://www.brummer.se/sv/online/privat/");
+		matcher = reAccounts.matcher(response);
 			
-			while (matcher.find()) {
-                /*
-                 * 1: Kontonamn
-                 * 2: Kontonummer
-                 * 3: Avkastning under året
-                 * 4: Genomsnittlig årlig avkastning sedan start
-                 * 5: Avkastning sedan start
-                 * 6: Marknadsvärde (kronor)
-                 */
-				
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(6).trim()), matcher.group(2)));
-	            
-				balance = balance.add(Helpers.parseBalance(matcher.group(6)));
-			}
-						if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
+		while (matcher.find()) {
+            /*
+             * 1: Kontonamn
+             * 2: Kontonummer
+             * 3: Avkastning under året
+             * 4: Genomsnittlig årlig avkastning sedan start
+             * 5: Avkastning sedan start
+             * 6: Marknadsvärde (kronor)
+             */
+
+			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(6).trim()), matcher.group(2)));
+
+			balance = balance.add(Helpers.parseBalance(matcher.group(6)));
 		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
 	}
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index f795e4a..e2cf936 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -76,15 +76,15 @@ public class CSN extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
     }
 
-	public CSN(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public CSN(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_csn));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
@@ -92,15 +92,9 @@ public class CSN extends Bank {
         response = urlopen.open("https://www.csn.se/bas/inloggning/pinkod.do");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("javascript", "on"));
-        try {
-            response = urlopen.open("https://www.csn.se/bas/javascript", postData);
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException("pl:CPE:"+e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException("pl:IOE:"+e.getMessage(), e);
-        }        
+
+        response = urlopen.open("https://www.csn.se/bas/javascript", postData);
+
         postData.clear();
         
         postData.add(new BasicNameValuePair("metod", "validerapinkod"));
@@ -110,29 +104,21 @@ public class CSN extends Bank {
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-            LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Matcher matcher = reLoginError.matcher(response);
-			if (matcher.find()) {
-			    throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
-			}
-			if (!response.contains("Inloggad&nbsp;som")) {
-				throw new BankException(res.getText(R.string.unable_to_login).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException("login:CPE:"+e.getCause().getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		Matcher matcher = reLoginError.matcher(response);
+		if (matcher.find()) {
+		    throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
 		}
-		catch (IOException e) {
-			throw new BankException("login:IOE:"+e.getMessage(), e);
+		if (!response.contains("Inloggad&nbsp;som")) {
+			throw new BankException(res.getText(R.string.unable_to_login).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -170,80 +156,69 @@ public class CSN extends Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 		}
-        catch (ClientProtocolException e) {
-           throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-           throw new BankException(e.getMessage(), e);
-        }		
         finally {
             super.updateComplete();
         }
 	}
 	
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         if (account.getAliasfor() == null || account.getAliasfor().length() == 0) return;
         
         Matcher matcher;
-        try {
-            response = urlopen.open("https://www.csn.se/studiemedel/utbetalningar/utbetalningar.do?javascript=off");
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                        EXAMPLE DATA
-                 * 1: Date                      2010-11-25
-                 * 2: Specification             Vecka 47-50
-                 * 3: Status                    Utbetald
-                 * 4: Amount                    8,140
-                 * 
-                 */
-                transactions.add(new Transaction(matcher.group(1).trim(),
-                        Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
-                        Helpers.parseBalance(matcher.group(4).replace(",", ""))));
-            }
-            response = urlopen.open("https://www.csn.se/aterbetalning/vadSkallJagBetalUnderAret/betalningstillfallen.do?javascript=off");
-            matcher = reTransactions.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                        EXAMPLE DATA
-                 * 1: Date                      2010-11-25
-                 * 2: Specification             Bankgiro 5580-3084
-                 * 3: OCR-number                4576225900
-                 * 4: Amount                    1,234
-                 * 
-                 */
-                transactions.add(new Transaction(matcher.group(1).trim(),
-                        Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
-                        Helpers.parseBalance(matcher.group(4).replace(",", "")).negate()));
-            }
-            
-            response = urlopen.open("https://www.csn.se/aterbetalning/harMinaInbetalningarKommitIn/registreradeInbetalningar.do?javascript=off");
-            matcher = reCompletedPayments.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                        EXAMPLE DATA
-                 * 1: Date                      2006-08-21
-                 * 2: Specification             Återkrav första halvåret 2006 lån 1
-                 * 3: Amount                    1,050
-                 * 
-                 */
-                transactions.add(new Transaction(matcher.group(1).trim(),
-                        Html.fromHtml(matcher.group(2)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(3).replace(",", "")).negate()));
-            }            
-            
-            Collections.sort(transactions, Collections.reverseOrder());
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        response = urlopen.open("https://www.csn.se/studiemedel/utbetalningar/utbetalningar.do?javascript=off");
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                        EXAMPLE DATA
+             * 1: Date                      2010-11-25
+             * 2: Specification             Vecka 47-50
+             * 3: Status                    Utbetald
+             * 4: Amount                    8,140
+             *
+             */
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
+                    Helpers.parseBalance(matcher.group(4).replace(",", ""))));
+        }
+        response = urlopen.open("https://www.csn.se/aterbetalning/vadSkallJagBetalUnderAret/betalningstillfallen.do?javascript=off");
+        matcher = reTransactions.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                        EXAMPLE DATA
+             * 1: Date                      2010-11-25
+             * 2: Specification             Bankgiro 5580-3084
+             * 3: OCR-number                4576225900
+             * 4: Amount                    1,234
+             *
+             */
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
+                    Helpers.parseBalance(matcher.group(4).replace(",", "")).negate()));
         }
+
+        response = urlopen.open("https://www.csn.se/aterbetalning/harMinaInbetalningarKommitIn/registreradeInbetalningar.do?javascript=off");
+        matcher = reCompletedPayments.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                        EXAMPLE DATA
+             * 1: Date                      2006-08-21
+             * 2: Specification             Återkrav första halvåret 2006 lån 1
+             * 3: Amount                    1,050
+             *
+             */
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3).replace(",", "")).negate()));
+        }
+
+        Collections.sort(transactions, Collections.reverseOrder());
+        account.setTransactions(transactions);
     }	
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 5b123c9..71eb3fb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -1,5 +1,6 @@
 package com.liato.bankdroid.banking.banks;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -41,13 +42,14 @@ public class Chalmrest extends Bank {
 		super.INPUT_HIDDEN_PASSWORD = true;
 	}
 
-	public Chalmrest(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Chalmrest(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || username.length() == 0) 
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
index 8cfe6f8..d94f410 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Chevrolet extends SEBKortBase {
 	private static final String TAG = "Chevrolet";
@@ -38,7 +40,8 @@ public class Chevrolet extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Chevrolet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Chevrolet(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "chse", "0086");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index 3fab5c1..4901308 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -77,14 +77,14 @@ public class DanskeBank extends Bank {
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
 	}
 
-	public DanskeBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public DanskeBank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_danskebank));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://mobil.danskebank.se/");
@@ -118,23 +118,17 @@ public class DanskeBank extends Bank {
     }
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("et personnummer eller servicekod du angett")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("et personnummer eller servicekod du angett")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -185,48 +179,35 @@ public class DanskeBank extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		finally {
+		} finally {
 		    super.updateComplete();
 		}
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 
 		//No transaction history for loans, funds and credit cards.
 		int accType = account.getType();
 		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
 
-		Matcher matcher;
-		try {
-			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s", mPersonnr, mSessionId, account.getId()));
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Transaction           Till Fondsparande
-                 * 2: Date                  2011-07-28
-                 * 3: Amount                ?
-                 * 4: Status                Väntar | Utförd 
-                 * 
-                 */
-				transactions.add(new Transaction(Html.fromHtml(matcher.group(2)).toString().trim(), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+		response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s", mPersonnr, mSessionId, account.getId()));
+		Matcher matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Transaction           Till Fondsparande
+             * 2: Date                  2011-07-28
+             * 3: Amount                ?
+             * 4: Status                Väntar | Utförd
+             *
+             */
+			transactions.add(new Transaction(Html.fromHtml(matcher.group(2)).toString().trim(), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 		}
+		account.setTransactions(transactions);
 	}	
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index 567e0cd..650e71a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -68,15 +68,15 @@ public class DinersClub extends Bank {
 		super.URL = URL;
 	}
 
-	public DinersClub(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public DinersClub(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
         response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
 
@@ -104,25 +104,17 @@ public class DinersClub extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://secure.dinersclub.se/dcs/login.aspx");
     }
 
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());		    
-			if (response.contains("Har du glömt ditt lösenord")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("Har du glömt ditt lösenord")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -170,33 +162,29 @@ public class DinersClub extends Bank {
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 		String response = null;
 		Matcher matcher;
-		try {
-			/* We're going to look at all the pages until we find one that has transactions on it */
-			response = urlopen.open(String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-			while (matcher.find()) {
-				/*
-				 * Capture groups:
-				 * GROUP				EXAMPLE DATA
-				 * 1: Trans. date		2010-10-06
-				 * 2: Specifications	Skyways Express Ab
-				 * 3: Foreign amount	30,30 EUR
-				 * 4: Amount			2.462,00 kr
-				 */
-
-				transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(4))));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+
+		/* We're going to look at all the pages until we find one that has transactions on it */
+		response = urlopen.open(String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
+		matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+		while (matcher.find()) {
+			/*
+			 * Capture groups:
+			 * GROUP				EXAMPLE DATA
+			 * 1: Trans. date		2010-10-06
+			 * 2: Specifications	Skyways Express Ab
+			 * 3: Foreign amount	30,30 EUR
+			 * 4: Amount			2.462,00 kr
+			 */
+
+			transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(4))));
 		}
+		account.setTransactions(transactions);
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
index 7a5c706..e47962a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Djurgarden extends SEBKortBase {
 	private static final String TAG = "Djurgarden";
@@ -38,7 +40,8 @@ public class Djurgarden extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Djurgarden(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Djurgarden(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "djse", "0116");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index ec6dcd6..184a1a6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -58,13 +58,14 @@ public class EasyCard extends Bank {
         super.INPUT_TYPE_PASSWORD   = INPUT_TYPE_PASSWORD;
     }
 
-    public EasyCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public EasyCard(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
 
         urlopen                         = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_easycard));
         response                        = urlopen.open(EasyCard.URL);
@@ -88,29 +89,21 @@ public class EasyCard extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        
-        try {
-            LoginPackage lp = preLogin();
-            response        = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-            // The string "Valuta" is always present on successful login.
-            if(response.contains("Inloggningen misslyckades")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            } else if (response.contains("sedan du") || !response.contains("Valuta")) {
-                throw new BankException(res.getText(R.string.unable_to_login).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response        = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
+        // The string "Valuta" is always present on successful login.
+        if(response.contains("Inloggningen misslyckades")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        } else if (response.contains("sedan du") || !response.contains("Valuta")) {
+            throw new BankException(res.getText(R.string.unable_to_login).toString());
+        }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
     
         super.update();
 
@@ -152,7 +145,8 @@ public class EasyCard extends Bank {
     }
     
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException 
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException
     {
         super.updateTransactions(account, urlopen);
         
@@ -177,4 +171,3 @@ public class EasyCard extends Bank {
         response = null;
     }
 }
-    
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index a4bc86b..b576c12 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -57,7 +57,7 @@ public class EspressoHouse extends Bank {
     }
 
     public EspressoHouse(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -83,38 +83,30 @@ public class EspressoHouse extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            if (!lp.isLoggedIn()) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        if (!lp.isLoggedIn()) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-        try {
-            urlopen = login();
-            String response = urlopen.open(API_URL);
-            dResponse = Jsoup.parse(response);
-            String card = dResponse.select(".transactionCardNumber").first().text().trim();
-            String cardNo = card.split(":")[1].trim();
-            String balance = dResponse.select(".balanceAmount").first().text();
-            balance = balance.substring(0, balance.length() - 2);
-            accounts.add(new Account(card,
-                    Helpers.parseBalance(balance),
-                    cardNo, Account.REGULAR, "SEK"));
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
+        urlopen = login();
+        String response = urlopen.open(API_URL);
+        dResponse = Jsoup.parse(response);
+        String card = dResponse.select(".transactionCardNumber").first().text().trim();
+        String cardNo = card.split(":")[1].trim();
+        String balance = dResponse.select(".balanceAmount").first().text();
+        balance = balance.substring(0, balance.length() - 2);
+        accounts.add(new Account(card,
+                Helpers.parseBalance(balance),
+                cardNo, Account.REGULAR, "SEK"));
         super.updateComplete();
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 6b94bcf..370b5f6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -24,6 +24,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class EurobonusMastercard extends SEBKortBase {
     private static final String TAG = "EurobonusMastercard";
@@ -39,7 +41,8 @@ public class EurobonusMastercard extends SEBKortBase {
         super.BANKTYPE_ID = BANKTYPE_ID;
     }
 
-    public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public EurobonusMastercard(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
         super(username, password, context, "sase", "0102");
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index 20161c3..fa9e560 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -24,6 +24,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class EurobonusMastercardDk extends SEBKortBase {
     private static final String TAG = "EurobonusMastercardDk";
@@ -40,7 +42,8 @@ public class EurobonusMastercardDk extends SEBKortBase {
         super.currency = "DKK";
     }
 
-    public EurobonusMastercardDk(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public EurobonusMastercardDk(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
         super(username, password, context, "sadk", "0101");
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index a4f295c..1170215 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -24,6 +24,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class EurobonusMastercardNo extends SEBKortBase {
 	private static final String TAG = "EurobonusMastercardNo";
@@ -40,7 +42,8 @@ public class EurobonusMastercardNo extends SEBKortBase {
         super.currency = "NOK";
     }
 	
-	public EurobonusMastercardNo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public EurobonusMastercardNo(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
 		super(username, password, context, "sano", "0117");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
index 094e75a..b6b6a51 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -25,6 +25,8 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import java.io.IOException;
+
 public class Eurocard extends SEBKortBase {
 	private static final String TAG = "Eurocard";
 	private static final String NAME = "Eurocard";
@@ -39,7 +41,8 @@ public class Eurocard extends SEBKortBase {
         super.BANKTYPE_ID = BANKTYPE_ID;
     }
 
-    public Eurocard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Eurocard(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
         super(username, password, context, "ecse", "0005", "secure.eurocard.se", new int[] {R.raw.cert_eurocard});
     }
 	
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 5ef20a2..fd5c7fe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -69,14 +69,14 @@ public class Everydaycard extends Bank {
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Everydaycard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Everydaycard(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
     	return preLoginInternal("http://valuta.g2solutions.se/mobil/web/logonSubmit.do");
     }
     
@@ -85,8 +85,7 @@ public class Everydaycard extends Bank {
 //    	return preLoginInternal("https://valuta.g2solutions.se/valuta/web/logonSubmit.do");
 //    }
 
-    private LoginPackage preLoginInternal(String url) throws BankException,
-    		ClientProtocolException, IOException {
+    private LoginPackage preLoginInternal(String url) throws BankException, IOException {
     	urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
     	List <NameValuePair> postData = new ArrayList <NameValuePair>();
     	postData.add(new BasicNameValuePair("nextPage", "firstPage"));                
@@ -96,25 +95,18 @@ public class Everydaycard extends Bank {
     }
     
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			//LoginPackage lp = preLoginNonMobile();
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktigt Login")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		//LoginPackage lp = preLoginNonMobile();
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("Felaktigt Login")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 68bd531..d85f00f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -66,15 +66,15 @@ public class FirstCard extends Bank {
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public FirstCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public FirstCard(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_firstcard));
         response = urlopen.open("https://www.firstcard.se/login.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -86,24 +86,17 @@ public class FirstCard extends Bank {
     }
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Logga in med din kod")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("Logga in med din kod")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -128,45 +121,34 @@ public class FirstCard extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-        finally {
+		} finally {
             super.updateComplete();
         }
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				/*
-				 * Capture groups:
-				 * GROUP						EXAMPLE DATA
-				 * 1: date						101006
-				 * 2: specification				GOOGLE *RealArcade
-				 * 3: currency					USD
-				 * 4: amount					3,49
-				 * 5: amount in local currency	24,08
-				 * 
-				 */
-				String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
-				strDate = "20"+strDate.charAt(0)+strDate.charAt(1)+"-"+strDate.charAt(2)+strDate.charAt(3)+"-"+strDate.charAt(4)+strDate.charAt(5);
-				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)).negate()));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+
+		response = urlopen.open("https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
+		Matcher matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+			/*
+			 * Capture groups:
+			 * GROUP						EXAMPLE DATA
+			 * 1: date						101006
+			 * 2: specification				GOOGLE *RealArcade
+			 * 3: currency					USD
+			 * 4: amount					3,49
+			 * 5: amount in local currency	24,08
+			 *
+			 */
+			String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
+			strDate = "20"+strDate.charAt(0)+strDate.charAt(1)+"-"+strDate.charAt(2)+strDate.charAt(3)+"-"+strDate.charAt(4)+strDate.charAt(5);
+			transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)).negate()));
 		}
+		account.setTransactions(transactions);
 	}
-	
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index 2078af6..ece96f9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -69,14 +69,14 @@ public class ForexBank extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
     }
 
-    public ForexBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public ForexBank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_forexbank));
         String baseUrl = "https://nettbank.edb.com";
         String res = urlopen.open(baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
@@ -121,101 +121,78 @@ public class ForexBank extends Bank {
         return new LoginPackage(urlopen, postData, null, formAction);
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
 
-            // Post
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(BASE_URL + lp.getLoginTarget(), lp.getPostData(), false);
+        // Post
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(BASE_URL + lp.getLoginTarget(), lp.getPostData(), false);
 
-            String result = EntityUtils.toString(httpResponse.getEntity());
+        String result = EntityUtils.toString(httpResponse.getEntity());
 
-            if(!result.contains("/mobilepayment/transigo/logon/logout")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        if(!result.contains("/mobilepayment/transigo/logon/logout")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-
-        try {
-            /*
-            "account_number.*\\>(\\d+)"; // Kontonummer
-            "account_name.*\\>(.+)<" // Kontonamn
-            "balance.*\>(\d+,\d\d)" // Saldo
-            "disposable.*\>(\d+,\d\d)" // Disponibelt
-
-            System.err.println("Kontonummer " + mAccountNumbers.group(i+1));
-            System.err.println("Kontonamn " + mAccountNames.group(i+1));
-            System.err.println("Saldo " + mAccountBalances.group(i+1));
-            System.err.println("Disponibelt " + mDisposables.group(i+1));
-             */
-            urlopen = login();
-
-            // Go to main menu
-            String result = urlopen.open("https://nettbank.edb.com/mobilepayment/transigo/menu/menu1");
-            result = result.replace("&nbsp;",""); // Remove non-breaking spaces, they fuck up balances
-
-            Matcher mAccountIds = reAccountIds.matcher(result);
-            Matcher mAccountNumbers = reAccountNumbers.matcher(result);
-            Matcher mAccountNames = reAccountName.matcher(result);
-            Matcher mAccountBalances = reAccountBalance.matcher(result);
-            Matcher mDisposables = reDisposable.matcher(result);
-
-            while(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
-                if(!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
-                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mDisposables.group(1).trim()), mAccountIds.group(1))); //Disponibelt
-                }
-                else {
-                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(1).trim()), mAccountIds.group(1)));
-                }
-
-                balance = balance.add(Helpers.parseBalance(mAccountBalances.group(1)));
+        /*
+        "account_number.*\\>(\\d+)"; // Kontonummer
+        "account_name.*\\>(.+)<" // Kontonamn
+        "balance.*\>(\d+,\d\d)" // Saldo
+        "disposable.*\>(\d+,\d\d)" // Disponibelt
+
+        System.err.println("Kontonummer " + mAccountNumbers.group(i+1));
+        System.err.println("Kontonamn " + mAccountNames.group(i+1));
+        System.err.println("Saldo " + mAccountBalances.group(i+1));
+        System.err.println("Disponibelt " + mDisposables.group(i+1));
+         */
+        urlopen = login();
+
+        // Go to main menu
+        String result = urlopen.open("https://nettbank.edb.com/mobilepayment/transigo/menu/menu1");
+        result = result.replace("&nbsp;",""); // Remove non-breaking spaces, they fuck up balances
+
+        Matcher mAccountIds = reAccountIds.matcher(result);
+        Matcher mAccountNumbers = reAccountNumbers.matcher(result);
+        Matcher mAccountNames = reAccountName.matcher(result);
+        Matcher mAccountBalances = reAccountBalance.matcher(result);
+        Matcher mDisposables = reDisposable.matcher(result);
+
+        while(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
+            if(!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
+                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mDisposables.group(1).trim()), mAccountIds.group(1))); //Disponibelt
             }
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            else {
+                accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(1).trim()), mAccountIds.group(1)));
             }
+
+            balance = balance.add(Helpers.parseBalance(mAccountBalances.group(1)));
         }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         super.updateComplete();
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         String accountId = account.getId(); 
-        String response = null;
         Matcher matcher;
-        try {
-            response = urlopen.open(BASE_URL + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey=" + accountId);
-            response = response.replace("&nbsp;", "");
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                transactions.add(new Transaction(matcher.group(1).trim(), matcher.group(3).trim(), Helpers.parseBalance(matcher.group(2))));
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        String response = urlopen.open(BASE_URL + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey=" + accountId);
+        response = response.replace("&nbsp;", "");
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            transactions.add(new Transaction(matcher.group(1).trim(), matcher.group(3).trim(), Helpers.parseBalance(matcher.group(2))));
         }
+        account.setTransactions(transactions);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index e00fbe5..43af2bb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -75,7 +75,8 @@ public class Handelsbanken extends Bank {
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Handelsbanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Handelsbanken(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
@@ -83,8 +84,7 @@ public class Handelsbanken extends Bank {
 	
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
         response = urlopen.open("https://m.handelsbanken.se/primary/");
         Matcher matcher = reLoginUrl.matcher(response);
@@ -100,25 +100,17 @@ public class Handelsbanken extends Bank {
     }
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("ontrollera dina uppgifter")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("ontrollera dina uppgifter")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -144,43 +136,30 @@ public class Handelsbanken extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-        finally {
+		} finally {
             super.updateComplete();
         }
 	}
 	
 
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 		Matcher matcher;
-		try {
-			String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			response = urlopen.open("https://m.handelsbanken.se/primary/_-"+accountWebId);
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			
-			// Sort transactions by date
-			Collections.sort(transactions, new Comparator<Transaction>() {
+		String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
+		response = urlopen.open("https://m.handelsbanken.se/primary/_-"+accountWebId);
+		matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+			transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+		}
+
+		// Sort transactions by date
+		Collections.sort(transactions, new Comparator<Transaction>() {
                 public int compare(Transaction t1, Transaction t2) {
-                    return t2.compareTo(t1);
+                   return t2.compareTo(t1);
                 }
-            });
-			
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-		}
+        });
+        account.setTransactions(transactions);
 	}
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index 47971a1..93b3301 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -70,7 +70,8 @@ public class Hemkop extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public Hemkop(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Hemkop(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -78,8 +79,7 @@ public class Hemkop extends Bank {
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_hemkop));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.hemkop.se/Mina-sidor/Logga-in/");
@@ -111,26 +111,18 @@ public class Hemkop extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://www.hemkop.se/Mina-sidor/Logga-in/");
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (!response.contains("Inloggad som")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-            response = urlopen.open("https://www.hemkop.se/Mina-sidor/Bonussaldo/");
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (!response.contains("Inloggad som")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
+        response = urlopen.open("https://www.hemkop.se/Mina-sidor/Bonussaldo/");
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -158,42 +150,37 @@ public class Hemkop extends Bank {
         }
         
         Account account = accounts.get(0);
-        try {
-            response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
-            d = Jsoup.parse(response);
-        	Elements es = d.select(".transactions tbody tr");
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            for (Element e : es) {
-                Transaction t = new Transaction(e.child(1).ownText().trim(),
-                					e.child(0).ownText().trim(),
-                        Helpers.parseBalance(e.child(3).ownText()));
-                if (!TextUtils.isEmpty(e.child(2).ownText())) {
-                    t.setCurrency(Helpers.parseCurrency(e.child(2).ownText().trim(), "SEK"));
-                }
-                transactions.add(t);
-        	}
-            account.setTransactions(transactions);
-            
-            es = d.select(".currentBalance,.disposable");
-            int i = 0;
-            for (Element e : es) {
-            	Account a = new Account(e.child(0).ownText().trim(), Helpers.parseBalance(e.child(1).ownText()), String.format("acc_cc_%d", i));
-            	a.setAliasfor("acc_0");
-            	accounts.add(a);
-            	i++;
+
+        response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
+        d = Jsoup.parse(response);
+    	Elements es = d.select(".transactions tbody tr");
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        for (Element e : es) {
+            Transaction t = new Transaction(e.child(1).ownText().trim(),
+            					e.child(0).ownText().trim(),
+                    Helpers.parseBalance(e.child(3).ownText()));
+            if (!TextUtils.isEmpty(e.child(2).ownText())) {
+                t.setCurrency(Helpers.parseCurrency(e.child(2).ownText().trim(), "SEK"));
             }
-            
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }        
-        
+            transactions.add(t);
+    	}
+        account.setTransactions(transactions);
+
+        es = d.select(".currentBalance,.disposable");
+        int i = 0;
+        for (Element e : es) {
+        	Account a = new Account(e.child(0).ownText().trim(), Helpers.parseBalance(e.child(1).ownText()), String.format("acc_cc_%d", i));
+        	a.setAliasfor("acc_0");
+        	accounts.add(a);
+        	i++;
+        }
+
         super.updateComplete();
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         /*
         if (!"acc_0".equals(account.getId())) return;
@@ -224,4 +211,4 @@ public class Hemkop extends Bank {
         }
         */
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
index 009cf16..96db0e6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class IKEA extends AbsIkanoPartner {
     private static final String TAG = "IKEA";
@@ -40,7 +42,8 @@ public class IKEA extends AbsIkanoPartner {
         this.structId = "1420";
     }
 
-    public IKEA(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public IKEA(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index a46d976..7259cf4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -73,7 +73,8 @@ public class IkanoBank extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public IkanoBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public IkanoBank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -81,8 +82,7 @@ public class IkanoBank extends Bank {
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanobank));
         response = urlopen.open("https://secure.ikanobank.se/login");
         Matcher matcher;
@@ -114,32 +114,24 @@ public class IkanoBank extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://secure.ikanobank.se/engines/page.aspx?structid=1895");
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Ogiltigt personnummer") || response.contains("felaktigt personnummer")) {
-                Matcher matcher = reErrorMessage.matcher(response);
-                if (matcher.find()) {
-                    throw new LoginException(Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
-                }
-                else {
-                    throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-                }
-                
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Ogiltigt personnummer") || response.contains("felaktigt personnummer")) {
+            Matcher matcher = reErrorMessage.matcher(response);
+            if (matcher.find()) {
+                throw new LoginException(Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
             }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+            else {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -168,7 +160,8 @@ public class IkanoBank extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
 
         // Find viewstate and eventvalidation from last page.
@@ -186,35 +179,28 @@ public class IkanoBank extends Bank {
         }
         String strEventValidation = matcher.group(1);       
 
-        try {
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            postData.add(new BasicNameValuePair("__EVENTTARGET", account.getId().replace("_", "$")));
-            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));            
-            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));            
-            postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));            
-            response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
-
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Date              2010-10-27
-                 * 2: Specification     ÍVERFÍRING
-                 * 3: Amount            50
-                 *   
-                 */                    
-                transactions.add(new Transaction(matcher.group(1).trim(),
-                        Html.fromHtml(matcher.group(2)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(3))));
-            }
-            account.setTransactions(transactions);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", account.getId().replace("_", "$")));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
 
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Date              2010-10-27
+             * 2: Specification     ÍVERFÍRING
+             * 3: Amount            50
+             *
+             */
+            transactions.add(new Transaction(matcher.group(1).trim(),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(3))));
         }
+        account.setTransactions(transactions);
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index e5cdbdc..ac510ca 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -67,7 +67,8 @@ public class Jojo extends Bank {
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
     }
 
-    public Jojo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Jojo(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -85,23 +86,17 @@ public class Jojo extends Bank {
         return new LoginPackage(urlopen, postData, response, URL + "/mobile/customer.html");
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (!response.contains("[Logga ut]")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (!response.contains("[Logga ut]")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index d2b1931..e5d5177 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -57,14 +57,14 @@ public class Marginalen extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
     
-    public Marginalen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Marginalen(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_marginalen, R.raw.cert_marginalen2));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
@@ -103,32 +103,25 @@ public class Marginalen extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-    	try {
-    		LoginPackage lp = preLogin();
-    		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-    		
-    		if (response.contains("Felmeddelande")) {
-    			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-    		}
-    		
-    		Matcher matcher;
-    		matcher = reAccountLink.matcher(response);
-    		if (!matcher.find())
-            	throw new BankException(res.getText(R.string.unable_to_find).toString() + " accounts link.");
-    		accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
-    	}
-    	catch (ClientProtocolException e) {
-    		throw new BankException("ClientProtolException:" + e.getMessage(), e);
-    	}
-    	catch (IOException e) {
-    		throw new BankException("IOException:" + e.getMessage(), e);
-    	}
-    	return urlopen;
+    public Urllib login() throws LoginException, BankException, IOException {
+    	LoginPackage lp = preLogin();
+    	response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+		if (response.contains("Felmeddelande")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		Matcher matcher;
+		matcher = reAccountLink.matcher(response);
+		if (!matcher.find())
+        	throw new BankException(res.getText(R.string.unable_to_find).toString() + " accounts link.");
+		accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
+
+	    return urlopen;
     }
     
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
     	super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -156,43 +149,31 @@ public class Marginalen extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		finally {
+		} finally {
 	      super.updateComplete();
 		}
 		
     }
     
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 		Matcher matcher;
-		try {
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            response = urlopen.open(BASE_URL + account.getId().replaceAll("&amp;", "&"));
-
-            matcher = reTransactions.matcher(response);
-            while (matcher.find()) {
-            	/*
-            	 * Capture groups:
-            	 * GROUP                    EXAMPLE DATA
-            	 * 1: Date                  2011-04-06
-            	 * 2: Specification         Pressbyran
-            	 * 3: Amount                -20
-            	 * 
-            	 */	                
-            	transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-            }
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        response = urlopen.open(BASE_URL + account.getId().replaceAll("&amp;", "&"));
+
+        matcher = reTransactions.matcher(response);
+        while (matcher.find()) {
+        	/*
+        	 * Capture groups:
+        	 * GROUP                    EXAMPLE DATA
+        	 * 1: Date                  2011-04-06
+        	 * 2: Specification         Pressbyran
+        	 * 3: Amount                -20
+        	 *
+        	 */
+        	transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+        }
+		account.setTransactions(transactions);
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 79fd488..307a559 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -68,7 +68,8 @@ public class McDonalds extends Bank {
 		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
 	}
 
-	public McDonalds(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public McDonalds(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
@@ -85,25 +86,17 @@ public class McDonalds extends Bank {
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("felaktigt kortnummer")) {
-                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("felaktigt kortnummer")) {
+            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         return urlopen;		
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || username.length() != 19) {
 			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
@@ -142,4 +135,4 @@ public class McDonalds extends Bank {
         }
         super.updateComplete();
 	}
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index e439bd6..51619b5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -53,7 +53,8 @@ public class Meniga extends Bank{
         super.setCurrency("ISK");
     }
 
-    public Meniga(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Meniga(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -70,38 +71,20 @@ public class Meniga extends Bank{
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-            if (response.contains("<div class=\"login\">")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-
-        try{
-            response = urlopen.open("https://www.meniga.is/mobile/language/?lang=is-IS");
-        }
-        catch (ClientProtocolException e){
-           throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        if (response.contains("<div class=\"login\">")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
+        response = urlopen.open("https://www.meniga.is/mobile/language/?lang=is-IS");
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -134,50 +117,40 @@ public class Meniga extends Bank{
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
         }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
         finally {
             super.updateComplete();
         }
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         if (account.getType() == Account.OTHER) return;
 
         String response;
         Matcher matcher;
-        try {
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            response = urlopen.open("https://www.meniga.is/Transactions?account="+account.getId());
-            matcher = reTransactions.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Id                    1231213
-                 * 2: Specification         Pressbyran
-                 * 3: Date in millisec      2142411351235
-                 * 4: Amount                -20
-                 *
-                 *
-                 */
-             Long date = Long.valueOf(matcher.group(3));
-             SimpleDateFormat ft = new SimpleDateFormat ("yy-MM-dd");
-             Transaction transaction = new Transaction(ft.format(date), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4)));
-             transaction.setCurrency("ISK");
-             transactions.add(transaction);
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        response = urlopen.open("https://www.meniga.is/Transactions?account="+account.getId());
+        matcher = reTransactions.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Id                    1231213
+             * 2: Specification         Pressbyran
+             * 3: Date in millisec      2142411351235
+             * 4: Amount                -20
+             *
+             *
+             */
+            Long date = Long.valueOf(matcher.group(3));
+            SimpleDateFormat ft = new SimpleDateFormat ("yy-MM-dd");
+            Transaction transaction = new Transaction(ft.format(date), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4)));
+            transaction.setCurrency("ISK");
+            transactions.add(transaction);
         }
+        account.setTransactions(transactions);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
index f74f577..c69ed3e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -57,7 +57,7 @@ public class MinPension extends Bank {
     }
 
     public MinPension(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -79,54 +79,46 @@ public class MinPension extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
 
-            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData(), true);
-            if (!response.contains("LoggaUt.aspx")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-            response = urlopen.open("https://www.minpension.se/mina-sidor/redirect?path=MinPension%2FDefault.aspx&bodyMargin=0");
-            Document document = Jsoup.parse(response);
-            Element e = document.select("#authenticationResult").first();
-            if (e == null) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-            List<NameValuePair> postData = new ArrayList<>();
-            postData.add(new BasicNameValuePair("authenticationResult", e.val()));
-            urlopen.open("https://minasidor.minpension.se/MinPension/Default.aspx", postData, true);
-
-            return urlopen;
-
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData(), true);
+        if (!response.contains("LoggaUt.aspx")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
+        response = urlopen.open("https://www.minpension.se/mina-sidor/redirect?path=MinPension%2FDefault.aspx&bodyMargin=0");
+        Document document = Jsoup.parse(response);
+        Element e = document.select("#authenticationResult").first();
+        if (e == null) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        List<NameValuePair> postData = new ArrayList<>();
+        postData.add(new BasicNameValuePair("authenticationResult", e.val()));
+        urlopen.open("https://minasidor.minpension.se/MinPension/Default.aspx", postData, true);
+
+        return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
 //Allmän pension
-            accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/AllmanPension.aspx",
-                    "#AllmänPensionTable tr",
-                    res.getText(R.string.public_pension).toString()));
+        accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/AllmanPension.aspx",
+                "#AllmänPensionTable tr",
+                res.getText(R.string.public_pension).toString()));
 //Tjänstepension
-            accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/Tjanstepension.aspx",
-                    "#TjänstepensionTable tr",
-                    res.getText(R.string.occupational_pension).toString()));
+        accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/Tjanstepension.aspx",
+                "#TjänstepensionTable tr",
+                res.getText(R.string.occupational_pension).toString()));
 //Privat pension
-            accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/PrivatPension.aspx",
-                    "#PrivatPensionTable tr",
-                    res.getText(R.string.private_pension).toString()));
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
+        accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/PrivatPension.aspx",
+                "#PrivatPensionTable tr",
+                res.getText(R.string.private_pension).toString()));
+
         super.updateComplete();
     }
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 30fd96b..88777b8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -64,14 +64,14 @@ public abstract class MobilbankenBase extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public MobilbankenBase(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public MobilbankenBase(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
@@ -96,25 +96,18 @@ public abstract class MobilbankenBase extends Bank {
     }
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 		
-			if (response.contains("eller pinkod")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+		if (response.contains("eller pinkod")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -146,33 +139,28 @@ public abstract class MobilbankenBase extends Bank {
 	}
 	
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
 
         Matcher matcher;
-        try {
-            response = urlopen.open(String.format("https://mobil-banken.se/%s/accountmovement.html?account_no=%s", targetId, account.getId()));
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Transaction           Kortköp QPARKSTOCKHOLM,  STOCKHOLM
-                 * 2: Amount                -40,00
-                 * 3: Date                  2010.12.23 
-                 * 
-                 */
-                transactions.add(new Transaction(
-                        matcher.group(3).trim().replace(".", "-"),
-                        Html.fromHtml(matcher.group(1)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(2))));
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        response = urlopen.open(String.format("https://mobil-banken.se/%s/accountmovement.html?account_no=%s", targetId, account.getId()));
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Transaction           Kortköp QPARKSTOCKHOLM,  STOCKHOLM
+             * 2: Amount                -40,00
+             * 3: Date                  2010.12.23
+             *
+             */
+            transactions.add(new Transaction(
+                    matcher.group(3).trim().replace(".", "-"),
+                    Html.fromHtml(matcher.group(1)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(2))));
         }
+        account.setTransactions(transactions);
     }   	
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index d9d6cad..ad3cebd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -82,14 +82,13 @@ public class NordeaDK extends Bank {
 	}
 
 	public NordeaDK(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException {
+			throws BankException, LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	protected LoginPackage preLogin() throws BankException,
-			ClientProtocolException, IOException {
+	protected LoginPackage preLogin() throws BankException, IOException {
 		if (urlopen == null) {
             urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
 		}
@@ -113,26 +112,20 @@ public class NordeaDK extends Bank {
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("class=\"icon error_icon\"")) {
-				throw new LoginException(res.getText(
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("class=\"icon error_icon\"")) {
+			throw new LoginException(res.getText(
 						R.string.invalid_username_password).toString());
-			}
-			this.updatePrefix();
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
 		}
+		this.updatePrefix();
 		return urlopen;
 	}
 
 	@Override
 	public void update() throws BankException, LoginException,
-			BankChoiceException {
+			BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0
 				|| password.length() == 0) {
@@ -180,7 +173,7 @@ public class NordeaDK extends Bank {
 
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen)
-			throws LoginException, BankException {
+			throws LoginException, BankException, IOException {
 		super.updateTransactions(account, urlopen);
 
 		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -198,7 +191,7 @@ public class NordeaDK extends Bank {
 	}
 
 	private ArrayList<Transaction> updateMonthTransactions(Account account,
-			Urllib urlopen, boolean oldTransactions) throws BankException {
+			Urllib urlopen, boolean oldTransactions) throws BankException, IOException {
 		String command = "command=";
 		command += (oldTransactions) ? "1" : "0";
 		String url = "https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions?productidx="
@@ -207,45 +200,37 @@ public class NordeaDK extends Bank {
 		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 
 		Matcher matcher;
-		try {
-			urlopen.addHeader("referer", this.referer);
-			this.response = urlopen.open(url);
-			this.updatePrefix();
-			this.referer = url;
-			
-			Matcher transYear = reTransactionYear.matcher(response);
-			String year = "";
-			if(transYear.find()) {
-				year = Html.fromHtml(transYear.group(1)).toString().trim();
-			}
-			
-			matcher = reTransactions.matcher(response);
-			/*
-			 * Capture groups: 
-			 * GROUP 	EXAMPLE 	DATA 
-			 * 1: 		Date 		29.07 
-			 * 2: 		Transaction	Bgs Check-in-konto 
-			 * 3: 		Amount 		906.56
-			 */
-
-			while (matcher.find()) {
-				String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
-				String text = Html.fromHtml(matcher.group(2)).toString().trim();
-				BigDecimal amount = Helpers.parseBalance(matcher.group(3));
-				String date = year+"-"+monthDate.substring(3,5)+"-"+monthDate.substring(0,2);
-				
-				Transaction transaction = new Transaction(date, text, amount,
-						super.currency);
-				transactions.add(transaction);
-			}
-			
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+		urlopen.addHeader("referer", this.referer);
+		this.response = urlopen.open(url);
+		this.updatePrefix();
+		this.referer = url;
+
+		Matcher transYear = reTransactionYear.matcher(response);
+		String year = "";
+		if(transYear.find()) {
+			year = Html.fromHtml(transYear.group(1)).toString().trim();
 		}
-		return transactions;
 
+		matcher = reTransactions.matcher(response);
+		/*
+		 * Capture groups:
+		 * GROUP 	EXAMPLE 	DATA
+		 * 1: 		Date 		29.07
+		 * 2: 		Transaction	Bgs Check-in-konto
+		 * 3: 		Amount 		906.56
+		 */
+
+		while (matcher.find()) {
+			String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
+			String text = Html.fromHtml(matcher.group(2)).toString().trim();
+			BigDecimal amount = Helpers.parseBalance(matcher.group(3));
+			String date = year+"-"+monthDate.substring(3,5)+"-"+monthDate.substring(0,2);
+
+			Transaction transaction = new Transaction(date, text, amount,
+					super.currency);
+			transactions.add(transaction);
+		}
+    	return transactions;
 	}
 
 	private void updatePrefix() throws BankException {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index ef6cbf1..fb73b72 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -65,15 +65,15 @@ public class Nordnet extends Bank {
         super.URL = URL;
     }
 
-    public Nordnet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Nordnet(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnet));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
@@ -101,25 +101,17 @@ public class Nordnet extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("fel vid inloggningen")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("fel vid inloggningen")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 434ab6c..ea61d33 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -68,15 +68,15 @@ public class Nordnetdirekt extends Bank {
         super.INPUT_HIDDEN_EXTRAS = INPUT_HIDDEN_EXTRAS;
 	}
 
-	public Nordnetdirekt(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Nordnetdirekt(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html");
@@ -92,25 +92,18 @@ public class Nordnetdirekt extends Bank {
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-            LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("fel vid inloggningen")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("fel vid inloggningen")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
+
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -148,5 +141,4 @@ public class Nordnetdirekt extends Bank {
             super.updateComplete();
         }
 	}
-  
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index ebe9d2d..e9e2d84 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -72,15 +72,15 @@ public class OKQ8 extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public OKQ8(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public OKQ8(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_okq8));
         Date d = new Date();
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -95,10 +95,10 @@ public class OKQ8 extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://nettbank.edb.com/Logon/logon/step1");
     }
 
-	public Urllib login() throws LoginException, BankException {
+	public Urllib login() throws LoginException, BankException, IOException {
         Matcher matcher;
         String value = null;
-		try {
+
 			LoginPackage lp = preLogin();
 			List <NameValuePair> postData = lp.getPostData();
 			response = urlopen.open(lp.getLoginTarget(), postData);
@@ -150,18 +150,11 @@ public class OKQ8 extends Bank {
 			{
 				throw new LoginException("Login failed.");
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -222,12 +215,7 @@ public class OKQ8 extends Bank {
 				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)).negate()));
 			}
 			accounts.get(0).setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-		}		
-        finally {
+		} finally {
             super.updateComplete();
         }
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
index 18365aa..f16884f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Opel extends SEBKortBase {
 	private static final String TAG = "Opel";
@@ -38,7 +40,8 @@ public class Opel extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Opel(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Opel(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "opse", "0107");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 5d011cb..0bc9502 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -63,14 +63,14 @@ public class Ostgotatrafiken extends Bank {
 		super.URL = URL;
 	}
 
-	public Ostgotatrafiken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Ostgotatrafiken(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	protected LoginPackage preLogin() throws BankException,
-	ClientProtocolException, IOException {
+	protected LoginPackage preLogin() throws BankException, IOException {
 		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview));
 
 		List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -82,25 +82,17 @@ public class Ostgotatrafiken extends Bank {
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (!response.contains("Logga ut")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (!response.contains("Logga ut")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		return urlopen;
+        return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -164,14 +156,7 @@ public class Ostgotatrafiken extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		finally {
+		} finally {
 			super.updateComplete();
 		}
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index a5e8274..51bd126 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -63,14 +63,14 @@ public class Osuuspankki extends Bank {
 		super.URL = URL;
 	}
 
-	public Osuuspankki(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Osuuspankki(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_osuuspankki, R.raw.cert_osuuspankki_mobile));
         response = urlopen.open("https://www.op.fi/op?kielikoodi=sv");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -85,24 +85,18 @@ public class Osuuspankki extends Bank {
     }
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			if (response.contains("du nya koder genom att bes")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+		if (response.contains("du nya koder genom att bes")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		return urlopen;
+        return urlopen;
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -141,37 +135,33 @@ public class Osuuspankki extends Bank {
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 
 		Matcher matcher;
-		try {
-			response = urlopen.open(String.format("https://www.op.fi/?id=%s&tilinro=%s&ecb=1&srcpl=4", (account.getType() == Account.OTHER ? "12701" : "12401"),account.getId()));
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Book. date            21.01
-                 * 2: Trans. date           20.01
-                 * 3: Description           ITUNES-EURO LUXEMBOURG
-                 * 4: Transaction type      BANKKORTSBET.
-                 * 5: Amount in EUR         -3,99 
-                 * 
-                 */
-			    String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split(".");
-			    Transaction transaction = new Transaction(Helpers.getTransactionDate(date[1], date[0]),
-                        Html.fromHtml(matcher.group(3)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(5)));
-			    transaction.setCurrency(account.getCurrency());
-				transactions.add(transaction);
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+
+        response = urlopen.open(String.format("https://www.op.fi/?id=%s&tilinro=%s&ecb=1&srcpl=4", (account.getType() == Account.OTHER ? "12701" : "12401"),account.getId()));
+		matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Book. date            21.01
+             * 2: Trans. date           20.01
+             * 3: Description           ITUNES-EURO LUXEMBOURG
+             * 4: Transaction type      BANKKORTSBET.
+             * 5: Amount in EUR         -3,99
+             *
+             */
+		    String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split(".");
+		    Transaction transaction = new Transaction(Helpers.getTransactionDate(date[1], date[0]),
+                    Html.fromHtml(matcher.group(3)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(5)));
+		    transaction.setCurrency(account.getCurrency());
+			transactions.add(transaction);
 		}
-	}	
-}
\ No newline at end of file
+		account.setTransactions(transactions);
+	}
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index ef05f51..6c7f682 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -70,15 +70,15 @@ public class PayPal extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
     }
 
-    public PayPal(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public PayPal(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
@@ -112,26 +112,20 @@ public class PayPal extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-            if (response.contains("your last action could not be completed")) {
-                throw new BankException("Error: PPL92");
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        if (response.contains("your last action could not be completed")) {
+            throw new BankException("Error: PPL92");
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -176,16 +170,8 @@ public class PayPal extends Bank {
             if (accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        finally {
+        } finally {
             super.updateComplete();
         }
     }
-
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index 805b29d..51cf772 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -64,7 +64,8 @@ public class Payson extends Bank {
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
     }
 
-    public Payson(String username, String password, Context context) throws BankChoiceException, BankException, LoginException {
+    public Payson(String username, String password, Context context) throws BankChoiceException,
+            BankException, LoginException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -88,13 +89,11 @@ public class Payson extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             userInfo = new JSONObject(urlopen.open("https://www.payson.se/myaccount/user/getuserinfo"));
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         } catch (JSONException e) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
@@ -102,7 +101,7 @@ public class Payson extends Bank {
     }
 
     @Override
-    public void update() throws BankChoiceException, BankException, LoginException {
+    public void update() throws BankChoiceException, BankException, LoginException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index 2c4ff87..e130542 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -62,15 +62,15 @@ public class PlusGirot extends Bank {
 		super.URL = URL;
 	}
 
-	public PlusGirot(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public PlusGirot(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_plusgirot));
         // Request first page to get cookies
         response = urlopen.open("https://kontoutdrag.plusgirot.se/ku/html/epostllg.htm");
@@ -82,25 +82,17 @@ public class PlusGirot extends Bank {
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-            LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("elaktigt kontonummer"))  {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("elaktigt kontonummer"))  {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
index 22e88ff..b4f2c2a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Preem extends AbsIkanoPartner {
     private static final String TAG = "Preem";
@@ -41,7 +43,8 @@ public class Preem extends AbsIkanoPartner {
         this.structId = "1437";
     }
 
-    public Preem(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Preem(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
index 4f0e6b6..21207f8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Quintessentially extends SEBKortBase {
 	private static final String TAG = "Quintessentially";
@@ -38,7 +40,8 @@ public class Quintessentially extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Quintessentially(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Quintessentially(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "quse", "0119");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index 85561da..0d0a027 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -58,14 +58,14 @@ public class ResursBank extends Bank {
         super.URL = "https://secure.resurs.se/internetbank/default.jsp";
     }
 
-    public ResursBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public ResursBank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_resursbank));
         response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -76,24 +76,18 @@ public class ResursBank extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-            if (response.contains("vid inloggningen")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+        if (response.contains("vid inloggningen")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -141,34 +135,29 @@ public class ResursBank extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         // Only update transactions for the main account
         if (!account.getId().startsWith("b_")) return;
 
-        try {
-            response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
-            Matcher matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Date                  2010-04-17
-                 * 2: Transaction           ONOFF L+äNNA
-                 * 3: Currency              always null?
-                 * 4: Amount                -95,00 kr 
-                 * 
-                 */
-                transactions.add(new Transaction(matcher.group(1),
-                        Html.fromHtml(matcher.group(2)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(4))));
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
+        Matcher matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Date                  2010-04-17
+             * 2: Transaction           ONOFF L+äNNA
+             * 3: Currency              always null?
+             * 4: Amount                -95,00 kr
+             *
+             */
+            transactions.add(new Transaction(matcher.group(1),
+                    Html.fromHtml(matcher.group(2)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4))));
         }
+        account.setTransactions(transactions);
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
index fadfbf9..aae2cf8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class SJPrio extends SEBKortBase {
 	private static final String TAG = "SJPrio";
@@ -38,8 +40,8 @@ public class SJPrio extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public SJPrio(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public SJPrio(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "sjse", "0104");
 	}
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
index 8de2dda..22f11ed 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Saab extends SEBKortBase {
 	private static final String TAG = "SAAB";
@@ -38,7 +40,8 @@ public class Saab extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Saab(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Saab(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "sbse", "0106");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
index 156eb7f..ec418c9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Seat extends AbsIkanoPartner {
     private static final String TAG = "Seat";
@@ -40,10 +42,9 @@ public class Seat extends AbsIkanoPartner {
         this.structId = "1301";
     }
 
-    public Seat(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Seat(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
-
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index ad76d0e..9a9abbf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -67,15 +67,15 @@ public class SevenDay extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public SevenDay(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public SevenDay(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sevenday));
         response = urlopen.open("https://www.sevenday.se/mina-sidor/mina-sidor.htm");
         
@@ -96,25 +96,17 @@ public class SevenDay extends Bank {
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-            LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Logga in med personnummer") || response.contains("kommer automatiskt till startsidan")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (response.contains("Logga in med personnummer") || response.contains("kommer automatiskt till startsidan")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
index d2fe884..98532df 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Shell extends AbsIkanoPartner {
     private static final String TAG = "Shell";
@@ -40,10 +42,9 @@ public class Shell extends AbsIkanoPartner {
         this.structId = "2035";
     }
 
-    public Shell(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Shell(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
-
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 5e0a2a1..9fd6b67 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -69,13 +69,13 @@ public class Skandiabanken extends Bank {
 	}
 
 	public Skandiabanken(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException {
+			throws BankException, LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
+	public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
 
 		HashMap<String, String> headers = urlopen.getHeaders();
@@ -106,10 +106,6 @@ public class Skandiabanken extends Bank {
 			else
 				throw new BankException("Http fel (" + e.getStatusCode() + ") "
 						+ e.getMessage(), e);
-		} catch (ClientProtocolException e) {
-			throw new BankException("ClientProtocolException " + e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException("IOException " + e.getMessage(), e);
 		} catch (JSONException e) {
 			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
 		}
@@ -133,7 +129,7 @@ public class Skandiabanken extends Bank {
 
 	@Override
 	public void update() throws BankException, LoginException,
-			BankChoiceException {
+			BankChoiceException, IOException {
 		super.update();
 
 		if (username == null || password == null || username.length() == 0
@@ -166,8 +162,6 @@ public class Skandiabanken extends Bank {
 				Account account = new Account(name, Helpers.parseBalance(balanceString), id, type);
 				accounts.add(account);
 			}
-		} catch (IOException e) {
-			throw new BankException("IOException " + e.getMessage(), e);
 		} catch (JSONException e) {
 			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
 		}
@@ -175,7 +169,7 @@ public class Skandiabanken extends Bank {
 
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen)
-			throws LoginException, BankException {
+			throws LoginException, BankException, IOException {
 		super.updateTransactions(account, urlopen);
 
 		if (customerId == 0)
@@ -183,10 +177,10 @@ public class Skandiabanken extends Bank {
 		
 		try {
 	        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-	        
+
 			String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
 					+ "/customer/" + customerId + "/account/" + account.getId();
-			
+
 			String accountJsonString = urlopen.open(accountTransactionsUrl);
 			JSONObject accountJSONObj = new JSONObject(accountJsonString);
 			JSONArray transactionsJSONArray = accountJSONObj.optJSONArray("transactions");
@@ -199,19 +193,17 @@ public class Skandiabanken extends Bank {
     				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
     				transactions.add(transaction);
     			}
-	            
+
 			    // Sort transactions by date
     			Collections.sort(transactions, new Comparator<Transaction>() {
     	            public int compare(Transaction t1, Transaction t2) {
     	                return t2.compareTo(t1);
     	            }
     	        });
-    			
+
     			account.setTransactions(transactions);
 			}
-			
-		} catch (IOException e) {
-			throw new BankException("IOException " + e.getMessage(), e);
+
 		} catch (JSONException e) {
 			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
 		}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
index 23900bc..90b21c7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Skoda extends AbsIkanoPartner {
     private static final String TAG = "Skoda";
@@ -40,7 +42,8 @@ public class Skoda extends AbsIkanoPartner {
         this.structId = "2461";
     }
 
-    public Skoda(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Skoda(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index cc72aa1..c775b2f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class SparbankenOresund extends MobilbankenBase {
 	private static final String TAG = "SparbankenOresund";
@@ -41,10 +43,9 @@ public class SparbankenOresund extends MobilbankenBase {
         this.targetId = "0003";
     }
 
-    public SparbankenOresund(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public SparbankenOresund(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
-
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index fbe37eb..e701b2b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class SparbankenSyd extends MobilbankenBase {
 	private static final String TAG = "SparbankenSyd";
@@ -41,10 +43,9 @@ public class SparbankenSyd extends MobilbankenBase {
         this.targetId = "0004";
     }
 
-    public SparbankenSyd(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public SparbankenSyd(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
-
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
index c2c1064..d07215e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import java.io.IOException;
+
 
 public class Statoil extends SEBKortBase {
 	private static final String TAG = "Statoil";
@@ -38,7 +40,8 @@ public class Statoil extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Statoil(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Statoil(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "stse", "0122");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 94bb866..4420243 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -70,15 +70,15 @@ public class Steam extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public Steam(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Steam(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_steam));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("redir", "account"));
@@ -88,28 +88,20 @@ public class Steam extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Enter the characters above")) {
-                throw new LoginException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
-            }
-			if (response.contains("Incorrect login.")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Enter the characters above")) {
+            throw new LoginException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
+        }
+		if (response.contains("Incorrect login.")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
index 2a6c739..b4b3932 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
@@ -8,6 +8,8 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import java.io.IOException;
+
 public class SupremeCard extends ResursBank {
 
     public SupremeCard(Context context) {
@@ -20,7 +22,8 @@ public class SupremeCard extends ResursBank {
         super.BANKTYPE_ID = IBankTypes.SUPREMECARD;
     }
 
-    public SupremeCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public SupremeCard(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         super(username, password, context);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 38372c2..7101ccf 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -60,14 +60,14 @@ public class SveaDirekt extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public SveaDirekt(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public SveaDirekt(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         if (urlopen == null) {
             urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sveadirekt));
             urlopen.getHttpclient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
@@ -89,25 +89,18 @@ public class SveaDirekt extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(LOGIN_URL, lp.getPostData());
-            if (response.contains("error-failed-to-login")) {
-                throw new LoginException(res.getText(
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(LOGIN_URL, lp.getPostData());
+        if (response.contains("error-failed-to-login")) {
+            throw new LoginException(res.getText(
                         R.string.invalid_username_password).toString());
-            }
-
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0
                 || password.length() == 0) {
@@ -140,17 +133,9 @@ public class SveaDirekt extends Bank {
                 account.setTransactions(parseTransactions(response));
             }
             this.setAccounts(accounts);
-        }
-        catch (ClientProtocolException e) {
-          throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        finally {
+        } finally {
           super.updateComplete();
         }
-
     }
 
     private ArrayList<Account> parseAccounts(Document pDocument) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index fe1976a..0c3a2b8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -66,13 +66,14 @@ public class SvenskaSpel extends Bank {
 		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
 	}
 
-	public SvenskaSpel(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public SvenskaSpel(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+	protected LoginPackage preLogin() throws BankException, IOException {
 		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
 
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
@@ -80,30 +81,22 @@ public class SvenskaSpel extends Bank {
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-
-			StringEntity postdata = new StringEntity(
-					"{\"userName\":\"" + username + "\",\"password\":\"" + password + "\"}");
-			HttpResponse httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), postdata, true);
-
-			if (httpResponse.getStatusLine().getStatusCode() != 200) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			response = EntityUtils.toString(httpResponse.getEntity());
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+
+		StringEntity postdata = new StringEntity(
+				"{\"userName\":\"" + username + "\",\"password\":\"" + password + "\"}");
+		HttpResponse httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), postdata, true);
+
+		if (httpResponse.getStatusLine().getStatusCode() != 200) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
+		response = EntityUtils.toString(httpResponse.getEntity());
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -128,4 +121,4 @@ public class SvenskaSpel extends Bank {
 		}
 		super.updateComplete();
 	}
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index e39b4d1..ec4fd36 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -64,7 +64,8 @@ public class TestBank extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public TestBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public TestBank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
@@ -76,7 +77,7 @@ public class TestBank extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -111,45 +112,32 @@ public class TestBank extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		finally {
+		} finally {
 		    super.updateComplete();
 		}
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 
 		//No transaction history for loans, funds and credit cards.
 		int accType = account.getType();
 		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
 
-		String response = null;
 		Matcher matcher;
-		try {
-			response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        String response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
+		matcher = reTransactions.matcher(response);
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		while (matcher.find()) {
+			transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 		}
+		account.setTransactions(transactions);
 	}
 
     @Override
     public int getImageResource() {
         return res.getIdentifier("icon_large", "drawable", context.getPackageName()); 
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 595016b..adf4bc0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -65,15 +65,15 @@ public class TicketRikskortet extends Bank {
         super.URL = URL;
     }
 
-    public TicketRikskortet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public TicketRikskortet(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
         response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
         Matcher matcher = reViewState.matcher(response);
@@ -100,25 +100,17 @@ public class TicketRikskortet extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://www.edenred.se/sv/System/Logga-in/");
     }
 
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());         
-            if (response.contains("Inloggningen misslyckades")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (response.contains("Inloggningen misslyckades")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -155,33 +147,27 @@ public class TicketRikskortet extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
 
-        String response = null;
         Matcher matcher;
-        try {
-            response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/Transaktioner/");
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Trans. date       2012-06-01
-                 * 2: Specification     DANMARKSG  KISTA
-                 * 3: Amount            - 85 kr
-                 * 
-                 */
-
-                transactions.add(new Transaction(matcher.group(1), Html.fromHtml(matcher.group(2).trim()).toString(), Helpers.parseBalance(matcher.group(3))));
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        String response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/Transaktioner/");
+        matcher = reTransactions.matcher(response);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Trans. date       2012-06-01
+             * 2: Specification     DANMARKSG  KISTA
+             * 3: Amount            - 85 kr
+             *
+             */
+
+            transactions.add(new Transaction(matcher.group(1), Html.fromHtml(matcher.group(2).trim()).toString(), Helpers.parseBalance(matcher.group(3))));
         }
+        account.setTransactions(transactions);
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 63f453e..550d32a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -70,15 +70,15 @@ public class TrustBuddy extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public TrustBuddy(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public TrustBuddy(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
         urlopen.setAllowCircularRedirects(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -88,65 +88,47 @@ public class TrustBuddy extends Bank {
         return new LoginPackage(urlopen, postData, null, "https://trustbuddy.com/se/logga_in/");
     }
     
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Matcher matcher = reError.matcher(response);
-			if (matcher.find()) {
-			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-			    if (errormsg.contains("Felaktigt")) {
-			        throw new LoginException(errormsg);    
-			    }
-			    else {
-	                 throw new BankException(errormsg);    
-			    }
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		Matcher matcher = reError.matcher(response);
+		if (matcher.find()) {
+		    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+		    if (errormsg.contains("Felaktigt")) {
+		        throw new LoginException(errormsg);
+		    }
+		    else {
+	             throw new BankException(errormsg);
+		    }
 		}
 		return urlopen;
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 
 		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://trustbuddy.com/se/din_sida/");
-			matcher = reAccounts.matcher(response);
+		String response = urlopen.open("https://trustbuddy.com/se/din_sida/");
+		Matcher matcher = reAccounts.matcher(response);
 			
-			while (matcher.find()) {
-                /*
-                 * 1: Land
-                 * 2: Saldo
-                 * 3: Valuta
-                 */
-				Account temp = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2).trim()), matcher.group(1).toLowerCase());
-				temp.setCurrency(matcher.group(3));
-				accounts.add(temp);
-	            
-				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-			}
-						if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
+		while (matcher.find()) {
+            /*
+             * 1: Land
+             * 2: Saldo
+             * 3: Valuta
+             */
+			Account temp = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2).trim()), matcher.group(1).toLowerCase());
+			temp.setCurrency(matcher.group(3));
+			accounts.add(temp);
+
+        	balance = balance.add(Helpers.parseBalance(matcher.group(2)));
 		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+		if (accounts.isEmpty()) {
+		    throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 20db645..142ecf4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -62,14 +62,14 @@ public class Vasttrafik extends Bank {
         super.URL = URL;
     }
 
-    public Vasttrafik(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Vasttrafik(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-    ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_vasttrafik));
         response = urlopen.open("https://www.vasttrafik.se/mina-sidor/logga-in/");
 
@@ -90,25 +90,17 @@ public class Vasttrafik extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (!response.contains("<span class=\"loggedInAs\">")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+        if (!response.contains("<span class=\"loggedInAs\">")) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -151,14 +143,7 @@ public class Vasttrafik extends Bank {
             if (accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        finally {
+        } finally {
             super.updateComplete();
         }
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 7e43724..873b077 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -68,13 +68,14 @@ public class Villabanken extends Bank {
 		super.URL = URL;
 	}
 
-	public Villabanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Villabanken(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+	protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_villabanken));
 		String preLoginResponse = urlopen.open(URL);
 		Matcher matcher = reRequestDigest.matcher(preLoginResponse);
@@ -137,25 +138,19 @@ public class Villabanken extends Bank {
 	}
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String loginResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (loginResponse.contains("misslyckades")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-            this.accountResponse = urlopen.open(accountUrl);
-
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		String loginResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		if (loginResponse.contains("misslyckades")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
+        this.accountResponse = urlopen.open(accountUrl);
+
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -196,7 +191,8 @@ public class Villabanken extends Bank {
 	}
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         if (account.getType() != Account.CCARD) return;
 
@@ -206,6 +202,5 @@ public class Villabanken extends Bank {
             transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate(), account.getCurrency()));
         }
         account.setTransactions(transactions);
-
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
index 2c33dc5..ed73df3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -22,6 +22,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Volkswagen extends AbsIkanoPartner {
     private static final String TAG = "Volkswagen";
@@ -40,10 +42,9 @@ public class Volkswagen extends AbsIkanoPartner {
         this.structId = "1319";
     }
 
-    public Volkswagen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Volkswagen(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
-
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 45ba389..b819a21 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -76,14 +76,14 @@ public class Volvofinans extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Volvofinans(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Volvofinans(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -95,30 +95,22 @@ public class Volvofinans extends Bank {
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException {
-	    try {
-	        LoginPackage lp = preLogin();
-	        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+	public Urllib login() throws LoginException, BankException, IOException {
+	    LoginPackage lp = preLogin();
+	    String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
-			if (response.contains("Fel personr/organisationsnr och/eller lösenord.")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-
-			if (response.contains("Internetbanken är stängd för tillfället och beräknas vara tillgänglig")) {
-				throw new LoginException(res.getText(R.string.bank_closed).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
+		if (response.contains("Fel personr/organisationsnr och/eller lösenord.")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+
+		if (response.contains("Internetbanken är stängd för tillfället och beräknas vara tillgänglig")) {
+			throw new LoginException(res.getText(R.string.bank_closed).toString());
 		}
 		return urlopen;
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -148,20 +140,14 @@ public class Volvofinans extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		finally {
+		} finally {
 	      super.updateComplete();
 		}
 	}
 	
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         String response = null;
         String url = mAccountUrlMappings.get(account.getId());
@@ -192,10 +178,6 @@ public class Volvofinans extends Bank {
                     throw new BankException(res.getText(R.string.no_accounts_found).toString());
                 }
 
-            } catch (ClientProtocolException e) {
-               throw new BankException(e.getMessage(), e);
-            } catch (IOException e) {
-                throw new BankException(e.getMessage(), e);
             } catch (JSONException e) {
                 throw new BankException(e.getMessage(), e);
             }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
index e73684f..1501d0a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
@@ -23,6 +23,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import java.io.IOException;
+
 
 public class Wallet extends SEBKortBase {
 	private static final String TAG = "wallet";
@@ -38,7 +40,8 @@ public class Wallet extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Wallet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Wallet(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		super(username, password, context, "wase", "0121");
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 1487d70..76d5f41 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -72,15 +72,15 @@ public class Zidisha extends Bank {
         super.currency = "USD";
 	}
 
-	public Zidisha(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Zidisha(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_zidisha));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.zidisha.org/");
@@ -99,22 +99,14 @@ public class Zidisha extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://www.zidisha.org/process.php");
     }
     
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
-		}
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 		return urlopen;
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -122,44 +114,35 @@ public class Zidisha extends Bank {
 
 		urlopen = login();
 		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.zidisha.org/index.php?p=19");
-			matcher = reAccounts.matcher(response);
-			
-			while (matcher.find()) {
-				/*
-				 * 1: Funds uploaded
-				 * 2: Available for withdrawal
-				 * 3: Lent by me
-				 * 4: Total Impact
-				 */
-				Account insattningar = new Account("Insättningar", Helpers.parseBalance(matcher.group(1)), "insattningar");
-				Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(2)), "tillgangligt");
-				Account utlanat      = new Account("Utlånat",      Helpers.parseBalance(matcher.group(3)), "utlanat");
-				Account balans       = new Account("Påverkan",     Helpers.parseBalance(matcher.group(4)), "impact");
-
-				insattningar.setCurrency("USD");
-				tillgangligt.setCurrency("USD");
-				utlanat.setCurrency("USD");
-				balans.setCurrency("USD");
-
-				accounts.add(insattningar);
-				accounts.add(tillgangligt);
-				accounts.add(utlanat);
-				accounts.add(balans);
-	            
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
+		response = urlopen.open("https://www.zidisha.org/index.php?p=19");
+		matcher = reAccounts.matcher(response);
+
+		while (matcher.find()) {
+			/*
+			 * 1: Funds uploaded
+			 * 2: Available for withdrawal
+			 * 3: Lent by me
+			 * 4: Total Impact
+			 */
+			Account insattningar = new Account("Insättningar", Helpers.parseBalance(matcher.group(1)), "insattningar");
+			Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(2)), "tillgangligt");
+			Account utlanat      = new Account("Utlånat",      Helpers.parseBalance(matcher.group(3)), "utlanat");
+			Account balans       = new Account("Påverkan",     Helpers.parseBalance(matcher.group(4)), "impact");
+
+			insattningar.setCurrency("USD");
+			tillgangligt.setCurrency("USD");
+			utlanat.setCurrency("USD");
+			balans.setCurrency("USD");
+
+			accounts.add(insattningar);
+			accounts.add(tillgangligt);
+			accounts.add(utlanat);
+			accounts.add(balans);
+
+			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
 	}
-
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index c91fc95..2a23823 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -64,14 +64,13 @@ public class Avanza extends Bank {
     }
 
     public Avanza(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("Referer", URL + "/start");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
@@ -179,10 +178,6 @@ public class Avanza extends Bank {
             }
         } catch (JsonParseException e) {
             throw new BankException(e.getMessage(), e);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         } catch (Exception e) {
             throw new BankException(e.getMessage(), e);
         }
@@ -191,7 +186,7 @@ public class Avanza extends Bank {
 
     @Override
     public void update() throws BankException, LoginException,
-            BankChoiceException {
+            BankChoiceException, IOException {
         super.update();
         if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
             throw new LoginException(res.getText(
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index b012940..7ad30c5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -66,12 +66,12 @@ public class Bitcoin extends Bank {
 	}
 
 	public Bitcoin(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException {
+			throws BankException, LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
-	public Urllib login() throws LoginException, BankException {
+	public Urllib login() throws LoginException, BankException, IOException {
 		urlopen = new Urllib(context);
 
 		try {
@@ -91,17 +91,14 @@ public class Bitcoin extends Bank {
 		} catch (JsonParseException e) {
 			throw new BankException(res.getText(
 					R.string.invalid_bitcoin_address).toString());
-		}catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
 		}
+
 		return urlopen;
 	}
 
 	@Override
 	public void update() throws BankException, LoginException,
-			BankChoiceException {
+			BankChoiceException, IOException {
 		super.update();
 		if (TextUtils.isEmpty(username)) {
 			throw new LoginException(res.getText(
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 85bd676..0c99eca 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -140,7 +140,8 @@ public class Coop extends Bank {
         super.STATIC_BALANCE = true;
     }
 
-    public Coop(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Coop(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
@@ -164,20 +165,16 @@ public class Coop extends Bank {
 
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            if (!lp.isLoggedIn()) {
-                throw new BankException(res.getString(R.string.invalid_username_password));
-            }
-            return urlopen;
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        if (!lp.isLoggedIn()) {
+            throw new BankException(res.getString(R.string.invalid_username_password));
         }
+        return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -185,85 +182,81 @@ public class Coop extends Bank {
 
         login();
 
-        try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
-            Document dResponse = Jsoup.parse(response);
-            Account poang = new Account("\u2014  Poäng",
-                    Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()),
-                    "poang", Account.OTHER, "");
-            List<Transaction> transactions = new ArrayList<>();
-            poang.setTransactions(transactions);
-            for (Element e : dResponse.select(".Timeline-item")) {
-                try {
-                    if (e.parent().hasClass("Timeline-group--emphasized")) {
-                        transactions.add(new Transaction(
-                                formatDate(e.ownText()),
-                                e.select(".Timeline-label").text(),
-                                Helpers.parseBalance(e.select(".Timeline-title").first().text()), ""));
-
-                    } else {
-                        transactions.add(new Transaction(
-                                formatDate(e.select(".Timeline-header .u-nbfcAlt span").text()),
-                                e.select(".u-block").text(),
-                                Helpers.parseBalance(e.select(".Timeline-header .Timeline-title").first().ownText()), ""));
-                    }
-                } finally { continue; }
+        response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
+        Document dResponse = Jsoup.parse(response);
+        Account poang = new Account("\u2014  Poäng",
+                Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()),
+                "poang", Account.OTHER, "");
+        List<Transaction> transactions = new ArrayList<>();
+        poang.setTransactions(transactions);
+        for (Element e : dResponse.select(".Timeline-item")) {
+            try {
+                if (e.parent().hasClass("Timeline-group--emphasized")) {
+                    transactions.add(new Transaction(
+                            formatDate(e.ownText()),
+                            e.select(".Timeline-label").text(),
+                            Helpers.parseBalance(e.select(".Timeline-title").first().text()), ""));
+
+                } else {
+                    transactions.add(new Transaction(
+                            formatDate(e.select(".Timeline-header .u-nbfcAlt span").text()),
+                            e.select(".u-block").text(),
+                            Helpers.parseBalance(e.select(".Timeline-header .Timeline-title").first().ownText()), ""));
+                }
+            } finally { continue; }
+        }
+        accounts.add(poang);
+        for (AccountType at : AccountType.values()) {
+            response = urlopen.open(at.getUrl());
+            Document d = Jsoup.parse(response);
+            Elements historik = d.select("#historik section");
+            TransactionParams params = new TransactionParams();
+            mTransactionParams.put(at, params);
+            if (historik != null && !historik.isEmpty()) {
+                String data = historik.first().attr("data-controller");
+                Matcher m = rePageGuid.matcher(data);
+                if (m.find()) {
+                    params.setPageGuid(m.group(1));
+                }
             }
-            accounts.add(poang);
-            for (AccountType at : AccountType.values()) {
-                response = urlopen.open(at.getUrl());
-                Document d = Jsoup.parse(response);
-                Elements historik = d.select("#historik section");
-                TransactionParams params = new TransactionParams();
-                mTransactionParams.put(at, params);
-                if (historik != null && !historik.isEmpty()) {
-                    String data = historik.first().attr("data-controller");
-                    Matcher m = rePageGuid.matcher(data);
-                    if (m.find()) {
-                        params.setPageGuid(m.group(1));
-                    }
+            Element date = d.getElementById("dateFrom");
+            if (date != null) {
+                params.setMinDate(date.hasAttr("min") ? date.attr("min") : null);
+                params.setMaxDate(date.hasAttr("max") ? date.attr("max") : null);
+            }
+            Elements es = d.select(".List:contains(Saldo)");
+            if (es != null && !es.isEmpty()) {
+                List<String> names = new ArrayList<>();
+                List<String> values = new ArrayList<>();
+                for (Element e : es.first().select("dt")) {
+                    names.add(e.text().replaceAll(":", "").trim());
                 }
-                Element date = d.getElementById("dateFrom");
-                if (date != null) {
-                    params.setMinDate(date.hasAttr("min") ? date.attr("min") : null);
-                    params.setMaxDate(date.hasAttr("max") ? date.attr("max") : null);
+                for (Element e : es.first().select("dd")) {
+                    values.add(e.text().trim());
                 }
-                Elements es = d.select(".List:contains(Saldo)");
-                if (es != null && !es.isEmpty()) {
-                    List<String> names = new ArrayList<>();
-                    List<String> values = new ArrayList<>();
-                    for (Element e : es.first().select("dt")) {
-                        names.add(e.text().replaceAll(":", "").trim());
-                    }
-                    for (Element e : es.first().select("dd")) {
-                        values.add(e.text().trim());
+                for (int i = 0; i < Math.min(names.size(), values.size()); i++) {
+                    Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)), String.format("%s%d", at.getPrefix(), i));
+                    a.setCurrency(Helpers.parseCurrency(values.get(i), "SEK"));
+                    if (a.getName().toLowerCase().contains("disponibelt")) {
+                        a.setType(Account.REGULAR);
+                        balance = a.getBalance();
+                        setCurrency(a.getCurrency());
+                    } else {
+                        a.setType(Account.OTHER);
                     }
-                    for (int i = 0; i < Math.min(names.size(), values.size()); i++) {
-                        Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)), String.format("%s%d", at.getPrefix(), i));
-                        a.setCurrency(Helpers.parseCurrency(values.get(i), "SEK"));
-                        if (a.getName().toLowerCase().contains("disponibelt")) {
-                            a.setType(Account.REGULAR);
-                            balance = a.getBalance();
-                            setCurrency(a.getCurrency());
-                        } else {
-                            a.setType(Account.OTHER);
-                        }
-
-                        if (i > 0) {
-                            a.setAliasfor(String.format("%s%d", at.getPrefix(), 0));
-                        }
-                        accounts.add(a);
+
+                    if (i > 0) {
+                        a.setAliasfor(String.format("%s%d", at.getPrefix(), 0));
                     }
+                    accounts.add(a);
                 }
             }
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
 
 
         try {
             response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
-            Document dResponse = Jsoup.parse(response);
+            dResponse = Jsoup.parse(response);
             Account a = new Account("Återbäring",
                     Helpers.parseBalance(dResponse.select(".Heading--coopNew").text()),
                     "refound", Account.OTHER, "SEK");
@@ -338,5 +331,4 @@ public class Coop extends Bank {
         }
         return null;
     }
-
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index 9748d42..553e6e1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -74,12 +74,12 @@ public class ICA extends Bank {
     }
 
     public ICA(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ica));
         urlopen.addHeader("Accept", "application/json;charset=UTF-8");
         urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
@@ -156,17 +156,13 @@ public class ICA extends Bank {
             httpResponse.getStatusLine();
         } catch (JsonParseException e) {
             throw new BankException(e.getMessage(), e);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
 
     @Override
     public void update() throws BankException, LoginException,
-            BankChoiceException {
+            BankChoiceException, IOException {
         super.update();
         if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
             throw new LoginException(res.getText(
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 6b5251c..b3f310e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -74,12 +74,12 @@ public class ICABanken extends Bank {
     }
 
     public ICABanken(String username, String password, Context context)
-            throws BankException, LoginException, BankChoiceException {
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken));
         urlopen.addHeader("ApiVersion", API_VERSION);
         urlopen.addHeader("Accept", "application/json");
@@ -89,31 +89,25 @@ public class ICABanken extends Bank {
         urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
         urlopen.addHeader("ClientAppVersion", "777");
 
-        try {
-            String response = urlopen.open(String.format("%s/login/passwordlogin?customerId=%s&password=%s", API_URL, username, password));
-            if(response == null || "".equals(response)) {
-                throw new LoginException(res.getText(
+        String response = urlopen.open(String.format("%s/login/passwordlogin?customerId=%s&password=%s", API_URL, username, password));
+        if(response == null || "".equals(response)) {
+            throw new LoginException(res.getText(
                         R.string.invalid_username_password).toString());
-            }
-            ObjectMapper vObjectMapper = new ObjectMapper();
-            vObjectMapper.setDateFormat(new SimpleDateFormat(
-                    "yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
-            LoginResponse loginResponse = vObjectMapper.readValue(response,
-                    LoginResponse.class);
-
-            addAccounts(loginResponse.getAccountList());
-
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
+        ObjectMapper vObjectMapper = new ObjectMapper();
+        vObjectMapper.setDateFormat(new SimpleDateFormat(
+                "yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
+        LoginResponse loginResponse = vObjectMapper.readValue(response,
+                LoginResponse.class);
+
+        addAccounts(loginResponse.getAccountList());
+
         return urlopen;
     }
 
     @Override
     public void update() throws BankException, LoginException,
-            BankChoiceException {
+            BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0
                 || password.length() == 0) {
@@ -130,11 +124,6 @@ public class ICABanken extends Bank {
 
     }
 
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen)
-            throws LoginException, BankException {
-    }
-
     private void addAccounts(IcaBankenAccountList pAccountList) {
         for (IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
             Account account = new Account(icaAccount.getName()
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index bd2f0ab..d98b94a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -94,16 +94,14 @@ public class Lansforsakringar extends Bank {
         mObjectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
     }
 
-    public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Lansforsakringar(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
-
-    
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         Urllib weblogin = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         weblogin.setAllowCircularRedirects(true);
 
@@ -196,7 +194,7 @@ public class Lansforsakringar extends Bank {
     }
     
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -225,7 +223,8 @@ public class Lansforsakringar extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         // No transaction history for funds and loans
         if (account.getType() != Account.REGULAR) return;
@@ -249,4 +248,4 @@ public class Lansforsakringar extends Bank {
         
         super.updateComplete();
     }       	
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index b9cd9fa..3407020 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -183,14 +183,14 @@ public class Nordea extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Nordea(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Nordea(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
 		this(context);
 		this.update(username, password);
 	}
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
 		urlopen = new Urllib(context);
 		Matcher matcher;
 		// Find "simple login" link
@@ -234,27 +234,18 @@ public class Nordea extends Bank {
     }
 
 	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-		    this.lastResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		    this.currentPageType = PageType.ENTRY;
-			if (this.lastResponse.contains("fel uppgifter")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (HttpResponseException e) {
-			throw new BankException(String.valueOf(e.getStatusCode()), e);
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage(), e);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage(), e);
+	public Urllib login() throws LoginException, BankException, IOException {
+		LoginPackage lp = preLogin();
+		this.lastResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		this.currentPageType = PageType.ENTRY;
+		if (this.lastResponse.contains("fel uppgifter")) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		return urlopen;
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException, BankChoiceException, IOException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -313,14 +304,7 @@ public class Nordea extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		}
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-		finally {
+		} finally {
 		    super.updateComplete();
 		}
 		
@@ -331,30 +315,24 @@ public class Nordea extends Bank {
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
 		super.updateTransactions(account, urlopen);
 
         int accType = account.getType();
-
-        try {
-            switch (accType) {
-                case Account.REGULAR:
-                    updateRegularTransactions(account, urlopen);
-                    break;
-                case Account.CCARD:
-                    updateCreditTransactions(account, urlopen);
-                    break;
-                default:
-                    break;
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+        switch (accType) {
+            case Account.REGULAR:
+                updateRegularTransactions(account, urlopen);
+                break;
+            case Account.CCARD:
+                updateCreditTransactions(account, urlopen);
+                break;
+            default:
+                break;
         }
 	}
 
-    private void goToPage(int pageType) throws ClientProtocolException, IOException {
+    private void goToPage(int pageType) throws IOException {
         // Convenience method for going to an overview page
         Matcher matcher;
         String link;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index a6486b4..d1702fe 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -64,10 +64,10 @@ public class Rikslunchen extends Bank {
         super.INPUT_HIDDEN_PASSWORD = true;
     }
 
-    public Rikslunchen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Rikslunchen(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
-
     }
 
     @Override
@@ -76,7 +76,7 @@ public class Rikslunchen extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (TextUtils.isEmpty(username)) {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
@@ -108,10 +108,6 @@ public class Rikslunchen extends Bank {
             accounts.add(new Account("Rikslunchen", balance, "1"));
         } catch (UnsupportedEncodingException e) {
             throw new BankException(e.getMessage(), e);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found)
@@ -119,5 +115,4 @@ public class Rikslunchen extends Bank {
         }
         super.updateComplete();
     }
-
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index be8a2b2..723f7c5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -82,14 +82,14 @@ public class SEB extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public SEB(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public SEB(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_seb_web));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://m.seb.se/");
@@ -103,30 +103,25 @@ public class SEB extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            urlopen = new Urllib(context, CertificateReader.getClientCertificate(context, R.raw.cert_client_seb, "openbankdata"), CertificateReader.getCertificates(context, R.raw.cert_seb));
-            urlopen.setFollowRedirects(false);
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            postData.add(new BasicNameValuePair("A1", username));
-            postData.add(new BasicNameValuePair("A2", password));
-            HttpResponse hr = urlopen.openAsHttpResponse("https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw", postData, true);
-            if (hr.getStatusLine().getStatusCode() == 200) {
-                throw new LoginException(res.getString(R.string.invalid_username_password));
-            } else if (hr.getStatusLine().getStatusCode() != 302) {
-                throw new BankException(res.getString(R.string.unable_to_login));
-            }
-            urlopen.setFollowRedirects(true);
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getClientCertificate(context, R.raw.cert_client_seb, "openbankdata"), CertificateReader.getCertificates(context, R.raw.cert_seb));
+        urlopen.setFollowRedirects(false);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("A1", username));
+        postData.add(new BasicNameValuePair("A2", password));
+        HttpResponse hr = urlopen.openAsHttpResponse("https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw", postData, true);
+        if (hr.getStatusLine().getStatusCode() == 200) {
+            throw new LoginException(res.getString(R.string.invalid_username_password));
+        } else if (hr.getStatusLine().getStatusCode() != 302) {
+            throw new BankException(res.getString(R.string.unable_to_login));
         }
+        urlopen.setFollowRedirects(true);
+
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -159,10 +154,6 @@ public class SEB extends Bank {
             e1.printStackTrace();
         } catch (JsonProcessingException e1) {
             e1.printStackTrace();
-        } catch (ClientProtocolException e1) {
-            e1.printStackTrace();
-        } catch (IOException e1) {
-            e1.printStackTrace();
         }
 
 
@@ -241,7 +232,8 @@ public class SEB extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
 
         //No transaction history for loans, funds and credit cards.
@@ -301,4 +293,4 @@ public class SEB extends Bank {
             throw new BankException(e.getMessage(), e);
         }
     }
-}
\ No newline at end of file
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index ba2d8f8..c3544cc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -89,19 +89,20 @@ public abstract class SEBKortBase extends Bank {
         mParamsErrorTarget = new BasicNameValuePair("errorTarget", URL);
     }
 
-    public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException, BankChoiceException {
+    public SEBKortBase(String username, String password, Context context, String url, String prodgroup)
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context, url, prodgroup);
         this.update(username, password);
     }
 
-    public SEBKortBase(String username, String password, Context context, String url, String prodgroup, String apiBase, int[] certificates) throws BankException, LoginException, BankChoiceException {
+    public SEBKortBase(String username, String password, Context context, String url, String prodgroup, String apiBase, int[] certificates)
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context, url, prodgroup, apiBase, certificates);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, mCertificates));
         //Get required cookies
         response = urlopen.open(String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
@@ -120,33 +121,27 @@ public abstract class SEBKortBase extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            urlopen.addHeader("Origin", String.format("https://%s", mApiBase));
-            urlopen.addHeader("Referer", String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
-            urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
-            List<NameValuePair> postData = lp.getPostData();
-            postData.remove(mParamsTarget);
-            postData.remove(mParamsErrorTarget);
-            postData.add(new BasicNameValuePair("target", String.format("/nis/m/%s/login/loginSuccess", mProviderPart)));
-            postData.add(new BasicNameValuePair("errorTarget", String.format("/nis/m/%s/external/login/loginError", mProviderPart)));
-
-            LoginResponse r = mObjectMapper.readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
-                    LoginResponse.class);
-            if ("Failure".equalsIgnoreCase(r.getReturnCode())) {
-                throw new LoginException(!TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString() : res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    public Urllib login() throws LoginException, BankException, IOException {
+        LoginPackage lp = preLogin();
+        urlopen.addHeader("Origin", String.format("https://%s", mApiBase));
+        urlopen.addHeader("Referer", String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
+        urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
+        List<NameValuePair> postData = lp.getPostData();
+        postData.remove(mParamsTarget);
+        postData.remove(mParamsErrorTarget);
+        postData.add(new BasicNameValuePair("target", String.format("/nis/m/%s/login/loginSuccess", mProviderPart)));
+        postData.add(new BasicNameValuePair("errorTarget", String.format("/nis/m/%s/external/login/loginError", mProviderPart)));
+
+        LoginResponse r = mObjectMapper.readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
+                LoginResponse.class);
+        if ("Failure".equalsIgnoreCase(r.getReturnCode())) {
+            throw new LoginException(!TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString() : res.getText(R.string.invalid_username_password).toString());
         }
         return urlopen;
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -179,10 +174,6 @@ public abstract class SEBKortBase extends Bank {
             if (accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         } finally {
             super.updateComplete();
         }
@@ -193,22 +184,20 @@ public abstract class SEBKortBase extends Bank {
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         if (account.getType() != Account.CCARD) return;
-        try {
-            PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/pendingTransactions/%s", mApiBase, mProviderPart, mBillingUnitIds.get(account))), PendingTransactionsResponse.class);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            for (CardGroup cg : r.getBody().getCardGroups()) {
-                for (TransactionGroup tg : cg.getTransactionGroups()) {
-                    for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg.getTransactions()) {
-                        transactions.add(new Transaction(Helpers.formatDate(new Date(t.getOriginalAmountDateDate())), t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate(), account.getCurrency()));
-                    }
+
+        PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/pendingTransactions/%s", mApiBase, mProviderPart, mBillingUnitIds.get(account))), PendingTransactionsResponse.class);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        for (CardGroup cg : r.getBody().getCardGroups()) {
+            for (TransactionGroup tg : cg.getTransactionGroups()) {
+                for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg.getTransactions()) {
+                    transactions.add(new Transaction(Helpers.formatDate(new Date(t.getOriginalAmountDateDate())), t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate(), account.getCurrency()));
                 }
             }
-            account.setTransactions(transactions);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         }
+        account.setTransactions(transactions);
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index e00da68..eb55fbc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -71,14 +71,14 @@ public abstract class AbstractSwedbank extends Bank {
         super.WEB_VIEW_ENABLED = WEB_VIEW_ENABLED;
     }
 
-    public AbstractSwedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public AbstractSwedbank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
 
     @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_swedbank));
         urlopen.addHeader("Authorization",getAuthenticationHeader());
         urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
@@ -87,7 +87,7 @@ public abstract class AbstractSwedbank extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
+    public Urllib login() throws LoginException, BankException, IOException {
         HttpResponse httpResponse = null;
         try {
             LoginPackage lp = preLogin();
@@ -116,12 +116,6 @@ public abstract class AbstractSwedbank extends Bank {
             } else {
                 throw new BankException("");
             }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         } finally {
             if(httpResponse != null) {
                 HttpEntity httpEntity = httpResponse.getEntity();
@@ -137,7 +131,7 @@ public abstract class AbstractSwedbank extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
+    public void update() throws BankException, LoginException, BankChoiceException, IOException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -163,17 +157,14 @@ public abstract class AbstractSwedbank extends Bank {
             if (this.accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
         } finally {
             updateComplete();
         }
     }
 
     @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException,
+            BankException, IOException {
         super.updateTransactions(account, urlopen);
         if(account.getType() == Account.CCARD) {
             updateCreditCardTransactions(account, urlopen);
@@ -185,55 +176,40 @@ public abstract class AbstractSwedbank extends Bank {
         else if(mIdMap.get(account.getId()) == null) {
             return;
         }
-        try {
 
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+mIdMap.get(account.getId())),false);
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+mIdMap.get(account.getId())),false);
 
-            TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(), TransactionsResponse.class);
-            List<Transaction> transactions = new ArrayList<Transaction>();
-            transactions.addAll(transformTransactions(response.getTransactions()));
-            transactions.addAll(transformTransactions(response.getReservedTransactions()));
-            account.setTransactions(transactions);
-
-        } catch(ClientProtocolException e) {
-            throw new BankException(e.getMessage(), e);
-        } catch(IOException e) {
-            throw new BankException(e.getMessage(), e);
-        }
+        TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(), TransactionsResponse.class);
+        List<Transaction> transactions = new ArrayList<Transaction>();
+        transactions.addAll(transformTransactions(response.getTransactions()));
+        transactions.addAll(transformTransactions(response.getReservedTransactions()));
+        account.setTransactions(transactions);
     }
 
     @Override
     public void closeConnection() {
         try {
             HttpResponse response = urlopen.openAsHttpResponse(getResourceUri("identification/logout"), HttpMethod.PUT);
-        } catch(ClientProtocolException e) {
-            // Ignore logout exceptions
         } catch(IOException e) {
             //Ignore logout exceptions
         } finally {
             super.closeConnection();
         }
-
     }
 
-    private void updateCreditCardTransactions(Account account, Urllib urlopen) throws BankException {
-        try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/cardaccount/"+mIdMap.get(account.getId())),false);
-            if(httpResponse.getStatusLine().getStatusCode() != 200) {
-                Log.i(TAG, "Couldn't find transactions for creditcard");
-                account.setTransactions(Collections.<Transaction>emptyList());
-                return;
-            }
-            CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),CardAccountResponse.class);
-            List<Transaction> transactions = new ArrayList<Transaction>();
-            transactions.addAll(transformCardTransactions(response.getTransactions()));
-            transactions.addAll(transformCardTransactions(response.getReservedTransactions()));
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-           throw new BankException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new BankException(e.getMessage(), e);
+    private void updateCreditCardTransactions(Account account, Urllib urlopen) throws BankException,
+            IOException {
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/cardaccount/"+mIdMap.get(account.getId())),false);
+        if(httpResponse.getStatusLine().getStatusCode() != 200) {
+            Log.i(TAG, "Couldn't find transactions for creditcard");
+            account.setTransactions(Collections.<Transaction>emptyList());
+            return;
         }
+        CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),CardAccountResponse.class);
+        List<Transaction> transactions = new ArrayList<Transaction>();
+        transactions.addAll(transformCardTransactions(response.getTransactions()));
+        transactions.addAll(transformCardTransactions(response.getReservedTransactions()));
+        account.setTransactions(transactions);
     }
 
     private List<Transaction> transformTransactions(List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
index 648d950..8eb1a88 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -7,6 +7,8 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import java.io.IOException;
+
 public class Sparbankerna extends AbstractSwedbank {
 
     private static final String TAG = "Sparbankerna";
@@ -25,7 +27,8 @@ public class Sparbankerna extends AbstractSwedbank {
 
     }
 
-    public Sparbankerna(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Sparbankerna(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
index ffe26ee..a671d2f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -7,6 +7,8 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import java.io.IOException;
+
 public class Swedbank extends AbstractSwedbank {
 
     private static final String TAG = "Swedbank";
@@ -25,7 +27,8 @@ public class Swedbank extends AbstractSwedbank {
 
     }
 
-    public Swedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+    public Swedbank(String username, String password, Context context) throws BankException,
+            LoginException, BankChoiceException, IOException {
         this(context);
         this.update(username, password);
     }

commit 026a63e8b0c7844798cbdcc4088fce90f14d2efe
Merge: 549551d 013b34a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 21:42:40 2015 +0100

    Merge pull request #484 from liato/feature/webview-background
    
    Webview background to white.

commit 013b34aadcf835040c987ee99362f6fbf69f38af
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 3 10:41:14 2015 +0100

    Fixes #482, set webView background to WHITE

diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index 842a2d1..3874b5e 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -42,6 +42,8 @@ import java.io.IOException;
 
 import eu.nullbyte.android.urllib.Urllib;
 
+import static android.graphics.Color.WHITE;
+
 public class WebViewActivity extends LockableActivity implements OnClickListener {
     private final static String TAG = "WebViewActivity";
     private static WebView mWebView;
@@ -78,6 +80,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                     Runnable runnable = new Runnable() {
                         public void run() {
 //                            activity.hideProgressBar();
+                            if (mFirstPageLoaded) mWebView.setBackgroundColor(WHITE);
                         }
                     };
                     // Let the progress bar hit 100% before we hide it.

commit 549551dba5f2798597a31f7ca5bf77f1c4e1c3ed
Merge: 68a1afb d619c63
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 20:56:29 2015 +0100

    Merge pull request #481 from liato/feature/minpension.se
    
    New bank, minpension.se. Fixes #288

commit 68a1afbe60cb949625dfd6e616715d3f6620e6e9
Merge: 0cd4d67 1c7872f
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Mar 4 20:47:01 2015 +0100

    Merge pull request #490 from liato/feature/travis-ignore-email-notifications
    
    Ignore email notifications for travis

commit d619c63e39a233029505e1a385c7ac6fc6c4c23d
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 3 00:42:47 2015 +0100

    New bank, minpension.se. Fixes #288

diff --git app/src/main/res/drawable/logo_minpension.png app/src/main/res/drawable/logo_minpension.png
new file mode 100644
index 0000000..a315add
Binary files /dev/null and app/src/main/res/drawable/logo_minpension.png differ
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index cf8a073..c78d92b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -31,6 +31,7 @@ import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.Marginalen;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Meniga;
+import com.liato.bankdroid.banking.banks.MinPension;
 import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.Nordnetdirekt;
@@ -241,6 +242,8 @@ public class LegacyBankFactory {
                 return new Bredband2VoIP(context);
             case IBankTypes.ESPRESSOHOUSE:
                 return new EspressoHouse(context);
+            case IBankTypes.MINPENSION:
+                return new MinPension(context);
             default:
                 throw new BankException("BankType id not found.");
         }
@@ -328,6 +331,7 @@ public class LegacyBankFactory {
         banks.add(new Ostgotatrafiken(context));
         banks.add(new Bredband2VoIP(context));
         banks.add(new EspressoHouse(context));
+        banks.add(new MinPension(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
new file mode 100644
index 0000000..f74f577
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MinPension.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class MinPension extends Bank {
+    public MinPension(Context context) {
+        super(context);
+        TAG = "MinPension";
+        NAME = "Min Pension.se";
+        NAME_SHORT = "minpension";
+        BANKTYPE_ID = IBankTypes.MINPENSION;
+        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+        INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE | InputType.TYPE_TEXT_VARIATION_PASSWORD;;
+        INPUT_HINT_USERNAME = res.getText(R.string.pno).toString();
+    }
+
+    public MinPension(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            IOException {
+        List<NameValuePair> postData = new ArrayList<>();
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_minpension));
+        String response = urlopen.open("https://www.minpension.se/AjaxifyContent/795");
+        Document jDoc = Jsoup.parse(response);
+        Element el = jDoc.select("input[name=__RequestVerificationToken]").first();
+        if (el == null) return null;
+        postData.add(new BasicNameValuePair("__RequestVerificationToken", el.val()));
+        postData.add(new BasicNameValuePair("viewModel.Personnummer", username));
+        postData.add(new BasicNameValuePair("viewModel.Kod", password));
+        LoginPackage lp = new LoginPackage(urlopen, postData, null, "https://www.minpension.se/inloggning/personlig-kod");
+        return lp;
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+
+            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData(), true);
+            if (!response.contains("LoggaUt.aspx")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+            response = urlopen.open("https://www.minpension.se/mina-sidor/redirect?path=MinPension%2FDefault.aspx&bodyMargin=0");
+            Document document = Jsoup.parse(response);
+            Element e = document.select("#authenticationResult").first();
+            if (e == null) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+            List<NameValuePair> postData = new ArrayList<>();
+            postData.add(new BasicNameValuePair("authenticationResult", e.val()));
+            urlopen.open("https://minasidor.minpension.se/MinPension/Default.aspx", postData, true);
+
+            return urlopen;
+
+        } catch (IOException e) {
+            throw new BankException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+//Allmän pension
+            accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/AllmanPension.aspx",
+                    "#AllmänPensionTable tr",
+                    res.getText(R.string.public_pension).toString()));
+//Tjänstepension
+            accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/Tjanstepension.aspx",
+                    "#TjänstepensionTable tr",
+                    res.getText(R.string.occupational_pension).toString()));
+//Privat pension
+            accounts.add(updateAccount("https://minasidor.minpension.se/MinPension/PrivatPension.aspx",
+                    "#PrivatPensionTable tr",
+                    res.getText(R.string.private_pension).toString()));
+        } catch (IOException e) {
+            throw new BankException(e.getMessage(), e);
+        }
+        super.updateComplete();
+    }
+
+    private Account updateAccount(String URL, String selector, String name) throws IOException {
+        String response = urlopen.open(URL);
+        Document dResponse = Jsoup.parse(response);
+        List<Transaction> transactions = new ArrayList<>();
+        String institute = "";
+        String subInstitute = "";
+        for (Element e : dResponse.select(selector)) {
+            if (e.hasClass("GroupRow")) {
+                institute = e.children().first().text();
+            } else if (e.hasClass("GroupMemberRow") || e.hasClass("SubRow")) {
+                Elements elements = e.children();
+                if (elements.size() == 6) { //Special case for "Allmän pension"
+                    if (elements.get(2).text().isEmpty()) {
+                        //   subInstitute =  " — " + elements.get(1).text(); /* Doesn't fit atm. */
+                    } else {
+                        transactions.add(new Transaction(elements.get(5).text(),
+                                institute + subInstitute + "\n — " + elements.get(1).text(),
+                                Helpers.parseBalance(elements.get(2).text())));
+                        subInstitute = "";
+                    }
+                } else if (elements.size() >= 7) {
+                    transactions.add(new Transaction(elements.get(6).text(),
+                            institute + "\n — " + elements.get(1).text(),
+                            Helpers.parseBalance(elements.get(4).text())));
+                }
+            }
+        }
+
+        balance = BigDecimal.ZERO;
+        for (Transaction t : transactions) balance = balance.add(t.getAmount());
+        Account account = new Account(name, balance, name, Account.REGULAR, "");
+        account.setTransactions(transactions);
+        return account;
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 7c8cb25..ea599d4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -102,4 +102,5 @@ public interface IBankTypes {
     public final static int OSTGOTATRAFIKEN = 78;
     public final static int BREDBAND2VOIP = 79;
     public final static int ESPRESSOHOUSE = 80;
+    public final static int MINPENSION = 81;
 }
diff --git bankdroid-legacy/src/main/res/raw/cert_minpension.pem bankdroid-legacy/src/main/res/raw/cert_minpension.pem
new file mode 100644
index 0000000..04543bb
--- /dev/null
+++ bankdroid-legacy/src/main/res/raw/cert_minpension.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----

+iz43
+-----END CERTIFICATE-----
+www.minpension.se:443
diff --git bankdroid-legacy/src/main/res/values-sv/strings.xml bankdroid-legacy/src/main/res/values-sv/strings.xml
index 77cb0b4..f63fab6 100644
--- bankdroid-legacy/src/main/res/values-sv/strings.xml
+++ bankdroid-legacy/src/main/res/values-sv/strings.xml
@@ -8,11 +8,15 @@
     <string name="points">poäng</string>
     <string name="card_id">Kort ID</string>
     <string name="balance">Saldo</string>
+    <string name="pno">ÅÅÅÅMMDDNNNN</string>
 
     <string name="nordnetdirekt_extras_title">Nyckel</string>
 
     <string name="bitcoin_address">Bitcoin-adress</string>
     <string name="invalid_bitcoin_address">Ogiltig bitcoin-adress.</string>
+    <string name="public_pension">Allmän pension</string>
+    <string name="occupational_pension">Tjänstepension</string>
+    <string name="private_pension">Privat pension</string>
 
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="unable_to_login">Kunde ej logga in. Var vänlig försök igen senare.</string>
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
index 648a17b..b73c531 100644
--- bankdroid-legacy/src/main/res/values/strings.xml
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -12,11 +12,15 @@
     <string name="points">points</string>
     <string name="card_id">Card ID</string>
     <string name="balance">Balance</string>
+    <string name="pno">YYYYMMDDNNNN</string>
 
     <string name="nordnetdirekt_extras_title">Key</string>
 
     <string name="bitcoin_address">Bitcoin address</string>
     <string name="invalid_bitcoin_address">Invalid bitcoin address.</string>
+    <string name="public_pension">Public pension</string>
+    <string name="occupational_pension">Occupational pension</string>
+    <string name="private_pension">Private pension</string>
 
     <string name="unable_to_find">Unable to find</string>
     <string name="unable_to_login">Unable to login. Please try again later.</string>

commit 1c7872f4ae5a1b4009b529ec214af1a0b52914b8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 20:34:06 2015 +0100

    Ignore email notifications for Travis builds

diff --git .travis.yml .travis.yml
index 1e2db0d..7a16044 100644
--- .travis.yml
+++ .travis.yml
@@ -12,6 +12,7 @@ android:
 script: ./gradlew check
 
 notifications:
+  email: false
   slack:
     secure: asrV7/94tGqJbhotBAkPFi80PWJY3lcu7uYo855kpujXQHP61b0gC5gHnAairdD+MtrwICOmsJE9KIK/HOIpFrzwE+IwxJ+p6cGL9kX9blX+ZThcz1HkZgEK/EgaMSUxLKZFGrz0LUdktoZ9h+VixeRg05S4VijA7A814iA78fI=
 

commit 0cd4d679e93f7c60814d372734827d5375dfec0e
Merge: 9bfe094 4c93b6d
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Mar 4 19:35:24 2015 +0100

    Merge pull request #486 from liato/feature/478-widget-crash-on-deleted-account
    
    Verify that both the bank and account exists before showing its transactions

commit 4c93b6dd9d0a9d60a7f3370914d1f8deb1209be0
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 17:46:36 2015 +0100

    Adds Swedish translations for error messages.

diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 116e766..97f7f43 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -247,4 +247,8 @@
     <!-- Color Picker -->
     <string name="dialog_color_picker">Färgväljare</string>
     <string name="press_color_to_apply">Tryck på färgen för att välja</string>
+
+    <!-- Error messages -->
+    <string name="error_bank_not_found">Den valda banken kunde inte hittas.</string>
+    <string name="error_account_not_found">Det valda kontot kunde inte hittas.</string>
 </resources>

commit 0dd345697bae0c00ad48431fb18eebe2953135bd
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 17:37:19 2015 +0100

    Fixes compilation error

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 35f6fa8..919bd86 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -118,7 +118,7 @@ public class MainActivity extends LockableActivity {
     			startActivity(intent);
 		    }
 		}
-        ((BankdroidApplication) getApplication()).showAndDeleteApplicationMessage(this);
+        ((BankdroidApplication) getApplication()).showAndDeleteApplicationMessage();
 	}
 
 	

commit 4e1e11a314383294049f913a1313a428b8ed0868
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 17:21:44 2015 +0100

    Adds check to verify that a cursor has returned a response.

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 6055de5..e576c3f 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -44,7 +44,7 @@ public class BankFactory {
 		DBAdapter db = new DBAdapter(context);
 		Cursor c = db.getBank(id);
 
-		if (c != null) {
+		if (c != null && c.getCount() > 0) {
 			try {
 				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
 				String password = "";
@@ -82,7 +82,7 @@ public class BankFactory {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
 		DBAdapter db = new DBAdapter(context);
 		Cursor c = db.fetchBanks();
-		if (c == null) {
+		if (c == null || c.getCount() == 0) {
 			return banks;
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
@@ -162,7 +162,7 @@ public class BankFactory {
 		ArrayList<Account> accounts = new ArrayList<Account>();
 		DBAdapter db = new DBAdapter(context);
 		Cursor c = db.fetchAccounts(bankId);
-		if (c == null) {
+		if (c == null || c.getCount() == 0) {
 			return accounts;
 		}
 		while (!c.isLast() && !c.isAfterLast()) {

commit a6be14a95efbc573f50f97396dfe7af8305066ff
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 17:20:53 2015 +0100

    Redirect user to main activity with an error message if error occurs.
    
    If bank or account could not be found in db.

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 97911a3..35f6fa8 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -118,6 +118,7 @@ public class MainActivity extends LockableActivity {
     			startActivity(intent);
 		    }
 		}
+        ((BankdroidApplication) getApplication()).showAndDeleteApplicationMessage(this);
 	}
 
 	
diff --git app/src/main/java/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
index fa63dd7..60b4353 100644
--- app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
+++ app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
@@ -17,6 +17,7 @@
 package com.liato.bankdroid;
 
 import android.content.Context;
+import android.content.Intent;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -45,7 +46,15 @@ public class TransactionsActivity extends LockableActivity {
         setContentView(R.layout.transactions);
         Bundle extras = getIntent().getExtras();
         Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
+        if(bank == null) {
+            redirectToMain(getString(R.string.error_bank_not_found));
+            return;
+        }
         Account account = BankFactory.accountFromDb(this, extras.getLong("bank") + "_" + extras.getString("account"), true);
+        if(account == null) {
+            redirectToMain(getString(R.string.error_account_not_found));
+            return;
+        }
         TextView viewBankName = (TextView) findViewById(R.id.txtListitemAccountsGroupAccountname);
         TextView viewAccountName = (TextView) findViewById(R.id.txtListitemAccountsGroupBankname);
         TextView viewAccountBalance = (TextView) findViewById(R.id.txtListitemAccountsGroupTotal);
@@ -174,4 +183,10 @@ public class TransactionsActivity extends LockableActivity {
 
     }
 
+    private void redirectToMain(String errorMessage) {
+        final Intent intent = new Intent(this, MainActivity.class);
+        ((BankdroidApplication) getApplicationContext()).setApplicationMessage(getString(R.string.error_bank_not_found));
+        startActivity(intent);
+    }
+
 }
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index ddbb52b..461b50d 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -302,4 +302,8 @@
     <!-- Color Picker -->
     <string name="dialog_color_picker">Color Picker</string>
     <string name="press_color_to_apply">Press on Color to apply</string>    
+
+    <!-- Error messages -->
+    <string name="error_bank_not_found">The chosen bank could not be found.</string>
+    <string name="error_account_not_found">The chosen account could not be found.</string>
 </resources>

commit 9bdafd82d4e9d270456574f6c3a704721be79c80
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Mar 4 17:17:58 2015 +0100

    Adds possibility to send error messages between activities.

diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index c66f6c6..6ab6fae 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -1,6 +1,7 @@
 package com.liato.bankdroid;
 
 import android.app.Application;
+import android.widget.Toast;
 
 import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.banking.Bank;
@@ -16,6 +17,8 @@ public class BankdroidApplication extends Application {
     public static final String LOG_KEY_LOCALE = "locale";
     public static final String LOG_KEY_BANKS = "banks";
 
+    private String message = "";
+
     @Override
     public void onCreate() {
         super.onCreate();
@@ -35,4 +38,16 @@ public class BankdroidApplication extends Application {
             Crashlytics.setString(LOG_KEY_BANKS, bankStringBuilder.substring(0, bankStringBuilder.length() - 1));
         }
     }
+
+    public void setApplicationMessage(String messageText) {
+        message = messageText == null ? "" : messageText;
+    }
+
+    public void showAndDeleteApplicationMessage() {
+        if (!message.isEmpty()) {
+            Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG);
+            message = "";
+            toast.show();
+        }
+    }
 }

commit 9bfe094178ba1c6484d88017f9322093449fcb5b
Merge: 27b85c5 5ae48f2
Author: liato <x@x00.us>
Date:   Wed Mar 4 08:38:48 2015 +0000

    Merge pull request #485 from liato/feature/localized-strings
    
    Fixes Swedish localization strings

commit 5ae48f21000a559ce0931d426f974d152f03db68
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Mar 4 09:36:25 2015 +0100

    Fixes Swedish localization strings

diff --git bankdroid-legacy/src/main/res/values-se/strings.xml bankdroid-legacy/src/main/res/values-sv/strings.xml
similarity index 100%
rename from bankdroid-legacy/src/main/res/values-se/strings.xml
rename to bankdroid-legacy/src/main/res/values-sv/strings.xml

commit 27b85c5ee7ce72bd0ab4ee0cb43b3d4ec1017f43
Merge: 09b0edf 67a9d34
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Mar 3 00:55:18 2015 +0100

    Merge pull request #480 from liato/feature/475-villabanken-crash-on-missing-balance
    
    Check that regex matches before adding account for Villabanken.

commit 09b0edf07eae7de41268e9a282cf6175aabe1e80
Author: liato <x@x00.us>
Date:   Mon Mar 2 22:55:18 2015 +0100

    Update readme with build status from travis.

diff --git README.rst README.rst
index f47451d..0be1f02 100644
--- README.rst
+++ README.rst
@@ -1,6 +1,10 @@
+.. image:: https://travis-ci.org/liato/android-bankdroid.svg?branch=master
+    :target: https://travis-ci.org/liato/android-bankdroid
+
 Bankdroid
 =========
 
+
 Bankdroid is an Android app for Swedish banks, payment cards and similar services. Key features include:
 
 * Automatic updates of your balance and transactions

commit c7d58f9d265e07a8a7fe56f3a47ec4b7973eea5f
Author: liato <x@x00.us>
Date:   Mon Mar 2 22:44:45 2015 +0100

    Don't build all branches with travis,

diff --git .travis.yml .travis.yml
index 71ff431..1e2db0d 100644
--- .travis.yml
+++ .travis.yml
@@ -14,3 +14,8 @@ script: ./gradlew check
 notifications:
   slack:
     secure: asrV7/94tGqJbhotBAkPFi80PWJY3lcu7uYo855kpujXQHP61b0gC5gHnAairdD+MtrwICOmsJE9KIK/HOIpFrzwE+IwxJ+p6cGL9kX9blX+ZThcz1HkZgEK/EgaMSUxLKZFGrz0LUdktoZ9h+VixeRg05S4VijA7A814iA78fI=
+
+branches:
+  except:
+    - gh-pages
+    - transaction-uid

commit cf854013c8ae48ed4ca297beea5dc4aca7d821d7
Author: liato <x@x00.us>
Date:   Mon Mar 2 22:39:41 2015 +0100

    Add slack notification to travis.

diff --git .travis.yml .travis.yml
index 67032d7..71ff431 100644
--- .travis.yml
+++ .travis.yml
@@ -10,3 +10,7 @@ android:
     - extra-android-m2repository
 
 script: ./gradlew check
+
+notifications:
+  slack:
+    secure: asrV7/94tGqJbhotBAkPFi80PWJY3lcu7uYo855kpujXQHP61b0gC5gHnAairdD+MtrwICOmsJE9KIK/HOIpFrzwE+IwxJ+p6cGL9kX9blX+ZThcz1HkZgEK/EgaMSUxLKZFGrz0LUdktoZ9h+VixeRg05S4VijA7A814iA78fI=

commit 67a9d3423b05f01d021d10e0f975d035f1f2c030
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 22:00:51 2015 +0100

    Check that regex matches before adding account for Villabanken.
    
    Fixes #475

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 1f87150..7e43724 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -165,35 +165,34 @@ public class Villabanken extends Bank {
 		Matcher matcher;
 
         matcher = reDisposableAmount.matcher(accountResponse);
-        matcher.find();
-        Account account = new Account("Disponibelt belopp", Helpers.parseBalance(matcher.group(2)), "0");
-        account.setType(Account.CCARD);
-        account.setCurrency(currency);
-        accounts.add(account);
-        balance = balance.add(account.getBalance());
-
+        if(matcher.find()) {
+            Account account = new Account("Disponibelt belopp", Helpers.parseBalance(matcher.group(2)), "0");
+            account.setType(Account.CCARD);
+            account.setCurrency(currency);
+            accounts.add(account);
+            balance = balance.add(account.getBalance());
+        }
         matcher = reBalance.matcher(accountResponse);
-        matcher.find();
-        account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
-        account.setType(Account.OTHER);
-        account.setAliasfor("Saldo alias");
-        account.setCurrency(currency);
-        accounts.add(account);
-
+        if(matcher.find()) {
+            Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
+            account.setType(Account.OTHER);
+            account.setAliasfor("Saldo alias");
+            account.setCurrency(currency);
+            accounts.add(account);
+        }
         matcher = reCreditLimit.matcher(accountResponse);
-        matcher.find();
-        account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
-        account.setType(Account.OTHER);
-        account.setAliasfor("Köpgräns alias");
-        account.setCurrency(currency);
-        accounts.add(account);
-
+        if(matcher.find()) {
+            Account account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
+            account.setType(Account.OTHER);
+            account.setAliasfor("Köpgräns alias");
+            account.setCurrency(currency);
+            accounts.add(account);
+        }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
 
         super.updateComplete();
-
 	}
 
     @Override

commit d8b5fef2bfeaf15768deebac148bc9113b8bac1e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 21:48:28 2015 +0100

    Adds travis-ci support

diff --git .travis.yml .travis.yml
new file mode 100644
index 0000000..67032d7
--- /dev/null
+++ .travis.yml
@@ -0,0 +1,12 @@
+language: android
+jdk: oraclejdk7
+env:
+  matrix:
+    - ANDROID_TARGET=android-21  ANDROID_ABI=armeabi-v7a
+
+android:
+  components:
+    - build-tools-21.1.1
+    - extra-android-m2repository
+
+script: ./gradlew check

commit 846ff204a3e052e54031ef806774790b99eee812
Merge: cda41b2 57973f6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 16:57:58 2015 +0100

    Merge pull request #477 from liato/feature/disableUpdateDuringRoaming
    
    Add option to disable autoupdate during roaming

commit 57973f6a0d36b7ff02af9c8b335491f3ec73771c
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 1 23:32:20 2015 +0100

    Fixes #247, add option to disable autoupdate during roaming

diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index f4c2458..ecb2a9e 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -83,7 +83,8 @@ public class AutoRefreshService extends Service {
         ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
         NetworkInfo ni = cm.getActiveNetworkInfo();
         if (ni != null &&
-                ni.isConnected()) {
+                ni.isConnected() &&
+                shouldUpdateOnRoaming(ni)) {
             if (InsideUpdatePeriod()){
                 new DataRetrieverTask().execute();
             }
@@ -94,6 +95,15 @@ public class AutoRefreshService extends Service {
         }
     }
 
+    private boolean shouldUpdateOnRoaming(NetworkInfo ni) {
+        final SharedPreferences prefs = PreferenceManager
+                .getDefaultSharedPreferences(this);
+        if (prefs.getBoolean("disable_during_roaming", false) && ni.isRoaming()) {
+            return false;
+        }
+        return true;
+    }
+
     private boolean InsideUpdatePeriod() {
 		final SharedPreferences prefs = PreferenceManager
 			.getDefaultSharedPreferences(this);
@@ -384,4 +394,4 @@ public class AutoRefreshService extends Service {
 			Log.e("", e.getMessage(), e);
 		}
 	}
-}
\ No newline at end of file
+}
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index a680c75..116e766 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -46,7 +46,9 @@
 	<string name="automatic_updates_title">Automatiska Uppdateringar</string>
 	<string name="autoupdates_enabled_title">Aktivera</string>
 	<string name="autoupdates_enabled_summary">Aktivera automatiska uppdateringar</string>
-	<string name="update_frequency_title">Uppdateringsfrekvens</string>
+    <string name="roaming">Roaming</string>
+    <string name="disable_during_roaming">Avaktivera automatiska uppdateringar vid roaming</string>
+    <string name="update_frequency_title">Uppdateringsfrekvens</string>
 	<string name="update_start_title">Starttid uppdatering</string>
 	<string name="update_stop_title">Sluttid uppdatering</string>
 	<string name="update_transaction_history_title">Uppdatera kontoutdrag</string>
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index 656a126..ddbb52b 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -48,6 +48,8 @@
 	<string name="automatic_updates_title">Automatic Updates</string>
 	<string name="autoupdates_enabled_title">Enable</string>
 	<string name="autoupdates_enabled_summary">Enable automatic updates</string>
+    <string name="roaming">Roaming</string>
+    <string name="disable_during_roaming">Disable automatic updates if roaming</string>
 	<string name="update_frequency_title">Update frequency</string>
 	<string name="update_start_title">Update start time</string>
 	<string name="update_stop_title">Update end time</string>
diff --git app/src/main/res/xml/settings.xml app/src/main/res/xml/settings.xml
index 3be47d9..cd156b0 100644
--- app/src/main/res/xml/settings.xml
+++ app/src/main/res/xml/settings.xml
@@ -69,6 +69,11 @@
 			android:defaultValue="true"
 			android:title="@string/autoupdates_enabled_title"
 			android:summary="@string/autoupdates_enabled_summary" />
+        <CheckBoxPreference
+            android:key="disable_during_roaming"
+            android:defaultValue="false"
+            android:title="@string/roaming"
+            android:summary="@string/disable_during_roaming" />
 		<ListPreference
 			android:title="@string/update_frequency_title"
 			android:key="refresh_rate"

commit cda41b2d4edd055985ca22aabf44def65c301b29
Merge: ac17c8f 49a7cef
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 08:26:13 2015 +0100

    Merge pull request #468 from liato/feature/networkInfo-test
    
    Fixes: Attempt to invoke virtual method 'boolean android.net.NetworkInfo...

commit ac17c8fe8f8532ddbded977cacc985fe66a014f7
Merge: 0f9c6df 8b31cd3
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Mar 2 08:17:16 2015 +0100

    Merge pull request #472 from liato/feature/471-crash-on-alert-dialog
    
    Check if activity is finishing before alert dialog is shown.

commit 0f9c6dfd98951d79a202a944ac5e92db7e6e973e
Merge: 123f607 4cc6336
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Mar 2 08:16:50 2015 +0100

    Merge pull request #474 from liato/feature/473-fix-httpentity-null-check
    
    Adds null check before calling toString on HttpEntity

commit 123f6071ede9145f472a5c7058cf93776da76ef2
Merge: ef0f912 0ddc8db
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Mar 2 08:14:57 2015 +0100

    Merge pull request #470 from liato/feature/189-database-locking
    
    Use a single database connection for the whole application.

commit 4cc6336eb25cc59d1630ba856ae5e278acefd3f2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 07:54:31 2015 +0100

    Adds null check before calling toString on HttpEntity
    
    Fixes #473

diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index 881bdb8..60feb01 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -147,7 +147,11 @@ public class Urllib {
         return open(url, postData, false);
     }
     public String open(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
-        return EntityUtils.toString(openAsHttpResponse(url, postData, forcePost).getEntity());
+        HttpEntity entity = openAsHttpResponse(url, postData, forcePost).getEntity();
+        if(entity == null) {
+            return "";
+        }
+        return EntityUtils.toString(entity);
     }
 
     public HttpResponse openAsHttpResponse(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {

commit 8b31cd36fab5ff746ed5a2096369f9990de7b064
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 07:40:34 2015 +0100

    Check if activity is finishing before alert dialog is shown.
    
    Fixes #471

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 766d047..c12a6c2 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -292,7 +292,9 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
     				});
 				}
 				AlertDialog alert = builder.create();
-				alert.show();
+                if(!context.isFinishing()) {
+                    alert.show();
+                }
 			}
 			else {
 				context.finish();

commit 0ddc8db3d9ccd930dff2c777b4c7b748f920f4d8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Mar 2 07:11:31 2015 +0100

    Use a single database connection for the whole application.
    
    To prevent database locking.
    See http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection
    
    Fixes #189

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 50b82d8..97911a3 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -308,9 +308,7 @@ public class MainActivity extends LockableActivity {
 				.setPositiveButton(context.getText(R.string.yes), new DialogInterface.OnClickListener() {
 					public void onClick(final DialogInterface dialog, final int id) {
 						final DBAdapter db = new DBAdapter(context);
-						db.open();
 						db.deleteBank(selected_bank.getDbId());
-						db.close();
 						dialog.cancel();
 						parent.refreshView();
 					}
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 8270002..7a3be92 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -224,7 +224,6 @@ public class AutoRefreshService extends Service {
 				return null;
 			}
 			final DBAdapter db = new DBAdapter(AutoRefreshService.this);
-			db.open();
 			BigDecimal currentBalance;
 			BigDecimal diff;
 			BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0"));
@@ -335,8 +334,6 @@ public class AutoRefreshService extends Service {
 				sendBroadcast(updateIntent);
 				sendWidgetRefresh(AutoRefreshService.this);
 			}
-			db.close();
-
 			return null;
 		}
 
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 14129c5..6055de5 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -42,7 +42,6 @@ public class BankFactory {
 	public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
 		Bank bank = null;
 		DBAdapter db = new DBAdapter(context);
-		db.open();
 		Cursor c = db.getBank(id);
 
 		if (c != null) {
@@ -76,17 +75,14 @@ public class BankFactory {
 				c.close();
 			}
 		}
-		db.close();
 		return bank;
 	}
 
 	public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
 		DBAdapter db = new DBAdapter(context);
-		db.open();
 		Cursor c = db.fetchBanks();
 		if (c == null) {
-			db.close();
 			return banks;
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
@@ -119,17 +115,14 @@ public class BankFactory {
 			}
 		}
 		c.close();
-		db.close();
 		return banks;
 	}
 
 	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
 		DBAdapter db = new DBAdapter(context);
-		db.open();
 		Cursor c = db.getAccount(accountId);
 
 		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
-			db.close();
 			return null;
 		}
 
@@ -162,18 +155,14 @@ public class BankFactory {
 			}
 			account.setTransactions(transactions);
 		}
-
-		db.close();
 		return account;
 	}
 
 	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
 		ArrayList<Account> accounts = new ArrayList<Account>();
 		DBAdapter db = new DBAdapter(context);
-		db.open();
 		Cursor c = db.fetchAccounts(bankId);
 		if (c == null) {
-			db.close();
 			return accounts;
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
@@ -195,7 +184,6 @@ public class BankFactory {
 			}
 		}
 		c.close();
-		db.close();
 		return accounts;
 	}
 
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index ed3f2ef..5e75711 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -43,8 +43,6 @@ public class DBAdapter {
     static final String DATABASE_NAME = "data";
     static final int DATABASE_VERSION = 11;
 
-    private final Context mCtx;
-
     /**
      * Constructor - takes the context to allow the database to be
      * opened/created
@@ -52,29 +50,9 @@ public class DBAdapter {
      * @param ctx the Context within which to work
      */
     public DBAdapter(Context ctx) {
-        this.mCtx = ctx;
-    }
-
-    /**
-     * Open the notes database. If it cannot be opened, try to create a new
-     * instance of the database. If it cannot be created, throw an exception to
-     * signal the failure
-     * 
-     * @return this (self reference, allowing this to be chained in an
-     *         initialization call)
-     * @throws SQLException if the database could be neither opened or created
-     */
-    public DBAdapter open() throws SQLException {
-        mDbHelper = new DatabaseHelper(mCtx);
+        mDbHelper = DatabaseHelper.getHelper(ctx);
         mDb = mDbHelper.getWritableDatabase();
-        return this;
     }
-    
-    public void close() {
-        mDbHelper.close();
-        mDb.close();
-    }
-
 
     public long createBank(Bank bank) {
     	return updateBank(bank);
@@ -228,9 +206,8 @@ public class DBAdapter {
     @Deprecated
     public static void save(Bank bank, Context context) {
         DBAdapter db = new DBAdapter(context);
-        db.open();
         long id = db.updateBank(bank);
-        db.close();
+
         bank.setDbid(id);
     }
 
@@ -239,10 +216,7 @@ public class DBAdapter {
     */
     @Deprecated
     public static void disable(Bank bank, Context context) {
-                    DBAdapter db = new DBAdapter(context);
-                    db.open();
-                    db.disableBank(bank.getDbId());
-                    db.close();
-               }
-
+        DBAdapter db = new DBAdapter(context);
+        db.disableBank(bank.getDbId());
+    }
 }
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index 7127579..ba1a430 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -27,7 +27,16 @@ import android.util.Log;
  */
 final public class DatabaseHelper extends SQLiteOpenHelper {
 
-	public DatabaseHelper(final Context context) {
+    private static DatabaseHelper instance;
+
+    public static synchronized DatabaseHelper getHelper(Context context) {
+        if(instance == null) {
+            instance = new DatabaseHelper(context);
+        }
+        return instance;
+    }
+
+	private DatabaseHelper(final Context context) {
 		super(context, DBAdapter.DATABASE_NAME, null,
 				DBAdapter.DATABASE_VERSION);
 	}
diff --git app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 180a4d9..f01362a 100644
--- app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -140,7 +140,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 	 */
 	@Override
 	public boolean onCreate() {
-		dbHelper = new DatabaseHelper(getContext());
+		dbHelper = DatabaseHelper.getHelper(getContext());
 		return true;
 	}
 

commit 49a7cef9e3e7b854b9d002c0fcb55b0fd06fc477
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 1 23:30:17 2015 +0100

    Fixes: Attempt to invoke virtual method 'boolean android.net.NetworkInfo.isConnectedOrConnecting()' on a null object reference

diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 8270002..f4c2458 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -32,6 +32,7 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.IBinder;
@@ -80,7 +81,9 @@ public class AutoRefreshService extends Service {
     
     private void handleStart(Intent intent, int startId) {
         ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
-        if (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()) {
+        NetworkInfo ni = cm.getActiveNetworkInfo();
+        if (ni != null &&
+                ni.isConnected()) {
             if (InsideUpdatePeriod()){
                 new DataRetrieverTask().execute();
             }

commit ef0f91244bdf47e1f2ba0aa2280d12f7fb63c943
Merge: 130e80c f836604
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 1 23:18:10 2015 +0100

    Merge pull request #467 from liato/feature/espressohouse-fix
    
    Fixes issues with transaction updates in Espresso House

commit 130e80c662aa587dadac78c703981cd7442c0844
Merge: a230275 a5c0ac9
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 1 20:32:37 2015 +0100

    Merge pull request #458 from jonasgroth/master
    
    Fixed transactions for Forex, fixes #257

commit a5c0ac9f8f7e108c1865048d1d0b625c3b79fc6e
Author: Jonas Groth <jonas@groth.im>
Date:   Sun Mar 1 17:24:18 2015 +0100

    Fixed transactions for Forex Bank

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index e628a99..2078af6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -56,8 +56,6 @@ public class ForexBank extends Bank {
 
     private Pattern reTransactions = Pattern.compile("item\\stransaction.+?(\\d{4}-\\d{2}-\\d{2}?).+?(-?\\d+,\\d{2}).*?left\">\\s+(.+?)\\s+</div>", Pattern.MULTILINE | Pattern.DOTALL);
 
-    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
-
     public ForexBank(Context context) {
         super(context);
         super.TAG = TAG;
@@ -177,15 +175,11 @@ public class ForexBank extends Bank {
             Matcher mDisposables = reDisposable.matcher(result);
 
             while(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
-                mIdMappings.put(Integer.toString(1), mAccountIds.group(1));
                 if(!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
-                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(mDisposables.group(1).trim()), Integer.toString(1)));
-                    Account account = new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(mAccountBalances.group(1).trim()), "a:" + 1);
-                    account.setAliasfor(Integer.toString(1));
-                    accounts.add(account);
+                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mDisposables.group(1).trim()), mAccountIds.group(1))); //Disponibelt
                 }
                 else {
-                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(1).trim()), Integer.toString(1)));
+                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(1).trim()), mAccountIds.group(1)));
                 }
 
                 balance = balance.add(Helpers.parseBalance(mAccountBalances.group(1)));
@@ -206,8 +200,7 @@ public class ForexBank extends Bank {
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
-        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
-        String accountId = mIdMappings.get(account.getId());
+        String accountId = account.getId(); 
         String response = null;
         Matcher matcher;
         try {

commit f8366048e962b243700404e0c142c8d85fcaf972
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 1 17:03:34 2015 +0100

    Fixes issues with transaction updates in Espresso House

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index a2ff212..a4bc86b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -44,6 +44,7 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class EspressoHouse extends Bank {
     private static final String API_URL = "http://www.espressohouse.com/coffee-card/min-sida/";
+    private Document dResponse = null;
 
     public EspressoHouse(Context context) {
         super(context);
@@ -51,7 +52,7 @@ public class EspressoHouse extends Bank {
         NAME = "Espresso House";
         NAME_SHORT = "espressohouse";
         BANKTYPE_ID = IBankTypes.ESPRESSOHOUSE;
-        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
         INPUT_TITLETEXT_USERNAME = R.string.email;
     }
 
@@ -100,33 +101,37 @@ public class EspressoHouse extends Bank {
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
-        urlopen = login();
         try {
+            urlopen = login();
             String response = urlopen.open(API_URL);
-            Document dResponse = Jsoup.parse(response);
+            dResponse = Jsoup.parse(response);
             String card = dResponse.select(".transactionCardNumber").first().text().trim();
             String cardNo = card.split(":")[1].trim();
             String balance = dResponse.select(".balanceAmount").first().text();
             balance = balance.substring(0, balance.length() - 2);
-            Account a = new Account(card,
+            accounts.add(new Account(card,
                     Helpers.parseBalance(balance),
-                    cardNo, Account.REGULAR, "SEK");
+                    cardNo, Account.REGULAR, "SEK"));
+        } catch (IOException e) {
+            throw new BankException(e.getMessage(), e);
+        }
+        super.updateComplete();
+    }
 
-            List<Element> eBalance = dResponse.select(".lineTotalAmount");
-            List<Element> eTransaction = dResponse.select(".lineTime");
-            List<Transaction> transactions = new ArrayList<>();
-            for (int i = 0; i < eTransaction.size(); i++) {
-                String s = eTransaction.get(i).text();
-                balance = eBalance.get(i).text();
-                balance = balance.substring(2, balance.length() - 2);
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        List<Element> eBalance = dResponse.select(".lineTotalAmount");
+        List<Element> eTransaction = dResponse.select(".lineTime");
+        List<Transaction> transactions = new ArrayList<>();
+        for (int i = 0; i < eTransaction.size() && i < eBalance.size(); i++) {
+            String s = eTransaction.get(i).text();
+            String balance = eBalance.get(i).text();
+            if (balance.length() >= 4 && s.length() >= 16) {
                 transactions.add(new Transaction(s.substring(s.length() - 16, s.length() - 6),
-                        s.substring(0, s.length() - 16), Helpers.parseBalance(balance)));
+                        s.substring(0, s.length() - 16),
+                        Helpers.parseBalance(balance.substring(2, balance.length() - 2))));
             }
-            a.setTransactions(transactions);
-            accounts.add(a);
-        } catch (Exception e) {
-            throw new BankException(e.getMessage(), e);
         }
-        super.updateComplete();
+        account.setTransactions(transactions);
     }
 }

commit a23027516f38be075c34ec0addb891dd92f3039e
Merge: 7381e4b 260f2ba
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 1 16:49:22 2015 +0100

    Merge pull request #465 from liato/feature/improved-error-handling
    
    Adds original exception where possible.

commit 260f2bae351bb9510f2614d8e28d6b391bceba0f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 1 16:37:17 2015 +0100

    Removes unnecessary logging.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index cc510a9..80f03e4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -122,11 +122,9 @@ public class AkeliusInvest extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 0bc542a..079f2e1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -123,11 +123,9 @@ public class AkeliusSpar extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index eb9b630..69db5c5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -97,11 +97,9 @@ public class BetterGlobe extends Bank {
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 		}
 		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index b1826c9..ca4653b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -128,11 +128,9 @@ public class BrummerKF extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index 73ff707..e628a99 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -137,11 +137,9 @@ public class ForexBank extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            Log.e(TAG, "ClientProtocolException: " + e.getMessage());
             throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            Log.e(TAG, "IOException: "+e.getMessage());
             throw new BankException(e.getMessage(), e);
         }
         return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 5b31ebb..e00fbe5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -109,11 +109,9 @@ public class Handelsbanken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.w(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.w(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;

commit 440239c4b35c4926dcd15729dac56441b2b7b95f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 1 13:31:51 2015 +0100

    Add original exception where possible.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index e4c0f39..45888eb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -111,9 +111,9 @@ public abstract class AbsIkanoPartner extends Bank {
             }
 
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -170,9 +170,9 @@ public abstract class AbsIkanoPartner extends Bank {
             }
 
             catch (ClientProtocolException e) {
-                throw new BankException(e.getMessage());
+                throw new BankException(e.getMessage(), e);
             } catch (IOException e) {
-                throw new BankException(e.getMessage());
+                throw new BankException(e.getMessage(), e);
             }
         }
         if (accounts.isEmpty()) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 3c82866..cc510a9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -123,11 +123,11 @@ public class AkeliusInvest extends Bank {
 		}
 		catch (ClientProtocolException e) {
 			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
 			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}	
@@ -177,10 +177,10 @@ public class AkeliusInvest extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} finally {
 		    super.updateComplete();
 		}
@@ -209,11 +209,9 @@ public class AkeliusInvest extends Bank {
 			
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+            throw new BankException(e.getMessage(), e);
+        }
 	}		
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 0a5e9a3..0bc542a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -124,11 +124,11 @@ public class AkeliusSpar extends Bank {
 		}
 		catch (ClientProtocolException e) {
 			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
 			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}	
@@ -177,10 +177,10 @@ public class AkeliusSpar extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} finally {
             super.updateComplete();
         }
@@ -209,11 +209,9 @@ public class AkeliusSpar extends Bank {
 			
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}		
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 4dee0a2..eac29ba 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -111,9 +111,9 @@ public class AmericanExpress extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -185,11 +185,9 @@ public class AmericanExpress extends Bank {
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 4d0a689..10ea936 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -89,10 +89,10 @@ public class AppeakPoker extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;		
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 1168f73..eb9b630 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -98,11 +98,11 @@ public class BetterGlobe extends Bank {
 		}
 		catch (ClientProtocolException e) {
 			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
 			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}	
@@ -158,10 +158,10 @@ public class BetterGlobe extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index 2003d56..467c10a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -110,10 +110,9 @@ public class Bioklubben extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -147,9 +146,7 @@ public class Bioklubben extends Bank {
             a.setTransactions(transactions);
 
         } catch (IOException e) {
-            if (e == null) {
-                throw new BankException(e.getMessage());
-            }
+                throw new BankException(e.getMessage(), e);
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 7c7426e..99f07aa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -85,9 +85,9 @@ public class BlekingeTrafiken extends Bank {
             }
             response = EntityUtils.toString(httpResponse.getEntity());
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -119,7 +119,7 @@ public class BlekingeTrafiken extends Bank {
             }
 
         } catch (JSONException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 9b182d7..a421789 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -95,9 +95,9 @@ public class Bredband2VoIP extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -123,7 +123,7 @@ public class Bredband2VoIP extends Bank {
                 }
             }
         } catch (Exception e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         super.updateComplete();
     }
@@ -153,7 +153,7 @@ public class Bredband2VoIP extends Bank {
             }
             account.setTransactions(transactions);
         } catch (IOException e) {
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index cedfc50..b1826c9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -129,11 +129,11 @@ public class BrummerKF extends Bank {
 		}
 		catch (ClientProtocolException e) {
 			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
 			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}	
@@ -170,10 +170,10 @@ public class BrummerKF extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index fd8d791..f795e4a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -96,10 +96,10 @@ public class CSN extends Bank {
             response = urlopen.open("https://www.csn.se/bas/javascript", postData);
         }
         catch (ClientProtocolException e) {
-            throw new BankException("pl:CPE:"+e.getMessage());
+            throw new BankException("pl:CPE:"+e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException("pl:IOE:"+e.getMessage());
+            throw new BankException("pl:IOE:"+e.getMessage(), e);
         }        
         postData.clear();
         
@@ -123,11 +123,10 @@ public class CSN extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException("login:CPE:"+e.getCause().getMessage());
+			throw new BankException("login:CPE:"+e.getCause().getMessage(), e);
 		}
 		catch (IOException e) {
-            e.printStackTrace();
-			throw new BankException("login:IOE:"+e.getMessage());
+			throw new BankException("login:IOE:"+e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -172,12 +171,10 @@ public class CSN extends Bank {
 			}
 		}
         catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+           throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+           throw new BankException(e.getMessage(), e);
         }		
         finally {
             super.updateComplete();
@@ -244,11 +241,9 @@ public class CSN extends Bank {
             Collections.sort(transactions, Collections.reverseOrder());
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }	
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 310baf9..5b123c9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -92,7 +92,7 @@ public class Chalmrest extends Bank {
 		}
 		catch (Exception e)
 		{
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		finally {
 			super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index be53510..3fab5c1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -126,9 +126,9 @@ public class DanskeBank extends Bank {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -187,10 +187,10 @@ public class DanskeBank extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		finally {
 		    super.updateComplete();
@@ -224,11 +224,9 @@ public class DanskeBank extends Bank {
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}	
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index d7a631e..567e0cd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -78,12 +78,8 @@ public class DinersClub extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
-        try {
-            response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw e;
-        }
+        response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
+
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
@@ -117,10 +113,10 @@ public class DinersClub extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -137,10 +133,10 @@ public class DinersClub extends Bank {
                 response = urlopen.open("https://secure.dinersclub.se/dcs/eSaldo/Default.aspx");
             }
             catch (ClientProtocolException e) {
-                throw new BankException(e.getMessage());
+                throw new BankException(e.getMessage(), e);
             }
             catch (IOException e) {
-                throw new BankException(e.getMessage());
+                throw new BankException(e.getMessage(), e);
             }
 		}
 
@@ -198,11 +194,9 @@ public class DinersClub extends Bank {
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index 18d15d3..ec6dcd6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -101,9 +101,9 @@ public class EasyCard extends Bank {
                 throw new BankException(res.getText(R.string.unable_to_login).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
 
         return urlopen;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index 90da198..a2ff212 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -89,7 +89,7 @@ public class EspressoHouse extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -125,7 +125,7 @@ public class EspressoHouse extends Bank {
             a.setTransactions(transactions);
             accounts.add(a);
         } catch (Exception e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         super.updateComplete();
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 2c34bc2..5ef20a2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -106,9 +106,9 @@ public class Everydaycard extends Bank {
 			}
 			
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index ec6c37e..68bd531 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -95,9 +95,9 @@ public class FirstCard extends Bank {
 			}
 			
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -129,11 +129,9 @@ public class FirstCard extends Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}			
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new BankException(e.getMessage(), e);
 		}
         finally {
             super.updateComplete();
@@ -165,11 +163,9 @@ public class FirstCard extends Bank {
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}
 	
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index ccd55bc..73ff707 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -138,11 +138,11 @@ public class ForexBank extends Bank {
         }
         catch (ClientProtocolException e) {
             Log.e(TAG, "ClientProtocolException: " + e.getMessage());
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
             Log.e(TAG, "IOException: "+e.getMessage());
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -197,10 +197,10 @@ public class ForexBank extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         super.updateComplete();
     }
@@ -222,9 +222,9 @@ public class ForexBank extends Bank {
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 1731f5d..5b31ebb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -110,11 +110,11 @@ public class Handelsbanken extends Bank {
 		}
 		catch (ClientProtocolException e) {
 			Log.w(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
 			Log.w(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -148,10 +148,10 @@ public class Handelsbanken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
         finally {
             super.updateComplete();
@@ -180,11 +180,9 @@ public class Handelsbanken extends Bank {
 			
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index 320cf59..47971a1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -121,10 +121,10 @@ public class Hemkop extends Bank {
             response = urlopen.open("https://www.hemkop.se/Mina-sidor/Bonussaldo/");
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -184,11 +184,9 @@ public class Hemkop extends Bank {
             }
             
         } catch (ClientProtocolException e) {
-        	e.printStackTrace();
-            Log.e(TAG, e.getMessage() != null ? e.getMessage() : "");
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-        	e.printStackTrace();
-            Log.e(TAG,  e.getMessage() != null ? e.getMessage() : "");
+            throw new BankException(e.getMessage(), e);
         }        
         
         super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 0102ac4..a46d976 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -130,10 +130,10 @@ public class IkanoBank extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -212,9 +212,9 @@ public class IkanoBank extends Bank {
             account.setTransactions(transactions);
 
         } catch (ClientProtocolException e) {
-            Log.e(TAG, "CPE: " + e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            Log.e(TAG, "IOE: "+ e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index ac2b2f6..e5cdbdc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -93,9 +93,9 @@ public class Jojo extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -141,7 +141,7 @@ public class Jojo extends Bank {
                 return Helpers.parseBalance(saldo.first().text().trim());
             }
         } catch (IOException e) {
-            e.printStackTrace();
+            // Ignore and defaults to zero
         }
         return BigDecimal.ZERO;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index ec47e5d..d2b1931 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -119,10 +119,10 @@ public class Marginalen extends Bank {
     		accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
     	}
     	catch (ClientProtocolException e) {
-    		throw new BankException("ClientProtolException:" + e.getMessage());
+    		throw new BankException("ClientProtolException:" + e.getMessage(), e);
     	}
     	catch (IOException e) {
-    		throw new BankException("IOException:" + e.getMessage());
+    		throw new BankException("IOException:" + e.getMessage(), e);
     	}
     	return urlopen;
     }
@@ -158,10 +158,10 @@ public class Marginalen extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		finally {
 	      super.updateComplete();
@@ -190,9 +190,9 @@ public class Marginalen extends Bank {
             }
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index f72ef15..79fd488 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -94,10 +94,10 @@ public class McDonalds extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;		
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index 6152ef4..e439bd6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -81,20 +81,20 @@ public class Meniga extends Bank{
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
 
         try{
             response = urlopen.open("https://www.meniga.is/mobile/language/?lang=is-IS");
         }
         catch (ClientProtocolException e){
-            //Do nothing
+           throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
 
         return urlopen;
@@ -135,10 +135,10 @@ public class Meniga extends Bank{
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         finally {
             super.updateComplete();
@@ -175,9 +175,9 @@ public class Meniga extends Bank{
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 97e21a5..30fd96b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -106,9 +106,9 @@ public abstract class MobilbankenBase extends Bank {
 			}
 			
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -170,11 +170,9 @@ public abstract class MobilbankenBase extends Bank {
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }   	
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index 98d235d..d9d6cad 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -123,11 +123,9 @@ public class NordeaDK extends Bank {
 			}
 			this.updatePrefix();
 		} catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: " + e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			Log.e(TAG, "IOException: " + e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -242,11 +240,9 @@ public class NordeaDK extends Bank {
 			}
 			
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 		return transactions;
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 2f1879e..ef6cbf1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -110,10 +110,10 @@ public class Nordnet extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index b79ca02..434ab6c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -101,10 +101,10 @@ public class Nordnetdirekt extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index 825179e..ebe9d2d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -152,10 +152,10 @@ public class OKQ8 extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -223,11 +223,9 @@ public class OKQ8 extends Bank {
 			}
 			accounts.get(0).setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}		
         finally {
             super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index 373a86f..5d011cb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -91,10 +91,10 @@ public class Ostgotatrafiken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -166,10 +166,10 @@ public class Ostgotatrafiken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		finally {
 			super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 6a515eb..a5e8274 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -94,10 +94,9 @@ public class Osuuspankki extends Bank {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-            e.printStackTrace();
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -170,11 +169,9 @@ public class Osuuspankki extends Bank {
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}	
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 85c3711..ef05f51 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -123,9 +123,9 @@ public class PayPal extends Bank {
                 throw new BankException("Error: PPL92");
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -178,12 +178,10 @@ public class PayPal extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
         finally {
             super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
index f281ffe..805b29d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -94,8 +94,7 @@ public class Payson extends Bank {
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             userInfo = new JSONObject(urlopen.open("https://www.payson.se/myaccount/user/getuserinfo"));
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (JSONException e) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
@@ -115,8 +114,7 @@ public class Payson extends Bank {
                     Helpers.parseBalance(userInfo.getString("balance")), "1");
             accounts.add(account);
         } catch (JSONException e) {
-            e.printStackTrace();
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            throw new BankException(res.getText(R.string.no_accounts_found).toString(), e);
         }
         super.updateComplete();
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index 725f0bd..2c4ff87 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -91,10 +91,10 @@ public class PlusGirot extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index 3e13029..85561da 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -85,9 +85,9 @@ public class ResursBank extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -166,11 +166,9 @@ public class ResursBank extends Bank {
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index f654a64..ad76d0e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -105,10 +105,10 @@ public class SevenDay extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 7152155..5e0a2a1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -101,17 +101,17 @@ public class Skandiabanken extends Bank {
 			urlopen.addHeader("x-smartrefill-customer", "" + customerId);
 		} catch (HttpResponseException e) {
 			if (e.getStatusCode() == 401)
-				throw new BankException(
+				throw new LoginException(
 						"Inloggning misslyckad fel användarnamn eller lösenord");
 			else
 				throw new BankException("Http fel (" + e.getStatusCode() + ") "
-						+ e.getMessage());
+						+ e.getMessage(), e);
 		} catch (ClientProtocolException e) {
-			throw new BankException("ClientProtocolException " + e.getMessage());
+			throw new BankException("ClientProtocolException " + e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException("IOException " + e.getMessage());
+			throw new BankException("IOException " + e.getMessage(), e);
 		} catch (JSONException e) {
-			throw new BankException("Oväntat svarsformat " + e.getMessage());
+			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
 		}
 
 		return urlopen;
@@ -167,9 +167,9 @@ public class Skandiabanken extends Bank {
 				accounts.add(account);
 			}
 		} catch (IOException e) {
-			throw new BankException("IOException " + e.getMessage());
+			throw new BankException("IOException " + e.getMessage(), e);
 		} catch (JSONException e) {
-			throw new BankException("Oväntat svarsformat " + e.getMessage());
+			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
 		}
 	}
 
@@ -211,9 +211,9 @@ public class Skandiabanken extends Bank {
 			}
 			
 		} catch (IOException e) {
-			throw new BankException("IOException " + e.getMessage());
+			throw new BankException("IOException " + e.getMessage(), e);
 		} catch (JSONException e) {
-			throw new BankException("Oväntat svarsformat " + e.getMessage());
+			throw new BankException("Oväntat svarsformat " + e.getMessage(), e);
 		}
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 5dfe5ae..94bb866 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -93,17 +93,17 @@ public class Steam extends Bank {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("Enter the characters above")) {
-                throw new BankException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
+                throw new LoginException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
             }
 			if (response.contains("Incorrect login.")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 770f9c1..38372c2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -99,11 +99,9 @@ public class SveaDirekt extends Bank {
             }
 
         } catch (ClientProtocolException e) {
-            Log.e(TAG, "ClientProtocolException: " + e.getMessage());
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            Log.e(TAG, "IOException: " + e.getMessage());
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -144,10 +142,10 @@ public class SveaDirekt extends Bank {
             this.setAccounts(accounts);
         }
         catch (ClientProtocolException e) {
-          throw new BankException(e.getMessage());
+          throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         finally {
           super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 5fdbba5..fe1976a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -94,10 +94,10 @@ public class SvenskaSpel extends Bank {
 			response = EntityUtils.toString(httpResponse.getEntity());
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index a99d0f2..e39b4d1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -113,10 +113,10 @@ public class TestBank extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		finally {
 		    super.updateComplete();
@@ -142,11 +142,9 @@ public class TestBank extends Bank {
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
 		}
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index fc73647..595016b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -109,10 +109,10 @@ public class TicketRikskortet extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -129,10 +129,10 @@ public class TicketRikskortet extends Bank {
                 response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/");
             }
             catch (ClientProtocolException e) {
-                throw new BankException(e.getMessage());
+                throw new BankException(e.getMessage(), e);
             }
             catch (IOException e) {
-                throw new BankException(e.getMessage());
+                throw new BankException(e.getMessage(), e);
             }
         }
 
@@ -179,11 +179,9 @@ public class TicketRikskortet extends Bank {
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 715dcc6..63f453e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -104,12 +104,10 @@ public class TrustBuddy extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}	
@@ -145,10 +143,10 @@ public class TrustBuddy extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 	}
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 5cbfb35..20db645 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -99,10 +99,10 @@ public class Vasttrafik extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -153,12 +153,10 @@ public class Vasttrafik extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
         finally {
             super.updateComplete();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index 91dc7f2..1f87150 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -147,9 +147,9 @@ public class Villabanken extends Bank {
             this.accountResponse = urlopen.open(accountUrl);
 
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index be77ac2..45ba389 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -109,10 +109,10 @@ public class Volvofinans extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -143,17 +143,17 @@ public class Volvofinans extends Bank {
 				}
 			}
 			catch (JSONException e) {
-				throw new BankException(e.getMessage());
+				throw new BankException(e.getMessage(), e);
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		finally {
 	      super.updateComplete();
@@ -193,14 +193,11 @@ public class Volvofinans extends Bank {
                 }
 
             } catch (ClientProtocolException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
+               throw new BankException(e.getMessage(), e);
             } catch (IOException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
+                throw new BankException(e.getMessage(), e);
             } catch (JSONException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
+                throw new BankException(e.getMessage(), e);
             }
         }
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index 2028cb0..1487d70 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -105,12 +105,10 @@ public class Zidisha extends Bank {
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 		}
 		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}	
@@ -157,10 +155,10 @@ public class Zidisha extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 5e990dd..c91fc95 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -178,16 +178,13 @@ public class Avanza extends Bank {
                 }
             }
         } catch (JsonParseException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (ClientProtocolException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (Exception e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -202,8 +199,7 @@ public class Avanza extends Bank {
         }
         login();
         if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found)
-                    .toString());
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         super.updateComplete();
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 706a562..b012940 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -92,11 +92,9 @@ public class Bitcoin extends Bank {
 			throw new BankException(res.getText(
 					R.string.invalid_bitcoin_address).toString());
 		}catch (ClientProtocolException e) {
-			e.printStackTrace();
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			e.printStackTrace();
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -111,8 +109,7 @@ public class Bitcoin extends Bank {
 		}
 		login();
 		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found)
-					.toString());
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
 		super.updateComplete();
 	}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index f77b0a0..85bd676 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -172,7 +172,7 @@ public class Coop extends Bank {
             }
             return urlopen;
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
     }
 
@@ -257,8 +257,7 @@ public class Coop extends Bank {
                 }
             }
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
 
 
@@ -270,8 +269,7 @@ public class Coop extends Bank {
                     "refound", Account.OTHER, "SEK");
             accounts.add(a);
         } catch (Exception e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
 
         if (accounts.isEmpty()) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index 7e3efe1..9748d42 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -155,14 +155,11 @@ public class ICA extends Bank {
             httpResponse = urlopen.openAsHttpResponse(API_URL + "logout", new ArrayList<NameValuePair>(), false);
             httpResponse.getStatusLine();
         } catch (JsonParseException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (ClientProtocolException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -183,7 +180,6 @@ public class ICA extends Bank {
         try {
             return readJsonValue(response.getEntity().getContent(), valueType);
         } catch (IOException e) {
-            e.printStackTrace();
             return null;
         }
     }
@@ -192,7 +188,6 @@ public class ICA extends Bank {
         try {
             return mObjectMapper.readValue(is, valueType);
         } catch (Exception e) {
-            e.printStackTrace();
             return null;
         }
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index f9c318b..6b5251c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -104,9 +104,9 @@ public class ICABanken extends Bank {
             addAccounts(loginResponse.getAccountList());
 
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index fb3ab50..bd2f0ab 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -155,8 +155,7 @@ public class Lansforsakringar extends Bank {
         try {
 			return mObjectMapper.readValue(is, valueType);
 		} catch (Exception e) {
-			e.printStackTrace();
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
     }
 
@@ -165,7 +164,7 @@ public class Lansforsakringar extends Bank {
 			return readJsonValue(urlopen.openStream(url, postData, false), valueType);
 		} catch (Exception e) {
 			e.printStackTrace();
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
     }
     
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index b0f2253..b9cd9fa 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -244,11 +244,11 @@ public class Nordea extends Bank {
 			}
 			
 		} catch (HttpResponseException e) {
-			throw new BankException(String.valueOf(e.getStatusCode()));
+			throw new BankException(String.valueOf(e.getStatusCode()), e);
 		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
+			throw new BankException(e.getMessage(), e);
 		}
 		return urlopen;
 	}
@@ -315,10 +315,10 @@ public class Nordea extends Bank {
 			}
 		}
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
 		finally {
 		    super.updateComplete();
@@ -348,11 +348,9 @@ public class Nordea extends Bank {
                     break;
             }
         } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
 	}
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 1b3577e..a6486b4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -94,27 +94,24 @@ public class Rikslunchen extends Bank {
             try {
                 resp = serializer.read(Envelope.class, is, false);
             } catch (Exception e) {
-                e.printStackTrace();
+                throw new BankException(e.getMessage(), e);
             }
 
             if (resp != null && resp.body != null && resp.body.fault != null && !TextUtils.isEmpty(resp.body.fault.faultstring)) {
-                throw new BankException(context.getString(R.string.invalid_card_number));
+                throw new LoginException(context.getString(R.string.invalid_card_number));
                 //faultString isn't always very descriptive
                 //throw new BankException(resp.body.fault.faultstring);
             } else if (resp == null || resp.body == null || resp.body.getBalanceResponse == null || resp.body.getBalanceResponse.responseReturn == null || resp.body.getBalanceResponse.responseReturn.amount == null) {
-                throw new BankException(context.getString(R.string.invalid_card_number));
+                throw new LoginException(context.getString(R.string.invalid_card_number));
             }
             BigDecimal balance = Helpers.parseBalance(resp.body.getBalanceResponse.responseReturn.amount);
             accounts.add(new Account("Rikslunchen", balance, "1"));
         } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (ClientProtocolException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found)
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index e0d4d91..be8a2b2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -118,10 +118,9 @@ public class SEB extends Bank {
             }
             urlopen.setFollowRedirects(true);
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -299,8 +298,7 @@ public class SEB extends Bank {
         try {
             return getObjectmapper().readValue(is, valueType);
         } catch (Exception e) {
-            e.printStackTrace();
-            return null;
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 7b2e397..ba2d8f8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -138,10 +138,9 @@ public abstract class SEBKortBase extends Bank {
                 throw new LoginException(!TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString() : res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         return urlopen;
     }
@@ -181,9 +180,9 @@ public abstract class SEBKortBase extends Bank {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } finally {
             super.updateComplete();
         }
@@ -207,12 +206,9 @@ public abstract class SEBKortBase extends Bank {
                     }
                 }
             }
-            //TODO: Sort?
-            //Collections.sort(transactions, Collections.reverseOrder());
             account.setTransactions(transactions);
         } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
     }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index de02071..e00da68 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -118,10 +118,10 @@ public abstract class AbstractSwedbank extends Bank {
             }
         }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } finally {
             if(httpResponse != null) {
                 HttpEntity httpEntity = httpResponse.getEntity();
@@ -129,7 +129,7 @@ public abstract class AbstractSwedbank extends Bank {
                     try {
                         httpEntity.consumeContent();
                     } catch (IOException e) {
-                        throw new BankException("");
+                        throw new BankException(e.getMessage(), e);
                     }
                 }
             }
@@ -150,7 +150,7 @@ public abstract class AbstractSwedbank extends Bank {
 
             HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/overview"), false);
             if(httpResponse.getStatusLine().getStatusCode() != 200) {
-                throw new BankException("");
+                throw new BankException(httpResponse.getStatusLine().toString());
             }
 
             OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),OverviewResponse.class);
@@ -164,9 +164,9 @@ public abstract class AbstractSwedbank extends Bank {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
         } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } finally {
             updateComplete();
         }
@@ -196,9 +196,9 @@ public abstract class AbstractSwedbank extends Bank {
             account.setTransactions(transactions);
 
         } catch(ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } catch(IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
     }
 
@@ -230,9 +230,9 @@ public abstract class AbstractSwedbank extends Bank {
             transactions.addAll(transformCardTransactions(response.getReservedTransactions()));
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-           throw new BankException(e.getMessage());
+           throw new BankException(e.getMessage(), e);
         } catch (IOException e) {
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         }
     }
 
@@ -320,7 +320,7 @@ public abstract class AbstractSwedbank extends Bank {
                     .toString().getBytes("UTF-8");
             return Base64.encodeToString(data,Base64.NO_WRAP);
         } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
+            // Ignore
         }
         return null;
     }
@@ -335,8 +335,7 @@ public abstract class AbstractSwedbank extends Bank {
         try {
             return mObjectMapper.readValue(is, valueType);
         } catch (Exception e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
+            throw new BankException(e.getMessage(), e);
         } finally {
             try {
                 is.close();
@@ -347,13 +346,12 @@ public abstract class AbstractSwedbank extends Bank {
 
     }
 
-    public String objectAsJson(Object value) {
+    public String objectAsJson(Object value) throws BankException {
         try {
             return mObjectMapper.writeValueAsString(value);
         } catch (JsonProcessingException e) {
-            e.printStackTrace();
+            throw new BankException(e.getMessage(), e);
         }
-        return null;
     }
 
     protected abstract String getAppId();
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
index b057b2b..57280fc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
@@ -21,4 +21,7 @@ public class BankException extends Exception {
 	public BankException(String message) {
 		super(message);
 	}
+    public BankException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
 }

commit 7381e4b1674f47a7200d4ed07b839738391d0f61
Merge: 1889e02 b6f840f
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Mar 1 11:04:25 2015 +0100

    Merge pull request #464 from liato/feature/swedbank-error-handling
    
    Use LoginException if user tries to use Swedbank with a Sparbanken account

commit b6f840ff29f222bc89a173801c3e24aa48ffd4d2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Mar 1 10:57:57 2015 +0100

    Use LoginException if user tries to use Swedbank with a Sparbanken account and vice versa.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index e2606e4..de02071 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -255,14 +255,14 @@ public abstract class AbstractSwedbank extends Bank {
         return transactionList;
     }
 
-    private ProfileResponse getAvailableProfiles() throws IOException, ClientProtocolException, BankException {
+    private ProfileResponse getAvailableProfiles() throws IOException, BankException, LoginException {
         HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/"), false);
         if (httpResponse.getStatusLine().getStatusCode() == 200) {
             ProfileResponse response = readJsonValue(httpResponse.getEntity().getContent(), ProfileResponse.class);
             if(response.getBanks().isEmpty()) {
                 String provider = response.isSwedbankProfile() ? "Swedbank" : response.isSavingbankProfile() ? "Sparbankerna" : null;
                 if(provider != null) {
-                    throw new BankException("You are trying to connect an account from " + provider + " to the " + NAME + " bank. Please use the " + provider + " bank instead.");
+                    throw new LoginException("You are trying to connect an account from " + provider + " to the " + NAME + " bank. Please use the " + provider + " bank instead.");
                 } else {
                     throw new BankException("No profiles available.");
                 }
@@ -272,7 +272,7 @@ public abstract class AbstractSwedbank extends Bank {
         throw new BankException("Could not fetch available profiles.");
     }
 
-    private void setDefaultProfile(String bankId) throws ClientProtocolException, IOException, BankException {
+    private void setDefaultProfile(String bankId) throws IOException, BankException {
         HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/private/" + bankId), true);
         httpResponse.getEntity().consumeContent();
         if (httpResponse.getStatusLine().getStatusCode() != 201) {

commit 1889e0273582f2f04b1aa9da29fd7cf634d46c3e
Merge: d8aa15b c3bce3c
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 21:44:27 2015 +0100

    Merge pull request #459 from liato/feature/457-lockpattern
    
    Replace @*android references.

commit d8aa15b07a64fc087c77c15799dae27e4d65f3d3
Merge: 2140a75 2c08f8e
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 21:43:29 2015 +0100

    Merge pull request #448 from robho/payson
    
    Adapt to new payson web page

commit c3bce3c278b401cfcb294a7871333beda2d9cd42
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 21:22:23 2015 +0100

    Replace @*android references.

diff --git app/src/main/res/layout-land/confirm_lock_pattern.xml app/src/main/res/layout-land/confirm_lock_pattern.xml
index 4dd5617..5739192 100644
--- app/src/main/res/layout-land/confirm_lock_pattern.xml
+++ app/src/main/res/layout-land/confirm_lock_pattern.xml
@@ -46,7 +46,7 @@
 	</LinearLayout>
 
 	<View
-		android:background="@*android:drawable/code_lock_left"
+		android:background="@drawable/code_lock_left"
 		android:layout_width="2dip"
 		android:layout_height="fill_parent" />
 	<!-- right side: lock pattern -->
diff --git app/src/main/res/layout/confirm_lock_pattern.xml app/src/main/res/layout/confirm_lock_pattern.xml
index a5c4f01..2e77959 100644
--- app/src/main/res/layout/confirm_lock_pattern.xml
+++ app/src/main/res/layout/confirm_lock_pattern.xml
@@ -28,7 +28,7 @@
         android:textSize="18sp"/>
 
     <View
-         android:background="@*android:drawable/code_lock_top"
+         android:background="@drawable/code_lock_top"
          android:layout_width="fill_parent"
          android:layout_height="2dip" />
     <com.liato.bankdroid.lockpattern.LockPatternView android:id="@+id/lockPattern"

commit 2140a75214c6be955ce5a58e5e813ded33549400 (tag: v1.9.8.0)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 17:00:08 2015 +0100

    Creates release v1.9.8.0

diff --git CHANGES.txt CHANGES.txt
index 7224c51..85e30a0 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -13,9 +13,10 @@ v1.9.8.0 (2015-02-27)
 * Fixes Swedbank and Sparbankerna if you have corporate credit card
 * Fixes www login for Coop
 * Fixes application crash if SonyEricsson's LiveView integration is enabled 
+* Fixes application crash if screen is rotated during a bank update
 * Improved error handling
 * Disabled www-button for Swedbank and Sparbankerna
-* Updated certificate for Östgötatrafiken
+* Updated certificate for Östgötatrafiken, AmericanExpress, Brummer KF
 * Removes support for Handelsbanken, SEB, Chevrolet, Djurgarden, EurobonusMastercard, EurobonusMastercardDk, EurobonusMastercardNo, Eurocard, Opel, Quintessentially, SJPrio, Saab, Statoil, Wallet because they now requires BankId.
 
 v1.9.7.4: (2015-02-21)
diff --git app/build.gradle app/build.gradle
index 75dbaa3..1c781bc 100644
--- app/build.gradle
+++ app/build.gradle
@@ -26,8 +26,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 201
-        versionName "1.9.8.0-RC4"
+        versionCode 202
+        versionName "1.9.8.0"
     }
 
     signingConfigs {

commit 22d594475b01914d026aa0b849e2fbd5ee48786c
Merge: a451a05 21aa57e
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 16:49:11 2015 +0100

    Merge pull request #455 from liato/feature/log-banknames
    
    Adds bank names to Crashlytics logging.

commit 21aa57e5d0af79194b604d29639ca46e883c32ae
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 16:45:49 2015 +0100

    Adds bank names to Crashlytics logging.

diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index a3d54fa..c66f6c6 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -3,7 +3,10 @@ package com.liato.bankdroid;
 import android.app.Application;
 
 import com.crashlytics.android.Crashlytics;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
 
+import java.util.List;
 import java.util.Locale;
 
 import io.fabric.sdk.android.Fabric;
@@ -11,11 +14,25 @@ import io.fabric.sdk.android.Fabric;
 public class BankdroidApplication extends Application {
 
     public static final String LOG_KEY_LOCALE = "locale";
+    public static final String LOG_KEY_BANKS = "banks";
 
     @Override
     public void onCreate() {
         super.onCreate();
         Fabric.with(this, new Crashlytics());
         Crashlytics.setString(LOG_KEY_LOCALE, Locale.getDefault().toString());
+        logBanks();
+    }
+
+    private void logBanks() {
+        List<Bank> banks = BankFactory.banksFromDb(this, false);
+        StringBuilder bankStringBuilder = new StringBuilder();
+        if (banks != null && !banks.isEmpty()) {
+            for (Bank bank : banks) {
+                bankStringBuilder.append(bank.getName())
+                        .append(",");
+            }
+            Crashlytics.setString(LOG_KEY_BANKS, bankStringBuilder.substring(0, bankStringBuilder.length() - 1));
+        }
     }
 }

commit a451a052c91da475870583757618be3d3c4d9021
Merge: d85e5e2 a317e59
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 16:31:54 2015 +0100

    Merge pull request #454 from liato/feature/add-locale-to-crash-report
    
    Adds default locale setting to crash reports.

commit a317e5923fc8739257b44d61ccdbb9cc41556c12
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 16:20:15 2015 +0100

    Adds default locale setting to crash reports.

diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
index b15c5bf..a3d54fa 100644
--- app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -4,13 +4,18 @@ import android.app.Application;
 
 import com.crashlytics.android.Crashlytics;
 
+import java.util.Locale;
+
 import io.fabric.sdk.android.Fabric;
 
 public class BankdroidApplication extends Application {
 
+    public static final String LOG_KEY_LOCALE = "locale";
+
     @Override
     public void onCreate() {
         super.onCreate();
         Fabric.with(this, new Crashlytics());
+        Crashlytics.setString(LOG_KEY_LOCALE, Locale.getDefault().toString());
     }
 }

commit d85e5e2f649dac66af5b37422e93edfccb1d72ad
Merge: 9cbfa29 d65e732
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 16:08:13 2015 +0100

    Merge pull request #453 from liato/feature/fix-transaction-sorting
    
    Ignore sorting for Transactions if there is a problem with date parsing

commit d65e73241e9c0d2f045ef5c9f050f1ba2bfd321f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 15:51:47 2015 +0100

    Ignore sorting for Transactions if there is a problem with parsing the date.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
index 4645948..f87f167 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
@@ -69,8 +69,12 @@ public class Transaction implements Comparable<Transaction> {
 
     @Override
 	public int compareTo(Transaction another) {
-		Integer thisdate = Integer.parseInt(date.replaceAll("-", ""));
-		Integer thatdate = Integer.parseInt((another).getDate().replaceAll("-", ""));
-		return thatdate - thisdate;
+		try {
+            Integer thisdate = Integer.parseInt(date.replaceAll("-", ""));
+            Integer thatdate = Integer.parseInt((another).getDate().replaceAll("-", ""));
+            return thatdate - thisdate;
+        } catch(NumberFormatException e) {
+            return 0;
+        }
 	}
 }

commit 9cbfa29301a494b0b81a5847b240f66659bc6f20
Merge: f4b7164 6f3ed5c
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 15:35:47 2015 +0100

    Merge pull request #452 from liato/feature/424-dismiss-dialog-on-rotation-error
    
    Fixes crash if dialog is shown when screen is rotated.

commit 6f3ed5c6b805906986cec6b0e27b7894bb248124
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 15:31:10 2015 +0100

    Fixes crash if dialog is shown when screen is rotated.

diff --git app/src/main/AndroidManifest.xml app/src/main/AndroidManifest.xml
index a91f503..49f3ca6 100644
--- app/src/main/AndroidManifest.xml
+++ app/src/main/AndroidManifest.xml
@@ -13,7 +13,7 @@
 			android:label="@string/app_name"
 			android:multiprocess="false"
 			android:alwaysRetainTaskState="false"
-			android:configChanges="keyboardHidden|orientation"
+			android:configChanges="keyboardHidden|orientation|screenSize"
 			android:theme="@style/BankdroidTheme">
 			<intent-filter>
 				<action
@@ -31,12 +31,12 @@
 			android:name=".WebViewActivity"
 			android:label="@string/app_name"
 			android:theme="@style/BankdroidTheme"
-			android:configChanges="keyboardHidden|orientation">
+			android:configChanges="keyboardHidden|orientation|screenSize">
 		</activity>
 		<activity
 			android:name=".BankEditActivity"
 			android:label="@string/app_name"
-			android:configChanges="keyboardHidden|orientation"
+			android:configChanges="keyboardHidden|orientation|screenSize"
 			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity

commit f4b7164416a8c377ab2c78d5d2860a3c4180934c
Merge: 76550c6 13d4ec7
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 14:30:03 2015 +0100

    Merge pull request #451 from liato/feature/450-make-crashlytics-optional
    
    Makes crashlytics optional.

commit 13d4ec7d8b2be59a27b382608e81c1d55c718853
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 14:05:15 2015 +0100

    Makes crashlytics optional.
    
    Fixes #450

diff --git app/build.gradle app/build.gradle
index cad56b4..75dbaa3 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,7 +8,10 @@ buildscript {
     }
 }
 apply plugin: 'com.android.application'
-apply plugin: 'io.fabric'
+
+if(new File('app/crashlytics.properties').exists()) {
+    apply plugin: 'io.fabric'
+}
 
 repositories {
     maven { url 'https://maven.fabric.io/public' }

commit 76550c602d5877fed8877c60f5fe356bc10d6d80
Merge: dabb262 c4b33b6
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Feb 28 11:30:04 2015 +0100

    Merge pull request #449 from liato/feature/update-certificates
    
    Update certificate for AmericanExpress

commit c4b33b6549a79ccf9edb0bea9fe03d7840536aaa
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 28 11:12:46 2015 +0100

    Update certificate for AmericanExpress

diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
index 916c3e5..faa567a 100644
--- bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
+++ bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----

-9TzIzLV/TRFmIpOYgN55mjpSOJoXpiA+pG5n7ZWkn+LiAQ+k

+P6OBQ0XaFaAWHO6xJ5ACxo2KX1ygAqvX2JEp0HqipyNBTlLau75BXw==
 -----END CERTIFICATE-----
 www.americanexpress.com:443

commit 2c08f8e2573d803430c4882c6f42bf862c7923f3
Author: Robert Hogberg <robert.hogberg@gmail.com>
Date:   Fri Feb 27 22:00:41 2015 +0100

    Adapt to new payson web page
    
    Payson was broken in bankdroid because of changes to payson's web page. Adapt.
    
    Support for listing transactions is not yet implemented. The transactions
    are no longer available in json format, but must instead be parsed from HTML.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 716398d..cf8a073 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
+import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.ResursBank;
@@ -66,7 +67,6 @@ import com.liato.bankdroid.banking.banks.ica.ICA;
 import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
-import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
 import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
new file mode 100644
index 0000000..f281ffe
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Payson.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010-2015 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Payson extends Bank {
+    private static final String TAG = "Payson";
+    private static final String NAME = "Payson";
+    private static final String NAME_SHORT = "payson";
+    private static final String URL = "https://www.payson.se/signin/";
+    private static final int BANKTYPE_ID = IBankTypes.PAYSON;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+
+    private Pattern reVerificationToken = Pattern.compile("<input[^>]+name=\"__RequestVerificationToken\"[^>]+value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+    private String response = null;
+    private JSONObject userInfo = null;
+
+    public Payson(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+    }
+
+    public Payson(String username, String password, Context context) throws BankChoiceException, BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_payson));
+        response = urlopen.open(URL);
+        Matcher matcher = reVerificationToken.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " RequestVerificationToken");
+        }
+        String verificationToken = matcher.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__RequestVerificationToken", verificationToken));
+        postData.add(new BasicNameValuePair("Username", username));
+        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("RedirectAfterLogin", ""));
+        return new LoginPackage(urlopen, postData, response, "https://www.payson.se/myaccount/account/SignIn/");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            userInfo = new JSONObject(urlopen.open("https://www.payson.se/myaccount/user/getuserinfo"));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (JSONException e) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankChoiceException, BankException, LoginException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        try {
+            Account account = new Account(res.getText(R.string.balance).toString(),
+                    Helpers.parseBalance(userInfo.getString("balance")), "1");
+            accounts.add(account);
+        } catch (JSONException e) {
+            e.printStackTrace();
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
deleted file mode 100644
index 78feb20..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks.payson;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.text.TextUtils;
-
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.banks.payson.model.TransactionHistory;
-import com.liato.bankdroid.banking.banks.payson.model.User;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Payson extends Bank {
-    private static final String TAG = "Payson";
-    private static final String NAME = "Payson";
-    private static final String NAME_SHORT = "payson";
-    private static final String URL = "https://www.payson.se/signin/";
-    private static final int BANKTYPE_ID = IBankTypes.PAYSON;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reCleanText = Pattern.compile("\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private String response = null;
-    private ObjectMapper mObjectMapper;
-
-    public Payson(Context context) {
-        super(context);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-    }
-
-    public Payson(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_payson));
-        response = urlopen.open("https://www.payson.se/signin/");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
-        }
-        String strViewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
-        }
-        String strEventValidation = matcher.group(1);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtEmail", username));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtPassword", password));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$btnLogin", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, "https://www.payson.se/signin/");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Felaktig E-postadress") || response.contains("Lösenord saknas") ||
-                    response.contains("E-postadress saknas")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
-        super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-
-        try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/User/GetUserInfo?DateTime=%s", System.currentTimeMillis()), new ArrayList<NameValuePair>(), false);
-            User user = readJsonValue(httpResponse, User.class);
-            httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/History/List2?rows=40&page=1&sidx=&sord=asc&freeTextSearchString=&take=40&currency=&timeSpanStartDate=&timeSpanEndDate=&minAmount=&maxAmount=&purchaseType=&purchasePart=&purchaseStatus=&_=%s", System.currentTimeMillis()), new ArrayList<NameValuePair>(), false);
-            TransactionHistory thistory = readJsonValue(httpResponse, TransactionHistory.class);
-
-            Account account = new Account("Saldo", Helpers.parseBalance(user.getBalance()), "1");
-            String currency = Helpers.parseCurrency(user.getBalance(), "SEK");
-            account.setCurrency(currency);
-            setCurrency(currency);
-            accounts.add(account);
-            balance = balance.add(account.getBalance());
-
-            if (thistory != null && thistory.getRows() != null) {
-                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                for (com.liato.bankdroid.banking.banks.payson.model.Transaction transaction : thistory.getRows()) {
-                    String date = transaction.getCreatedDate().substring(0, 10);
-                    String description = !TextUtils.isEmpty(transaction.getMessage()) ? transaction.getMessage() : transaction.getSummary();
-
-                    Transaction t = new Transaction(date, Html.fromHtml(description).toString(), Helpers.parseBalance(transaction.getAmount()));
-                    t.setCurrency(Helpers.parseCurrency(transaction.getCurrencySymbol(), account.getCurrency()));
-                    transactions.add(t);
-                }
-                account.setTransactions(transactions);
-
-            }
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        } catch (JsonParseException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
-        } catch (ClientProtocolException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
-        } catch (IOException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
-        }
-        super.updateComplete();
-    }
-
-    private <T> T readJsonValue(HttpResponse response, Class<T> valueType) throws BankException {
-        try {
-            return readJsonValue(response.getEntity().getContent(), valueType);
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
-        try {
-            return getObjectmapper().readValue(is, valueType);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private ObjectMapper getObjectmapper() {
-        if (mObjectMapper == null) {
-            mObjectMapper = new ObjectMapper();
-            mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-            mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
-        }
-        return mObjectMapper;
-    }
-}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
deleted file mode 100644
index 364b661..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
+++ /dev/null
@@ -1,214 +0,0 @@
-package com.liato.bankdroid.banking.banks.payson.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Transaction {
-
-    @JsonProperty("Uri")
-    private String uri;
-    @JsonProperty("CreatedDate")
-    private String createdDate;
-    @JsonProperty("AmountDisplayValue")
-    private String amountDisplayValue;
-    @JsonProperty("CreditedAmountDisplayValue")
-    private String creditedAmountDisplayValue;
-    @JsonProperty("PurchaseId")
-    private String purchaseId;
-    @JsonProperty("Message")
-    private String message;
-    @JsonProperty("Summary")
-    private String summary;
-    @JsonProperty("Status")
-    private String status;
-    @JsonProperty("StatusId")
-    private String statusId;
-    @JsonProperty("PurchaseType")
-    private String purchaseType;
-    @JsonProperty("PurchaseTypeRaw")
-    private String purchaseTypeRaw;
-    @JsonProperty("IsActionable")
-    private String isActionable;
-    @JsonProperty("IsGuarantee")
-    private String isGuarantee;
-    @JsonProperty("ReceiverEmail")
-    private String receiverEmail;
-    @JsonProperty("SenderEmail")
-    private String senderEmail;
-    @JsonProperty("CurrencySymbol")
-    private String currencySymbol;
-    @JsonProperty("Amount")
-    private String amount;
-
-    @JsonProperty("Uri")
-    public String getUri() {
-        return uri;
-    }
-
-    @JsonProperty("Uri")
-    public void setUri(String uri) {
-        this.uri = uri;
-    }
-
-    @JsonProperty("CreatedDate")
-    public String getCreatedDate() {
-        return createdDate;
-    }
-
-    @JsonProperty("CreatedDate")
-    public void setCreatedDate(String createdDate) {
-        this.createdDate = createdDate;
-    }
-
-    @JsonProperty("AmountDisplayValue")
-    public String getAmountDisplayValue() {
-        return amountDisplayValue;
-    }
-
-    @JsonProperty("AmountDisplayValue")
-    public void setAmountDisplayValue(String amountDisplayValue) {
-        this.amountDisplayValue = amountDisplayValue;
-    }
-
-    @JsonProperty("CreditedAmountDisplayValue")
-    public String getCreditedAmountDisplayValue() {
-        return creditedAmountDisplayValue;
-    }
-
-    @JsonProperty("CreditedAmountDisplayValue")
-    public void setCreditedAmountDisplayValue(String creditedAmountDisplayValue) {
-        this.creditedAmountDisplayValue = creditedAmountDisplayValue;
-    }
-
-    @JsonProperty("PurchaseId")
-    public String getPurchaseId() {
-        return purchaseId;
-    }
-
-    @JsonProperty("PurchaseId")
-    public void setPurchaseId(String purchaseId) {
-        this.purchaseId = purchaseId;
-    }
-
-    @JsonProperty("Message")
-    public String getMessage() {
-        return message;
-    }
-
-    @JsonProperty("Message")
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-    @JsonProperty("Summary")
-    public String getSummary() {
-        return summary;
-    }
-
-    @JsonProperty("Summary")
-    public void setSummary(String summary) {
-        this.summary = summary;
-    }
-
-    @JsonProperty("Status")
-    public String getStatus() {
-        return status;
-    }
-
-    @JsonProperty("Status")
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    @JsonProperty("StatusId")
-    public String getStatusId() {
-        return statusId;
-    }
-
-    @JsonProperty("StatusId")
-    public void setStatusId(String statusId) {
-        this.statusId = statusId;
-    }
-
-    @JsonProperty("PurchaseType")
-    public String getPurchaseType() {
-        return purchaseType;
-    }
-
-    @JsonProperty("PurchaseType")
-    public void setPurchaseType(String purchaseType) {
-        this.purchaseType = purchaseType;
-    }
-
-    @JsonProperty("PurchaseTypeRaw")
-    public String getPurchaseTypeRaw() {
-        return purchaseTypeRaw;
-    }
-
-    @JsonProperty("PurchaseTypeRaw")
-    public void setPurchaseTypeRaw(String purchaseTypeRaw) {
-        this.purchaseTypeRaw = purchaseTypeRaw;
-    }
-
-    @JsonProperty("IsActionable")
-    public String getIsActionable() {
-        return isActionable;
-    }
-
-    @JsonProperty("IsActionable")
-    public void setIsActionable(String isActionable) {
-        this.isActionable = isActionable;
-    }
-
-    @JsonProperty("IsGuarantee")
-    public String getIsGuarantee() {
-        return isGuarantee;
-    }
-
-    @JsonProperty("IsGuarantee")
-    public void setIsGuarantee(String isGuarantee) {
-        this.isGuarantee = isGuarantee;
-    }
-
-    @JsonProperty("ReceiverEmail")
-    public String getReceiverEmail() {
-        return receiverEmail;
-    }
-
-    @JsonProperty("ReceiverEmail")
-    public void setReceiverEmail(String receiverEmail) {
-        this.receiverEmail = receiverEmail;
-    }
-
-    @JsonProperty("SenderEmail")
-    public String getSenderEmail() {
-        return senderEmail;
-    }
-
-    @JsonProperty("SenderEmail")
-    public void setSenderEmail(String senderEmail) {
-        this.senderEmail = senderEmail;
-    }
-
-    @JsonProperty("CurrencySymbol")
-    public String getCurrencySymbol() {
-        return currencySymbol;
-    }
-
-    @JsonProperty("CurrencySymbol")
-    public void setCurrencySymbol(String currencySymbol) {
-        this.currencySymbol = currencySymbol;
-    }
-
-    @JsonProperty("Amount")
-    public String getAmount() {
-        return amount;
-    }
-
-    @JsonProperty("Amount")
-    public void setAmount(String amount) {
-        this.amount = amount;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
deleted file mode 100644
index ea38877..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.liato.bankdroid.banking.banks.payson.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class TransactionHistory {
-
-    @JsonProperty("total")
-    private int total;
-    @JsonProperty("TotalUnFilteredCount")
-    private int totalUnFilteredCount;
-    @JsonProperty("rows")
-    private List<Transaction> rows = new ArrayList<Transaction>();
-    @JsonProperty("MaxItemAmount")
-    private double maxItemAmount;
-
-    @JsonProperty("total")
-    public int getTotal() {
-        return total;
-    }
-
-    @JsonProperty("total")
-    public void setTotal(int total) {
-        this.total = total;
-    }
-
-    @JsonProperty("TotalUnFilteredCount")
-    public int getTotalUnFilteredCount() {
-        return totalUnFilteredCount;
-    }
-
-    @JsonProperty("TotalUnFilteredCount")
-    public void setTotalUnFilteredCount(int totalUnFilteredCount) {
-        this.totalUnFilteredCount = totalUnFilteredCount;
-    }
-
-    @JsonProperty("rows")
-    public List<Transaction> getRows() {
-        return rows;
-    }
-
-    @JsonProperty("rows")
-    public void setRows(List<Transaction> rows) {
-        this.rows = rows;
-    }
-
-    @JsonProperty("MaxItemAmount")
-    public double getMaxItemAmount() {
-        return maxItemAmount;
-    }
-
-    @JsonProperty("MaxItemAmount")
-    public void setMaxItemAmount(double maxItemAmount) {
-        this.maxItemAmount = maxItemAmount;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
deleted file mode 100644
index 07112eb..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.liato.bankdroid.banking.banks.payson.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class User {
-
-    @JsonProperty("userName")
-    private String userName;
-    @JsonProperty("balance")
-    private String balance;
-    @JsonProperty("pending")
-    private String pending;
-
-    @JsonProperty("userName")
-    public String getUserName() {
-        return userName;
-    }
-
-    @JsonProperty("userName")
-    public void setUserName(String userName) {
-        this.userName = userName;
-    }
-
-    @JsonProperty("balance")
-    public String getBalance() {
-        return balance;
-    }
-
-    @JsonProperty("balance")
-    public void setBalance(String balance) {
-        this.balance = balance;
-    }
-
-    @JsonProperty("pending")
-    public String getPending() {
-        return pending;
-    }
-
-    @JsonProperty("pending")
-    public void setPending(String pending) {
-        this.pending = pending;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/res/values-se/strings.xml bankdroid-legacy/src/main/res/values-se/strings.xml
index 0fb9cfc..77cb0b4 100644
--- bankdroid-legacy/src/main/res/values-se/strings.xml
+++ bankdroid-legacy/src/main/res/values-se/strings.xml
@@ -7,6 +7,7 @@
     <string name="email">E-post</string>
     <string name="points">poäng</string>
     <string name="card_id">Kort ID</string>
+    <string name="balance">Saldo</string>
 
     <string name="nordnetdirekt_extras_title">Nyckel</string>
 
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
index 2bbf14e..648a17b 100644
--- bankdroid-legacy/src/main/res/values/strings.xml
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -11,6 +11,7 @@
     <string name="email">E-mail</string>
     <string name="points">points</string>
     <string name="card_id">Card ID</string>
+    <string name="balance">Balance</string>
 
     <string name="nordnetdirekt_extras_title">Key</string>
 

commit dabb262b99bbe877d3578375682cd6e192bc47e0
Merge: 7c30218 99e9487
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 17:11:40 2015 +0100

    Merge pull request #446 from liato/feature/refresh-certificates
    
    Update certificate for Brummer KF

commit 7c30218cce0d4f0d4d7f9a2ba8bb877b182967e3
Merge: 2bafe49 79c32d9
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 17:10:50 2015 +0100

    Merge pull request #444 from liato/feature/fix-jojo-keyboard
    
    Use email keyboard layout for Jojo Reskassa.

commit 2bafe49f25f402be62d47f1651d64190448a7f82
Merge: 651c33b d943d9d
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 17:09:40 2015 +0100

    Merge pull request #445 from liato/feature/fix-espressohouse-keyboard
    
    Use email keyboard layout for EspressoHouse.

commit 99e948784b7ec8d75924d431f0691833eb8c21f8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 16:43:35 2015 +0100

    Update certificate for Brummer KF

diff --git bankdroid-legacy/src/main/res/raw/cert_brummer.pem bankdroid-legacy/src/main/res/raw/cert_brummer.pem
index f982dd2..57a3884 100644
--- bankdroid-legacy/src/main/res/raw/cert_brummer.pem
+++ bankdroid-legacy/src/main/res/raw/cert_brummer.pem
@@ -1,31 +1,43 @@
 -----BEGIN CERTIFICATE-----

-kfLSPLGscWmnR6JTBY7mdzkaCBkFXIyqN06pV3kxzxjtCqBwdg==

+U20t5htcdjfC2PmbN/Y6FxQ=
 -----END CERTIFICATE-----
 www.brummer.se:443

commit d943d9ddd2d0ff4fecbd6a7342496710195262fa
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 16:35:35 2015 +0100

    Use email keyboard layout for EspressoHouse.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
index afc8ea9..90da198 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -17,6 +17,7 @@
 package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
+import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.Account;
@@ -50,6 +51,8 @@ public class EspressoHouse extends Bank {
         NAME = "Espresso House";
         NAME_SHORT = "espressohouse";
         BANKTYPE_ID = IBankTypes.ESPRESSOHOUSE;
+        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+        INPUT_TITLETEXT_USERNAME = R.string.email;
     }
 
     public EspressoHouse(String username, String password, Context context)

commit 79c32d9df2e89048dd4fcb14ef84f8bd873ab7ff
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 16:06:43 2015 +0100

    Use email keyboard layout for Jojo Reskassa.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 3e02920..ac2b2f6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -17,6 +17,7 @@
 package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
+import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.legacy.R;
@@ -49,6 +50,7 @@ public class Jojo extends Bank {
     private static final String NAME_SHORT = "jojo";
     private static final String URL = "https://www.shop.skanetrafiken.se";
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 
     private static final String NAME_NOT_SET = "KortnamnSaknas";
 
@@ -62,6 +64,7 @@ public class Jojo extends Bank {
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
         super.INPUT_TITLETEXT_USERNAME = R.string.email;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
     }
 
     public Jojo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {

commit 651c33bf5050f9951f1238ba6ec006b24cdf9d1c (tag: v1.9.8.0-RC4)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 15:09:19 2015 +0100

    Creates v1.9.8.0-RC4 release.

diff --git app/build.gradle app/build.gradle
index 3ec9946..cad56b4 100644
--- app/build.gradle
+++ app/build.gradle
@@ -23,8 +23,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 200
-        versionName "1.9.8.0-RC3"
+        versionCode 201
+        versionName "1.9.8.0-RC4"
     }
 
     signingConfigs {

commit b25940e7d798104b2621e3f1cb7890ff1dbe60b3
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 15:07:47 2015 +0100

    Fixes Crashlytics missing reporting issue

diff --git app/build.gradle app/build.gradle
index b380512..3ec9946 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,10 +8,7 @@ buildscript {
     }
 }
 apply plugin: 'com.android.application'
-
-if(new File('crashlytics.properties').exists()) {
-    apply plugin: 'io.fabric'
-}
+apply plugin: 'io.fabric'
 
 repositories {
     maven { url 'https://maven.fabric.io/public' }

commit 38329b99db8bd464998dd06200d605e727c620c2 (tag: v1.9.8.0-RC3)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 12:37:09 2015 +0100

    Creates release 1.9.8.0-RC3

diff --git CHANGES.txt CHANGES.txt
index da18fa6..7224c51 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,5 +1,6 @@
-v1.9.8.0 (2015-02-26)
+v1.9.8.0 (2015-02-27)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
+* Adds support for EspressoHouse (thanks to fredrike)
 * Adds support for multiple travel cards for JoJo Reskassa
 * Sets subaccounts for Avanza to hidden by default (thanks to fredrike)
 * Order transactions by descending date
@@ -9,6 +10,11 @@ v1.9.8.0 (2015-02-26)
 * Fixes application crash for Coop.
 * Fixes application crash when setting LockPattern on some devices
 * Fixes support for Nordea accounts with number in the account name
+* Fixes Swedbank and Sparbankerna if you have corporate credit card
+* Fixes www login for Coop
+* Fixes application crash if SonyEricsson's LiveView integration is enabled 
+* Improved error handling
+* Disabled www-button for Swedbank and Sparbankerna
 * Updated certificate for Östgötatrafiken
 * Removes support for Handelsbanken, SEB, Chevrolet, Djurgarden, EurobonusMastercard, EurobonusMastercardDk, EurobonusMastercardNo, Eurocard, Opel, Quintessentially, SJPrio, Saab, Statoil, Wallet because they now requires BankId.
 
diff --git app/build.gradle app/build.gradle
index e7a3d48..b380512 100644
--- app/build.gradle
+++ app/build.gradle
@@ -26,8 +26,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 199
-        versionName "1.9.8.0-RC2"
+        versionCode 200
+        versionName "1.9.8.0-RC3"
     }
 
     signingConfigs {

commit ac364ba9098df80eef1bbff5f9362df031b798ed
Merge: 9ea9c35 d9c6c20
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 12:26:38 2015 +0100

    Merge pull request #440 from fredrike/espressoHouse
    
    Added support for Espresso House, closes #275

commit d9c6c2089fa47f512bcc3aafc6238c434bceca0b
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 12:02:30 2015 +0100

    added support for Espresso House, closes #275

diff --git app/src/main/res/drawable/logo_espressohouse.png app/src/main/res/drawable/logo_espressohouse.png
new file mode 100644
index 0000000..ccea1ed
Binary files /dev/null and app/src/main/res/drawable/logo_espressohouse.png differ
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index 750a3b1..716398d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.EasyCard;
+import com.liato.bankdroid.banking.banks.EspressoHouse;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.ForexBank;
@@ -238,6 +239,8 @@ public class LegacyBankFactory {
                 return new Ostgotatrafiken(context);
             case IBankTypes.BREDBAND2VOIP:
                 return new Bredband2VoIP(context);
+            case IBankTypes.ESPRESSOHOUSE:
+                return new EspressoHouse(context);
             default:
                 throw new BankException("BankType id not found.");
         }
@@ -324,6 +327,7 @@ public class LegacyBankFactory {
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
         banks.add(new Bredband2VoIP(context));
+        banks.add(new EspressoHouse(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
new file mode 100644
index 0000000..afc8ea9
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EspressoHouse.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class EspressoHouse extends Bank {
+    private static final String API_URL = "http://www.espressohouse.com/coffee-card/min-sida/";
+
+    public EspressoHouse(Context context) {
+        super(context);
+        TAG = "EspressoHouse";
+        NAME = "Espresso House";
+        NAME_SHORT = "espressohouse";
+        BANKTYPE_ID = IBankTypes.ESPRESSOHOUSE;
+    }
+
+    public EspressoHouse(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            IOException {
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        urlopen = new Urllib(context);
+        urlopen.setFollowRedirects(false);
+        postData.add(new BasicNameValuePair("__EVENTTARGET",
+                "ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$LoginButton"));
+        postData.add(new BasicNameValuePair("ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$UserName",
+                username));
+        postData.add(new BasicNameValuePair("ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolderDefault$LoginView1$LoginUser$Password",
+                password));
+        HttpResponse httpResponse = urlopen.openAsHttpResponse("http://www.espressohouse.com/coffee-card/logga-inladda/", postData, true);
+        LoginPackage lp = new LoginPackage(urlopen, postData, null, API_URL);
+        if (httpResponse.getStatusLine().getStatusCode() == 302) {
+            lp.setIsLoggedIn(true);
+        }
+        return lp;
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            if (!lp.isLoggedIn()) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            String response = urlopen.open(API_URL);
+            Document dResponse = Jsoup.parse(response);
+            String card = dResponse.select(".transactionCardNumber").first().text().trim();
+            String cardNo = card.split(":")[1].trim();
+            String balance = dResponse.select(".balanceAmount").first().text();
+            balance = balance.substring(0, balance.length() - 2);
+            Account a = new Account(card,
+                    Helpers.parseBalance(balance),
+                    cardNo, Account.REGULAR, "SEK");
+
+            List<Element> eBalance = dResponse.select(".lineTotalAmount");
+            List<Element> eTransaction = dResponse.select(".lineTime");
+            List<Transaction> transactions = new ArrayList<>();
+            for (int i = 0; i < eTransaction.size(); i++) {
+                String s = eTransaction.get(i).text();
+                balance = eBalance.get(i).text();
+                balance = balance.substring(2, balance.length() - 2);
+                transactions.add(new Transaction(s.substring(s.length() - 16, s.length() - 6),
+                        s.substring(0, s.length() - 16), Helpers.parseBalance(balance)));
+            }
+            a.setTransactions(transactions);
+            accounts.add(a);
+        } catch (Exception e) {
+            throw new BankException(e.getMessage());
+        }
+        super.updateComplete();
+    }
+}
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 7ad24a5..7c8cb25 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -101,4 +101,5 @@ public interface IBankTypes {
     public final static int BLEKINGETRAFIKEN = 77;
     public final static int OSTGOTATRAFIKEN = 78;
     public final static int BREDBAND2VOIP = 79;
+    public final static int ESPRESSOHOUSE = 80;
 }

commit 9ea9c354e64050dbf40f07bef18f1e38f4c6483e
Merge: b0f6d5f 0a19ce5
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 12:23:08 2015 +0100

    Merge pull request #442 from liato/feature/381-swedbank-account-problems
    
    Sets transactions to empty list for Swedbank CreditCard

commit 0a19ce5199be08ddd4d1aeb01d80ae173d59f3b4
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 12:13:11 2015 +0100

    Sets transactions to empty list for Swedbank CreditCard if problem occurs during transaction fetching.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index c7430e8..e2606e4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -5,6 +5,7 @@ import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.Base64;
+import android.util.Log;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -39,6 +40,7 @@ import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -218,7 +220,9 @@ public abstract class AbstractSwedbank extends Bank {
         try {
             HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/cardaccount/"+mIdMap.get(account.getId())),false);
             if(httpResponse.getStatusLine().getStatusCode() != 200) {
-                throw new BankException(httpResponse.getStatusLine().toString());
+                Log.i(TAG, "Couldn't find transactions for creditcard");
+                account.setTransactions(Collections.<Transaction>emptyList());
+                return;
             }
             CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),CardAccountResponse.class);
             List<Transaction> transactions = new ArrayList<Transaction>();

commit b0f6d5feb8309c7707616e591b91e58acbf7a45c
Merge: 78074a1 019fba9
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 08:54:19 2015 +0100

    Merge pull request #439 from liato/feature/437-add-crashlytics-support
    
    Adds Crashlytics crash reporting.

commit 78074a10d8fac411e817091da8525a15f344bdc7
Merge: 298bb34 b360fc1
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 08:42:43 2015 +0100

    Merge pull request #438 from fredrike/www-logon
    
    Fixes www-login for sites with cookies without expiration

commit 298bb34eac7fafde6c5408e514f4916692cb62a4
Merge: a89f2c8 f182238
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 08:40:07 2015 +0100

    Merge pull request #432 from liato/feature/disable-www-button
    
    Thank you!

commit 019fba9031b0cd8081a1c0eb44eb8c5360ebf3ce
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 08:12:20 2015 +0100

    Adds Crashlytics crash reporting.
    
    Fixes #437

diff --git .gitignore .gitignore
index ca0d8c1..884bba3 100644
--- .gitignore
+++ .gitignore
@@ -44,4 +44,5 @@ out/
 app/src/main/java/com/liato/bankdroid/db/Crypto.*
 app/src/main/java/com/liato/bankdroid/db/Crypto.java.dev
 dev/
-app/release.keystore
\ No newline at end of file
+app/release.keystore
+app/crashlytics.properties
diff --git app/build.gradle app/build.gradle
index 118bbc3..e7a3d48 100644
--- app/build.gradle
+++ app/build.gradle
@@ -1,5 +1,23 @@
+buildscript {
+    repositories {
+        maven { url 'https://maven.fabric.io/public' }
+    }
+
+    dependencies {
+        classpath 'io.fabric.tools:gradle:1.+'
+    }
+}
 apply plugin: 'com.android.application'
 
+if(new File('crashlytics.properties').exists()) {
+    apply plugin: 'io.fabric'
+}
+
+repositories {
+    maven { url 'https://maven.fabric.io/public' }
+}
+
+
 android {
     compileSdkVersion 21
     buildToolsVersion "21.1.1"
@@ -47,6 +65,9 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
             signingConfig signingConfigs.release
         }
+        debug {
+            ext.enableCrashlytics = false
+        }
     }
 
     lintOptions {
@@ -60,4 +81,7 @@ dependencies {
     compile project(':bankdroid-legacy')
     compile "com.android.support:appcompat-v7:21.0.+"
     compile 'com.google.collections:google-collections:1.0'
+    compile('com.crashlytics.sdk.android:crashlytics:2.2.1@aar') {
+        transitive = true;
+    }
 }
diff --git app/crashlytics.properties.example app/crashlytics.properties.example
new file mode 100644
index 0000000..1b76723
--- /dev/null
+++ app/crashlytics.properties.example
@@ -0,0 +1,2 @@
+apiSecret=YOUR_BUILD_SECRET
+apiKey=YOUR_API_KEY
diff --git app/proguard-rules.pro app/proguard-rules.pro
index 70a3619..dbad36b 100644
--- app/proguard-rules.pro
+++ app/proguard-rules.pro
@@ -15,3 +15,6 @@
 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 #   public *;
 #}
+
+-keep class com.crashlytics.** { *; }
+-dontwarn com.crashlytics.**
diff --git app/src/main/AndroidManifest.xml app/src/main/AndroidManifest.xml
index 7ca05ec..a91f503 100644
--- app/src/main/AndroidManifest.xml
+++ app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid">
 	<application
+        android:name="com.liato.bankdroid.BankdroidApplication"
 		android:icon="@drawable/ic_launcher"
 		android:label="@string/app_name"
 	    android:hardwareAccelerated="true"
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 37af946..766d047 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -45,6 +45,7 @@ import android.widget.ImageView;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -249,6 +250,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 				}
 			} catch (BankException e) {
 				this.exc = e;
+                Crashlytics.logException(e);
 			} catch (LoginException e) {
 				this.exc = e;
 			}
diff --git app/src/main/java/com/liato/bankdroid/BankdroidApplication.java app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
new file mode 100644
index 0000000..b15c5bf
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/BankdroidApplication.java
@@ -0,0 +1,16 @@
+package com.liato.bankdroid;
+
+import android.app.Application;
+
+import com.crashlytics.android.Crashlytics;
+
+import io.fabric.sdk.android.Fabric;
+
+public class BankdroidApplication extends Application {
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Fabric.with(this, new Crashlytics());
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index 46942d4..be51536 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -27,6 +27,7 @@ import android.os.AsyncTask;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
+import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -93,6 +94,8 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 			} catch (final BankException e) {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
 						+ ")");
+
+                Crashlytics.logException(e);
 			} catch (final LoginException e) {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
 						+ ")");
diff --git app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 22fbf96..8270002 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -39,6 +39,7 @@ import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
+import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.MainActivity;
 import com.liato.bankdroid.R;
@@ -313,6 +314,8 @@ public class AutoRefreshService extends Service {
 					// Refresh widgets if an update fails
 					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
 							+ "'; BankException: " + e.getMessage());
+
+                    Crashlytics.logException(e);
 				} catch (final LoginException e) {
 					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
 							+ "'; LoginException: " + e.getMessage());
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 999e1d2..8bc2cdc 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -34,6 +34,7 @@ import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
+import com.crashlytics.android.Crashlytics;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.MainActivity;
 import com.liato.bankdroid.R;
@@ -370,6 +371,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 				} 
 				catch (BankException e) {
     				Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+                    Crashlytics.logException(e);
 				} catch (LoginException e) {
 					Log.e("", "Disabling bank: "+bank.getDbId());
 					DBAdapter.disable(bank,context);

commit f182238e6f1efb3e362829790c6c2ef2febd9951
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 08:23:14 2015 +0100

    Disable www button for Swedbank and Sparbankerna
    
    Fixes #433

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index da660f3..c7430e8 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -51,6 +51,7 @@ import eu.nullbyte.android.urllib.Urllib;
 public abstract class AbstractSwedbank extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+    private static final boolean WEB_VIEW_ENABLED = false;
 
     private static final String API_BASE = "https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/";
 
@@ -65,7 +66,7 @@ public abstract class AbstractSwedbank extends Bank {
 
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-
+        super.WEB_VIEW_ENABLED = WEB_VIEW_ENABLED;
     }
 
     public AbstractSwedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {

commit b6b8a2d8122c0012acb15c92fd07546a921e7aad
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 27 08:22:31 2015 +0100

    Add feature to disable the www button for single banks.

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 002a3e7..50b82d8 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -243,6 +243,7 @@ public class MainActivity extends LockableActivity {
 			final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
             final Button btnHide = (Button) root.findViewById(R.id.btnHide);
             final Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
+            final Button btnWWW = (Button) root.findViewById(R.id.btnWWW);
             if (selected_bank.getHideAccounts()) {
                 btnHide.setVisibility(View.GONE);
                 btnUnhide.setVisibility(View.VISIBLE);
@@ -252,9 +253,13 @@ public class MainActivity extends LockableActivity {
                 btnHide.setVisibility(View.VISIBLE);
                 btnUnhide.setVisibility(View.GONE);
                 btnHide.setOnClickListener(this);
+            }
+            if(selected_bank.isWebViewEnabled()) {
+                btnWWW.setOnClickListener(this);
+            } else {
+                btnWWW.setVisibility(View.GONE);
             }
 			root.findViewById(R.id.btnRefresh).setOnClickListener(this);
-			root.findViewById(R.id.btnWWW).setOnClickListener(this);
 			root.findViewById(R.id.btnEdit).setOnClickListener(this);
 			root.findViewById(R.id.btnRemove).setOnClickListener(this);
 
@@ -275,7 +280,7 @@ public class MainActivity extends LockableActivity {
 				parent.refreshView();
 				return;
 			case R.id.btnWWW:
-				if (selected_bank != null) {
+				if (selected_bank != null && selected_bank.isWebViewEnabled()) {
 					//Uri uri = Uri.parse(selected_bank.getURL());
 					//Intent intent = new Intent(Intent.ACTION_VIEW, uri);
 					final Intent intent = new Intent(context, WebViewActivity.class);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 6de97a4..874a210 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -62,7 +62,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     protected boolean STATIC_BALANCE = false;
     protected boolean BROKEN = false;
     protected boolean DISPLAY_DECIMALS = true;
-
+    protected boolean WEB_VIEW_ENABLED = true;
     protected Context context;
     protected Resources res;
 
@@ -293,6 +293,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return INPUT_TITLETEXT_EXTRAS;
     }
 
+    public boolean isWebViewEnabled() {
+        return WEB_VIEW_ENABLED;
+    }
 
     // Returns true if the current implementation of this bank is broken.
     public boolean isBroken() {

commit a89f2c8c63e8ff973f3d7f8e850d3fd67779b997
Merge: 0476245 0734dcc
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 00:08:14 2015 +0100

    Merge pull request #435 from liato/feature/434-liveview-notification-crash
    
    Updates icon name for SonyMobile LiveView menu icon.

commit 0476245d33e22dd981f404a5741e8a55119f9710
Merge: f02bdfc b475a7a
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 00:07:42 2015 +0100

    Merge pull request #436 from liato/feature/console-build-without-password
    
    Only require keystore password for the assembleRelease task.

commit b360fc1db9622ce15efeb4039e5247f18dc7fe58
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 27 00:04:33 2015 +0100

    fixes www-login for sites with cookies without expiration

diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index 5b10dab..842a2d1 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -121,6 +121,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                         public void run() {
                             if ((cookieStore != null) && !cookieStore.getCookies().isEmpty()) {
                                 CookieManager cookieManager = CookieManager.getInstance();
+                                CookieManager.getInstance().removeSessionCookie();
                                 String cookieString;
                                 for (Cookie cookie : cookieStore.getCookies()) {
                                     cookieString = String.format("%s=%s;%spath=%s; domain=%s;",

commit b475a7a17e5e3ce884e5118e514c6bd74374baf3
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 22:25:04 2015 +0100

    Only require keystore password for the assembleRelease task.

diff --git app/build.gradle app/build.gradle
index 178d8b5..118bbc3 100644
--- app/build.gradle
+++ app/build.gradle
@@ -12,28 +12,33 @@ android {
         versionName "1.9.8.0-RC2"
     }
 
-    final Console console = System.console();
-    if (console != null) {
-
-        // Building from console
-        signingConfigs {
-            release {
-                storeFile file("release.keystore")
-                storePassword console.readLine("\nEnter keystore password: ")
-                keyAlias "andmrkt"
-                keyPassword console.readLine("Enter key password: ")
-            }
+    signingConfigs {
+        release {
+            storeFile file("release.keystore")
+            storePassword ""
+            keyAlias "andmrkt"
+            keyPassword ""
         }
+    }
 
-    } else {
-
-        // Building from IDE
-        signingConfigs {
-            release {
-
+    // Get signing keys for release
+    gradle.taskGraph.whenReady { taskGraph ->
+        if(taskGraph.hasTask(':app:assembleRelease')) {
+            if(System.console() != null) { 
+                def keystorePassword = System.console().readPassword("\nEnter keystore password: ")
+                keystorePassword = new String(keystorePassword)
+                if(keystorePassword.isEmpty()) {
+                    throw new InvalidUserDataException("You must enter a keystore password to proceed.")
+                }
+                def password = System.console().readPassword("Enter key password: ")
+                password = new String(password)
+                if(password.isEmpty()) {
+                    throw new InvalidUserDataException("You must enter a password to proceed.")
+                }
+                android.signingConfigs.release.storePassword keystorePassword
+                android.signingConfigs.release.keyPassword password
             }
         }
-
     }
         
     buildTypes {

commit 0734dcc3ce66894cc45576969d450576ae5bc796
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 21:09:07 2015 +0100

    Updates icon name for SonyMobile LiveView menu icon.
    
    Fixes #434

diff --git app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
index 7a1d0d1..04c7b54 100644
--- app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
+++ app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
@@ -128,7 +128,7 @@ public class LiveViewService extends Service {
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
 
         // Load menu icon
-        int iconId = PluginUtils.getDynamicResourceId(this, "icon", "drawable");
+        int iconId = PluginUtils.getDynamicResourceId(this, "ic_launcher", "drawable");
         mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
     }
 

commit f02bdfc3df24d6ddfa3c4343ae4bacc9d361ccb9 (tag: v1.9.8.0-RC2)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 18:25:00 2015 +0100

    Creates release 1.9.8.0-RC2

diff --git CHANGES.txt CHANGES.txt
index ebd67de..da18fa6 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,10 +1,14 @@
-v1.9.8.0 (2015-02-25)
+v1.9.8.0 (2015-02-26)
 * Adds support for Bredband2's VoIP service (thanks to fredrike)
 * Adds support for multiple travel cards for JoJo Reskassa
 * Sets subaccounts for Avanza to hidden by default (thanks to fredrike)
 * Order transactions by descending date
 * Fixes www login for Blekingetrafiken (thanks to fredrike)
 * Fixes www login for Avanza (thanks to fredrike)
+* Fixes date formatting for VolvoFinans
+* Fixes application crash for Coop.
+* Fixes application crash when setting LockPattern on some devices
+* Fixes support for Nordea accounts with number in the account name
 * Updated certificate for Östgötatrafiken
 * Removes support for Handelsbanken, SEB, Chevrolet, Djurgarden, EurobonusMastercard, EurobonusMastercardDk, EurobonusMastercardNo, Eurocard, Opel, Quintessentially, SJPrio, Saab, Statoil, Wallet because they now requires BankId.
 
diff --git app/build.gradle app/build.gradle
index c6c3fec..178d8b5 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 198
-        versionName "1.9.8.0-RC1"
+        versionCode 199
+        versionName "1.9.8.0-RC2"
     }
 
     final Console console = System.console();

commit aebed4ada2246b9e4afae9ea6132c3d50bbe346c
Merge: 7ffcfc4 e1a5a12
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 18:14:11 2015 +0100

    Merge pull request #431 from fredrike/coop-fix
    
    Rewrite of login at Coop. Fixes #430

commit e1a5a12488f5b4db1b685a966aa953dc756df28d
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Feb 26 15:31:03 2015 +0100

    fixes #430, rewrite of login at Coop

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index fc1b496..f77b0a0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -19,30 +19,21 @@ package com.liato.bankdroid.banking.banks.coop;
 import android.content.Context;
 import android.text.TextUtils;
 
-import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.banks.coop.model.AuthenticateRequest;
-import com.liato.bankdroid.banking.banks.coop.model.AuthenticateResponse;
-import com.liato.bankdroid.banking.banks.coop.model.RefundSummaryRequest;
-import com.liato.bankdroid.banking.banks.coop.model.RefundSummaryResponse;
 import com.liato.bankdroid.banking.banks.coop.model.web.Result;
-import com.liato.bankdroid.banking.banks.coop.model.web.WebAuthenticateRequest;
 import com.liato.bankdroid.banking.banks.coop.model.web.WebTransactionHistoryResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -50,8 +41,6 @@ import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.util.ArrayList;
@@ -70,8 +59,7 @@ public class Coop extends Bank {
     private static final String NAME_SHORT = "coop";
     private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
     private static final int BANKTYPE_ID = IBankTypes.COOP;
-    private static final String APPLICATION_ID = "17B2F3F1-841B-40B5-B91C-A5F33DE73C18";
-    private static final Map<String, String> MONTHS = new HashMap<String, String>();
+    private static final Map<String, String> MONTHS = new HashMap<>();
     static {
         String[] ms = new String[] {"januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"};
         for (int i = 0; i < ms.length; i++) {
@@ -87,8 +75,8 @@ public class Coop extends Bank {
         MEDMERA_MER("mer_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Mer/"),
         MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 
-        String prefix;
-        String url;
+        final String prefix;
+        final String url;
         private AccountType(String prefix, String url) {
             this.prefix = prefix;
             this.url = url;
@@ -137,16 +125,10 @@ public class Coop extends Bank {
         }
     }
 
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
- //   private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern rePageGuid = Pattern.compile("pageGuid\"\\s*:\\s*\"([^\"]+)", Pattern.CASE_INSENSITIVE);
+    private final Pattern rePageGuid = Pattern.compile("pageGuid\"\\s*:\\s*\"([^\"]+)", Pattern.CASE_INSENSITIVE);
     private ObjectMapper mObjectMapper;
     private String response;
-    private String mToken;
-    private String mUserId;
-    private Map<AccountType, TransactionParams> mTransactionParams = new HashMap<AccountType, TransactionParams>();
+    private final Map<AccountType, TransactionParams> mTransactionParams = new HashMap<>();
 
     public Coop(Context context) {
         super(context);
@@ -165,22 +147,16 @@ public class Coop extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop, R.raw.cert_coop2));
-        urlopen.addHeader("Origin", "https://www.coop.se");
-        urlopen.addHeader("Referer", "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
-        response = urlopen.open("https://www.coop.se/");
-        Document d = Jsoup.parse(response);
-        String pageGuid = d.select("input[name=pageGuid]").first().val();
-        WebAuthenticateRequest webAuthReq = new WebAuthenticateRequest(pageGuid, username, password);
-        urlopen.addHeader("Content-Type", "application/json");
-        HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(webAuthReq));
-
-        HttpResponse httpResponse = urlopen.openAsHttpResponse("https://www.coop.se/Services/PlainService.svc/JsonExecute", e, true);
+            IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
+        urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
+        HttpResponse httpResponse = urlopen.openAsHttpResponse("https://www.coop.se/Personliga-Baren/Logga-in/?method=Login",
+                new StringEntity("{\"isBar\":\"true\",\"username\":\"" + username + "\",\"password\":\"" + password + "\"}"),
+                true);
         if (httpResponse.getStatusLine().getStatusCode() != 200) {
             throw new BankException(res.getString(R.string.invalid_username_password));
         }
-
+        urlopen.removeHeader("X-Requested-With");
         LoginPackage lp = new LoginPackage(urlopen, null, response, "https://www.coop.se/Mina-sidor/Oversikt/");
         lp.setIsLoggedIn(true);
         return lp;
@@ -190,35 +166,14 @@ public class Coop extends Bank {
     @Override
     public Urllib login() throws LoginException, BankException {
         try {
-            //Coop MedMera Kort/Visa information and transactions are not available from the json api
-            //so we'll have to login once to the web site and once to the api.
             LoginPackage lp = preLogin();
             if (!lp.isLoggedIn()) {
                 throw new BankException(res.getString(R.string.invalid_username_password));
             }
-
-            AuthenticateRequest authReq = new AuthenticateRequest(username, password, APPLICATION_ID);
-            HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(authReq));
-//            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
-            urlopen.addHeader("Content-Type", "application/json");
-            InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/UserService.svc/Authenticate", e, true);
-            AuthenticateResponse authResponse = readJsonValue(is, AuthenticateResponse.class);
-            if (authResponse == null) {
-                throw new BankException(res.getString(R.string.unable_to_login));
-            }
-            if (authResponse.getAuthenticateResult() == null || authResponse.getErrorid() != null || authResponse.getAuthenticateResult() == null) {
-                throw new LoginException(res.getString(R.string.invalid_username_password));
-            }
-            mToken = authResponse.getAuthenticateResult().getToken();
-            mUserId = Integer.toString(authResponse.getAuthenticateResult().getUserID());
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
+            return urlopen;
+        } catch (IOException e) {
             throw new BankException(e.getMessage());
         }
-        return urlopen;
     }
 
     @Override
@@ -236,7 +191,7 @@ public class Coop extends Bank {
             Account poang = new Account("\u2014  Poäng",
                     Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()),
                     "poang", Account.OTHER, "");
-            List<Transaction> transactions = new ArrayList<Transaction>();
+            List<Transaction> transactions = new ArrayList<>();
             poang.setTransactions(transactions);
             for (Element e : dResponse.select(".Timeline-item")) {
                 try {
@@ -275,8 +230,8 @@ public class Coop extends Bank {
                 }
                 Elements es = d.select(".List:contains(Saldo)");
                 if (es != null && !es.isEmpty()) {
-                    List<String> names = new ArrayList<String>();
-                    List<String> values = new ArrayList<String>();
+                    List<String> names = new ArrayList<>();
+                    List<String> values = new ArrayList<>();
                     for (Element e : es.first().select("dt")) {
                         names.add(e.text().replaceAll(":", "").trim());
                     }
@@ -301,9 +256,6 @@ public class Coop extends Bank {
                     }
                 }
             }
-        } catch (ClientProtocolException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
         } catch (IOException e) {
             e.printStackTrace();
             throw new BankException(e.getMessage());
@@ -311,28 +263,13 @@ public class Coop extends Bank {
 
 
         try {
-            RefundSummaryRequest refsumReq = new RefundSummaryRequest(mUserId, mToken, APPLICATION_ID);
-            HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(refsumReq));
-            InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/RefundService.svc/RefundSummary", e, true);
-            RefundSummaryResponse refsumResp = readJsonValue(is, RefundSummaryResponse.class);
-            if (refsumResp != null && refsumResp.getRefundSummaryResult() != null) {
-                Account a = new Account("Återbäring på ditt kort", BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getAccountBalance()), "refsummary");
-                a.setCurrency("SEK");
-                if (accounts.isEmpty()) {
-                    balance = a.getBalance();
-                    setCurrency(a.getCurrency());
-                }
-                accounts.add(a);
-                a = new Account(String.format("Återbäring för %s", refsumResp.getRefundSummaryResult().getMonthName()), BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getTotalRefund()), "refsummary_month");
-                accounts.add(a);
-            }
-        } catch (JsonParseException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
-        } catch (ClientProtocolException e) {
-            e.printStackTrace();
-            throw new BankException(e.getMessage());
-        } catch (IOException e) {
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Information-om-aterbaringen/");
+            Document dResponse = Jsoup.parse(response);
+            Account a = new Account("Återbäring",
+                    Helpers.parseBalance(dResponse.select(".Heading--coopNew").text()),
+                    "refound", Account.OTHER, "SEK");
+            accounts.add(a);
+        } catch (Exception e) {
             e.printStackTrace();
             throw new BankException(e.getMessage());
         }
@@ -352,15 +289,6 @@ public class Coop extends Bank {
         return mObjectMapper;
     }
 
-    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
-        try {
-            return getObjectmapper().readValue(is, valueType);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         AccountType at = getAccuntType(account.getId());
@@ -371,7 +299,7 @@ public class Coop extends Bank {
             String url = String.format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s", tp.getPageGuid(), data, System.currentTimeMillis());
             WebTransactionHistoryResponse transactionsResponse = getObjectmapper().readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
             if (transactionsResponse != null && transactionsResponse.getModel() != null) {
-                List<Transaction> transactions = new ArrayList<Transaction>();
+                List<Transaction> transactions = new ArrayList<>();
                 account.setTransactions(transactions);
                 for (Result r : transactionsResponse.getModel().getResults()) {
                     StringBuilder title = new StringBuilder(!TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
@@ -383,15 +311,7 @@ public class Coop extends Bank {
                     }
                 }
             }
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-        } catch (ClientProtocolException e) {
-            e.printStackTrace();
-        } catch (JsonMappingException e) {
-            e.printStackTrace();
-        } catch (JsonParseException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
deleted file mode 100644
index a970220..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class AuthenticateRequest {
-
-    @JsonProperty("password")
-    private String password;
-    @JsonProperty("username")
-    private String username;
-    @JsonProperty("applicationID")
-    private String applicationID;
-
-    public AuthenticateRequest(String username, String password, String applicationID) {
-        this.username = username;
-        this.password = password;
-        this.applicationID = applicationID;
-    }
-
-    public AuthenticateRequest() {
-
-    }
-
-    @JsonProperty("password")
-    public String getPassword() {
-        return password;
-    }
-
-    @JsonProperty("password")
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    @JsonProperty("username")
-    public String getUsername() {
-        return username;
-    }
-
-    @JsonProperty("username")
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    @JsonProperty("applicationID")
-    public String getApplicationID() {
-        return applicationID;
-    }
-
-    @JsonProperty("applicationID")
-    public void setApplicationID(String applicationID) {
-        this.applicationID = applicationID;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
deleted file mode 100644
index 0958a18..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class AuthenticateResponse extends BaseResponse {
-
-    @JsonProperty("AuthenticateResult")
-    private AuthenticateResult authenticateResult;
-
-    @JsonProperty("AuthenticateResult")
-    public AuthenticateResult getAuthenticateResult() {
-        return authenticateResult;
-    }
-
-    @JsonProperty("AuthenticateResult")
-    public void setAuthenticateResult(AuthenticateResult authenticateResult) {
-        this.authenticateResult = authenticateResult;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
deleted file mode 100644
index 15e955d..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class AuthenticateResult {
-
-    @JsonProperty("Token")
-    private String token;
-    @JsonProperty("UserID")
-    private int userID;
-
-    @JsonProperty("Token")
-    public String getToken() {
-        return token;
-    }
-
-    @JsonProperty("Token")
-    public void setToken(String token) {
-        this.token = token;
-    }
-
-    @JsonProperty("UserID")
-    public int getUserID() {
-        return userID;
-    }
-
-    @JsonProperty("UserID")
-    public void setUserID(int userID) {
-        this.userID = userID;
-    }
-
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
deleted file mode 100644
index f13c645..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class BaseResponse {
-
-    @JsonProperty("errorid")
-    private String errorid;
-    @JsonProperty("message")
-    private String message;
-
-    @JsonProperty("errorid")
-    public String getErrorid() {
-        return errorid;
-    }
-
-    @JsonProperty("errorid")
-    public void setErrorid(String errorid) {
-        this.errorid = errorid;
-    }
-
-    @JsonProperty("message")
-    public String getMessage() {
-        return message;
-    }
-
-    @JsonProperty("message")
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
deleted file mode 100644
index 1e19efc..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class RefundSummaryRequest {
-
-    @JsonProperty("token")
-    private String token;
-    @JsonProperty("userID")
-    private String userID;
-    @JsonProperty("applicationID")
-    private String applicationID;
-
-    public RefundSummaryRequest(String userID, String token, String applicationID) {
-        this.userID = userID;
-        this.token = token;
-        this.applicationID = applicationID;
-    }
-
-    public RefundSummaryRequest() {
-
-    }
-
-    @JsonProperty("token")
-    public String getToken() {
-        return token;
-    }
-
-    @JsonProperty("token")
-    public void setToken(String token) {
-        this.token = token;
-    }
-
-    @JsonProperty("userID")
-    public String getUserID() {
-        return userID;
-    }
-
-    @JsonProperty("userID")
-    public void setUserID(String userID) {
-        this.userID = userID;
-    }
-
-    @JsonProperty("applicationID")
-    public String getApplicationID() {
-        return applicationID;
-    }
-
-    @JsonProperty("applicationID")
-    public void setApplicationID(String applicationID) {
-        this.applicationID = applicationID;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
deleted file mode 100644
index d985aa4..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class RefundSummaryResponse extends BaseResponse {
-
-    @JsonProperty("RefundSummaryResult")
-    private RefundSummaryResult refundSummaryResult;
-
-    @JsonProperty("RefundSummaryResult")
-    public RefundSummaryResult getRefundSummaryResult() {
-        return refundSummaryResult;
-    }
-
-    @JsonProperty("RefundSummaryResult")
-    public void setRefundSummaryResult(RefundSummaryResult refundSummaryResult) {
-        this.refundSummaryResult = refundSummaryResult;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
deleted file mode 100644
index 79e9761..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class RefundSummaryResult {
-
-    @JsonProperty("AccountBalance")
-    private double accountBalance;
-    @JsonProperty("MonthName")
-    private String monthName;
-    @JsonProperty("PeriodRefund")
-    private int periodRefund;
-    @JsonProperty("ProfileNextRateDistance")
-    private int profileNextRateDistance;
-    @JsonProperty("ProfileRate")
-    private double profileRate;
-    @JsonProperty("TotalRefund")
-    private int totalRefund;
-
-    @JsonProperty("AccountBalance")
-    public double getAccountBalance() {
-        return accountBalance;
-    }
-
-    @JsonProperty("AccountBalance")
-    public void setAccountBalance(double accountBalance) {
-        this.accountBalance = accountBalance;
-    }
-
-    @JsonProperty("MonthName")
-    public String getMonthName() {
-        return monthName;
-    }
-
-    @JsonProperty("MonthName")
-    public void setMonthName(String monthName) {
-        this.monthName = monthName;
-    }
-
-    @JsonProperty("PeriodRefund")
-    public int getPeriodRefund() {
-        return periodRefund;
-    }
-
-    @JsonProperty("PeriodRefund")
-    public void setPeriodRefund(int periodRefund) {
-        this.periodRefund = periodRefund;
-    }
-
-    @JsonProperty("ProfileNextRateDistance")
-    public int getProfileNextRateDistance() {
-        return profileNextRateDistance;
-    }
-
-    @JsonProperty("ProfileNextRateDistance")
-    public void setProfileNextRateDistance(int profileNextRateDistance) {
-        this.profileNextRateDistance = profileNextRateDistance;
-    }
-
-    @JsonProperty("ProfileRate")
-    public double getProfileRate() {
-        return profileRate;
-    }
-
-    @JsonProperty("ProfileRate")
-    public void setProfileRate(double profileRate) {
-        this.profileRate = profileRate;
-    }
-
-    @JsonProperty("TotalRefund")
-    public int getTotalRefund() {
-        return totalRefund;
-    }
-
-    @JsonProperty("TotalRefund")
-    public void setTotalRefund(int totalRefund) {
-        this.totalRefund = totalRefund;
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
deleted file mode 100644
index 62d105e..0000000
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.liato.bankdroid.banking.banks.coop.model.web;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class WebAuthenticateRequest {
-    @JsonProperty("methodName")
-    private String methodName = "Login";
-    @JsonProperty("pageGuid")
-    private String pageGuid;
-    @JsonProperty("data")
-    private Data data;
-
-    public WebAuthenticateRequest(String pageGuid, String username, String password) {
-        this.pageGuid = pageGuid;
-        data = new Data(username, password);
-    }
-
-    @JsonProperty("methodName")
-    public String getMethodName() {
-        return methodName;
-    }
-
-    @JsonProperty("methodName")
-    public void setMethodName(String methodName) {
-        this.methodName = methodName;
-    }
-
-    @JsonProperty("pageGuid")
-    public String getPageGuid() {
-        return pageGuid;
-    }
-
-    @JsonProperty("pageGuid")
-    public void setPageGuid(String pageGuid) {
-        this.pageGuid = pageGuid;
-    }
-
-    @JsonProperty("data")
-    public Data getData() {
-        return data;
-    }
-
-    @JsonProperty("data")
-    public void setData(Data data) {
-        this.data = data;
-    }
-
-
-    public static class Data {
-
-        @JsonProperty("username")
-        private String username;
-        @JsonProperty("password")
-        private String password;
-
-        public Data(String username, String password) {
-            this.username = username;
-            this.password = password;
-        }
-
-        @JsonProperty("username")
-        public String getUsername() {
-            return username;
-        }
-
-        @JsonProperty("username")
-        public void setUsername(String username) {
-            this.username = username;
-        }
-
-        @JsonProperty("password")
-        public String getPassword() {
-            return password;
-        }
-
-        @JsonProperty("password")
-        public void setPassword(String password) {
-            this.password = password;
-        }
-
-    }
-
-}
\ No newline at end of file
diff --git bankdroid-legacy/src/main/res/raw/cert_coop2.pem bankdroid-legacy/src/main/res/raw/cert_coop2.pem
deleted file mode 100644
index 6ba98c5..0000000
--- bankdroid-legacy/src/main/res/raw/cert_coop2.pem
+++ /dev/null
@@ -1,32 +0,0 @@
------BEGIN CERTIFICATE-----

-jCsIfvDy
------END CERTIFICATE-----

commit 7ffcfc4b65822bf34bded6c931b337c4f81eb5f9
Merge: e940c6a abc14ea
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 07:37:29 2015 +0100

    Merge pull request #429 from liato/feature/424-dialog-dismiss-after-finished-activity
    
    Check if activity is finishing before dismissing dialog

commit abc14eadc317ec8040b9db91c261b8e900b6e6ec
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 07:36:29 2015 +0100

    Check if activity is finishing before dismissing dialog from background tasks.
    
    Fixes #424

diff --git app/src/main/java/com/liato/bankdroid/ActivityHelper.java app/src/main/java/com/liato/bankdroid/ActivityHelper.java
new file mode 100644
index 0000000..6aa0815
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/ActivityHelper.java
@@ -0,0 +1,28 @@
+package com.liato.bankdroid;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.ContextWrapper;
+
+public class ActivityHelper {
+
+    public static void dismissDialog(Dialog dialog) {
+        if(dialog.isShowing()) { //check if dialog is showing.
+
+            //get the Context object that was used to great the dialog
+            Context context = ((ContextWrapper) dialog.getContext()).getBaseContext();
+
+            //if the Context used here was an activity AND it hasn't been finished
+            //then dismiss it
+            if(context instanceof Activity) {
+                if(!((Activity)context).isFinishing()) {
+                    dialog.dismiss();
+                }
+            } else { //if the Context used wasnt an Activity, then dismiss it too
+                dialog.dismiss();
+            }
+        }
+    }
+
+}
diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 8be1073..37af946 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -260,9 +260,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 
 		protected void onPostExecute(final Void unused) {
 			AutoRefreshService.sendWidgetRefresh(context);
-			if (this.dialog.isShowing()) {
-				this.dialog.dismiss();
-			}
+            ActivityHelper.dismissDialog(this.dialog);
 			if (this.exc != null) {
 				AlertDialog.Builder builder = new AlertDialog.Builder(context);
 				if (this.exc instanceof BankChoiceException) {
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index 7ea837b..46942d4 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -129,9 +129,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 	protected void onPostExecute(final Void unused) {
 		parent.refreshView();
 		AutoRefreshService.sendWidgetRefresh(parent);
-		if (this.dialog.isShowing()) {
-			this.dialog.dismiss();
-		}
+		ActivityHelper.dismissDialog(this.dialog);
 
 		if ((this.errors != null) && !this.errors.isEmpty()) {
 			final StringBuilder errormsg = new StringBuilder();

commit e940c6a5a64a00efb6e1ae6c9fd4a1cccc5de175
Merge: 01c2f8c b9805b2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 07:30:47 2015 +0100

    Merge pull request #428 from liato/feature/427-dateparse-error-volvofinans
    
    Add Locale.UK for date parser to be able to parse the CET time zone.

commit 01c2f8ced6c674a7dafb4f7ebe6a74f2e5157b5b
Merge: 8dae6a4 216e7e5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 07:30:29 2015 +0100

    Merge pull request #425 from liato/feature/421-lockpattern-drawable-error
    
    Fix application crash when setting LockPattern.

commit b9805b27cbf1470a0f93af13d2c8ed894d7ec293
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 26 07:27:23 2015 +0100

    Add Locale.UK for date parser to be able to parse the CET time zone.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 6595f55..be77ac2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -61,7 +61,7 @@ public class Volvofinans extends Bank {
 	private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    private static SimpleDateFormat DATE_PARSER = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
+    private static SimpleDateFormat DATE_PARSER = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy", Locale.UK);
     private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd", new Locale("sv_SE"));
     private HashMap<String, String> mAccountUrlMappings = new HashMap<String, String>();
     

commit 8dae6a42eafdf7ab7cf0704b44f8c1fcbe8e5e47
Merge: b355ff6 1aeb9ba
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 25 21:35:18 2015 +0100

    Merge pull request #426 from fredrike/nordea-patch
    
    Fixes #422, problem with numbers in Nordea account names

commit 1aeb9bad6978f2e81b3276530c657c312b529b2f
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Feb 25 21:20:40 2015 +0100

    fixes #422, problem with numbers in Nordea account names

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 608848f..b0f2253 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -164,7 +164,7 @@ public class Nordea extends Bank {
     );
     
     private Pattern reAccountSelect = Pattern.compile("<select[^>]+name=\"transactionaccount\"[^>]*>(.*?)</select>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountOption = Pattern.compile("<option[^>]+value=\"([\\d]+)\"[^>]*>.*?([*\\d]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountOption = Pattern.compile("<option[^>]+value=\"([\\d]+)\"[^>]*>.*?(\\*{12}\\d{4})", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     
     // Nordea generates unique urls on each page load and serves content from session info,
     // so we need to find new links in lastResponse after each page load.

commit 216e7e551eb111bdb12627045cd1d6a84ae31459
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 25 20:10:15 2015 +0100

    Adds code_lock drawables. Fix #421

diff --git app/src/main/res/drawable-hdpi-v4/code_lock_bottom.9.png app/src/main/res/drawable-hdpi-v4/code_lock_bottom.9.png
new file mode 100644
index 0000000..e72d0f7
Binary files /dev/null and app/src/main/res/drawable-hdpi-v4/code_lock_bottom.9.png differ
diff --git app/src/main/res/drawable-hdpi-v4/code_lock_left.9.png app/src/main/res/drawable-hdpi-v4/code_lock_left.9.png
new file mode 100644
index 0000000..76ff1f5
Binary files /dev/null and app/src/main/res/drawable-hdpi-v4/code_lock_left.9.png differ
diff --git app/src/main/res/drawable-hdpi-v4/code_lock_top.9.png app/src/main/res/drawable-hdpi-v4/code_lock_top.9.png
new file mode 100644
index 0000000..20af255
Binary files /dev/null and app/src/main/res/drawable-hdpi-v4/code_lock_top.9.png differ
diff --git app/src/main/res/layout-land/choose_lock_pattern.xml app/src/main/res/layout-land/choose_lock_pattern.xml
index b43796a..e32dc0a 100644
--- app/src/main/res/layout-land/choose_lock_pattern.xml
+++ app/src/main/res/layout-land/choose_lock_pattern.xml
@@ -75,7 +75,7 @@
 	</LinearLayout>
 
 	<View
-		android:background="@*android:drawable/code_lock_left"
+		android:background="@drawable/code_lock_left"
 		android:layout_width="2dip"
 		android:layout_height="fill_parent" />
 	<!-- right side: lock pattern -->
diff --git app/src/main/res/layout/choose_lock_pattern.xml app/src/main/res/layout/choose_lock_pattern.xml
index 59b75d6..54e8888 100644
--- app/src/main/res/layout/choose_lock_pattern.xml
+++ app/src/main/res/layout/choose_lock_pattern.xml
@@ -28,14 +28,14 @@
         android:textSize="18sp"/>
 
     <View
-         android:background="@*android:drawable/code_lock_top"
+         android:background="@drawable/code_lock_top"
          android:layout_width="fill_parent"
          android:layout_height="2dip" />
     <com.liato.bankdroid.lockpattern.LockPatternView android:id="@+id/lockPattern"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />
     <View
-         android:background="@*android:drawable/code_lock_bottom"
+         android:background="@drawable/code_lock_bottom"
          android:layout_width="fill_parent"
          android:layout_height="8dip" />
 

commit b355ff6777ee5c795a083abe97f9b829f019049b (tag: v1.9.8.0-RC1)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 25 07:33:25 2015 +0100

    Creates release 1.9.8.0-RC1

diff --git CHANGES.txt CHANGES.txt
index 0888538..ebd67de 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,13 @@
+v1.9.8.0 (2015-02-25)
+* Adds support for Bredband2's VoIP service (thanks to fredrike)
+* Adds support for multiple travel cards for JoJo Reskassa
+* Sets subaccounts for Avanza to hidden by default (thanks to fredrike)
+* Order transactions by descending date
+* Fixes www login for Blekingetrafiken (thanks to fredrike)
+* Fixes www login for Avanza (thanks to fredrike)
+* Updated certificate for Östgötatrafiken
+* Removes support for Handelsbanken, SEB, Chevrolet, Djurgarden, EurobonusMastercard, EurobonusMastercardDk, EurobonusMastercardNo, Eurocard, Opel, Quintessentially, SJPrio, Saab, Statoil, Wallet because they now requires BankId.
+
 v1.9.7.4: (2015-02-21)
 * Updated certificates for ICA Banken, Västtrafik, Brummer KF, Diners Club, Ikano Bank, Marginalen, Trustbuddy, Zidisha, AmericanExpress, TicketRikskortet
 * Adds support for Coop's MedMera-Före and MedMera-Efter (thanks to fredrike)
diff --git app/build.gradle app/build.gradle
index 0320dc5..c6c3fec 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 197
-        versionName "1.9.7.4"
+        versionCode 198
+        versionName "1.9.8.0-RC1"
     }
 
     final Console console = System.console();

commit d65db1b3d731ded10e6bf1018c2a848b5da83520
Merge: af79631 93a8362
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 23:56:07 2015 +0100

    Merge pull request #420 from fredrike/bredband2-voip
    
    Fix for bredband2-voip due to #408

commit 93a83624288afd0ff428353381da52b196454fd1
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 23:51:51 2015 +0100

    more updates after #408

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index e4856de..4fa6e91 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -14,6 +14,7 @@ import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
 import com.liato.bankdroid.banking.banks.BrummerKF;
+import com.liato.bankdroid.banking.banks.Bredband2VoIP;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
@@ -249,6 +250,8 @@ public class LegacyBankFactory {
                 return new BlekingeTrafiken(context);
             case IBankTypes.OSTGOTATRAFIKEN:
                 return new Ostgotatrafiken(context);
+            case IBankTypes.BREDBAND2VOIP:
+                return new Bredband2VoIP(context);
             default:
                 throw new BankException("BankType id not found.");
         }
@@ -334,6 +337,7 @@ public class LegacyBankFactory {
         banks.add(new Sparbankerna(context));
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
+        banks.add(new Bredband2VoIP(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 5d4dc5d..9b182d7 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -21,7 +21,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;

commit af79631be1e3eb028a6776d109998a8cc9bf6804
Merge: 85e840c 2b57623
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 23:50:56 2015 +0100

    Merge pull request #419 from liato/feature/remove-banks-which-require-bankid
    
    Remove banks that require BankId

commit 2b576232bb78a16a61a0ee5c5d22ed7674ce7b16
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 23:37:49 2015 +0100

    Remove banks that require BankId

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index e4856de..7cefc71 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -16,19 +16,12 @@ import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
 import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
-import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.DinersClub;
-import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EasyCard;
-import com.liato.bankdroid.banking.banks.EurobonusMastercard;
-import com.liato.bankdroid.banking.banks.EurobonusMastercardDk;
-import com.liato.bankdroid.banking.banks.EurobonusMastercardNo;
-import com.liato.bankdroid.banking.banks.Eurocard;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.ForexBank;
-import com.liato.bankdroid.banking.banks.Handelsbanken;
 import com.liato.bankdroid.banking.banks.Hemkop;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
@@ -40,16 +33,12 @@ import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
-import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
-import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.SJPrio;
-import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
@@ -57,7 +46,6 @@ import com.liato.bankdroid.banking.banks.Skandiabanken;
 import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
-import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
@@ -68,7 +56,6 @@ import com.liato.bankdroid.banking.banks.Vasttrafik;
 import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
-import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
@@ -79,7 +66,6 @@ import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
-import com.liato.bankdroid.banking.banks.seb.SEB;
 import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
 import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
 import com.liato.bankdroid.banking.exceptions.BankException;
@@ -105,14 +91,14 @@ public class LegacyBankFactory {
                 return new Lansforsakringar(context);
             case IBankTypes.ICABANKEN:
                 return new ICABanken(context);
-            case IBankTypes.HANDELSBANKEN:
-                return new Handelsbanken(context);
+            // case IBankTypes.HANDELSBANKEN:
+            //     return new Handelsbanken(context);
             case IBankTypes.COOP:
                 return new Coop(context);
             case IBankTypes.ICA:
                 return new ICA(context);
-            case IBankTypes.STATOIL:
-                return new Statoil(context);
+            // case IBankTypes.STATOIL:
+            //    return new Statoil(context);
             case IBankTypes.AVANZA:
                 return new Avanza(context);
             case IBankTypes.VILLABANKEN:
@@ -121,8 +107,8 @@ public class LegacyBankFactory {
                 return new AvanzaMini(context);
             case IBankTypes.OKQ8:
                 return new OKQ8(context);
-            case IBankTypes.EUROCARD:
-                return new Eurocard(context);
+            // case IBankTypes.EUROCARD:
+            //     return new Eurocard(context);
             case IBankTypes.FIRSTCARD:
                 return new FirstCard(context);
             case IBankTypes.PAYPAL:
@@ -131,24 +117,24 @@ public class LegacyBankFactory {
                 return new Payson(context);
             case IBankTypes.JOJO:
                 return new Jojo(context);
-            //case IBankTypes.STEAM:
+            // case IBankTypes.STEAM:
             //    return new Steam(context);
             case IBankTypes.DINERSCLUB:
                 return new DinersClub(context);
             case IBankTypes.IKANOBANK:
                 return new IkanoBank(context);
-            case IBankTypes.SASEUROBONUSMASTERCARD:
-                return new EurobonusMastercard(context);
-            case IBankTypes.SASEUROBONUSMASTERCARD_NO:
-                return new EurobonusMastercardNo(context);
-            case IBankTypes.SASEUROBONUSMASTERCARD_DK:
-                return new EurobonusMastercardDk(context);
+            //  case IBankTypes.SASEUROBONUSMASTERCARD:
+            //      return new EurobonusMastercard(context);
+            //  case IBankTypes.SASEUROBONUSMASTERCARD_NO:
+            //      return new EurobonusMastercardNo(context);
+            //  case IBankTypes.SASEUROBONUSMASTERCARD_DK:
+            //      return new EurobonusMastercardDk(context);
             case IBankTypes.RIKSLUNCHEN:
                 return new Rikslunchen(context);
             case IBankTypes.HEMKOP:
                 return new Hemkop(context);
-            case IBankTypes.SEB:
-                return new SEB(context);
+            // case IBankTypes.SEB:
+            //     return new SEB(context);
             case IBankTypes.NORDNET:
                 return new Nordnet(context);
             case IBankTypes.SEVENDAY:
@@ -165,20 +151,20 @@ public class LegacyBankFactory {
                 return new AmericanExpress(context);
             case IBankTypes.MCDONALDS:
                 return new McDonalds(context);
-            case IBankTypes.SAAB:
-                return new Saab(context);
-            case IBankTypes.WALLET:
-                return new Wallet(context);
-            case IBankTypes.CHEVROLET:
-                return new Chevrolet(context);
-            case IBankTypes.SJPRIO:
-                return new SJPrio(context);
-            case IBankTypes.OPEL:
-                return new Opel(context);
-            case IBankTypes.DJURGARDEN:
-                return new Djurgarden(context);
-            case IBankTypes.QUINTESSENTIALLY:
-                return new Quintessentially(context);
+            // case IBankTypes.SAAB:
+            //     return new Saab(context);
+            // case IBankTypes.WALLET:
+            //     return new Wallet(context);
+            //  case IBankTypes.CHEVROLET:
+            //      return new Chevrolet(context);
+            //  case IBankTypes.SJPRIO:
+            //      return new SJPrio(context);
+            //  case IBankTypes.OPEL:
+            //      return new Opel(context);
+            // case IBankTypes.DJURGARDEN:
+            //     return new Djurgarden(context);
+            //   case IBankTypes.QUINTESSENTIALLY:
+            //       return new Quintessentially(context);
             case IBankTypes.PLUSGIROT:
                 return new PlusGirot(context);
             case IBankTypes.SHELL:
@@ -264,26 +250,26 @@ public class LegacyBankFactory {
         banks.add(new Nordea(context));
         banks.add(new ICABanken(context));
         banks.add(new Lansforsakringar(context));
-        banks.add(new Handelsbanken(context));
+        // banks.add(new Handelsbanken(context));
         banks.add(new Coop(context));
         banks.add(new ICA(context));
-        banks.add(new Statoil(context));
+        // banks.add(new Statoil(context));
         banks.add(new Avanza(context));
         banks.add(new Villabanken(context));
         banks.add(new AvanzaMini(context));
         banks.add(new OKQ8(context));
-        banks.add(new Eurocard(context));
+        // banks.add(new Eurocard(context));
         banks.add(new FirstCard(context));
         banks.add(new PayPal(context));
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
-        //banks.add(new Steam(context));
+        // banks.add(new Steam(context));
         banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
-        banks.add(new EurobonusMastercard(context));
+        // banks.add(new EurobonusMastercard(context));
         banks.add(new Rikslunchen(context));
         banks.add(new Hemkop(context));
-        banks.add(new SEB(context));
+        // banks.add(new SEB(context));
         banks.add(new Nordnet(context));
         banks.add(new SevenDay(context));
         banks.add(new Osuuspankki(context));
@@ -291,19 +277,19 @@ public class LegacyBankFactory {
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
         banks.add(new McDonalds(context));
-        banks.add(new SJPrio(context));
+        // banks.add(new SJPrio(context));
         banks.add(new SparbankenSyd(context));
-//        banks.add(new SparbankenOresund(context));
-        banks.add(new Opel(context));
+        // banks.add(new SparbankenOresund(context));
+        // banks.add(new Opel(context));
         banks.add(new Skandiabanken(context));
         banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));
-        banks.add(new Saab(context));
-        banks.add(new Wallet(context));
-        banks.add(new Chevrolet(context));
-        banks.add(new Djurgarden(context));
-        banks.add(new Quintessentially(context));
+        // banks.add(new Saab(context));
+        // banks.add(new Wallet(context));
+        // banks.add(new Chevrolet(context));
+        // banks.add(new Djurgarden(context));
+        // banks.add(new Quintessentially(context));
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
         banks.add(new Audi(context));
@@ -311,7 +297,7 @@ public class LegacyBankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
-//        banks.add(new DanskeBank(context));
+        // banks.add(new DanskeBank(context));
         banks.add(new NordeaDK(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
@@ -326,9 +312,9 @@ public class LegacyBankFactory {
         banks.add(new Zidisha(context));
         banks.add(new BetterGlobe(context));
         banks.add(new ForexBank(context));
-        banks.add(new EurobonusMastercardNo(context));
+        // banks.add(new EurobonusMastercardNo(context));
         banks.add(new Bitcoin(context));
-        banks.add(new EurobonusMastercardDk(context));
+        // banks.add(new EurobonusMastercardDk(context));
         banks.add(new SveaDirekt(context));
         banks.add(new SupremeCard(context));
         banks.add(new Sparbankerna(context));

commit 85e840c6b9e6008abb3d60c1ee0ae742f0f51b98
Merge: 94b8259 d7f9d4a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 23:09:50 2015 +0100

    Merge pull request #409 from fredrike/bredband2-voip
    
    Added support for Bredband2 voip

commit d7f9d4ab0242b23cedaca5b24d3e8804b66131e5
Merge: 619925b 05664ba
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 23:08:34 2015 +0100

    updates after #408

commit 94b82590bf3a016a037da60b817ca28ec89d201a
Merge: 476a7c7 8fc7536
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 23:06:34 2015 +0100

    Merge pull request #418 from liato/feature/certificates
    
    Updates certificates.

commit 8fc7536da385c603a9809f7a1480d10dbe0616c6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 23:05:05 2015 +0100

    Updates certificates.

diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
index 5207955..191f412 100644
--- bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
+++ bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
@@ -1,32 +1,35 @@
 -----BEGIN CERTIFICATE-----

-YQuw4+jd

+MCe7Jchh43bGAvJhOzi706Enkio=
 -----END CERTIFICATE-----
 webtick.ostgotatrafiken.se:443
diff --git tools/refresh_bank_certificates tools/refresh_bank_certificates
index c282e59..acc54a5 100755
--- tools/refresh_bank_certificates
+++ tools/refresh_bank_certificates
@@ -88,7 +88,7 @@ def write_certificate(cert_file, host, cert):
 
 if __name__ == "__main__":
     certificate_files_pattern = os.path.normpath(os.path.dirname(
-        os.path.realpath(__file__)) + "/../app/src/main/res/raw/*.pem")
+        os.path.realpath(__file__)) + "/../bankdroid-legacy/src/main/res/raw/*.pem")
     for cert_file in glob.glob(certificate_files_pattern):
         host = read_host_information(cert_file)
         if host is None:

commit 476a7c77975c1518c17ba57af56c7f5c681848ea
Merge: a3a9d6e b589105
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:53:16 2015 +0100

    Merge pull request #414 from fredrike/blekingetrafiken
    
    Fixed crashes when selecting www-login in Blekingetrafiken

commit a3a9d6e324b520b0c0876fe030b6f1f03af73933
Merge: e738ac5 26c65b5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:52:35 2015 +0100

    Merge pull request #410 from fredrike/avanza-patch
    
    Defaults sub-accounts on Avanza to 'Hidden'

commit e738ac50c13b469920340634540ea1cb324fa2e2
Merge: 36c1883 c57bf08
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:52:02 2015 +0100

    Merge pull request #417 from liato/feature/sort_transactions
    
    Sort transactions in descending order.

commit c57bf087c3a3c9bf4ce0895bf7cc3889abe27f49
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 11:39:46 2015 +0100

    Sort transactions in descending order.
    
    Fixes #388

diff --git app/src/main/java/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
index c5ca11d..fa63dd7 100644
--- app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
+++ app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
@@ -32,6 +32,7 @@ import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.Transaction;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 public class TransactionsActivity extends LockableActivity {
@@ -56,7 +57,8 @@ public class TransactionsActivity extends LockableActivity {
         icon.setImageResource(bank.getImageResource());
         List<Transaction> transactions = account.getTransactions();
 
-        if (transactions.size() > 0) {
+        if (!transactions.isEmpty()) {
+            Collections.sort(transactions);
             findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
             TransactionsAdapter adapter = new TransactionsAdapter(transactions);
             ListView viewTransactionsList = (ListView) findViewById(R.id.lstTransactionsList);
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
index 34d2503..4645948 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
@@ -71,6 +71,6 @@ public class Transaction implements Comparable<Transaction> {
 	public int compareTo(Transaction another) {
 		Integer thisdate = Integer.parseInt(date.replaceAll("-", ""));
 		Integer thatdate = Integer.parseInt((another).getDate().replaceAll("-", ""));
-		return thisdate - thatdate;
+		return thatdate - thisdate;
 	}
 }

commit 36c1883c4bfbe1271c1bf3f6699c27474286d56d
Merge: 78185a6 fba335e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:43:45 2015 +0100

    Merge pull request #416 from liato/feature/fix-jojo
    
    Use personal account for Jojo Reskassa.

commit fba335e177c25ad26ba9f8334303b6807e54e217
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:36:39 2015 +0100

    Fix imports

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 9386071..3e02920 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -19,7 +19,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;

commit c52399a8105ff29e951e204119966fa1dd90764a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:13:37 2015 +0100

    Use personal account for Jojo Reskassa.
    Makes it possible to get all your registered cards.
    
    Fixes #383

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 0e5755a..9386071 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -17,10 +17,9 @@
 package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
-import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.legacy.R;
+import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
@@ -37,6 +36,7 @@ import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -47,9 +47,11 @@ public class Jojo extends Bank {
     private static final String TAG = "Jojo";
     private static final String NAME = "Jojo Reskassa";
     private static final String NAME_SHORT = "jojo";
-    private static final String URL = "https://www.skanetrafiken.se/templates/MSRootPage.aspx?id=2935&epslanguage=SV";
+    private static final String URL = "https://www.shop.skanetrafiken.se";
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
 
+    private static final String NAME_NOT_SET = "KortnamnSaknas";
+
     private String response = null;
 
     public Jojo(Context context) {
@@ -59,9 +61,7 @@ public class Jojo extends Bank {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-        super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
-        super.INPUT_TITLETEXT_PASSWORD = R.string.cvc;
+        super.INPUT_TITLETEXT_USERNAME = R.string.email;
     }
 
     public Jojo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -69,24 +69,25 @@ public class Jojo extends Bank {
         this.update(username, password);
     }
 
-
     @Override
     protected LoginPackage preLogin() throws BankException,
             IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_jojo));
+
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("cardno", username));
-        postData.add(new BasicNameValuePair("backno", password));
-        postData.add(new BasicNameValuePair("ST_CHECK_SALDO", "Se saldo"));
-        return new LoginPackage(urlopen, postData, response, "https://www.shop.skanetrafiken.se/kollasaldo.html");
+        postData.add(new BasicNameValuePair("GOTO", "/mobile/minakort.html"));
+        postData.add(new BasicNameValuePair("login", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("CUSTOMER_LOGIN", "LOGGA IN"));
+        return new LoginPackage(urlopen, postData, response, URL + "/mobile/customer.html");
     }
 
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Kortnumret finns inte.")) {
-                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+            if (!response.contains("[Logga ut]")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
@@ -103,23 +104,17 @@ public class Jojo extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        Document d = Jsoup.parse(response);
 
-        Elements es = d.select(".saldo_ok_wrapper > table > tbody tr");
-        if (es != null) {
-            for (int i = 0; i < 2; i++) {
-
-                int index = 0+i;
-                if (es.size()>=index) {
-                    Element e = es.get(index);
-                    Element name = e.select(".first").first();
-                    Element amount = e.select(".right").first();
-                    if (name != null && amount != null) {
-                        Account a = new Account(name.text().replaceAll(":", "").trim(), Helpers.parseBalance(amount.text()), Integer.toString(i));
-                        accounts.add(a);
-                        balance = balance.add(a.getBalance());
-                    }
-                }
+        Document d = Jsoup.parse(response);
+        Elements cards = d.select(".my_cards_allinfo table tbody");
+        if (!cards.isEmpty()) {
+            for(Element card : cards) {
+                String cardNumber = card.select("tr:first-child td").text().trim();
+                BigDecimal saldo = getSaldo(cardNumber);
+                String name = card.select("tr:nth-child(2) td").text().trim();
+                String displayName = NAME_NOT_SET.equals(name) ? cardNumber : name;
+                accounts.add(new Account(displayName, saldo, cardNumber));
+                balance = balance.add(saldo);
             }
         }
 
@@ -128,4 +123,23 @@ public class Jojo extends Bank {
         }
         super.updateComplete();
     }
+
+
+    private BigDecimal getSaldo(String cardNumber) {
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("cardno", cardNumber));
+        postData.add(new BasicNameValuePair("fromlist","1"));
+        postData.add(new BasicNameValuePair("ST_CHECK_SALDO", "1"));
+        try {
+            String saldoData = urlopen.open(URL + "/saldodata.html",postData,true);
+            Document saldoDocument = Jsoup.parse(saldoData);
+            Elements saldo = saldoDocument.select("td.greenrow.right h3");
+            if(!saldo.isEmpty()) {
+                return Helpers.parseBalance(saldo.first().text().trim());
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return BigDecimal.ZERO;
+    }
 }

commit 26c65b52920725f16fe8f5b4cd20d84666cb5494
Merge: f73c2e8 05664ba
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 22:40:47 2015 +0100

    updates after #408

commit 78185a69ca02fa2f31c79cc973126e4691b7b589
Merge: 05664ba a9fd2ec
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:40:41 2015 +0100

    Merge pull request #415 from liato/feature/fix-lint-error
    
    Do not abort build on lint errors.

commit a9fd2ec3eb34b2a6ba76497ce9315f2e1c03e280
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:39:49 2015 +0100

    Do not abort build on lint errors.

diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index 021b743..b6057de 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -16,6 +16,10 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+
+    lintOptions {
+        abortOnError false
+    }
 }
 
 dependencies {

commit b589105d37db6bf38c9edea3cea85dda705f8a7a
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 22:05:24 2015 +0100

    Fixed crashes when selecting www-login in Blekingetrafiken

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index 8edc402..7c7426e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -40,7 +40,7 @@ public class BlekingeTrafiken extends Bank {
     private static final String TAG = "Blekingetrafiken";
     private static final String NAME = "Blekingetrafiken";
     private static final String NAME_SHORT = "blekingetrafiken";
-    private static final String URL = "https://www.blekingetrafiken.se/webshop/card/balance/";
+    private static final String URL = "https://www.blekingetrafiken.se";
     private static final int BANKTYPE_ID = IBankTypes.BLEKINGETRAFIKEN;
     private String response = null;
 
@@ -68,15 +68,17 @@ public class BlekingeTrafiken extends Bank {
     protected LoginPackage preLogin() throws BankException,
             IOException {
         urlopen = new Urllib(context);
-        urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
-        urlopen.addHeader("Accept","application/json");
-        return new LoginPackage(urlopen, null , null, URL);
+        LoginPackage lp = new LoginPackage(urlopen, null, null, URL);
+        lp.setIsLoggedIn(true); //Well we don't support logging in ATM.
+        return lp;
     }
 
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(URL,
+            urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
+            urlopen.addHeader("Accept","application/json");
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(URL + "/webshop/card/balance/",
                     new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
             if(httpResponse.getStatusLine().getStatusCode() != 200) {
                 throw new LoginException(res.getText(R.string.invalid_card_number).toString());

commit 05664ba362f610f8c20add53e5de576b9005cf82
Merge: d9691ed d681ff0
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:03:40 2015 +0100

    Merge pull request #413 from fredrike/asset-move
    
    moved logo_text_big.png

commit d9691ed5b3cf8487264419a38c508eb0b1d6d8d6
Merge: 0e416e3 2ffc769
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Feb 24 22:00:40 2015 +0100

    Merge pull request #408 from liato/feature/refactoring
    
    Move banks to separate module.

commit d681ff061af47a3c5cee06de097718dbff26cec5
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 22:00:17 2015 +0100

    moved logo_text_big.png

diff --git assets/logo_text_big.png app/src/main/assets/logo_text_big.png
similarity index 100%
rename from assets/logo_text_big.png
rename to app/src/main/assets/logo_text_big.png

commit 619925b6927280466dddcd11db9e5c9521dc1e50
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 21:14:23 2015 +0100

    Bredband2-VoIP: rename, fix for www-login and reindent

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 36b8305..9d0382a 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -29,7 +29,7 @@ import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
-import com.liato.bankdroid.banking.banks.Bredband2VoIp;
+import com.liato.bankdroid.banking.banks.Bredband2VoIP;
 import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
@@ -273,7 +273,7 @@ public class BankFactory {
         case IBankTypes.OSTGOTATRAFIKEN:
             return new Ostgotatrafiken(context);
          case IBankTypes.BREDBAND2VOIP:
-            return new Bredband2VoIp(context);
+            return new Bredband2VoIP(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -360,7 +360,7 @@ public class BankFactory {
         banks.add(new Sparbankerna(context));
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
-        banks.add(new Bredband2VoIp(context));
+        banks.add(new Bredband2VoIP(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) {
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
similarity index 87%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
index 2a143c0..5d4dc5d 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIP.java
@@ -44,7 +44,7 @@ import java.util.regex.Pattern;
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
-public class Bredband2VoIp extends Bank {
+public class Bredband2VoIP extends Bank {
     private static final String API_URL = "https://portal.bredband2.com/";
 
     private Pattern reSaldoUrl = Pattern.compile("<a href=\"/voip/digisipbalance/iPhoneProviderID/(\\d+)/\" class=\"digisipBalance\" target=\"_blank\">Saldo</a>", Pattern.CASE_INSENSITIVE);
@@ -53,17 +53,17 @@ public class Bredband2VoIp extends Bank {
     private Pattern reTransactions = Pattern.compile("^\\s+([\\d-]+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)", Pattern.MULTILINE);
     private String response = null;
 
-    public Bredband2VoIp(Context context) {
+    public Bredband2VoIP(Context context) {
         super(context);
-        TAG = "Bredband2VoIp";
-        NAME = "Bredband2 VoIp";
+        TAG = "Bredband2VoIP";
+        NAME = "Bredband2 VoIP";
         NAME_SHORT = "bredband2voip";
         BANKTYPE_ID = IBankTypes.BREDBAND2VOIP;
         super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
         super.INPUT_HINT_USERNAME = "19XXXXXX-XXXX";
     }
 
-    public Bredband2VoIp(String username, String password, Context context)
+    public Bredband2VoIP(String username, String password, Context context)
             throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
@@ -71,25 +71,27 @@ public class Bredband2VoIp extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException,
-        ClientProtocolException, IOException {
+            ClientProtocolException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bredband2));
-        urlopen.setAllowCircularRedirects(true);
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        List<NameValuePair> postData = new ArrayList <NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.add(new BasicNameValuePair("cUsername", username));
         postData.add(new BasicNameValuePair("cPassword", password));
         postData.add(new BasicNameValuePair("bIsCompany", "0"));
         postData.add(new BasicNameValuePair("submit", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, API_URL + "index/");
+        response = urlopen.open(API_URL + "index/", postData, true);
+        if (!response.contains("Logga ut")) {
+            throw new BankException(res.getText(R.string.invalid_username_password).toString());
+        }
+        LoginPackage lp = new LoginPackage(urlopen, postData, response, API_URL + "index/");
+        lp.setIsLoggedIn(true);
+        return lp;
     }
 
     @Override
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-            if (!response.contains("Logga ut")) {
+            if (!lp.isLoggedIn()) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         } catch (ClientProtocolException e) {
@@ -114,7 +116,7 @@ public class Bredband2VoIp extends Bank {
                 String account = mSaldoUrl.group(1);
                 String r = urlopen.open(API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
                 Matcher mSaldo = reSaldo.matcher(r);
-                if(mSaldo.find()) {
+                if (mSaldo.find()) {
                     accounts.add(new Account(account,
                             Helpers.parseBalance(mSaldo.group(1)),
                             account));
@@ -140,13 +142,12 @@ public class Bredband2VoIp extends Bank {
                     String url = mInvoiceUrl.group(1);
                     String sInvoice = urlopen.open(API_URL + url);
                     Matcher mTransaction = reTransactions.matcher(sInvoice);
-                    while(mTransaction.find()) {
+                    while (mTransaction.find()) {
                         transactions.add(new Transaction(mTransaction.group(2),
                                 mTransaction.group(1) + "  —  " + mTransaction.group(4),
                                 Helpers.parseBalance(mTransaction.group(5)).negate()));
                     }
-                }
-                catch (Exception e) {
+                } catch (Exception e) {
                     Log.w(TAG, "Unable to parse: " + mInvoiceUrl.group(1));
                 }
             }

commit f73c2e80fc96ae520faf596df032a7bf9008a61a
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 20:44:47 2015 +0100

    resolves #260, problem with Avanza web-login

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 1a0f0ca..14a2e21 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -38,6 +38,9 @@ import com.liato.bankdroid.provider.IBankTypes;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.json.JSONException;
+import org.json.JSONObject;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -56,9 +59,8 @@ public class Avanza extends Bank {
         TAG = "Avanza";
         NAME = "Avanza";
         NAME_SHORT = "avanza";
-        URL = "https://www.avanza.se/";
+        URL = "https://iphone.avanza.se";
         BANKTYPE_ID = IBankTypes.AVANZA;
-//        STATIC_BALANCE = true;
     }
 
     public Avanza(String username, String password, Context context)
@@ -67,6 +69,28 @@ public class Avanza extends Bank {
         this.update(username, password);
     }
 
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen.addHeader("Referer", URL + "/start");
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("j_username", username));
+        postData.add(new BasicNameValuePair("j_password", password));
+        postData.add(new BasicNameValuePair("url", URL + "/start"));
+        String response = urlopen.open(URL + "/ab/handlelogin", postData);
+        String homeUrl = "";
+        try {
+            JSONObject jsonResponse = new JSONObject(response);
+            homeUrl = jsonResponse.getString("redirectUrl");
+        } catch (JSONException e) {
+            throw new BankException(res.getString(R.string.invalid_username_password));
+        }
+        LoginPackage lp = new LoginPackage(urlopen, postData, "", URL + homeUrl);
+        lp.setIsLoggedIn(true);
+        return lp;
+    }
+
     public Urllib login() throws LoginException, BankException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
@@ -89,7 +113,7 @@ public class Avanza extends Bank {
                 if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
                     ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount :  account.getCurrencyAccounts()) {
+                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account.getCurrencyAccounts()) {
                         transactions.add(new Transaction(Helpers.formatDate(now),
                                 "\u2014  " + currencyAccount.getCurrency() + "  \u2014",
                                 BigDecimal.valueOf(currencyAccount.getBalance()),
@@ -120,7 +144,7 @@ public class Avanza extends Bank {
                 // Add subtypes for account as own account.
                 if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
-                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount :  account.getCurrencyAccounts()) {
+                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount : account.getCurrencyAccounts()) {
                         Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
                                 currencyAccount.getCurrency(),
                                 new BigDecimal(currencyAccount.getBalance()),
@@ -135,8 +159,8 @@ public class Avanza extends Bank {
                             continue;
                         }
                         Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
-                                    positionAgList.getInstrumentTypeName() +
-                                    "  " + positionAgList.getTotalProfitPercent() + "% ",
+                                positionAgList.getInstrumentTypeName() +
+                                "  " + positionAgList.getTotalProfitPercent() + "% ",
                                 new BigDecimal(positionAgList.getTotalValue()),
                                 account.getAccountId() + positionAgList.getInstrumentTypeName(),
                                 Account.OTHER, a.getCurrency());

commit af2c03353b776b4fe3f75aeb7c57c31cfd1eab1d
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Tue Feb 24 13:20:13 2015 +0100

    removed transaction sorting as it is implemented by #411

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
index 0ec67b0..2a143c0 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
@@ -140,14 +140,11 @@ public class Bredband2VoIp extends Bank {
                     String url = mInvoiceUrl.group(1);
                     String sInvoice = urlopen.open(API_URL + url);
                     Matcher mTransaction = reTransactions.matcher(sInvoice);
-                    ArrayList<Transaction> tr = new ArrayList<Transaction>();
                     while(mTransaction.find()) {
-                        tr.add(0, new Transaction(mTransaction.group(2),
+                        transactions.add(new Transaction(mTransaction.group(2),
                                 mTransaction.group(1) + "  —  " + mTransaction.group(4),
                                 Helpers.parseBalance(mTransaction.group(5)).negate()));
                     }
-                    //Needed as the list is in reverse order.
-                    transactions.addAll(tr);
                 }
                 catch (Exception e) {
                     Log.w(TAG, "Unable to parse: " + mInvoiceUrl.group(1));

commit 0edc81cbb1284a784495ba15aefa7344b9e4b425
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Feb 23 09:21:52 2015 +0100

    defaults subaccounts on Avanza to 'Hidden'

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 4d01e6b..1a0f0ca 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -121,12 +121,14 @@ public class Avanza extends Bank {
                 if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
                     for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount :  account.getCurrencyAccounts()) {
-                        accounts.add(new Account("\u2014  " + account.getAccountId() + ",  " +
+                        Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
                                 currencyAccount.getCurrency(),
                                 new BigDecimal(currencyAccount.getBalance()),
                                 account.getAccountId() + currencyAccount.getCurrency(),
                                 Account.OTHER,
-                                currencyAccount.getCurrency()));
+                                currencyAccount.getCurrency());
+                        b.setHidden(true);
+                        accounts.add(b);
                     }
                     for (PositionAggregation positionAgList : account.getPositionAggregations()) {
                         if (positionAgList.getPositions().isEmpty()) {
@@ -138,6 +140,7 @@ public class Avanza extends Bank {
                                 new BigDecimal(positionAgList.getTotalValue()),
                                 account.getAccountId() + positionAgList.getInstrumentTypeName(),
                                 Account.OTHER, a.getCurrency());
+                        b.setHidden(true);
                         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
                         for (Position p : positionAgList.getPositions()) {
                             transactions.add(new Transaction(Helpers.formatDate(now),
@@ -159,6 +162,8 @@ public class Avanza extends Bank {
         } catch (IOException e) {
             e.printStackTrace();
             throw new BankException(e.getMessage());
+        } catch (Exception e) {
+            throw new BankException(e.getMessage());
         }
         return urlopen;
     }

commit 7a8c08aad993142b091c026949f7f57d18923aee
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Feb 22 23:26:00 2015 +0100

    added support for Bredband2's VoIP service

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 7948be5..36b8305 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -29,6 +29,7 @@ import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
+import com.liato.bankdroid.banking.banks.Bredband2VoIp;
 import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
@@ -166,13 +167,13 @@ public class BankFactory {
         case IBankTypes.SASEUROBONUSMASTERCARD_DK:
             return new EurobonusMastercardDk(context);
         case IBankTypes.RIKSLUNCHEN:
-            return new Rikslunchen(context);            
+            return new Rikslunchen(context);
         case IBankTypes.HEMKOP:
-            return new Hemkop(context);            
+            return new Hemkop(context);
         case IBankTypes.SEB:
-            return new SEB(context);            
+            return new SEB(context);
         case IBankTypes.NORDNET:
-            return new Nordnet(context);            
+            return new Nordnet(context);
         case IBankTypes.SEVENDAY:
             return new SevenDay(context);
         case IBankTypes.OSUUSPANKKI:
@@ -271,11 +272,13 @@ public class BankFactory {
             return new BlekingeTrafiken(context);
         case IBankTypes.OSTGOTATRAFIKEN:
             return new Ostgotatrafiken(context);
+         case IBankTypes.BREDBAND2VOIP:
+            return new Bredband2VoIp(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
 	}
-	
+
 
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
@@ -357,9 +360,10 @@ public class BankFactory {
         banks.add(new Sparbankerna(context));
         banks.add(new BlekingeTrafiken(context));
         banks.add(new Ostgotatrafiken(context));
+        banks.add(new Bredband2VoIp(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-        if (prefs.getBoolean("debug_mode", false)) { 
+        if (prefs.getBoolean("debug_mode", false)) {
             banks.add(new TestBank(context));
         }
 		return banks;
@@ -381,7 +385,7 @@ public class BankFactory {
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 				}
-				
+
 				bank.setData(c.getString(c.getColumnIndex("username")),
 							 password,
 							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
@@ -419,7 +423,7 @@ public class BankFactory {
 			c.moveToNext();
 			try {
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				
+
 	            String password = "";
                 try {
                     password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
@@ -448,12 +452,12 @@ public class BankFactory {
 		db.close();
 		return banks;
 	}
-	
+
 	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
 		DBAdapter db = new DBAdapter(context);
 		db.open();
 		Cursor c = db.getAccount(accountId);
-       
+
 		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
 			db.close();
 			return null;
@@ -488,11 +492,11 @@ public class BankFactory {
 			}
 			account.setTransactions(transactions);
 		}
-		
+
 		db.close();
 		return account;
 	}
-	
+
 	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
 		ArrayList<Account> accounts = new ArrayList<Account>();
 		DBAdapter db = new DBAdapter(context);
@@ -511,7 +515,7 @@ public class BankFactory {
                                               c.getLong(c.getColumnIndex("bankid")),
                                               c.getInt(c.getColumnIndex("acctype")));
     	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
+    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
                 account.setCurrency(c.getString(c.getColumnIndex("currency")));
                 account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
     			accounts.add(account);
@@ -524,5 +528,5 @@ public class BankFactory {
 		db.close();
 		return accounts;
 	}
-	
+
 }
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
new file mode 100644
index 0000000..0ec67b0
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Bredband2VoIp.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Bredband2VoIp extends Bank {
+    private static final String API_URL = "https://portal.bredband2.com/";
+
+    private Pattern reSaldoUrl = Pattern.compile("<a href=\"/voip/digisipbalance/iPhoneProviderID/(\\d+)/\" class=\"digisipBalance\" target=\"_blank\">Saldo</a>", Pattern.CASE_INSENSITIVE);
+    private Pattern reSaldo = Pattern.compile("<td class=\"white\">(\\d+.\\d{2}) kr", Pattern.CASE_INSENSITIVE);
+    private Pattern reInvoiceUrl = Pattern.compile("<a href=\"([^\"]+)\"/\" class=\"invoice\"");
+    private Pattern reTransactions = Pattern.compile("^\\s+([\\d-]+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)", Pattern.MULTILINE);
+    private String response = null;
+
+    public Bredband2VoIp(Context context) {
+        super(context);
+        TAG = "Bredband2VoIp";
+        NAME = "Bredband2 VoIp";
+        NAME_SHORT = "bredband2voip";
+        BANKTYPE_ID = IBankTypes.BREDBAND2VOIP;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+        super.INPUT_HINT_USERNAME = "19XXXXXX-XXXX";
+    }
+
+    public Bredband2VoIp(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+        ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bredband2));
+        urlopen.setAllowCircularRedirects(true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        List<NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("cUsername", username));
+        postData.add(new BasicNameValuePair("cPassword", password));
+        postData.add(new BasicNameValuePair("bIsCompany", "0"));
+        postData.add(new BasicNameValuePair("submit", "Logga in"));
+        return new LoginPackage(urlopen, postData, response, API_URL + "index/");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+            if (!response.contains("Logga ut")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            response = urlopen.open(API_URL + "services/");
+            Matcher mSaldoUrl = reSaldoUrl.matcher(response);
+            while (mSaldoUrl.find()) {
+                String account = mSaldoUrl.group(1);
+                String r = urlopen.open(API_URL + "voip/digisipbalance/iPhoneProviderID/" + account + "/");
+                Matcher mSaldo = reSaldo.matcher(r);
+                if(mSaldo.find()) {
+                    accounts.add(new Account(account,
+                            Helpers.parseBalance(mSaldo.group(1)),
+                            account));
+                }
+            }
+        } catch (Exception e) {
+            throw new BankException(e.getMessage());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        try {
+            response = urlopen.open(API_URL + "voip/invoicelist/iPhoneProviderID/" + account.getId());
+            Matcher mInvoiceUrl = reInvoiceUrl.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            int i = 1;
+            while (mInvoiceUrl.find() && i++ <= 2) {
+                try {
+                    String url = mInvoiceUrl.group(1);
+                    String sInvoice = urlopen.open(API_URL + url);
+                    Matcher mTransaction = reTransactions.matcher(sInvoice);
+                    ArrayList<Transaction> tr = new ArrayList<Transaction>();
+                    while(mTransaction.find()) {
+                        tr.add(0, new Transaction(mTransaction.group(2),
+                                mTransaction.group(1) + "  —  " + mTransaction.group(4),
+                                Helpers.parseBalance(mTransaction.group(5)).negate()));
+                    }
+                    //Needed as the list is in reverse order.
+                    transactions.addAll(tr);
+                }
+                catch (Exception e) {
+                    Log.w(TAG, "Unable to parse: " + mInvoiceUrl.group(1));
+                }
+            }
+            account.setTransactions(transactions);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 0c16f43..7ad24a5 100644
--- app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -100,4 +100,5 @@ public interface IBankTypes {
     public final static int SPARBANKERNA = 76;
     public final static int BLEKINGETRAFIKEN = 77;
     public final static int OSTGOTATRAFIKEN = 78;
+    public final static int BREDBAND2VOIP = 79;
 }
diff --git app/src/main/res/drawable/logo_bredband2voip.png app/src/main/res/drawable/logo_bredband2voip.png
new file mode 100644
index 0000000..2d6ac5c
Binary files /dev/null and app/src/main/res/drawable/logo_bredband2voip.png differ
diff --git app/src/main/res/raw/cert_bredband2.pem app/src/main/res/raw/cert_bredband2.pem
new file mode 100644
index 0000000..70bd81b
--- /dev/null
+++ app/src/main/res/raw/cert_bredband2.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+euHPQ+ReZHHFHgtYW244JPa1YzxUj+0pA7j3gTbf+dCDiLCzn+eW
+-----END CERTIFICATE-----
+portal.bredband2.com:443

commit 2ffc769ce796f9f811f6d0951c4dfaaece0ede49
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 21:17:19 2015 +0100

    Moves fromBanktypeId method to LegacyBankFactory.

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index fcdefe2..14129c5 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -17,92 +17,11 @@
 package com.liato.bankdroid.banking;
 
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.database.Cursor;
-import android.preference.PreferenceManager;
 
-import com.liato.bankdroid.banking.banks.AkeliusInvest;
-import com.liato.bankdroid.banking.banks.AkeliusSpar;
-import com.liato.bankdroid.banking.banks.AmericanExpress;
-import com.liato.bankdroid.banking.banks.AppeakPoker;
-import com.liato.bankdroid.banking.banks.Audi;
-import com.liato.bankdroid.banking.banks.AvanzaMini;
-import com.liato.bankdroid.banking.banks.BetterGlobe;
-import com.liato.bankdroid.banking.banks.Bioklubben;
-import com.liato.bankdroid.banking.banks.BrummerKF;
-import com.liato.bankdroid.banking.banks.CSN;
-import com.liato.bankdroid.banking.banks.Chalmrest;
-import com.liato.bankdroid.banking.banks.Chevrolet;
-import com.liato.bankdroid.banking.banks.DanskeBank;
-import com.liato.bankdroid.banking.banks.DinersClub;
-import com.liato.bankdroid.banking.banks.Djurgarden;
-import com.liato.bankdroid.banking.banks.EasyCard;
-import com.liato.bankdroid.banking.banks.EurobonusMastercard;
-import com.liato.bankdroid.banking.banks.EurobonusMastercardDk;
-import com.liato.bankdroid.banking.banks.EurobonusMastercardNo;
-import com.liato.bankdroid.banking.banks.Eurocard;
-import com.liato.bankdroid.banking.banks.Everydaycard;
-import com.liato.bankdroid.banking.banks.FirstCard;
-import com.liato.bankdroid.banking.banks.ForexBank;
-import com.liato.bankdroid.banking.banks.Handelsbanken;
-import com.liato.bankdroid.banking.banks.Hemkop;
-import com.liato.bankdroid.banking.banks.IKEA;
-import com.liato.bankdroid.banking.banks.IkanoBank;
-import com.liato.bankdroid.banking.banks.Jojo;
-import com.liato.bankdroid.banking.banks.Marginalen;
-import com.liato.bankdroid.banking.banks.McDonalds;
-import com.liato.bankdroid.banking.banks.Meniga;
-import com.liato.bankdroid.banking.banks.NordeaDK;
-import com.liato.bankdroid.banking.banks.Nordnet;
-import com.liato.bankdroid.banking.banks.Nordnetdirekt;
-import com.liato.bankdroid.banking.banks.OKQ8;
-import com.liato.bankdroid.banking.banks.Opel;
-import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
-import com.liato.bankdroid.banking.banks.Osuuspankki;
-import com.liato.bankdroid.banking.banks.PayPal;
-import com.liato.bankdroid.banking.banks.PlusGirot;
-import com.liato.bankdroid.banking.banks.Preem;
-import com.liato.bankdroid.banking.banks.Quintessentially;
-import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.seb.SEB;
-import com.liato.bankdroid.banking.banks.SJPrio;
-import com.liato.bankdroid.banking.banks.Saab;
-import com.liato.bankdroid.banking.banks.Seat;
-import com.liato.bankdroid.banking.banks.SevenDay;
-import com.liato.bankdroid.banking.banks.Shell;
-import com.liato.bankdroid.banking.banks.Skandiabanken;
-import com.liato.bankdroid.banking.banks.Skoda;
-import com.liato.bankdroid.banking.banks.SparbankenOresund;
-import com.liato.bankdroid.banking.banks.SparbankenSyd;
-import com.liato.bankdroid.banking.banks.Statoil;
-import com.liato.bankdroid.banking.banks.SupremeCard;
-import com.liato.bankdroid.banking.banks.SveaDirekt;
-import com.liato.bankdroid.banking.banks.SvenskaSpel;
-import com.liato.bankdroid.banking.banks.TestBank;
-import com.liato.bankdroid.banking.banks.TicketRikskortet;
-import com.liato.bankdroid.banking.banks.TrustBuddy;
-import com.liato.bankdroid.banking.banks.Vasttrafik;
-import com.liato.bankdroid.banking.banks.Villabanken;
-import com.liato.bankdroid.banking.banks.Volkswagen;
-import com.liato.bankdroid.banking.banks.Volvofinans;
-import com.liato.bankdroid.banking.banks.Wallet;
-import com.liato.bankdroid.banking.banks.Zidisha;
-import com.liato.bankdroid.banking.banks.avanza.Avanza;
-import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
-import com.liato.bankdroid.banking.banks.coop.Coop;
-import com.liato.bankdroid.banking.banks.ica.ICA;
-import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
-import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
-import com.liato.bankdroid.banking.banks.nordea.Nordea;
-import com.liato.bankdroid.banking.banks.payson.Payson;
-import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
-import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
-import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
-import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.provider.IBankTypes;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 
@@ -112,168 +31,7 @@ import java.util.ArrayList;
 public class BankFactory {
 
 	public static Bank fromBanktypeId(int id, Context context) throws BankException {
-		switch (id) {
-        case IBankTypes.TESTBANK:
-            return new TestBank(context);
-        case IBankTypes.AKELIUSINVEST:
-            return new AkeliusInvest(context);
-        case IBankTypes.AKELIUSSPAR:
-            return new AkeliusSpar(context);
-        case IBankTypes.SWEDBANK:
-            return new Swedbank(context);
-		case IBankTypes.NORDEA:
-			return new Nordea(context);
-		case IBankTypes.LANSFORSAKRINGAR:
-			return new Lansforsakringar(context);
-		case IBankTypes.ICABANKEN:
-			return new ICABanken(context);
-		case IBankTypes.HANDELSBANKEN:
-			return new Handelsbanken(context);
-		case IBankTypes.COOP:
-			return new Coop(context);
-		case IBankTypes.ICA:
-			return new ICA(context);
-		case IBankTypes.STATOIL:
-			return new Statoil(context);
-		case IBankTypes.AVANZA:
-			return new Avanza(context);
-		case IBankTypes.VILLABANKEN:
-			return new Villabanken(context);
-        case IBankTypes.AVANZAMINI:
-            return new AvanzaMini(context);
-        case IBankTypes.OKQ8:
-            return new OKQ8(context);
-        case IBankTypes.EUROCARD:
-            return new Eurocard(context);
-        case IBankTypes.FIRSTCARD:
-            return new FirstCard(context);
-        case IBankTypes.PAYPAL:
-            return new PayPal(context);
-        case IBankTypes.PAYSON:
-            return new Payson(context);
-        case IBankTypes.JOJO:
-            return new Jojo(context);
-        //case IBankTypes.STEAM:
-        //    return new Steam(context);
-        case IBankTypes.DINERSCLUB:
-            return new DinersClub(context);
-        case IBankTypes.IKANOBANK:
-            return new IkanoBank(context);
-        case IBankTypes.SASEUROBONUSMASTERCARD:
-        	return new EurobonusMastercard(context);
-        case IBankTypes.SASEUROBONUSMASTERCARD_NO:
-        	return new EurobonusMastercardNo(context);
-        case IBankTypes.SASEUROBONUSMASTERCARD_DK:
-            return new EurobonusMastercardDk(context);
-        case IBankTypes.RIKSLUNCHEN:
-            return new Rikslunchen(context);
-        case IBankTypes.HEMKOP:
-            return new Hemkop(context);
-        case IBankTypes.SEB:
-            return new SEB(context);
-        case IBankTypes.NORDNET:
-            return new Nordnet(context);
-        case IBankTypes.SEVENDAY:
-            return new SevenDay(context);
-        case IBankTypes.OSUUSPANKKI:
-            return new Osuuspankki(context);
-        case IBankTypes.VOLVOFINANS:
-            return new Volvofinans(context);
-        case IBankTypes.CSN:
-            return new CSN(context);
-        case IBankTypes.RESURSBANK:
-            return new ResursBank(context);
-        case IBankTypes.AMERICANEXPRESS:
-            return new AmericanExpress(context);
-        case IBankTypes.MCDONALDS:
-            return new McDonalds(context);
-        case IBankTypes.SAAB:
-            return new Saab(context);
-        case IBankTypes.WALLET:
-            return new Wallet(context);
-        case IBankTypes.CHEVROLET:
-            return new Chevrolet(context);
-        case IBankTypes.SJPRIO:
-            return new SJPrio(context);
-        case IBankTypes.OPEL:
-            return new Opel(context);
-        case IBankTypes.DJURGARDEN:
-            return new Djurgarden(context);
-        case IBankTypes.QUINTESSENTIALLY:
-            return new Quintessentially(context);
-        case IBankTypes.PLUSGIROT:
-            return new PlusGirot(context);
-        case IBankTypes.SHELL:
-            return new Shell(context);
-        case IBankTypes.VOLKSWAGEN:
-            return new Volkswagen(context);
-        case IBankTypes.AUDI:
-            return new Audi(context);
-        case IBankTypes.PREEM:
-            return new Preem(context);
-        case IBankTypes.SEAT:
-            return new Seat(context);
-        case IBankTypes.SKODA:
-            return new Skoda(context);
-        case IBankTypes.IKEA:
-            return new IKEA(context);
-        case IBankTypes.SPARBANKEN_SYD:
-            return new SparbankenSyd(context);
-        case IBankTypes.SPARBANKEN_ORESUND:
-            return new SparbankenOresund(context);
-        case IBankTypes.NORDNETDIREKT:
-            return new Nordnetdirekt(context);
-        case IBankTypes.SKANDIABANKEN:
-            return new Skandiabanken(context);
-        case IBankTypes.DANSKEBANK:
-            return new DanskeBank(context);
-        case IBankTypes.NORDEA_DK:
-        	return new NordeaDK(context);
-        case IBankTypes.VASTTRAFIK:
-            return new Vasttrafik(context);
-        case IBankTypes.EVERYDAYCARD:
-            return new Everydaycard(context);
-        case IBankTypes.MENIGA:
-            return new Meniga(context);
-        case IBankTypes.RIKSKORTET:
-            return new TicketRikskortet(context);
-        case IBankTypes.BIOKLUBBEN:
-            return new Bioklubben(context);
-        case IBankTypes.CHALMREST:
-        	return new Chalmrest(context);
-        case IBankTypes.MARGINALEN:
-            return new Marginalen(context);
-        case IBankTypes.SVENSKASPEL:
-            return new SvenskaSpel(context);
-        case IBankTypes.EASYCARD:
-            return new EasyCard(context);
-        case IBankTypes.APPEAKPOKER:
-            return new AppeakPoker(context);
-        case IBankTypes.TRUSTBUDDY:
-            return new TrustBuddy(context);
-        case IBankTypes.BRUMMER_KF:
-       	    return new BrummerKF(context);
-        case IBankTypes.ZIDISHA:
-       	    return new Zidisha(context);
-        case IBankTypes.BETTERGLOBE:
-        	return new BetterGlobe(context);
-        case IBankTypes.FOREX:
-            return new ForexBank(context);
-        case IBankTypes.BITCOIN:
-            return new Bitcoin(context);
-        case IBankTypes.SVEADIREKT:
-            return new SveaDirekt(context);
-        case IBankTypes.SUPREMECARD:
-            return new SupremeCard(context);
-        case IBankTypes.SPARBANKERNA:
-            return new Sparbankerna(context);
-        case IBankTypes.BLEKINGETRAFIKEN:
-            return new BlekingeTrafiken(context);
-        case IBankTypes.OSTGOTATRAFIKEN:
-            return new Ostgotatrafiken(context);
-		default:
-			throw new BankException("BankType id not found.");
-		}
+		return LegacyBankFactory.fromBanktypeId(id, context);
 	}
 
 
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
index a0446a9..e4856de 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -17,6 +17,7 @@ import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
+import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EasyCard;
@@ -54,6 +55,7 @@ import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skandiabanken;
 import com.liato.bankdroid.banking.banks.Skoda;
+import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.SupremeCard;
@@ -80,11 +82,177 @@ import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.banks.seb.SEB;
 import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
 import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import java.util.ArrayList;
 
 public class LegacyBankFactory {
 
+    public static Bank fromBanktypeId(int id, Context context) throws BankException {
+        switch (id) {
+            case IBankTypes.TESTBANK:
+                return new TestBank(context);
+            case IBankTypes.AKELIUSINVEST:
+                return new AkeliusInvest(context);
+            case IBankTypes.AKELIUSSPAR:
+                return new AkeliusSpar(context);
+            case IBankTypes.SWEDBANK:
+                return new Swedbank(context);
+            case IBankTypes.NORDEA:
+                return new Nordea(context);
+            case IBankTypes.LANSFORSAKRINGAR:
+                return new Lansforsakringar(context);
+            case IBankTypes.ICABANKEN:
+                return new ICABanken(context);
+            case IBankTypes.HANDELSBANKEN:
+                return new Handelsbanken(context);
+            case IBankTypes.COOP:
+                return new Coop(context);
+            case IBankTypes.ICA:
+                return new ICA(context);
+            case IBankTypes.STATOIL:
+                return new Statoil(context);
+            case IBankTypes.AVANZA:
+                return new Avanza(context);
+            case IBankTypes.VILLABANKEN:
+                return new Villabanken(context);
+            case IBankTypes.AVANZAMINI:
+                return new AvanzaMini(context);
+            case IBankTypes.OKQ8:
+                return new OKQ8(context);
+            case IBankTypes.EUROCARD:
+                return new Eurocard(context);
+            case IBankTypes.FIRSTCARD:
+                return new FirstCard(context);
+            case IBankTypes.PAYPAL:
+                return new PayPal(context);
+            case IBankTypes.PAYSON:
+                return new Payson(context);
+            case IBankTypes.JOJO:
+                return new Jojo(context);
+            //case IBankTypes.STEAM:
+            //    return new Steam(context);
+            case IBankTypes.DINERSCLUB:
+                return new DinersClub(context);
+            case IBankTypes.IKANOBANK:
+                return new IkanoBank(context);
+            case IBankTypes.SASEUROBONUSMASTERCARD:
+                return new EurobonusMastercard(context);
+            case IBankTypes.SASEUROBONUSMASTERCARD_NO:
+                return new EurobonusMastercardNo(context);
+            case IBankTypes.SASEUROBONUSMASTERCARD_DK:
+                return new EurobonusMastercardDk(context);
+            case IBankTypes.RIKSLUNCHEN:
+                return new Rikslunchen(context);
+            case IBankTypes.HEMKOP:
+                return new Hemkop(context);
+            case IBankTypes.SEB:
+                return new SEB(context);
+            case IBankTypes.NORDNET:
+                return new Nordnet(context);
+            case IBankTypes.SEVENDAY:
+                return new SevenDay(context);
+            case IBankTypes.OSUUSPANKKI:
+                return new Osuuspankki(context);
+            case IBankTypes.VOLVOFINANS:
+                return new Volvofinans(context);
+            case IBankTypes.CSN:
+                return new CSN(context);
+            case IBankTypes.RESURSBANK:
+                return new ResursBank(context);
+            case IBankTypes.AMERICANEXPRESS:
+                return new AmericanExpress(context);
+            case IBankTypes.MCDONALDS:
+                return new McDonalds(context);
+            case IBankTypes.SAAB:
+                return new Saab(context);
+            case IBankTypes.WALLET:
+                return new Wallet(context);
+            case IBankTypes.CHEVROLET:
+                return new Chevrolet(context);
+            case IBankTypes.SJPRIO:
+                return new SJPrio(context);
+            case IBankTypes.OPEL:
+                return new Opel(context);
+            case IBankTypes.DJURGARDEN:
+                return new Djurgarden(context);
+            case IBankTypes.QUINTESSENTIALLY:
+                return new Quintessentially(context);
+            case IBankTypes.PLUSGIROT:
+                return new PlusGirot(context);
+            case IBankTypes.SHELL:
+                return new Shell(context);
+            case IBankTypes.VOLKSWAGEN:
+                return new Volkswagen(context);
+            case IBankTypes.AUDI:
+                return new Audi(context);
+            case IBankTypes.PREEM:
+                return new Preem(context);
+            case IBankTypes.SEAT:
+                return new Seat(context);
+            case IBankTypes.SKODA:
+                return new Skoda(context);
+            case IBankTypes.IKEA:
+                return new IKEA(context);
+            case IBankTypes.SPARBANKEN_SYD:
+                return new SparbankenSyd(context);
+            case IBankTypes.SPARBANKEN_ORESUND:
+                return new SparbankenOresund(context);
+            case IBankTypes.NORDNETDIREKT:
+                return new Nordnetdirekt(context);
+            case IBankTypes.SKANDIABANKEN:
+                return new Skandiabanken(context);
+            case IBankTypes.DANSKEBANK:
+                return new DanskeBank(context);
+            case IBankTypes.NORDEA_DK:
+                return new NordeaDK(context);
+            case IBankTypes.VASTTRAFIK:
+                return new Vasttrafik(context);
+            case IBankTypes.EVERYDAYCARD:
+                return new Everydaycard(context);
+            case IBankTypes.MENIGA:
+                return new Meniga(context);
+            case IBankTypes.RIKSKORTET:
+                return new TicketRikskortet(context);
+            case IBankTypes.BIOKLUBBEN:
+                return new Bioklubben(context);
+            case IBankTypes.CHALMREST:
+                return new Chalmrest(context);
+            case IBankTypes.MARGINALEN:
+                return new Marginalen(context);
+            case IBankTypes.SVENSKASPEL:
+                return new SvenskaSpel(context);
+            case IBankTypes.EASYCARD:
+                return new EasyCard(context);
+            case IBankTypes.APPEAKPOKER:
+                return new AppeakPoker(context);
+            case IBankTypes.TRUSTBUDDY:
+                return new TrustBuddy(context);
+            case IBankTypes.BRUMMER_KF:
+                return new BrummerKF(context);
+            case IBankTypes.ZIDISHA:
+                return new Zidisha(context);
+            case IBankTypes.BETTERGLOBE:
+                return new BetterGlobe(context);
+            case IBankTypes.FOREX:
+                return new ForexBank(context);
+            case IBankTypes.BITCOIN:
+                return new Bitcoin(context);
+            case IBankTypes.SVEADIREKT:
+                return new SveaDirekt(context);
+            case IBankTypes.SUPREMECARD:
+                return new SupremeCard(context);
+            case IBankTypes.SPARBANKERNA:
+                return new Sparbankerna(context);
+            case IBankTypes.BLEKINGETRAFIKEN:
+                return new BlekingeTrafiken(context);
+            case IBankTypes.OSTGOTATRAFIKEN:
+                return new Ostgotatrafiken(context);
+            default:
+                throw new BankException("BankType id not found.");
+        }
+    }
 
     public static ArrayList<Bank> listBanks(Context context) {
         ArrayList<Bank> banks = new ArrayList<Bank>();

commit e5ce566d66e3bf13ea9807a899e13526776c6358
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 21:11:37 2015 +0100

    Adds Manifest file for legacy module.

diff --git bankdroid-legacy/src/main/AndroidManifest.xml bankdroid-legacy/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..55d6e46
--- /dev/null
+++ bankdroid-legacy/src/main/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.liato.bankdroid.legacy">
+
+    <application android:allowBackup="true" android:label="@string/app_name">
+
+    </application>
+
+</manifest>
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
index daef209..2bbf14e 100644
--- bankdroid-legacy/src/main/res/values/strings.xml
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
 <resources>
-    <string name="app_name">bankdroid-legacy</string>
+    <string name="app_name">bankdroid</string>
 
     <string name="username">Username</string>
     <string name="password">Password</string>

commit 389418603f83966afc9ba7e0073ce37f57e97576
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 21:07:03 2015 +0100

    Moves certificates to new legacy module.

diff --git app/src/main/res/raw/cert_akeliusinvest.pem bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
similarity index 100%
rename from app/src/main/res/raw/cert_akeliusinvest.pem
rename to bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
diff --git app/src/main/res/raw/cert_akeliusspar.pem bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
similarity index 100%
rename from app/src/main/res/raw/cert_akeliusspar.pem
rename to bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
diff --git app/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
similarity index 100%
rename from app/src/main/res/raw/cert_americanexpress.pem
rename to bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
diff --git app/src/main/res/raw/cert_americanexpress2.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
similarity index 100%
rename from app/src/main/res/raw/cert_americanexpress2.pem
rename to bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
diff --git app/src/main/res/raw/cert_americanexpress_global.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
similarity index 100%
rename from app/src/main/res/raw/cert_americanexpress_global.pem
rename to bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
diff --git app/src/main/res/raw/cert_avanza.pem bankdroid-legacy/src/main/res/raw/cert_avanza.pem
similarity index 100%
rename from app/src/main/res/raw/cert_avanza.pem
rename to bankdroid-legacy/src/main/res/raw/cert_avanza.pem
diff --git app/src/main/res/raw/cert_brummer.pem bankdroid-legacy/src/main/res/raw/cert_brummer.pem
similarity index 100%
rename from app/src/main/res/raw/cert_brummer.pem
rename to bankdroid-legacy/src/main/res/raw/cert_brummer.pem
diff --git app/src/main/res/raw/cert_client_seb.p12 bankdroid-legacy/src/main/res/raw/cert_client_seb.p12
similarity index 100%
rename from app/src/main/res/raw/cert_client_seb.p12
rename to bankdroid-legacy/src/main/res/raw/cert_client_seb.p12
diff --git app/src/main/res/raw/cert_coop.pem bankdroid-legacy/src/main/res/raw/cert_coop.pem
similarity index 100%
rename from app/src/main/res/raw/cert_coop.pem
rename to bankdroid-legacy/src/main/res/raw/cert_coop.pem
diff --git app/src/main/res/raw/cert_coop2.pem bankdroid-legacy/src/main/res/raw/cert_coop2.pem
similarity index 100%
rename from app/src/main/res/raw/cert_coop2.pem
rename to bankdroid-legacy/src/main/res/raw/cert_coop2.pem
diff --git app/src/main/res/raw/cert_csn.pem bankdroid-legacy/src/main/res/raw/cert_csn.pem
similarity index 100%
rename from app/src/main/res/raw/cert_csn.pem
rename to bankdroid-legacy/src/main/res/raw/cert_csn.pem
diff --git app/src/main/res/raw/cert_danskebank.pem bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_danskebank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
diff --git app/src/main/res/raw/cert_dinersclub.pem bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
similarity index 100%
rename from app/src/main/res/raw/cert_dinersclub.pem
rename to bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
diff --git app/src/main/res/raw/cert_easycard.pem bankdroid-legacy/src/main/res/raw/cert_easycard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_easycard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_easycard.pem
diff --git app/src/main/res/raw/cert_eurocard.pem bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_eurocard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
diff --git app/src/main/res/raw/cert_everydaycard.pem bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_everydaycard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
diff --git app/src/main/res/raw/cert_firstcard.pem bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_firstcard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
diff --git app/src/main/res/raw/cert_forexbank.pem bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_forexbank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
diff --git app/src/main/res/raw/cert_handelsbanken.pem bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_handelsbanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
diff --git app/src/main/res/raw/cert_hemkop.pem bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
similarity index 100%
rename from app/src/main/res/raw/cert_hemkop.pem
rename to bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
diff --git app/src/main/res/raw/cert_ica.pem bankdroid-legacy/src/main/res/raw/cert_ica.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ica.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ica.pem
diff --git app/src/main/res/raw/cert_icabanken.pem bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_icabanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
diff --git app/src/main/res/raw/cert_ikanobank.pem bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ikanobank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
diff --git app/src/main/res/raw/cert_ikanopartner.pem bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ikanopartner.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
diff --git app/src/main/res/raw/cert_jojo.pem bankdroid-legacy/src/main/res/raw/cert_jojo.pem
similarity index 100%
rename from app/src/main/res/raw/cert_jojo.pem
rename to bankdroid-legacy/src/main/res/raw/cert_jojo.pem
diff --git app/src/main/res/raw/cert_lansforsakringar.pem bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
similarity index 100%
rename from app/src/main/res/raw/cert_lansforsakringar.pem
rename to bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
diff --git app/src/main/res/raw/cert_marginalen.pem bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
similarity index 100%
rename from app/src/main/res/raw/cert_marginalen.pem
rename to bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
diff --git app/src/main/res/raw/cert_marginalen2.pem bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
similarity index 100%
rename from app/src/main/res/raw/cert_marginalen2.pem
rename to bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
diff --git app/src/main/res/raw/cert_meniga.pem bankdroid-legacy/src/main/res/raw/cert_meniga.pem
similarity index 100%
rename from app/src/main/res/raw/cert_meniga.pem
rename to bankdroid-legacy/src/main/res/raw/cert_meniga.pem
diff --git app/src/main/res/raw/cert_mobilbanken.pem bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_mobilbanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
diff --git app/src/main/res/raw/cert_nordea_dk.pem bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
similarity index 100%
rename from app/src/main/res/raw/cert_nordea_dk.pem
rename to bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
diff --git app/src/main/res/raw/cert_nordnet.pem bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
similarity index 100%
rename from app/src/main/res/raw/cert_nordnet.pem
rename to bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
diff --git app/src/main/res/raw/cert_nordnetdirekt.pem bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
similarity index 100%
rename from app/src/main/res/raw/cert_nordnetdirekt.pem
rename to bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
diff --git app/src/main/res/raw/cert_okq8.pem bankdroid-legacy/src/main/res/raw/cert_okq8.pem
similarity index 100%
rename from app/src/main/res/raw/cert_okq8.pem
rename to bankdroid-legacy/src/main/res/raw/cert_okq8.pem
diff --git app/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ostgotatrafiken_login.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
diff --git app/src/main/res/raw/cert_ostgotatrafiken_overview.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
diff --git app/src/main/res/raw/cert_osuuspankki.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
similarity index 100%
rename from app/src/main/res/raw/cert_osuuspankki.pem
rename to bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
diff --git app/src/main/res/raw/cert_osuuspankki_mobile.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
similarity index 100%
rename from app/src/main/res/raw/cert_osuuspankki_mobile.pem
rename to bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
diff --git app/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
similarity index 100%
rename from app/src/main/res/raw/cert_paypal.pem
rename to bankdroid-legacy/src/main/res/raw/cert_paypal.pem
diff --git app/src/main/res/raw/cert_payson.pem bankdroid-legacy/src/main/res/raw/cert_payson.pem
similarity index 100%
rename from app/src/main/res/raw/cert_payson.pem
rename to bankdroid-legacy/src/main/res/raw/cert_payson.pem
diff --git app/src/main/res/raw/cert_plusgirot.pem bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
similarity index 100%
rename from app/src/main/res/raw/cert_plusgirot.pem
rename to bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
diff --git app/src/main/res/raw/cert_resursbank.pem bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_resursbank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
diff --git app/src/main/res/raw/cert_rikslunchen.pem bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
similarity index 100%
rename from app/src/main/res/raw/cert_rikslunchen.pem
rename to bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
diff --git app/src/main/res/raw/cert_seb.pem bankdroid-legacy/src/main/res/raw/cert_seb.pem
similarity index 100%
rename from app/src/main/res/raw/cert_seb.pem
rename to bankdroid-legacy/src/main/res/raw/cert_seb.pem
diff --git app/src/main/res/raw/cert_seb_web.pem bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
similarity index 100%
rename from app/src/main/res/raw/cert_seb_web.pem
rename to bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
diff --git app/src/main/res/raw/cert_sebkort.pem bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
similarity index 100%
rename from app/src/main/res/raw/cert_sebkort.pem
rename to bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
diff --git app/src/main/res/raw/cert_sevenday.pem bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
similarity index 100%
rename from app/src/main/res/raw/cert_sevenday.pem
rename to bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
diff --git app/src/main/res/raw/cert_skandiabanken.pem bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_skandiabanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
diff --git app/src/main/res/raw/cert_steam.pem bankdroid-legacy/src/main/res/raw/cert_steam.pem
similarity index 100%
rename from app/src/main/res/raw/cert_steam.pem
rename to bankdroid-legacy/src/main/res/raw/cert_steam.pem
diff --git app/src/main/res/raw/cert_sveadirekt.pem bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
similarity index 100%
rename from app/src/main/res/raw/cert_sveadirekt.pem
rename to bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
diff --git app/src/main/res/raw/cert_svenskaspel.pem bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
similarity index 100%
rename from app/src/main/res/raw/cert_svenskaspel.pem
rename to bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
diff --git app/src/main/res/raw/cert_swedbank.pem bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_swedbank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
diff --git app/src/main/res/raw/cert_ticketrikskortet.pem bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ticketrikskortet.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
diff --git app/src/main/res/raw/cert_trustbuddy.pem bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
similarity index 100%
rename from app/src/main/res/raw/cert_trustbuddy.pem
rename to bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
diff --git app/src/main/res/raw/cert_vasttrafik.pem bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
similarity index 100%
rename from app/src/main/res/raw/cert_vasttrafik.pem
rename to bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
diff --git app/src/main/res/raw/cert_villabanken.pem bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_villabanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
diff --git app/src/main/res/raw/cert_volvofinans.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
similarity index 100%
rename from app/src/main/res/raw/cert_volvofinans.pem
rename to bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
diff --git app/src/main/res/raw/cert_volvofinans_logged_in.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
similarity index 100%
rename from app/src/main/res/raw/cert_volvofinans_logged_in.pem
rename to bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
diff --git app/src/main/res/raw/cert_zidisha.pem bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
similarity index 100%
rename from app/src/main/res/raw/cert_zidisha.pem
rename to bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
diff --git app/src/main/res/raw/loading.html bankdroid-legacy/src/main/res/raw/loading.html
similarity index 100%
rename from app/src/main/res/raw/loading.html
rename to bankdroid-legacy/src/main/res/raw/loading.html
diff --git app/src/main/res/raw/swedbank_transactions.htm bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm
similarity index 100%
rename from app/src/main/res/raw/swedbank_transactions.htm
rename to bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm

commit 5f49e152eabf74ec4d16de2b36a1302a67aa24f8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 21:00:30 2015 +0100

    Temporary moves back certificates due to pull request

diff --git bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem app/src/main/res/raw/cert_akeliusinvest.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
rename to app/src/main/res/raw/cert_akeliusinvest.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem app/src/main/res/raw/cert_akeliusspar.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
rename to app/src/main/res/raw/cert_akeliusspar.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem app/src/main/res/raw/cert_americanexpress.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
rename to app/src/main/res/raw/cert_americanexpress.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem app/src/main/res/raw/cert_americanexpress2.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
rename to app/src/main/res/raw/cert_americanexpress2.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem app/src/main/res/raw/cert_americanexpress_global.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
rename to app/src/main/res/raw/cert_americanexpress_global.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_avanza.pem app/src/main/res/raw/cert_avanza.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_avanza.pem
rename to app/src/main/res/raw/cert_avanza.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_brummer.pem app/src/main/res/raw/cert_brummer.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_brummer.pem
rename to app/src/main/res/raw/cert_brummer.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_client_seb.p12 app/src/main/res/raw/cert_client_seb.p12
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_client_seb.p12
rename to app/src/main/res/raw/cert_client_seb.p12
diff --git bankdroid-legacy/src/main/res/raw/cert_coop.pem app/src/main/res/raw/cert_coop.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_coop.pem
rename to app/src/main/res/raw/cert_coop.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_coop2.pem app/src/main/res/raw/cert_coop2.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_coop2.pem
rename to app/src/main/res/raw/cert_coop2.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_csn.pem app/src/main/res/raw/cert_csn.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_csn.pem
rename to app/src/main/res/raw/cert_csn.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_danskebank.pem app/src/main/res/raw/cert_danskebank.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
rename to app/src/main/res/raw/cert_danskebank.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem app/src/main/res/raw/cert_dinersclub.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
rename to app/src/main/res/raw/cert_dinersclub.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_easycard.pem app/src/main/res/raw/cert_easycard.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_easycard.pem
rename to app/src/main/res/raw/cert_easycard.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_eurocard.pem app/src/main/res/raw/cert_eurocard.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
rename to app/src/main/res/raw/cert_eurocard.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem app/src/main/res/raw/cert_everydaycard.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
rename to app/src/main/res/raw/cert_everydaycard.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_firstcard.pem app/src/main/res/raw/cert_firstcard.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
rename to app/src/main/res/raw/cert_firstcard.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_forexbank.pem app/src/main/res/raw/cert_forexbank.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
rename to app/src/main/res/raw/cert_forexbank.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem app/src/main/res/raw/cert_handelsbanken.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
rename to app/src/main/res/raw/cert_handelsbanken.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_hemkop.pem app/src/main/res/raw/cert_hemkop.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
rename to app/src/main/res/raw/cert_hemkop.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_ica.pem app/src/main/res/raw/cert_ica.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_ica.pem
rename to app/src/main/res/raw/cert_ica.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_icabanken.pem app/src/main/res/raw/cert_icabanken.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
rename to app/src/main/res/raw/cert_icabanken.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem app/src/main/res/raw/cert_ikanobank.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
rename to app/src/main/res/raw/cert_ikanobank.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem app/src/main/res/raw/cert_ikanopartner.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
rename to app/src/main/res/raw/cert_ikanopartner.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_jojo.pem app/src/main/res/raw/cert_jojo.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_jojo.pem
rename to app/src/main/res/raw/cert_jojo.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem app/src/main/res/raw/cert_lansforsakringar.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
rename to app/src/main/res/raw/cert_lansforsakringar.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_marginalen.pem app/src/main/res/raw/cert_marginalen.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
rename to app/src/main/res/raw/cert_marginalen.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem app/src/main/res/raw/cert_marginalen2.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
rename to app/src/main/res/raw/cert_marginalen2.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_meniga.pem app/src/main/res/raw/cert_meniga.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_meniga.pem
rename to app/src/main/res/raw/cert_meniga.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem app/src/main/res/raw/cert_mobilbanken.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
rename to app/src/main/res/raw/cert_mobilbanken.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem app/src/main/res/raw/cert_nordea_dk.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
rename to app/src/main/res/raw/cert_nordea_dk.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_nordnet.pem app/src/main/res/raw/cert_nordnet.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
rename to app/src/main/res/raw/cert_nordnet.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem app/src/main/res/raw/cert_nordnetdirekt.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
rename to app/src/main/res/raw/cert_nordnetdirekt.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_okq8.pem app/src/main/res/raw/cert_okq8.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_okq8.pem
rename to app/src/main/res/raw/cert_okq8.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem app/src/main/res/raw/cert_ostgotatrafiken_login.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
rename to app/src/main/res/raw/cert_ostgotatrafiken_login.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
rename to app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem app/src/main/res/raw/cert_osuuspankki.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
rename to app/src/main/res/raw/cert_osuuspankki.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem app/src/main/res/raw/cert_osuuspankki_mobile.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
rename to app/src/main/res/raw/cert_osuuspankki_mobile.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_paypal.pem app/src/main/res/raw/cert_paypal.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_paypal.pem
rename to app/src/main/res/raw/cert_paypal.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_payson.pem app/src/main/res/raw/cert_payson.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_payson.pem
rename to app/src/main/res/raw/cert_payson.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem app/src/main/res/raw/cert_plusgirot.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
rename to app/src/main/res/raw/cert_plusgirot.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_resursbank.pem app/src/main/res/raw/cert_resursbank.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
rename to app/src/main/res/raw/cert_resursbank.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem app/src/main/res/raw/cert_rikslunchen.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
rename to app/src/main/res/raw/cert_rikslunchen.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_seb.pem app/src/main/res/raw/cert_seb.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_seb.pem
rename to app/src/main/res/raw/cert_seb.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_seb_web.pem app/src/main/res/raw/cert_seb_web.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
rename to app/src/main/res/raw/cert_seb_web.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_sebkort.pem app/src/main/res/raw/cert_sebkort.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
rename to app/src/main/res/raw/cert_sebkort.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_sevenday.pem app/src/main/res/raw/cert_sevenday.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
rename to app/src/main/res/raw/cert_sevenday.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem app/src/main/res/raw/cert_skandiabanken.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
rename to app/src/main/res/raw/cert_skandiabanken.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_steam.pem app/src/main/res/raw/cert_steam.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_steam.pem
rename to app/src/main/res/raw/cert_steam.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem app/src/main/res/raw/cert_sveadirekt.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
rename to app/src/main/res/raw/cert_sveadirekt.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem app/src/main/res/raw/cert_svenskaspel.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
rename to app/src/main/res/raw/cert_svenskaspel.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_swedbank.pem app/src/main/res/raw/cert_swedbank.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
rename to app/src/main/res/raw/cert_swedbank.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem app/src/main/res/raw/cert_ticketrikskortet.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
rename to app/src/main/res/raw/cert_ticketrikskortet.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem app/src/main/res/raw/cert_trustbuddy.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
rename to app/src/main/res/raw/cert_trustbuddy.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem app/src/main/res/raw/cert_vasttrafik.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
rename to app/src/main/res/raw/cert_vasttrafik.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_villabanken.pem app/src/main/res/raw/cert_villabanken.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
rename to app/src/main/res/raw/cert_villabanken.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem app/src/main/res/raw/cert_volvofinans.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
rename to app/src/main/res/raw/cert_volvofinans.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem app/src/main/res/raw/cert_volvofinans_logged_in.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
rename to app/src/main/res/raw/cert_volvofinans_logged_in.pem
diff --git bankdroid-legacy/src/main/res/raw/cert_zidisha.pem app/src/main/res/raw/cert_zidisha.pem
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
rename to app/src/main/res/raw/cert_zidisha.pem
diff --git bankdroid-legacy/src/main/res/raw/loading.html app/src/main/res/raw/loading.html
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/loading.html
rename to app/src/main/res/raw/loading.html
diff --git bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm app/src/main/res/raw/swedbank_transactions.htm
similarity index 100%
rename from bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm
rename to app/src/main/res/raw/swedbank_transactions.htm

commit a3192780f6145fc46d8f5d299586609668a16c65
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 19:23:56 2015 +0100

    Moves save and disable bank logic into DbAdapter.

diff --git app/src/main/java/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
index 623c056..8be1073 100644
--- app/src/main/java/com/liato/bankdroid/BankEditActivity.java
+++ app/src/main/java/com/liato/bankdroid/BankEditActivity.java
@@ -53,6 +53,7 @@ import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
 
 public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private final static String TAG = "BankEditActivity";
@@ -233,7 +234,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 				bank.update();
 				bank.updateAllTransactions();
 				bank.closeConnection();
-				bank.save();
+				DBAdapter.save(bank, context);
 
 				// Transactions updated.
 				final SharedPreferences prefs = PreferenceManager
diff --git app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
index 76a42c9..7ea837b 100644
--- app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
+++ app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
 
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
     private final static String TAG = "DataRetrieverTask";
@@ -87,7 +88,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 				bank.update();
 				bank.updateAllTransactions();
 				bank.closeConnection();
-				bank.save();
+				DBAdapter.save(bank, parent);
 				i++;
 			} catch (final BankException e) {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
@@ -95,7 +96,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 			} catch (final LoginException e) {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
 						+ ")");
-				bank.disable();
+				DBAdapter.disable(bank, parent);
 			}
             catch (BankChoiceException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 2450748..002a3e7 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -81,7 +81,7 @@ public class MainActivity extends LockableActivity {
 				} else if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
 					selected_bank.toggleHideAccounts();
-					selected_bank.save();
+					DBAdapter.save(selected_bank, MainActivity.this);
 					refreshView();
 					return true;
 				}
@@ -271,7 +271,7 @@ public class MainActivity extends LockableActivity {
 			case R.id.btnUnhide:
 				this.dismiss();
 				selected_bank.toggleHideAccounts();
-				selected_bank.save();
+				DBAdapter.save(selected_bank, context);
 				parent.refreshView();
 				return;
 			case R.id.btnWWW:
@@ -379,25 +379,25 @@ public class MainActivity extends LockableActivity {
 			case R.id.btnHide:
 				this.dismiss();
 				selected_account.setHidden(true);
-				selected_account.getBank().save();
+				DBAdapter.save(selected_account.getBank(), parent);
 				parent.refreshView();
 				return;
 			case R.id.btnUnhide:
 				this.dismiss();
 				selected_account.setHidden(false);
-				selected_account.getBank().save();
+				DBAdapter.save(selected_account.getBank(), parent);
 				parent.refreshView();
 				return;
 			case R.id.btnEnableNotifications:
 				this.dismiss();
 				selected_account.setNotify(true);
-				selected_account.getBank().save();
+				DBAdapter.save(selected_account.getBank(), parent);
 				parent.refreshView();
 				return;
 			case R.id.btnDisableNotifications:
 				this.dismiss();
 				selected_account.setNotify(false);
-				selected_account.getBank().save();
+				DBAdapter.save(selected_account.getBank(), parent);
 				parent.refreshView();
 				return;
 
diff --git app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 15397ee..999e1d2 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -43,6 +43,7 @@ import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
 
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 	private final static String TAG = "BankdroidWidgetProvider";
@@ -363,7 +364,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 						    bank.updateAllTransactions();
 						}
 						bank.closeConnection();
-						bank.save();
+						DBAdapter.save(bank, context);
 					}
 
 				} 
@@ -371,7 +372,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
     				Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
 				} catch (LoginException e) {
 					Log.e("", "Disabling bank: "+bank.getDbId());
-					bank.disable();
+					DBAdapter.disable(bank,context);
 				}
                 catch (BankChoiceException e) {
                     Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index e851c49..ed3f2ef 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -221,6 +221,28 @@ public class DBAdapter {
     	}
 		return c;
     }
-    
+
+    /**
+    * @deprecated Only used during refactoring. Should be removed before next major version (2.0)
+    */
+    @Deprecated
+    public static void save(Bank bank, Context context) {
+        DBAdapter db = new DBAdapter(context);
+        db.open();
+        long id = db.updateBank(bank);
+        db.close();
+        bank.setDbid(id);
+    }
+
+    /**
+    * @deprecated Only used during refactoring. Should be removed before next major version (2.0)
+    */
+    @Deprecated
+    public static void disable(Bank bank, Context context) {
+                    DBAdapter db = new DBAdapter(context);
+                    db.open();
+                    db.disableBank(bank.getDbId());
+                    db.close();
+               }
 
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index 815d1f6..6de97a4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -38,7 +38,6 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
@@ -236,12 +235,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return disabled;
     }
 
-    public void disable() {
-        DBAdapter db = new DBAdapter(context);
-        db.open();
-        db.disableBank(dbid);
-        db.close();
-    }
 
     public void setDisabled(boolean disabled) {
         this.disabled = disabled;
@@ -256,13 +249,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.username = username;
     }
 
-    public void save() {
-        DBAdapter db = new DBAdapter(context);
-        db.open();
-        dbid = db.updateBank(this); // Update ID on insert as well.
-        db.close();
-    }
-
     public String getURL() {
         return URL;
     }

commit 0236a09289b129bce824e6fd20a5f1a80bbfb559
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 18:58:24 2015 +0100

    Refactor BankFactory for later use in next major version.

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 25acf07..fcdefe2 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -278,91 +278,7 @@ public class BankFactory {
 
 
 	public static ArrayList<Bank> listBanks(Context context) {
-		ArrayList<Bank> banks = new ArrayList<Bank>();
-		banks.add(new AkeliusInvest(context));
-		banks.add(new AkeliusSpar(context));
-		banks.add(new TrustBuddy(context));
-		banks.add(new BrummerKF(context));
-		banks.add(new Swedbank(context));
-		banks.add(new Nordea(context));
-		banks.add(new ICABanken(context));
-		banks.add(new Lansforsakringar(context));
-		banks.add(new Handelsbanken(context));
-		banks.add(new Coop(context));
-		banks.add(new ICA(context));
-		banks.add(new Statoil(context));
-		banks.add(new Avanza(context));
-		banks.add(new Villabanken(context));
-		banks.add(new AvanzaMini(context));
-        banks.add(new OKQ8(context));
-		banks.add(new Eurocard(context));
-        banks.add(new FirstCard(context));
-        banks.add(new PayPal(context));
-        banks.add(new Payson(context));
-        banks.add(new Jojo(context));
-        //banks.add(new Steam(context));
-        banks.add(new DinersClub(context));
-        banks.add(new IkanoBank(context));
-        banks.add(new EurobonusMastercard(context));
-        banks.add(new Rikslunchen(context));
-        banks.add(new Hemkop(context));
-        banks.add(new SEB(context));
-        banks.add(new Nordnet(context));
-        banks.add(new SevenDay(context));
-        banks.add(new Osuuspankki(context));
-        banks.add(new Volvofinans(context));
-        banks.add(new CSN(context));
-        banks.add(new ResursBank(context));
-        banks.add(new McDonalds(context));
-        banks.add(new SJPrio(context));
-        banks.add(new SparbankenSyd(context));
-//        banks.add(new SparbankenOresund(context));
-        banks.add(new Opel(context));
-        banks.add(new Skandiabanken(context));
-        banks.add(new AmericanExpress(context));
-        banks.add(new PlusGirot(context));
-        banks.add(new Nordnetdirekt(context));
-        banks.add(new Saab(context));
-        banks.add(new Wallet(context));
-        banks.add(new Chevrolet(context));
-        banks.add(new Djurgarden(context));
-        banks.add(new Quintessentially(context));
-        banks.add(new Shell(context));
-        banks.add(new Volkswagen(context));
-        banks.add(new Audi(context));
-        banks.add(new Preem(context));
-        banks.add(new Seat(context));
-        banks.add(new Skoda(context));
-        banks.add(new IKEA(context));
-//        banks.add(new DanskeBank(context));
-        banks.add(new NordeaDK(context));
-        banks.add(new Vasttrafik(context));
-        banks.add(new Everydaycard(context));
-        banks.add(new Meniga(context));
-        banks.add(new TicketRikskortet(context));
-        banks.add(new Bioklubben(context));
-        banks.add(new Chalmrest(context));
-        banks.add(new Marginalen(context));
-        banks.add(new SvenskaSpel(context));
-        banks.add(new EasyCard(context));
-        banks.add(new AppeakPoker(context));
-        banks.add(new Zidisha(context));
-        banks.add(new BetterGlobe(context));
-        banks.add(new ForexBank(context));
-        banks.add(new EurobonusMastercardNo(context));
-        banks.add(new Bitcoin(context));
-        banks.add(new EurobonusMastercardDk(context));
-        banks.add(new SveaDirekt(context));
-        banks.add(new SupremeCard(context));
-        banks.add(new Sparbankerna(context));
-        banks.add(new BlekingeTrafiken(context));
-        banks.add(new Ostgotatrafiken(context));
-
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-        if (prefs.getBoolean("debug_mode", false)) { 
-            banks.add(new TestBank(context));
-        }
-		return banks;
+        return LegacyBankFactory.listBanks(context);
 	}
 
 	public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
new file mode 100644
index 0000000..a0446a9
--- /dev/null
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/LegacyBankFactory.java
@@ -0,0 +1,176 @@
+package com.liato.bankdroid.banking;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import com.liato.bankdroid.banking.banks.AkeliusInvest;
+import com.liato.bankdroid.banking.banks.AkeliusSpar;
+import com.liato.bankdroid.banking.banks.AmericanExpress;
+import com.liato.bankdroid.banking.banks.AppeakPoker;
+import com.liato.bankdroid.banking.banks.Audi;
+import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.BetterGlobe;
+import com.liato.bankdroid.banking.banks.Bioklubben;
+import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
+import com.liato.bankdroid.banking.banks.BrummerKF;
+import com.liato.bankdroid.banking.banks.CSN;
+import com.liato.bankdroid.banking.banks.Chalmrest;
+import com.liato.bankdroid.banking.banks.Chevrolet;
+import com.liato.bankdroid.banking.banks.DinersClub;
+import com.liato.bankdroid.banking.banks.Djurgarden;
+import com.liato.bankdroid.banking.banks.EasyCard;
+import com.liato.bankdroid.banking.banks.EurobonusMastercard;
+import com.liato.bankdroid.banking.banks.EurobonusMastercardDk;
+import com.liato.bankdroid.banking.banks.EurobonusMastercardNo;
+import com.liato.bankdroid.banking.banks.Eurocard;
+import com.liato.bankdroid.banking.banks.Everydaycard;
+import com.liato.bankdroid.banking.banks.FirstCard;
+import com.liato.bankdroid.banking.banks.ForexBank;
+import com.liato.bankdroid.banking.banks.Handelsbanken;
+import com.liato.bankdroid.banking.banks.Hemkop;
+import com.liato.bankdroid.banking.banks.IKEA;
+import com.liato.bankdroid.banking.banks.IkanoBank;
+import com.liato.bankdroid.banking.banks.Jojo;
+import com.liato.bankdroid.banking.banks.Marginalen;
+import com.liato.bankdroid.banking.banks.McDonalds;
+import com.liato.bankdroid.banking.banks.Meniga;
+import com.liato.bankdroid.banking.banks.NordeaDK;
+import com.liato.bankdroid.banking.banks.Nordnet;
+import com.liato.bankdroid.banking.banks.Nordnetdirekt;
+import com.liato.bankdroid.banking.banks.OKQ8;
+import com.liato.bankdroid.banking.banks.Opel;
+import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
+import com.liato.bankdroid.banking.banks.Osuuspankki;
+import com.liato.bankdroid.banking.banks.PayPal;
+import com.liato.bankdroid.banking.banks.PlusGirot;
+import com.liato.bankdroid.banking.banks.Preem;
+import com.liato.bankdroid.banking.banks.Quintessentially;
+import com.liato.bankdroid.banking.banks.ResursBank;
+import com.liato.bankdroid.banking.banks.SJPrio;
+import com.liato.bankdroid.banking.banks.Saab;
+import com.liato.bankdroid.banking.banks.Seat;
+import com.liato.bankdroid.banking.banks.SevenDay;
+import com.liato.bankdroid.banking.banks.Shell;
+import com.liato.bankdroid.banking.banks.Skandiabanken;
+import com.liato.bankdroid.banking.banks.Skoda;
+import com.liato.bankdroid.banking.banks.SparbankenSyd;
+import com.liato.bankdroid.banking.banks.Statoil;
+import com.liato.bankdroid.banking.banks.SupremeCard;
+import com.liato.bankdroid.banking.banks.SveaDirekt;
+import com.liato.bankdroid.banking.banks.SvenskaSpel;
+import com.liato.bankdroid.banking.banks.TestBank;
+import com.liato.bankdroid.banking.banks.TicketRikskortet;
+import com.liato.bankdroid.banking.banks.TrustBuddy;
+import com.liato.bankdroid.banking.banks.Vasttrafik;
+import com.liato.bankdroid.banking.banks.Villabanken;
+import com.liato.bankdroid.banking.banks.Volkswagen;
+import com.liato.bankdroid.banking.banks.Volvofinans;
+import com.liato.bankdroid.banking.banks.Wallet;
+import com.liato.bankdroid.banking.banks.Zidisha;
+import com.liato.bankdroid.banking.banks.avanza.Avanza;
+import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
+import com.liato.bankdroid.banking.banks.coop.Coop;
+import com.liato.bankdroid.banking.banks.ica.ICA;
+import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
+import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.nordea.Nordea;
+import com.liato.bankdroid.banking.banks.payson.Payson;
+import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
+import com.liato.bankdroid.banking.banks.seb.SEB;
+import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
+import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
+
+import java.util.ArrayList;
+
+public class LegacyBankFactory {
+
+
+    public static ArrayList<Bank> listBanks(Context context) {
+        ArrayList<Bank> banks = new ArrayList<Bank>();
+        banks.add(new AkeliusInvest(context));
+        banks.add(new AkeliusSpar(context));
+        banks.add(new TrustBuddy(context));
+        banks.add(new BrummerKF(context));
+        banks.add(new Swedbank(context));
+        banks.add(new Nordea(context));
+        banks.add(new ICABanken(context));
+        banks.add(new Lansforsakringar(context));
+        banks.add(new Handelsbanken(context));
+        banks.add(new Coop(context));
+        banks.add(new ICA(context));
+        banks.add(new Statoil(context));
+        banks.add(new Avanza(context));
+        banks.add(new Villabanken(context));
+        banks.add(new AvanzaMini(context));
+        banks.add(new OKQ8(context));
+        banks.add(new Eurocard(context));
+        banks.add(new FirstCard(context));
+        banks.add(new PayPal(context));
+        banks.add(new Payson(context));
+        banks.add(new Jojo(context));
+        //banks.add(new Steam(context));
+        banks.add(new DinersClub(context));
+        banks.add(new IkanoBank(context));
+        banks.add(new EurobonusMastercard(context));
+        banks.add(new Rikslunchen(context));
+        banks.add(new Hemkop(context));
+        banks.add(new SEB(context));
+        banks.add(new Nordnet(context));
+        banks.add(new SevenDay(context));
+        banks.add(new Osuuspankki(context));
+        banks.add(new Volvofinans(context));
+        banks.add(new CSN(context));
+        banks.add(new ResursBank(context));
+        banks.add(new McDonalds(context));
+        banks.add(new SJPrio(context));
+        banks.add(new SparbankenSyd(context));
+//        banks.add(new SparbankenOresund(context));
+        banks.add(new Opel(context));
+        banks.add(new Skandiabanken(context));
+        banks.add(new AmericanExpress(context));
+        banks.add(new PlusGirot(context));
+        banks.add(new Nordnetdirekt(context));
+        banks.add(new Saab(context));
+        banks.add(new Wallet(context));
+        banks.add(new Chevrolet(context));
+        banks.add(new Djurgarden(context));
+        banks.add(new Quintessentially(context));
+        banks.add(new Shell(context));
+        banks.add(new Volkswagen(context));
+        banks.add(new Audi(context));
+        banks.add(new Preem(context));
+        banks.add(new Seat(context));
+        banks.add(new Skoda(context));
+        banks.add(new IKEA(context));
+//        banks.add(new DanskeBank(context));
+        banks.add(new NordeaDK(context));
+        banks.add(new Vasttrafik(context));
+        banks.add(new Everydaycard(context));
+        banks.add(new Meniga(context));
+        banks.add(new TicketRikskortet(context));
+        banks.add(new Bioklubben(context));
+        banks.add(new Chalmrest(context));
+        banks.add(new Marginalen(context));
+        banks.add(new SvenskaSpel(context));
+        banks.add(new EasyCard(context));
+        banks.add(new AppeakPoker(context));
+        banks.add(new Zidisha(context));
+        banks.add(new BetterGlobe(context));
+        banks.add(new ForexBank(context));
+        banks.add(new EurobonusMastercardNo(context));
+        banks.add(new Bitcoin(context));
+        banks.add(new EurobonusMastercardDk(context));
+        banks.add(new SveaDirekt(context));
+        banks.add(new SupremeCard(context));
+        banks.add(new Sparbankerna(context));
+        banks.add(new BlekingeTrafiken(context));
+        banks.add(new Ostgotatrafiken(context));
+
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (prefs.getBoolean("debug_mode", false)) {
+            banks.add(new TestBank(context));
+        }
+        return banks;
+    }
+}

commit 29a9cac22142ae018b3ea8df82c3a3f2add6c623
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 18:56:16 2015 +0100

    Move back BankFactory from legacy module.

diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
similarity index 98%
rename from bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankFactory.java
rename to app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 7948be5..25acf07 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -166,13 +166,13 @@ public class BankFactory {
         case IBankTypes.SASEUROBONUSMASTERCARD_DK:
             return new EurobonusMastercardDk(context);
         case IBankTypes.RIKSLUNCHEN:
-            return new Rikslunchen(context);            
+            return new Rikslunchen(context);
         case IBankTypes.HEMKOP:
-            return new Hemkop(context);            
+            return new Hemkop(context);
         case IBankTypes.SEB:
-            return new SEB(context);            
+            return new SEB(context);
         case IBankTypes.NORDNET:
-            return new Nordnet(context);            
+            return new Nordnet(context);
         case IBankTypes.SEVENDAY:
             return new SevenDay(context);
         case IBankTypes.OSUUSPANKKI:
@@ -275,7 +275,7 @@ public class BankFactory {
 			throw new BankException("BankType id not found.");
 		}
 	}
-	
+
 
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
@@ -381,7 +381,7 @@ public class BankFactory {
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 				}
-				
+
 				bank.setData(c.getString(c.getColumnIndex("username")),
 							 password,
 							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
@@ -419,7 +419,7 @@ public class BankFactory {
 			c.moveToNext();
 			try {
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				
+
 	            String password = "";
                 try {
                     password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
@@ -448,12 +448,12 @@ public class BankFactory {
 		db.close();
 		return banks;
 	}
-	
+
 	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
 		DBAdapter db = new DBAdapter(context);
 		db.open();
 		Cursor c = db.getAccount(accountId);
-       
+
 		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
 			db.close();
 			return null;
@@ -488,11 +488,11 @@ public class BankFactory {
 			}
 			account.setTransactions(transactions);
 		}
-		
+
 		db.close();
 		return account;
 	}
-	
+
 	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
 		ArrayList<Account> accounts = new ArrayList<Account>();
 		DBAdapter db = new DBAdapter(context);
@@ -511,7 +511,7 @@ public class BankFactory {
                                               c.getLong(c.getColumnIndex("bankid")),
                                               c.getInt(c.getColumnIndex("acctype")));
     	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
+    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
                 account.setCurrency(c.getString(c.getColumnIndex("currency")));
                 account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
     			accounts.add(account);
@@ -524,5 +524,5 @@ public class BankFactory {
 		db.close();
 		return accounts;
 	}
-	
+
 }

commit 91a981675247876eab99395bdc2a22dd5c2cc845
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 18:50:12 2015 +0100

    Fixes imports and strings.

diff --git app/build.gradle app/build.gradle
index 8a2fc95..0320dc5 100644
--- app/build.gradle
+++ app/build.gradle
@@ -54,16 +54,5 @@ dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile project(':bankdroid-legacy')
     compile "com.android.support:appcompat-v7:21.0.+"
-    compile 'org.apache.commons:commons-io:1.3.2'
     compile 'com.google.collections:google-collections:1.0'
-    compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
-    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
-    compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
-    compile 'org.jsoup:jsoup:1.7.3'
-    compile('org.simpleframework:simple-xml:2.7.+') {
-        exclude module: 'stax'
-        exclude module: 'stax-api'
-        exclude module: 'xpp3'
-    }
-
 }
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 0300d55..a680c75 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -13,28 +13,14 @@
     <string name="could_not_create_account">Kunde ej skapa konto</string>
     <string name="menu_edit">Redigera</string>
     <string name="menu_remove">Radera</string>
-    <string name="invalid_username_password">Användarnamn och lösenord stämmer ej.</string>
-    <string name="invalid_username">Ogiltigt användarnamn.</string>
-    <string name="invalid_card_number">Ogiltigt kortnummer.</string>
-    <string name="invalid_bitcoin_address">Ogiltig bitcoin-adress.</string>
-    <string name="unable_to_find">Kunde ej hitta</string>
-    <string name="no_accounts_found">Inga konton funna</string>
     <string name="transparent_background">Transparent bakgrund</string>
-    <string name="bank_closed">Banken är för närvarande stängd.</string>
-    <string name="unable_to_login">Kunde ej logga in. Var vänlig försök igen senare.</string>
-    <string name="account_number">Kontonummer</string>
-    <string name="control_code">Kontrollkod</string>
-    <string name="server_error_try_again">Serverfel. Var god försök igen om en stund.</string>
     <string name="settings">Inställningar</string>
     <string name="refresh">Uppdatera</string>
     <string name="add_account">Lägg till konto</string>
 
-    <string name="username">Användarnamn</string>
-    <string name="password">Lösenord</string>
     <string name="bank">Bank</string>
     <string name="custom_name">Eget Namn (frivilligt)</string>
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
-    <string name="email">E-post</string>
 
     <string name="cancel">AVBRYT</string>
     <string name="save">SPARA</string>
@@ -249,12 +235,7 @@
     </string>
 	<string name="lock_cancel">Avbryt</string>
 	<string name="lock_ok">Ok</string>
-    
-	<string name="card_id">Kort ID</string>
-	<string name="card_number">Kortnummer</string>
-	<string name="bitcoin_address">Bitcoin-adress</string>
-		
-	<string name="nordnetdirekt_extras_title">Nyckel</string>
+
 	<string name="select_a_bank">Välj en bank</string>
 	<string name="invalid_integer">%1$s är inte ett giltigt positivt heltal, var god försök igen.</string>
 	<string name="pair_message">Applikationen nedan vill ta del av kontotyp och transaktionsdata från BankDroid.</string>
@@ -263,7 +244,5 @@
 
     <!-- Color Picker -->
     <string name="dialog_color_picker">Färgväljare</string>
-    <string name="press_color_to_apply">Tryck på färgen för att välja</string>    
-    
-    <string name="points">poäng</string>
+    <string name="press_color_to_apply">Tryck på färgen för att välja</string>
 </resources>
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index b649b81..656a126 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -12,29 +12,16 @@
     <string name="could_not_create_account">Could not create account</string>
     <string name="menu_edit">Edit</string>
     <string name="menu_remove">Remove</string>
-    <string name="invalid_username_password">Invalid username or password.</string>
-    <string name="invalid_username">Invalid username.</string>
-    <string name="invalid_card_number">Invalid card number.</string>
-    <string name="invalid_bitcoin_address">Invalid bitcoin address.</string>
-    <string name="unable_to_find">Unable to find</string>
-    <string name="no_accounts_found">No accounts found</string>
     <string name="transparent_background">Transparent background</string>
-    <string name="bank_closed">The bank is currently closed.</string>
-    <string name="unable_to_login">Unable to login. Please try again later.</string>
-    <string name="account_number">Account number</string>
-    <string name="control_code">Control code</string>
-    <string name="server_error_try_again">Server error. Please try again later.</string>
     <string name="settings">Settings</string>
     <string name="refresh">Refresh</string>
     <string name="add_account">Add account</string>
 
-    <string name="username">Username</string>
-    <string name="password">Password</string>
+
     <string name="custom_name">Custom Name (optional)</string>
-    <string name="extras_field">Extras</string>
+
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
-    <string name="email">E-mail</string>
 
     <string name="cancel">CANCEL</string>
     <string name="save">SAVE</string>
@@ -300,16 +287,10 @@
     </string>
 	<string name="lock_cancel">Cancel</string>
 	<string name="lock_ok">Ok</string>
-         
-	<string name="card_id">Card ID</string>
-	<string name="card_number">Card number</string>
-	<string name="bitcoin_address">Bitcoin address</string>
-    <string name="cvc">CVC</string>
 
 	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 
-	<string name="nordnetdirekt_extras_title">Key</string>
 	<string name="select_a_bank">Select a bank</string>
 	<string name="invalid_integer">%1$s is not a valid positive integer, please try again.</string>
 	<string name="pair_message">The Application below wants to access account types and transaction data from BankDroid.</string>
@@ -319,6 +300,4 @@
     <!-- Color Picker -->
     <string name="dialog_color_picker">Color Picker</string>
     <string name="press_color_to_apply">Press on Color to apply</string>    
-    
-    <string name="points">points</string>
 </resources>
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
index e92300a..021b743 100644
--- bankdroid-legacy/build.gradle
+++ bankdroid-legacy/build.gradle
@@ -20,5 +20,15 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:21.0.3'
+    compile 'com.android.support:appcompat-v7:21.0.+'
+    compile 'org.apache.commons:commons-io:1.3.2'
+    compile 'org.jsoup:jsoup:1.7.3'
+    compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
+    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
+    compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
+    compile('org.simpleframework:simple-xml:2.7.+') {
+        exclude module: 'stax'
+        exclude module: 'stax-api'
+        exclude module: 'xpp3'
+    }
 }
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
index b53e49d..6fdb08c 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
@@ -36,6 +36,8 @@ import android.os.Build;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import com.liato.bankdroid.legacy.R;
+
 public class Helpers {
 	private static String USER_AGENT;
     private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD",
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index e3fb62c..e4c0f39 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -33,13 +33,13 @@ import android.text.InputType;
 import android.text.TextUtils;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 2326e01..3c82866 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -32,13 +32,13 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.CertificateReader;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index f51b6cf..0a5e9a3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -33,13 +33,13 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.CertificateReader;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index c81adfa..4dee0a2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -36,13 +36,13 @@ import android.text.Html;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.CertificateReader;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 71a62b6..4d0a689 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -30,7 +30,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 66c17f1..1168f73 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -32,7 +32,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index a9008b4..2003d56 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -19,7 +19,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index f375c49..8edc402 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -20,7 +20,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
index 87862aa..cedfc50 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -33,7 +33,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
index 4f74059..fd8d791 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
@@ -34,7 +34,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index a0b561c..310baf9 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -14,7 +14,7 @@ import org.apache.http.util.EntityUtils;
 import android.content.Context;
 import android.text.InputType;
 
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
index 8f8eed8..be53510 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -34,7 +34,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
index e0d7c1c..d7a631e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -31,7 +31,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
index 2c85e57..18d15d3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -15,7 +15,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
index ce648e7..094e75a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -18,7 +18,7 @@ package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
 
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
index 4770b07..2c34bc2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -32,7 +32,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 //import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
index 7239948..ec6c37e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -31,7 +31,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
index 06a6872..ccd55bc 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -19,7 +19,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 761bf2d..1731f5d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -35,7 +35,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
index edbaf34..320cf59 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -36,7 +36,7 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
index 1890dca..0102ac4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -32,7 +32,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index cc034c5..0e5755a 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -20,7 +20,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index c6c1ee4..ec47e5d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -16,7 +16,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
index 75df832..f72ef15 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -31,7 +31,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
index c14f3b8..6152ef4 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
@@ -4,7 +4,7 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 9961bb3..97e21a5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -32,7 +32,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
index 93d8af5..98d235d 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -17,7 +17,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
index 7dacb9c..2f1879e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -34,7 +34,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index d170c48..b79ca02 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -31,7 +31,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
index 51e53dc..825179e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -33,7 +33,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
index aba1105..373a86f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -29,7 +29,7 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 705fa5b..6a515eb 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -30,7 +30,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index c60b754..85c3711 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -35,7 +35,7 @@ import android.text.InputType;
 import android.text.TextUtils;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index a3bc952..725f0bd 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -30,7 +30,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
index f1fca98..3e13029 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -31,7 +31,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
index 69d85ef..f654a64 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -31,7 +31,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 3b76c0d..7152155 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -20,7 +20,7 @@ import android.provider.Settings.Secure;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
index 6c9a97e..5dfe5ae 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
@@ -36,7 +36,7 @@ import android.text.Html;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
index aaa5799..2a6c739 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
@@ -2,7 +2,7 @@ package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
 
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 34f2bf6..770f9c1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -4,7 +4,7 @@ import android.content.Context;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.Bank;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index f297567..5fdbba5 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -32,7 +32,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
index c30dd55..a99d0f2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
@@ -28,7 +28,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 8b5b449..fc73647 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -30,7 +30,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
index b2614e0..715dcc6 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -32,7 +32,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index f47582e..5cbfb35 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -30,7 +30,7 @@ import android.content.Context;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
index c1f5e6f..91dc7f2 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -29,7 +29,7 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
index 7d223c6..6595f55 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -41,7 +41,7 @@ import android.content.Context;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
index e08b654..2028cb0 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -31,7 +31,7 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 4d01e6b..03cd4a1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -23,7 +23,7 @@ import android.util.Base64;
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 0feb7bd..706a562 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -28,7 +28,7 @@ import android.text.TextUtils;
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.bitcoin.model.BlockchainResponse;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index c011976..fc1b496 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -24,7 +24,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
index bf618fd..7e3efe1 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -23,7 +23,7 @@ import android.util.Base64;
 
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 4034fef..f9c318b 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -29,7 +29,7 @@ import android.os.Build;
 import android.text.InputType;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 45f0579..fb3ab50 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -41,7 +41,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 6db0eb5..608848f 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -33,7 +33,7 @@ import android.text.Html;
 import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
index baf607c..78feb20 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
@@ -25,7 +25,7 @@ import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 6003b70..1b3577e 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -21,7 +21,7 @@ import android.text.InputType;
 import android.text.TextUtils;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.rikslunchen.model.Envelope;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
index 5042a9b..e0d4d91 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -23,7 +23,7 @@ import android.util.Log;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.seb.model.DEVID;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 8a2ec23..7b2e397 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -24,7 +24,7 @@ import android.text.TextUtils;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
diff --git bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index b101cfc..da660f3 100644
--- bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -9,7 +9,7 @@ import android.util.Base64;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankChoice;
diff --git bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index ae10b8a..881bdb8 100644
--- bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -24,8 +24,7 @@ import android.content.res.Configuration;
 import android.os.Build;
 import android.preference.PreferenceManager;
 
-import com.liato.bankdroid.BuildConfig;
-import com.liato.bankdroid.R;
+import com.liato.bankdroid.legacy.R;
 
 import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpEntity;
diff --git bankdroid-legacy/src/main/res/values-se/strings.xml bankdroid-legacy/src/main/res/values-se/strings.xml
new file mode 100644
index 0000000..0fb9cfc
--- /dev/null
+++ bankdroid-legacy/src/main/res/values-se/strings.xml
@@ -0,0 +1,25 @@
+<resources>
+    <string name="username">Användarnamn</string>
+    <string name="password">Lösenord</string>
+    <string name="card_number">Kortnummer</string>
+    <string name="account_number">Kontonummer</string>
+    <string name="control_code">Kontrollkod</string>
+    <string name="email">E-post</string>
+    <string name="points">poäng</string>
+    <string name="card_id">Kort ID</string>
+
+    <string name="nordnetdirekt_extras_title">Nyckel</string>
+
+    <string name="bitcoin_address">Bitcoin-adress</string>
+    <string name="invalid_bitcoin_address">Ogiltig bitcoin-adress.</string>
+
+    <string name="unable_to_find">Kunde ej hitta</string>
+    <string name="unable_to_login">Kunde ej logga in. Var vänlig försök igen senare.</string>
+    <string name="invalid_username_password">Användarnamn och lösenord stämmer ej.</string>
+    <string name="no_accounts_found">Inga konton funna</string>
+    <string name="invalid_username">Ogiltigt användarnamn.</string>
+    <string name="invalid_card_number">Ogiltigt kortnummer.</string>
+    <string name="bank_closed">Banken är för närvarande stängd.</string>
+    <string name="server_error_try_again">Serverfel. Var god försök igen om en stund.</string>
+
+</resources>
diff --git bankdroid-legacy/src/main/res/values/strings.xml bankdroid-legacy/src/main/res/values/strings.xml
new file mode 100644
index 0000000..daef209
--- /dev/null
+++ bankdroid-legacy/src/main/res/values/strings.xml
@@ -0,0 +1,29 @@
+<resources>
+    <string name="app_name">bankdroid-legacy</string>
+
+    <string name="username">Username</string>
+    <string name="password">Password</string>
+    <string name="extras_field">Extras</string>
+    <string name="card_number">Card number</string>
+    <string name="cvc">CVC</string>
+    <string name="account_number">Account number</string>
+    <string name="control_code">Control code</string>
+    <string name="email">E-mail</string>
+    <string name="points">points</string>
+    <string name="card_id">Card ID</string>
+
+    <string name="nordnetdirekt_extras_title">Key</string>
+
+    <string name="bitcoin_address">Bitcoin address</string>
+    <string name="invalid_bitcoin_address">Invalid bitcoin address.</string>
+
+    <string name="unable_to_find">Unable to find</string>
+    <string name="unable_to_login">Unable to login. Please try again later.</string>
+    <string name="invalid_username_password">Invalid username or password.</string>
+    <string name="no_accounts_found">No accounts found</string>
+    <string name="invalid_username">Invalid username.</string>
+    <string name="invalid_card_number">Invalid card number.</string>
+    <string name="bank_closed">The bank is currently closed.</string>
+    <string name="server_error_try_again">Server error. Please try again later.</string>
+
+</resources>

commit 75856916a6bb08d677685b1611ad8a6839224fd9
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 18:48:51 2015 +0100

    Moves utils to legacy module

diff --git app/src/main/java/com/liato/bankdroid/utils/Installation.java bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/utils/Installation.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/utils/Installation.java

commit 241718d229bb0296b93465c27033bc37368ceec5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 18:22:14 2015 +0100

    Moves all certificates to new legacy module.

diff --git app/src/main/res/raw/cert_akeliusinvest.pem bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
similarity index 100%
rename from app/src/main/res/raw/cert_akeliusinvest.pem
rename to bankdroid-legacy/src/main/res/raw/cert_akeliusinvest.pem
diff --git app/src/main/res/raw/cert_akeliusspar.pem bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
similarity index 100%
rename from app/src/main/res/raw/cert_akeliusspar.pem
rename to bankdroid-legacy/src/main/res/raw/cert_akeliusspar.pem
diff --git app/src/main/res/raw/cert_americanexpress.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
similarity index 100%
rename from app/src/main/res/raw/cert_americanexpress.pem
rename to bankdroid-legacy/src/main/res/raw/cert_americanexpress.pem
diff --git app/src/main/res/raw/cert_americanexpress2.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
similarity index 100%
rename from app/src/main/res/raw/cert_americanexpress2.pem
rename to bankdroid-legacy/src/main/res/raw/cert_americanexpress2.pem
diff --git app/src/main/res/raw/cert_americanexpress_global.pem bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
similarity index 100%
rename from app/src/main/res/raw/cert_americanexpress_global.pem
rename to bankdroid-legacy/src/main/res/raw/cert_americanexpress_global.pem
diff --git app/src/main/res/raw/cert_avanza.pem bankdroid-legacy/src/main/res/raw/cert_avanza.pem
similarity index 100%
rename from app/src/main/res/raw/cert_avanza.pem
rename to bankdroid-legacy/src/main/res/raw/cert_avanza.pem
diff --git app/src/main/res/raw/cert_brummer.pem bankdroid-legacy/src/main/res/raw/cert_brummer.pem
similarity index 100%
rename from app/src/main/res/raw/cert_brummer.pem
rename to bankdroid-legacy/src/main/res/raw/cert_brummer.pem
diff --git app/src/main/res/raw/cert_client_seb.p12 bankdroid-legacy/src/main/res/raw/cert_client_seb.p12
similarity index 100%
rename from app/src/main/res/raw/cert_client_seb.p12
rename to bankdroid-legacy/src/main/res/raw/cert_client_seb.p12
diff --git app/src/main/res/raw/cert_coop.pem bankdroid-legacy/src/main/res/raw/cert_coop.pem
similarity index 100%
rename from app/src/main/res/raw/cert_coop.pem
rename to bankdroid-legacy/src/main/res/raw/cert_coop.pem
diff --git app/src/main/res/raw/cert_coop2.pem bankdroid-legacy/src/main/res/raw/cert_coop2.pem
similarity index 100%
rename from app/src/main/res/raw/cert_coop2.pem
rename to bankdroid-legacy/src/main/res/raw/cert_coop2.pem
diff --git app/src/main/res/raw/cert_csn.pem bankdroid-legacy/src/main/res/raw/cert_csn.pem
similarity index 100%
rename from app/src/main/res/raw/cert_csn.pem
rename to bankdroid-legacy/src/main/res/raw/cert_csn.pem
diff --git app/src/main/res/raw/cert_danskebank.pem bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_danskebank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_danskebank.pem
diff --git app/src/main/res/raw/cert_dinersclub.pem bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
similarity index 100%
rename from app/src/main/res/raw/cert_dinersclub.pem
rename to bankdroid-legacy/src/main/res/raw/cert_dinersclub.pem
diff --git app/src/main/res/raw/cert_easycard.pem bankdroid-legacy/src/main/res/raw/cert_easycard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_easycard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_easycard.pem
diff --git app/src/main/res/raw/cert_eurocard.pem bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_eurocard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_eurocard.pem
diff --git app/src/main/res/raw/cert_everydaycard.pem bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_everydaycard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_everydaycard.pem
diff --git app/src/main/res/raw/cert_firstcard.pem bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
similarity index 100%
rename from app/src/main/res/raw/cert_firstcard.pem
rename to bankdroid-legacy/src/main/res/raw/cert_firstcard.pem
diff --git app/src/main/res/raw/cert_forexbank.pem bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_forexbank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_forexbank.pem
diff --git app/src/main/res/raw/cert_handelsbanken.pem bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_handelsbanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_handelsbanken.pem
diff --git app/src/main/res/raw/cert_hemkop.pem bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
similarity index 100%
rename from app/src/main/res/raw/cert_hemkop.pem
rename to bankdroid-legacy/src/main/res/raw/cert_hemkop.pem
diff --git app/src/main/res/raw/cert_ica.pem bankdroid-legacy/src/main/res/raw/cert_ica.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ica.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ica.pem
diff --git app/src/main/res/raw/cert_icabanken.pem bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_icabanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_icabanken.pem
diff --git app/src/main/res/raw/cert_ikanobank.pem bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ikanobank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ikanobank.pem
diff --git app/src/main/res/raw/cert_ikanopartner.pem bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ikanopartner.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ikanopartner.pem
diff --git app/src/main/res/raw/cert_jojo.pem bankdroid-legacy/src/main/res/raw/cert_jojo.pem
similarity index 100%
rename from app/src/main/res/raw/cert_jojo.pem
rename to bankdroid-legacy/src/main/res/raw/cert_jojo.pem
diff --git app/src/main/res/raw/cert_lansforsakringar.pem bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
similarity index 100%
rename from app/src/main/res/raw/cert_lansforsakringar.pem
rename to bankdroid-legacy/src/main/res/raw/cert_lansforsakringar.pem
diff --git app/src/main/res/raw/cert_marginalen.pem bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
similarity index 100%
rename from app/src/main/res/raw/cert_marginalen.pem
rename to bankdroid-legacy/src/main/res/raw/cert_marginalen.pem
diff --git app/src/main/res/raw/cert_marginalen2.pem bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
similarity index 100%
rename from app/src/main/res/raw/cert_marginalen2.pem
rename to bankdroid-legacy/src/main/res/raw/cert_marginalen2.pem
diff --git app/src/main/res/raw/cert_meniga.pem bankdroid-legacy/src/main/res/raw/cert_meniga.pem
similarity index 100%
rename from app/src/main/res/raw/cert_meniga.pem
rename to bankdroid-legacy/src/main/res/raw/cert_meniga.pem
diff --git app/src/main/res/raw/cert_mobilbanken.pem bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_mobilbanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_mobilbanken.pem
diff --git app/src/main/res/raw/cert_nordea_dk.pem bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
similarity index 100%
rename from app/src/main/res/raw/cert_nordea_dk.pem
rename to bankdroid-legacy/src/main/res/raw/cert_nordea_dk.pem
diff --git app/src/main/res/raw/cert_nordnet.pem bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
similarity index 100%
rename from app/src/main/res/raw/cert_nordnet.pem
rename to bankdroid-legacy/src/main/res/raw/cert_nordnet.pem
diff --git app/src/main/res/raw/cert_nordnetdirekt.pem bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
similarity index 100%
rename from app/src/main/res/raw/cert_nordnetdirekt.pem
rename to bankdroid-legacy/src/main/res/raw/cert_nordnetdirekt.pem
diff --git app/src/main/res/raw/cert_okq8.pem bankdroid-legacy/src/main/res/raw/cert_okq8.pem
similarity index 100%
rename from app/src/main/res/raw/cert_okq8.pem
rename to bankdroid-legacy/src/main/res/raw/cert_okq8.pem
diff --git app/src/main/res/raw/cert_ostgotatrafiken_login.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ostgotatrafiken_login.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_login.pem
diff --git app/src/main/res/raw/cert_ostgotatrafiken_overview.pem bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ostgotatrafiken_overview.pem
diff --git app/src/main/res/raw/cert_osuuspankki.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
similarity index 100%
rename from app/src/main/res/raw/cert_osuuspankki.pem
rename to bankdroid-legacy/src/main/res/raw/cert_osuuspankki.pem
diff --git app/src/main/res/raw/cert_osuuspankki_mobile.pem bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
similarity index 100%
rename from app/src/main/res/raw/cert_osuuspankki_mobile.pem
rename to bankdroid-legacy/src/main/res/raw/cert_osuuspankki_mobile.pem
diff --git app/src/main/res/raw/cert_paypal.pem bankdroid-legacy/src/main/res/raw/cert_paypal.pem
similarity index 100%
rename from app/src/main/res/raw/cert_paypal.pem
rename to bankdroid-legacy/src/main/res/raw/cert_paypal.pem
diff --git app/src/main/res/raw/cert_payson.pem bankdroid-legacy/src/main/res/raw/cert_payson.pem
similarity index 100%
rename from app/src/main/res/raw/cert_payson.pem
rename to bankdroid-legacy/src/main/res/raw/cert_payson.pem
diff --git app/src/main/res/raw/cert_plusgirot.pem bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
similarity index 100%
rename from app/src/main/res/raw/cert_plusgirot.pem
rename to bankdroid-legacy/src/main/res/raw/cert_plusgirot.pem
diff --git app/src/main/res/raw/cert_resursbank.pem bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_resursbank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_resursbank.pem
diff --git app/src/main/res/raw/cert_rikslunchen.pem bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
similarity index 100%
rename from app/src/main/res/raw/cert_rikslunchen.pem
rename to bankdroid-legacy/src/main/res/raw/cert_rikslunchen.pem
diff --git app/src/main/res/raw/cert_seb.pem bankdroid-legacy/src/main/res/raw/cert_seb.pem
similarity index 100%
rename from app/src/main/res/raw/cert_seb.pem
rename to bankdroid-legacy/src/main/res/raw/cert_seb.pem
diff --git app/src/main/res/raw/cert_seb_web.pem bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
similarity index 100%
rename from app/src/main/res/raw/cert_seb_web.pem
rename to bankdroid-legacy/src/main/res/raw/cert_seb_web.pem
diff --git app/src/main/res/raw/cert_sebkort.pem bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
similarity index 100%
rename from app/src/main/res/raw/cert_sebkort.pem
rename to bankdroid-legacy/src/main/res/raw/cert_sebkort.pem
diff --git app/src/main/res/raw/cert_sevenday.pem bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
similarity index 100%
rename from app/src/main/res/raw/cert_sevenday.pem
rename to bankdroid-legacy/src/main/res/raw/cert_sevenday.pem
diff --git app/src/main/res/raw/cert_skandiabanken.pem bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_skandiabanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_skandiabanken.pem
diff --git app/src/main/res/raw/cert_steam.pem bankdroid-legacy/src/main/res/raw/cert_steam.pem
similarity index 100%
rename from app/src/main/res/raw/cert_steam.pem
rename to bankdroid-legacy/src/main/res/raw/cert_steam.pem
diff --git app/src/main/res/raw/cert_sveadirekt.pem bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
similarity index 100%
rename from app/src/main/res/raw/cert_sveadirekt.pem
rename to bankdroid-legacy/src/main/res/raw/cert_sveadirekt.pem
diff --git app/src/main/res/raw/cert_svenskaspel.pem bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
similarity index 100%
rename from app/src/main/res/raw/cert_svenskaspel.pem
rename to bankdroid-legacy/src/main/res/raw/cert_svenskaspel.pem
diff --git app/src/main/res/raw/cert_swedbank.pem bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
similarity index 100%
rename from app/src/main/res/raw/cert_swedbank.pem
rename to bankdroid-legacy/src/main/res/raw/cert_swedbank.pem
diff --git app/src/main/res/raw/cert_ticketrikskortet.pem bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
similarity index 100%
rename from app/src/main/res/raw/cert_ticketrikskortet.pem
rename to bankdroid-legacy/src/main/res/raw/cert_ticketrikskortet.pem
diff --git app/src/main/res/raw/cert_trustbuddy.pem bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
similarity index 100%
rename from app/src/main/res/raw/cert_trustbuddy.pem
rename to bankdroid-legacy/src/main/res/raw/cert_trustbuddy.pem
diff --git app/src/main/res/raw/cert_vasttrafik.pem bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
similarity index 100%
rename from app/src/main/res/raw/cert_vasttrafik.pem
rename to bankdroid-legacy/src/main/res/raw/cert_vasttrafik.pem
diff --git app/src/main/res/raw/cert_villabanken.pem bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_villabanken.pem
rename to bankdroid-legacy/src/main/res/raw/cert_villabanken.pem
diff --git app/src/main/res/raw/cert_volvofinans.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
similarity index 100%
rename from app/src/main/res/raw/cert_volvofinans.pem
rename to bankdroid-legacy/src/main/res/raw/cert_volvofinans.pem
diff --git app/src/main/res/raw/cert_volvofinans_logged_in.pem bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
similarity index 100%
rename from app/src/main/res/raw/cert_volvofinans_logged_in.pem
rename to bankdroid-legacy/src/main/res/raw/cert_volvofinans_logged_in.pem
diff --git app/src/main/res/raw/cert_zidisha.pem bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
similarity index 100%
rename from app/src/main/res/raw/cert_zidisha.pem
rename to bankdroid-legacy/src/main/res/raw/cert_zidisha.pem
diff --git app/src/main/res/raw/loading.html bankdroid-legacy/src/main/res/raw/loading.html
similarity index 100%
rename from app/src/main/res/raw/loading.html
rename to bankdroid-legacy/src/main/res/raw/loading.html
diff --git app/src/main/res/raw/swedbank_transactions.htm bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm
similarity index 100%
rename from app/src/main/res/raw/swedbank_transactions.htm
rename to bankdroid-legacy/src/main/res/raw/swedbank_transactions.htm

commit 3d8de01f9e2abffc8813cfb68036db92a1a95431
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 18:19:55 2015 +0100

    Moves all bank implementations into legacy module.

diff --git app/src/main/java/com/liato/bankdroid/Helpers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/Helpers.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/Helpers.java
diff --git app/src/main/java/com/liato/bankdroid/banking/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
similarity index 99%
rename from app/src/main/java/com/liato/bankdroid/banking/Account.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
index 46097e6..d65072f 100644
--- app/src/main/java/com/liato/bankdroid/banking/Account.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Account.java
@@ -17,7 +17,6 @@
 package com.liato.bankdroid.banking;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.List;
 
 import com.liato.bankdroid.provider.IAccountTypes;
diff --git app/src/main/java/com/liato/bankdroid/banking/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
similarity index 99%
rename from app/src/main/java/com/liato/bankdroid/banking/Bank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
index a5ae6a2..815d1f6 100644
--- app/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -35,11 +35,11 @@ import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.legacy.R;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
diff --git app/src/main/java/com/liato/bankdroid/banking/BankChoice.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankChoice.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/BankChoice.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankChoice.java
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankFactory.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/BankFactory.java
diff --git app/src/main/java/com/liato/bankdroid/banking/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/Transaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/Transaction.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Audi.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
similarity index 98%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
index b053557..66c17f1 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -28,7 +28,6 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
@@ -36,13 +35,11 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class BetterGlobe extends Bank {
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/CSN.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
similarity index 99%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index d6501a3..cc034c5 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -39,7 +39,6 @@ import org.jsoup.select.Elements;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Pattern;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Opel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
similarity index 99%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 7e9aec3..c60b754 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -33,7 +33,6 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
similarity index 99%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
index de3ae82..a3bc952 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -28,7 +28,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Preem.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Saab.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Seat.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Shell.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Steam.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
similarity index 98%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
index 8791338..34f2bf6 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -25,11 +25,7 @@ import org.jsoup.select.Elements;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Currency;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
similarity index 98%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
index 508a339..5c6dab3 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
@@ -3,7 +3,6 @@ package com.liato.bankdroid.banking.banks.avanza.model;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
similarity index 97%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
index fe2dddb..aee3ad3 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
@@ -6,9 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 public class Request implements Serializable {
 
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
similarity index 97%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
index b2c4f61..283e2f8 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
@@ -4,8 +4,6 @@ package com.liato.bankdroid.banking.banks.swedbank.model;
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-import java.util.Date;
-
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class CardTransaction {
 
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
similarity index 97%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
index 3dbe381..d2c862f 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
+++ bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import java.math.BigDecimal;
-import java.util.Date;
 
 @JsonIgnoreProperties(ignoreUnknown = true)
 public class Transaction {
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
diff --git app/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
diff --git app/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
diff --git app/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
diff --git app/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
diff --git app/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
diff --git app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
similarity index 100%
rename from app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
rename to bankdroid-legacy/src/main/java/com/liato/bankdroid/provider/IBankTypes.java

commit 54488ecd7b97e7331d3413690e0ef7d783351e61
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 17:57:56 2015 +0100

    Moves Urllib into legacy module.

diff --git app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
similarity index 100%
rename from app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
rename to bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
diff --git app/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
similarity index 100%
rename from app/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
rename to bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
diff --git app/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
similarity index 100%
rename from app/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
rename to bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
diff --git app/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
similarity index 100%
rename from app/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
rename to bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
diff --git app/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java
similarity index 100%
rename from app/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java
rename to bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java
diff --git app/src/main/java/eu/nullbyte/android/urllib/Urllib.java bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java
similarity index 100%
rename from app/src/main/java/eu/nullbyte/android/urllib/Urllib.java
rename to bankdroid-legacy/src/main/java/eu/nullbyte/android/urllib/Urllib.java

commit 11033f446f44d5812d781def1359973f53ab851f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 17:56:18 2015 +0100

    Adds new module for bank implementations.

diff --git app/build.gradle app/build.gradle
index 5c3e519..8a2fc95 100644
--- app/build.gradle
+++ app/build.gradle
@@ -52,6 +52,7 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile project(':bankdroid-legacy')
     compile "com.android.support:appcompat-v7:21.0.+"
     compile 'org.apache.commons:commons-io:1.3.2'
     compile 'com.google.collections:google-collections:1.0'
diff --git bankdroid-legacy/build.gradle bankdroid-legacy/build.gradle
new file mode 100644
index 0000000..e92300a
--- /dev/null
+++ bankdroid-legacy/build.gradle
@@ -0,0 +1,24 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        minSdkVersion 9
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile 'com.android.support:appcompat-v7:21.0.3'
+}
diff --git settings.gradle settings.gradle
index e7b4def..369e949 100644
--- settings.gradle
+++ settings.gradle
@@ -1 +1 @@
-include ':app'
+include ':app', ':bankdroid-legacy'

commit 0e416e3a980156ad4be0fefbb54a3c9586bd3cd5
Merge: 00ce54c 7848759
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Feb 22 21:02:23 2015 +0100

    Merge pull request #407 from robho/script_to_update_certificates
    
    Add script to automatically update all certificates

commit 7848759ac3404ddf5452357b8a4d94f9f3d3713e
Author: Robert Hogberg <robert.hogberg@gmail.com>
Date:   Fri Feb 20 23:48:59 2015 +0100

    Add script to automatically update the bank certificates
    
    When running the script the bank certificates will be automatically
    downloaded from each bank's server and updated.
    
    This script requires that each certificate contains information about which
    server to contact to download the certificate. This server information is
    not available in a certificate, but has been manually added in each
    certificate file on a separate line following the certificate's pem data. This
    added line does not affect bankdroid's handling of the certificates.
    
    All existing certificates have been refreshed using this script, except:
    * cert_americanexpress2.pem (because I don't know which server it belongs to)
    * cert_coop2.pem (because I don't know which server it belongs to)
    * cert_marginalen2.pem (because I don't know which server it belongs to)
    * cert_everydaycard.pem (because valuta.g2solutions.se:443 isn't reachable)
    
    These certificates have been removed since they were unused:
    * cert_bioklubben.pem
    * cert_nordea.pem

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
index bb1e91a..a9008b4 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -40,7 +40,6 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
-import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bioklubben extends Bank {
@@ -73,7 +72,7 @@ public class Bioklubben extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bioklubben));
+        urlopen = new Urllib(context);
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("http://bioklubben.sf.se/Start.aspx");
 
@@ -157,4 +156,4 @@ public class Bioklubben extends Bank {
         }
         super.updateComplete();
     }
-}
\ No newline at end of file
+}
diff --git app/src/main/res/raw/cert_akeliusinvest.pem app/src/main/res/raw/cert_akeliusinvest.pem
index ed553be..c376aa2 100644
--- app/src/main/res/raw/cert_akeliusinvest.pem
+++ app/src/main/res/raw/cert_akeliusinvest.pem
@@ -28,3 +28,4 @@ gevQp2BPpaNjUBbb28mxucuWuYV17k8U+ZRV09HRziVUm7qdf3etabK1aOMAjabd
 DZU4CIGakRvUYOAl6nkbQ3NwSDngpLSm3JJPLQS8VZoxMFnE9rS5vC5vb11qwg9R
 EeinVbKw
 -----END CERTIFICATE-----
+online.akeliusinvest.com:443
diff --git app/src/main/res/raw/cert_akeliusspar.pem app/src/main/res/raw/cert_akeliusspar.pem
index 3bc318c..2432760 100644
--- app/src/main/res/raw/cert_akeliusspar.pem
+++ app/src/main/res/raw/cert_akeliusspar.pem
@@ -29,3 +29,4 @@ Ttn1FMCsGzx3TvHlos4nmr5r3eETimisI/I8l+IqHSb7O8KC4CpGk34eGpQD0i+Z
 qMCI1vaVcgf8ac8POOd6B20dqDr1s8mdp7H5e4KqWW5H9WdYp31RmjbcAiIkTKeS
 8irFtCk8VpC+XNWWVdm0ib5peSsXcqaHOTKz00E=
 -----END CERTIFICATE-----
+www.online.akeliusspar.se:443
diff --git app/src/main/res/raw/cert_americanexpress.pem app/src/main/res/raw/cert_americanexpress.pem
index 9221fb8..916c3e5 100644
--- app/src/main/res/raw/cert_americanexpress.pem
+++ app/src/main/res/raw/cert_americanexpress.pem
@@ -35,3 +35,4 @@ sGJmYJUTcx3u1BJ3EvnW9fa2zrZIeLeWkJa6jKyDvwdXrsh8gOaMPsVXBDs3eO1P
 e/i/xKNSFxw/4OyjQ8OHM2ihN7AMVDZrRcl7dAr0dS0+OpYHFFpSt7IL9BywSC7z
 9TzIzLV/TRFmIpOYgN55mjpSOJoXpiA+pG5n7ZWkn+LiAQ+k
 -----END CERTIFICATE-----
+www.americanexpress.com:443
diff --git app/src/main/res/raw/cert_americanexpress_global.pem app/src/main/res/raw/cert_americanexpress_global.pem
index bc65ec4..c680add 100644
--- app/src/main/res/raw/cert_americanexpress_global.pem
+++ app/src/main/res/raw/cert_americanexpress_global.pem
@@ -1,32 +1,33 @@
------BEGIN CERTIFICATE-----

-Sh3UmBWpiuWsR+Wp2+geW7Lc2ULeyeTWM9CVCUNUtXskjg==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+Sh3UmBWpiuWsR+Wp2+geW7Lc2ULeyeTWM9CVCUNUtXskjg==
+-----END CERTIFICATE-----
+global.americanexpress.com:443
diff --git app/src/main/res/raw/cert_avanza.pem app/src/main/res/raw/cert_avanza.pem
index f6c862c..a589201 100644
--- app/src/main/res/raw/cert_avanza.pem
+++ app/src/main/res/raw/cert_avanza.pem
@@ -25,3 +25,4 @@ FVieCvIBnzPgsKq9+Kbr89kr/9U+SYVGb3p8avthrMaAsEegLR3jYfDNK6hHP9ko
 bjzveRMsU9Wf74/OJdW8Vp1DaXC3AetmbgyMbDQyvEMTB1Qw/Hbxni5ze4ukX9GB
 UJM2koY+ZtcwVM4YjfAIi2YzYdzYccsODhamwBVtpe38WcF1pQw=
 -----END CERTIFICATE-----
+iphone.avanza.se:443
diff --git app/src/main/res/raw/cert_bioklubben.pem app/src/main/res/raw/cert_bioklubben.pem
deleted file mode 100644
index 59685ac..0000000
--- app/src/main/res/raw/cert_bioklubben.pem
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----

-CymqjlSx+5sQ6fzET22+ENOvOyglP8vJ/7/IxIBCfRPfRWEAZAk=
------END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_brummer.pem app/src/main/res/raw/cert_brummer.pem
index 09e0d9d..f982dd2 100644
--- app/src/main/res/raw/cert_brummer.pem
+++ app/src/main/res/raw/cert_brummer.pem
@@ -1,30 +1,31 @@
------BEGIN CERTIFICATE-----

-kfLSPLGscWmnR6JTBY7mdzkaCBkFXIyqN06pV3kxzxjtCqBwdg==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+kfLSPLGscWmnR6JTBY7mdzkaCBkFXIyqN06pV3kxzxjtCqBwdg==
+-----END CERTIFICATE-----
+www.brummer.se:443
diff --git app/src/main/res/raw/cert_coop.pem app/src/main/res/raw/cert_coop.pem
index 5f64262..e8b64aa 100644
--- app/src/main/res/raw/cert_coop.pem
+++ app/src/main/res/raw/cert_coop.pem
@@ -1,34 +1,33 @@
 -----BEGIN CERTIFICATE-----

-+UX0heR9QWX+dqsYLQBl7dK2geZcww==

+jCsIfvDy
 -----END CERTIFICATE-----
+www.coop.se:443
diff --git app/src/main/res/raw/cert_csn.pem app/src/main/res/raw/cert_csn.pem
index 2e34bce..a545900 100644
--- app/src/main/res/raw/cert_csn.pem
+++ app/src/main/res/raw/cert_csn.pem
@@ -29,3 +29,4 @@ SRaHWORHUIh1KGhTzzKlAmrq3q4xx0upqCAj32ryqOr2lX0pnlmUSZVB19uP9YBg
 ngVtjfj/1RM7bUlwMTsAcXXXbccz4CPceZUU8niujzFSneTfkeVhrDDSe94fltkm
 OFeejCXt98KVdMUSG0s7Zm6eB7pFq1dbYBlS/V30aNo=
 -----END CERTIFICATE-----
+www.csn.se:443
diff --git app/src/main/res/raw/cert_danskebank.pem app/src/main/res/raw/cert_danskebank.pem
index c598978..1694f1a 100644
--- app/src/main/res/raw/cert_danskebank.pem
+++ app/src/main/res/raw/cert_danskebank.pem
@@ -28,3 +28,4 @@ NrgFNBmWL8KbFSqx72krU4ykspNyIciZQgkShaKUZUOvB0NY3AfVbDwAK5FaITAe
 6fB66GuRh/4IUIv3bKWH1BzUye768StTl0EaNVi2AdyU3YaaSayAOZ7ywWE0Xmwm
 f7/fEt942nMenqvNpWMF9jNb3rYNS9phdg==
 -----END CERTIFICATE-----
+mobil.danskebank.se:443
diff --git app/src/main/res/raw/cert_dinersclub.pem app/src/main/res/raw/cert_dinersclub.pem
index 5e7ce2c..ec3b3d7 100644
--- app/src/main/res/raw/cert_dinersclub.pem
+++ app/src/main/res/raw/cert_dinersclub.pem
@@ -1,34 +1,35 @@
------BEGIN CERTIFICATE-----

-JEoC5a8o3g==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+JEoC5a8o3g==
+-----END CERTIFICATE-----
+secure.dinersclub.se:443
diff --git app/src/main/res/raw/cert_easycard.pem app/src/main/res/raw/cert_easycard.pem
index 27ac3dc..046878c 100644
--- app/src/main/res/raw/cert_easycard.pem
+++ app/src/main/res/raw/cert_easycard.pem
@@ -1,32 +1,33 @@
------BEGIN CERTIFICATE-----

-9zMG3j0JdTv4xPZSSQHq
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+9zMG3j0JdTv4xPZSSQHq
+-----END CERTIFICATE-----
+kundportal.cerdo.se:443
diff --git app/src/main/res/raw/cert_eurocard.pem app/src/main/res/raw/cert_eurocard.pem
index 967dd2b..1194e02 100644
--- app/src/main/res/raw/cert_eurocard.pem
+++ app/src/main/res/raw/cert_eurocard.pem
@@ -31,3 +31,4 @@ GgyjIiqf+5UekfeAFIs2LJ3CB7xr+UFWUoZe0qkbAUTLTe9KDf5GPjjvmYKZgOgL
 y6hoAfJ+82xLl46g4U9lqfhUIhCdh8xsGMl3aua3ddnVYDKkVcVl9XBwsLmqstJi
 NR3ikmS2NPy8Ftd0TdpyWp8X50dGZbZD7n9ZBBpqRiU=
 -----END CERTIFICATE-----
+secure.eurocard.se:443
diff --git app/src/main/res/raw/cert_everydaycard.pem app/src/main/res/raw/cert_everydaycard.pem
index b4dd7e2..be37da2 100644
--- app/src/main/res/raw/cert_everydaycard.pem
+++ app/src/main/res/raw/cert_everydaycard.pem
@@ -32,3 +32,4 @@ vpu48GxD5+i0nPN/eC2QMBKP9qx7XVZmniVmeJHS3L2yqyCLKJLElp7mFJeoobKB
 edBN56YoGX05tao7kk0VjtvsbXhud7WSMpKJz2yWqWad6U9puLyn2wfUkW/ziH42
 MQExvCzr7SArqeO38h9ZpSK6RkmdDiCLyRu07giHUb1ZI5sN/05Fsak5zkUpZA==
 -----END CERTIFICATE-----
+valuta.g2solutions.se:443
diff --git app/src/main/res/raw/cert_firstcard.pem app/src/main/res/raw/cert_firstcard.pem
index 792f1c7..5e5cff0 100644
--- app/src/main/res/raw/cert_firstcard.pem
+++ app/src/main/res/raw/cert_firstcard.pem
@@ -1,31 +1,32 @@
------BEGIN CERTIFICATE-----

-01KidfzMdyRulQ4m6g==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+NA3K8eVpSw==
+-----END CERTIFICATE-----
+www.firstcard.se:443
diff --git app/src/main/res/raw/cert_forexbank.pem app/src/main/res/raw/cert_forexbank.pem
index 77d95ce..fe542c8 100644
--- app/src/main/res/raw/cert_forexbank.pem
+++ app/src/main/res/raw/cert_forexbank.pem
@@ -30,3 +30,4 @@ TufF8vso8N26k69wV2lfg1DWhqsCRL/oSaEklhCMsCU6cE1XDZfMRxbJrdk/LFG8
 2U5gtD+fZqD3OSP+pe3kvSkTxSAkdZs5F8SJJ5w8E7pgdDgnC6nzo23wR8/JrDUd
 JpPqCokWT4kF
 -----END CERTIFICATE-----
+nettbank.edb.com:443
diff --git app/src/main/res/raw/cert_handelsbanken.pem app/src/main/res/raw/cert_handelsbanken.pem
index 9ceba5c..97b34ef 100644
--- app/src/main/res/raw/cert_handelsbanken.pem
+++ app/src/main/res/raw/cert_handelsbanken.pem
@@ -31,3 +31,4 @@ jMtMgKuRHJBJ9hhZoU5upxVuO3zBVSTB9O+LtoR0XFs5gGqFP7lO1TxlIPHnbBH3
 QPitXRUCz7+7fwKmSJOEz2Rd7NVNg8dJ8nBAHKSVfTgOK6kezgZdzxr5bxEuNhjt
 91AySnUbhs2yRijm12ZF8CAgfEPhK8Hu++/IdlffFhE=
 -----END CERTIFICATE-----
+m.handelsbanken.se:443
diff --git app/src/main/res/raw/cert_hemkop.pem app/src/main/res/raw/cert_hemkop.pem
index 6b760d8..63e4db4 100644
--- app/src/main/res/raw/cert_hemkop.pem
+++ app/src/main/res/raw/cert_hemkop.pem
@@ -33,3 +33,4 @@ ijaTGOW3etHoW84Boit6cNXL4SUqgFZYWDYGUUrh+WM2MWjJLiJpR8SkMk+sZ/Uc
 LG5dMULRF7RtwNY9Mwztm7NljXd3Y/Ymn9JEKvN3etmFwnkeARLjnZve3GEr65wk
 volhqsuGij2QcsZR2V5tF9iSsmo=
 -----END CERTIFICATE-----
+www.hemkop.se:443
diff --git app/src/main/res/raw/cert_ica.pem app/src/main/res/raw/cert_ica.pem
index d8e49ca..52a0eb8 100644
--- app/src/main/res/raw/cert_ica.pem
+++ app/src/main/res/raw/cert_ica.pem
@@ -1,29 +1,30 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
+api.ica.se:443
diff --git app/src/main/res/raw/cert_icabanken.pem app/src/main/res/raw/cert_icabanken.pem
index 5ccc9b0..21acf2a 100644
--- app/src/main/res/raw/cert_icabanken.pem
+++ app/src/main/res/raw/cert_icabanken.pem
@@ -35,3 +35,4 @@ zyEioUq785bpDEmFObijD7Uck3hRCxkA1ad2RPWYkjwD0x3ZpD4RPZXhHR+1chDf
 2MmQlMPkcYfE1Xs4citEsDQT3E6CnUTifS93LfEzW1s5hFw2qa5u8UedgdYwWTnJ
 /VrS5ELpPoKBy12oEsZPYXcCDm/eV0K22WcT50StSwwcMRXqTbOs9JrteR0C0qE=
 -----END CERTIFICATE-----
+appserver.icabanken.se:443
diff --git app/src/main/res/raw/cert_ikanobank.pem app/src/main/res/raw/cert_ikanobank.pem
index e07ed5d..f4cf3a6 100644
--- app/src/main/res/raw/cert_ikanobank.pem
+++ app/src/main/res/raw/cert_ikanobank.pem
@@ -1,38 +1,39 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
+secure.ikanobank.se:443
diff --git app/src/main/res/raw/cert_ikanopartner.pem app/src/main/res/raw/cert_ikanopartner.pem
index de03a0d..e6fb824 100644
--- app/src/main/res/raw/cert_ikanopartner.pem
+++ app/src/main/res/raw/cert_ikanopartner.pem
@@ -31,3 +31,4 @@ PkF/CtDaNSdQmleSdHn4YUSA8BQwzeKPh9BKpY9JJq7P4BEiQdkkvmWfepRoQ1ud
 PeJXVGRNQ7tFkdayPmJ7wgXrWRk7l5QN+cNndNfgngXKv3FbexVTYSmQM3Ak1D5/
 npgXOrhX
 -----END CERTIFICATE-----
+partner.ikanobank.se:443
diff --git app/src/main/res/raw/cert_jojo.pem app/src/main/res/raw/cert_jojo.pem
index e04d01e..3a270b5 100644
--- app/src/main/res/raw/cert_jojo.pem
+++ app/src/main/res/raw/cert_jojo.pem
@@ -1,32 +1,33 @@
------BEGIN CERTIFICATE-----

-8d7oaZCE7jQQ
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+8d7oaZCE7jQQ
+-----END CERTIFICATE-----
+www.shop.skanetrafiken.se:443
diff --git app/src/main/res/raw/cert_lansforsakringar.pem app/src/main/res/raw/cert_lansforsakringar.pem
index cc8b79b..ea2bf8b 100644
--- app/src/main/res/raw/cert_lansforsakringar.pem
+++ app/src/main/res/raw/cert_lansforsakringar.pem
@@ -33,3 +33,4 @@ EH5qDQuK4y0HJOAWRTPnQpKq2HdfO6q/6nuvA/Mv+hVVgh4/HeCC88U20GztyDA3
 Fa14RHtTHg6j0BWfxJ5e5RZIeuBNttJvWTvANXQxkl85ThoAaF9Qedf0XCIzjUGn
 TA==
 -----END CERTIFICATE-----
+mobil.lansforsakringar.se:443
diff --git app/src/main/res/raw/cert_marginalen.pem app/src/main/res/raw/cert_marginalen.pem
index bde1811..19aff72 100644
--- app/src/main/res/raw/cert_marginalen.pem
+++ app/src/main/res/raw/cert_marginalen.pem
@@ -1,34 +1,38 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
+secure1.marginalen.se:443
diff --git app/src/main/res/raw/cert_meniga.pem app/src/main/res/raw/cert_meniga.pem
index cab4773..a1d12c3 100644
--- app/src/main/res/raw/cert_meniga.pem
+++ app/src/main/res/raw/cert_meniga.pem
@@ -1,30 +1,33 @@
------BEGIN CERTIFICATE-----

-83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0=
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+dUrs
+-----END CERTIFICATE-----
+www.meniga.is:443
diff --git app/src/main/res/raw/cert_mobilbanken.pem app/src/main/res/raw/cert_mobilbanken.pem
index f437418..fd7c6ee 100644
--- app/src/main/res/raw/cert_mobilbanken.pem
+++ app/src/main/res/raw/cert_mobilbanken.pem
@@ -1,37 +1,36 @@
 -----BEGIN CERTIFICATE-----

-I9g29oOgu4jg3vE=

+9E2iMPGN
 -----END CERTIFICATE-----
+mobil-banken.se:443
diff --git app/src/main/res/raw/cert_nordea.pem app/src/main/res/raw/cert_nordea.pem
deleted file mode 100644
index 2679590..0000000
--- app/src/main/res/raw/cert_nordea.pem
+++ /dev/null
@@ -1,33 +0,0 @@
------BEGIN CERTIFICATE-----

-Um/nnOXcEdoRBnDG1vPBe3X0/p2Po6Cv0EKn5lb1UC8=
------END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_nordea_dk.pem app/src/main/res/raw/cert_nordea_dk.pem
index 3aefa0b..51851d2 100644
--- app/src/main/res/raw/cert_nordea_dk.pem
+++ app/src/main/res/raw/cert_nordea_dk.pem
@@ -1,32 +1,33 @@
------BEGIN CERTIFICATE-----

-K3OZVKYhUxpbYw==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+K3OZVKYhUxpbYw==
+-----END CERTIFICATE-----
+www.netbank.nordea.dk:443
diff --git app/src/main/res/raw/cert_nordnet.pem app/src/main/res/raw/cert_nordnet.pem
index 3e61d16..87a82db 100644
--- app/src/main/res/raw/cert_nordnet.pem
+++ app/src/main/res/raw/cert_nordnet.pem
@@ -31,3 +31,4 @@ SBJIlp9/nKDbJx3VaEGhiDQiE+eEbKPyLo9I6qEtwrpAfygHgWOHpayRXOzz7G/3
 pWNNH/PJv4/XVmnuGuDd820vXqr/RaGixxGzxXON4gQ1pPTph8Dqs6P2uh1fvuau
 eUOjBvU=
 -----END CERTIFICATE-----
+www.nordnet.se:443
diff --git app/src/main/res/raw/cert_nordnetdirekt.pem app/src/main/res/raw/cert_nordnetdirekt.pem
index a5da0cd..c883cf3 100644
--- app/src/main/res/raw/cert_nordnetdirekt.pem
+++ app/src/main/res/raw/cert_nordnetdirekt.pem
@@ -31,3 +31,4 @@ DVd2REmAX5AzOWCIQa+QTIrpLYCBh0+JUQjMA+HULw2NJp8sFZHuSbq5QgrmFFu7
 ENlIDIIFEqpAYUsxFgay7KL85yovxi/o248glIOvuyl92SggbbT8pDHtnnsKCka8
 jDDzXCaMqI+kp/U034Taez46yNgJp0QDzs2CSNQ=
 -----END CERTIFICATE-----
+www.nordnetdirekt.se:443
diff --git app/src/main/res/raw/cert_okq8.pem app/src/main/res/raw/cert_okq8.pem
index 77d95ce..fe542c8 100644
--- app/src/main/res/raw/cert_okq8.pem
+++ app/src/main/res/raw/cert_okq8.pem
@@ -30,3 +30,4 @@ TufF8vso8N26k69wV2lfg1DWhqsCRL/oSaEklhCMsCU6cE1XDZfMRxbJrdk/LFG8
 2U5gtD+fZqD3OSP+pe3kvSkTxSAkdZs5F8SJJ5w8E7pgdDgnC6nzo23wR8/JrDUd
 JpPqCokWT4kF
 -----END CERTIFICATE-----
+nettbank.edb.com:443
diff --git app/src/main/res/raw/cert_ostgotatrafiken_login.pem app/src/main/res/raw/cert_ostgotatrafiken_login.pem
index 4776515..4e09fac 100644
--- app/src/main/res/raw/cert_ostgotatrafiken_login.pem
+++ app/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -1,34 +1,35 @@
------BEGIN CERTIFICATE-----

-MCe7Jchh43bGAvJhOzi706Enkio=
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+MCe7Jchh43bGAvJhOzi706Enkio=
+-----END CERTIFICATE-----
+www.ostgotatrafiken.se:443
diff --git app/src/main/res/raw/cert_ostgotatrafiken_overview.pem app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
index 461e140..5207955 100644
--- app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
+++ app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
@@ -1,31 +1,32 @@
------BEGIN CERTIFICATE-----

-YQuw4+jd
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+YQuw4+jd
+-----END CERTIFICATE-----
+webtick.ostgotatrafiken.se:443
diff --git app/src/main/res/raw/cert_osuuspankki.pem app/src/main/res/raw/cert_osuuspankki.pem
index d0df8a2..3700ce3 100644
--- app/src/main/res/raw/cert_osuuspankki.pem
+++ app/src/main/res/raw/cert_osuuspankki.pem
@@ -1,33 +1,37 @@
 -----BEGIN CERTIFICATE-----

-7C+vTCxnNpaIBNdzQ7uSIQTVJQSWx2cHjYxVlrg=

+N7hoKxb3BouwbQLgoBmuRL0GQ1hJdNI=
 -----END CERTIFICATE-----
+www.op.fi:443
diff --git app/src/main/res/raw/cert_osuuspankki_mobile.pem app/src/main/res/raw/cert_osuuspankki_mobile.pem
index 7e28598..dea6f73 100644
--- app/src/main/res/raw/cert_osuuspankki_mobile.pem
+++ app/src/main/res/raw/cert_osuuspankki_mobile.pem
@@ -1,10 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIIFFzCCA/+gAwIBAgIQaPQlWM3nMBnPHN+Xv2vznjANBgkqhkiG9w0BAQUFADCB
+MIIFADCCA+igAwIBAgIQYrnplQ0ovOONm49HDYyS/zANBgkqhkiG9w0BAQUFADCB
 tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMm
-VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTMwOTEy
-MDAwMDAwWhcNMTQwOTEzMjM1OTU5WjBeMQswCQYDVQQGEwJGSTERMA8GA1UECBMI
+VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTQwOTEx
+MDAwMDAwWhcNMTUwOTE0MjM1OTU5WjBeMQswCQYDVQQGEwJGSTERMA8GA1UECBMI
 SGVsc2lua2kxETAPBgNVBAcUCEhlbHNpbmtpMRcwFQYDVQQKFA5PUC1Qb2hqb2xh
 IG9zazEQMA4GA1UEAxQHbS5vcC5maTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
 AQoCggEBAM+na9nBf+eHhhHtUY6c3T3wzEiieSejF6xmvTgTzQ3mdF1kvVPmZAUq
@@ -12,19 +12,19 @@ AQoCggEBAM+na9nBf+eHhhHtUY6c3T3wzEiieSejF6xmvTgTzQ3mdF1kvVPmZAUq
 Zp836cBAAmSTGC55gH3AQ2aq0F1U3p9jQJ8E/obW1zNcyOcHpCJ9NxisW231KN/H
 QVoOn6fijZxboP0iHE2yhOG50WCtP02qQgYo6vsn6qsXhmBQ21NZrL8pAAjW08SC
 NpMX+9UFWurVGABa3/rKJd9940gA0ZYYEFEHP9p57Lcm5vf8hxFEQIBt6/h6grO/
-eAWPcQbk246YVoNeeXuPqCyNfJeLQRkCAwEAAaOCAXcwggFzMBIGA1UdEQQLMAmC
+eAWPcQbk246YVoNeeXuPqCyNfJeLQRkCAwEAAaOCAWAwggFcMBIGA1UdEQQLMAmC
 B20ub3AuZmkwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYI

-Cub+YU2Z3sMnI2U=

+vKHI1z2ijHtap/OBlU9IDHUddFf92Av/6nDh1gxaYUxD5oHy
 -----END CERTIFICATE-----
+m.op.fi:443
diff --git app/src/main/res/raw/cert_paypal.pem app/src/main/res/raw/cert_paypal.pem
index accd937..3704c0c 100644
--- app/src/main/res/raw/cert_paypal.pem
+++ app/src/main/res/raw/cert_paypal.pem
@@ -33,3 +33,4 @@ xIigb5Ms7zjSYcfs8zd9yTKlXB5IDoVsRyp/xjBewvYu3eNNrP/vSCbHUXRHMkYL
 zXoKXVvFje0XvN4JvOmTqXyFnIimg7zW5R8FEN+yT6LFlwCLV8cN58dXV4d9E59c
 XPfzzQCJDYWaonDa
 -----END CERTIFICATE-----
+www.paypal.com:443
diff --git app/src/main/res/raw/cert_payson.pem app/src/main/res/raw/cert_payson.pem
index b6a167a..87e8266 100644
--- app/src/main/res/raw/cert_payson.pem
+++ app/src/main/res/raw/cert_payson.pem
@@ -1,32 +1,39 @@
 -----BEGIN CERTIFICATE-----

-NUlgdUKK

+Utz4DO4Z7SsyjWrNA3DVbXN+zZw=
 -----END CERTIFICATE-----
+www.payson.se:443
diff --git app/src/main/res/raw/cert_plusgirot.pem app/src/main/res/raw/cert_plusgirot.pem
index f592f65..db17b74 100644
--- app/src/main/res/raw/cert_plusgirot.pem
+++ app/src/main/res/raw/cert_plusgirot.pem
@@ -1,31 +1,32 @@
------BEGIN CERTIFICATE-----

-fKYgH5kI57BEfo89BUTdKQoCnx4qnYObUJVNsAM+
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+LXXg08b96tbNjynAlWNK
+-----END CERTIFICATE-----
+kontoutdrag.plusgirot.se:443
diff --git app/src/main/res/raw/cert_resursbank.pem app/src/main/res/raw/cert_resursbank.pem
index b92f70c..b768ea9 100644
--- app/src/main/res/raw/cert_resursbank.pem
+++ app/src/main/res/raw/cert_resursbank.pem
@@ -36,3 +36,4 @@ E+sIKHvrsMcPAqhBo72d5Hza7EQhHUMfwBZeXDExOI1tZ5RTOv39t0ne208ja0wS
 rKpk1g4Nh4rHwPLYO+0fs3tfDMhEpPYa8CxSqswEmeXb1hiVSjuKaG7BqlSc62m/
 e+GhpRTaPL2e1wlLsHt3Pg4I8V2VikbNJwfPgscs5BeW
 -----END CERTIFICATE-----
+secure.resurs.se:443
diff --git app/src/main/res/raw/cert_rikslunchen.pem app/src/main/res/raw/cert_rikslunchen.pem
index c8c035b..db32543 100644
--- app/src/main/res/raw/cert_rikslunchen.pem
+++ app/src/main/res/raw/cert_rikslunchen.pem
@@ -28,3 +28,4 @@ X8u7npVmoqvw4yZmgHZWDKZEtbhUOTrxaSad0QwMKcRPt98euPXvmKowDrZ+eOiH
 WYxx8k8pauRBPQliQcWx9r1EbNQdlSuu8RnvIlhnqB+OypSpvKlqpg9y1tBqimtT
 UU9mph83MDGlCY1EwuHPGorjoqGjYjXl/63EOvKmXEKYMCd6fb4Dfq2F
 -----END CERTIFICATE-----
+www.rikslunchen.se:443
diff --git app/src/main/res/raw/cert_seb.pem app/src/main/res/raw/cert_seb.pem
index f866163..9a25f83 100644
--- app/src/main/res/raw/cert_seb.pem
+++ app/src/main/res/raw/cert_seb.pem
@@ -31,3 +31,4 @@ YgAtBEfbx0s73EvXV5Mq6IpUA+1SCem3NDnNTt+EXsXMxZys6QoglaDes7MKK/6Y
 98DQFF+BoTlMQ44Xfp3LP0AnTXMpIg2eDHETrqmgET+AQ9xJgji04LT+UggLr75C
 YzLm2CrBWbKi6C2uth4xbS4cldJHWWSCimVXLC8xhKzl
 -----END CERTIFICATE-----
+mP.seb.se:443
diff --git app/src/main/res/raw/cert_seb_web.pem app/src/main/res/raw/cert_seb_web.pem
index 15c1a40..5f8fa9e 100644
--- app/src/main/res/raw/cert_seb_web.pem
+++ app/src/main/res/raw/cert_seb_web.pem
@@ -1,30 +1,34 @@
 -----BEGIN CERTIFICATE-----
-MIIFKTCCBBGgAwIBAgIQMVXtCg4RnD0vL5LDol7aQzANBgkqhkiG9w0BAQUFADCB
-vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+MIIFuzCCBKOgAwIBAgIQE6ghsEHHMRG/OvkO2naVWDANBgkqhkiG9w0BAQUFADCB
+vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug

-cgz4UMS+A3qV9vPIs0HH5WQ8wkpYjv85ju7492w=

+e4+R3di3uW33Agbv9Mgdh4m6gencdR5343WmT8LnIw==
 -----END CERTIFICATE-----
+m.seb.se:443
diff --git app/src/main/res/raw/cert_sebkort.pem app/src/main/res/raw/cert_sebkort.pem
index fc83a60..76f2b23 100644
--- app/src/main/res/raw/cert_sebkort.pem
+++ app/src/main/res/raw/cert_sebkort.pem
@@ -31,3 +31,4 @@ e+RzYNIj0YapwWVYA2uFe1EyDYgUF/8u/w4DSU40xajwN2qVf4y/mSxeTF5YZJ7x
 xym+da7UbsF1WZkCzlSo9Q+cpGyr82zVqb3/syifXUYPPCy6szMnmzkPlUTopuzH
 pHce9HZ1zxrFmLmJyNW4gYB3aJ8UD7J/Ba/v0s6Xrs1SQVCAkpIC7/3MqQ==
 -----END CERTIFICATE-----
+secure.sebkort.com:443
diff --git app/src/main/res/raw/cert_sevenday.pem app/src/main/res/raw/cert_sevenday.pem
index 89a213c..86541f3 100644
--- app/src/main/res/raw/cert_sevenday.pem
+++ app/src/main/res/raw/cert_sevenday.pem
@@ -25,3 +25,4 @@ wsygjnnUpRyGbrxeY29w6TfChOQwb+7vxxCgRPJBrDTGdJmZ6rhE+ZrSNqcCd1ra
 vB8pWPwNeaFHRPrYrlzUXfkS0xak7GFCU+WW4qPG73VLdPnh/GcidtSjDSZKGSkv
 ETEyMuB5fsINZXXfHm6F2x4e0+b8aQ==
 -----END CERTIFICATE-----
+www.sevenday.se:443
diff --git app/src/main/res/raw/cert_skandiabanken.pem app/src/main/res/raw/cert_skandiabanken.pem
index 5f24435..22ac4ac 100644
--- app/src/main/res/raw/cert_skandiabanken.pem
+++ app/src/main/res/raw/cert_skandiabanken.pem
@@ -29,3 +29,4 @@ uZT3bKUGlwMXERu9LJE691wEv27NLqi0eF3B0D8yGbpwQDhba8TblyDUHpog647j
 mOBn8zVza5C2zxeUwzZV/ftGzJlvzsAOTzKUYOdD3y0Hs3gQ8GkeazFgf0NZnP4L
 xdCATkln5Q==
 -----END CERTIFICATE-----
+smartrefill.se:443
diff --git app/src/main/res/raw/cert_steam.pem app/src/main/res/raw/cert_steam.pem
index 17112e7..8d6baac 100644
--- app/src/main/res/raw/cert_steam.pem
+++ app/src/main/res/raw/cert_steam.pem
@@ -1,34 +1,50 @@
 -----BEGIN CERTIFICATE-----

-R/VAuYULZeKj+BWoYS4TCTWFmQQwkVtak1li4vIdIXC8

+HkaHD0QgAJR/FOM+dAxTFElveUtaSoA=
 -----END CERTIFICATE-----
+store.steampowered.com:443
diff --git app/src/main/res/raw/cert_sveadirekt.pem app/src/main/res/raw/cert_sveadirekt.pem
index 7046bec..f2821b9 100644
--- app/src/main/res/raw/cert_sveadirekt.pem
+++ app/src/main/res/raw/cert_sveadirekt.pem
@@ -29,3 +29,4 @@ BeptJUGnQk6XGK7GJXcQoFRaqm7A6QEICG3lab28eMnWcXxMtVvDB53AQeSi2yIz
 YHcX36doc9S8NX2Ok0hdcdObd+clvW2lQt75PNhKsFj6qYTWexyjNXqhTO27/2kW
 jTbm8JCmR3UCgK1vGvwZnHRRk/tdGtP0s1rWGaoOmPxzxEE4xdQBrP447HAwtw==
 -----END CERTIFICATE-----
+services.sveadirekt.se:443
diff --git app/src/main/res/raw/cert_svenskaspel.pem app/src/main/res/raw/cert_svenskaspel.pem
index c541f04..8ae5872 100644
--- app/src/main/res/raw/cert_svenskaspel.pem
+++ app/src/main/res/raw/cert_svenskaspel.pem
@@ -1,34 +1,35 @@
------BEGIN CERTIFICATE-----

-orkj7QfRvV5ZNIpCKDJdonffdb+PuSwzWBVLMT/N/g==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+orkj7QfRvV5ZNIpCKDJdonffdb+PuSwzWBVLMT/N/g==
+-----END CERTIFICATE-----
+api.www.svenskaspel.se:443
diff --git app/src/main/res/raw/cert_swedbank.pem app/src/main/res/raw/cert_swedbank.pem
index fe641c3..4097e2a 100644
--- app/src/main/res/raw/cert_swedbank.pem
+++ app/src/main/res/raw/cert_swedbank.pem
@@ -1,31 +1,32 @@
------BEGIN CERTIFICATE-----

-EhN57wT5
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+EhN57wT5
+-----END CERTIFICATE-----
+auth.api.swedbank.se:443
diff --git app/src/main/res/raw/cert_ticketrikskortet.pem app/src/main/res/raw/cert_ticketrikskortet.pem
index f56cd1d..5a084a1 100644
--- app/src/main/res/raw/cert_ticketrikskortet.pem
+++ app/src/main/res/raw/cert_ticketrikskortet.pem
@@ -1,30 +1,31 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
+www.edenred.se:443
diff --git app/src/main/res/raw/cert_trustbuddy.pem app/src/main/res/raw/cert_trustbuddy.pem
index fe1a01d..6a8a9c4 100644
--- app/src/main/res/raw/cert_trustbuddy.pem
+++ app/src/main/res/raw/cert_trustbuddy.pem
@@ -1,42 +1,43 @@
------BEGIN CERTIFICATE-----

-NkPZyQ==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+NkPZyQ==
+-----END CERTIFICATE-----
+trustbuddy.com:443
diff --git app/src/main/res/raw/cert_vasttrafik.pem app/src/main/res/raw/cert_vasttrafik.pem
index a8c7df3..ecc7ed3 100644
--- app/src/main/res/raw/cert_vasttrafik.pem
+++ app/src/main/res/raw/cert_vasttrafik.pem
@@ -1,29 +1,30 @@
------BEGIN CERTIFICATE-----

-7lu66yWdSo3BXrk0mpe3BvNNjGY5R0U=
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+7lu66yWdSo3BXrk0mpe3BvNNjGY5R0U=
+-----END CERTIFICATE-----
+www.vasttrafik.se:443
diff --git app/src/main/res/raw/cert_villabanken.pem app/src/main/res/raw/cert_villabanken.pem
index 9ebe38c..046878c 100644
--- app/src/main/res/raw/cert_villabanken.pem
+++ app/src/main/res/raw/cert_villabanken.pem
@@ -30,3 +30,4 @@ vMlDN9BxPczgEETqU7LCaXYlef51QFoDz9ByxUpp/eq2jnF3tDCCRlGUL28tLo25
 5odT5/8Kr3rrw6s6oi7k0DXMQUFz4jP9ePXIKOVEN9u0Muk5A0E36kssEIEi7fde
 9zMG3j0JdTv4xPZSSQHq
 -----END CERTIFICATE-----
+kundportal.cerdo.se:443
diff --git app/src/main/res/raw/cert_volvofinans.pem app/src/main/res/raw/cert_volvofinans.pem
index 83bc563..1b09ae3 100644
--- app/src/main/res/raw/cert_volvofinans.pem
+++ app/src/main/res/raw/cert_volvofinans.pem
@@ -36,3 +36,4 @@ xcOARTjxTLnJRPNDju7xKsMRFZYiJ7KO62JXZ56iimoboM8cRd74665QneS66HED
 CYebJcA1Ua41R0GE+PKNhVLIaW5nfm/su2A865AmKK5DYFjg0NrzrgB9uQsKUwrO
 sN/gfwvxMEN+/vG1PlRjDjlF2BkvnZhkt2Lc6GD552FhtLeYarLsgEiL
 -----END CERTIFICATE-----
+secure.volvofinans.se:443
diff --git app/src/main/res/raw/cert_volvofinans_logged_in.pem app/src/main/res/raw/cert_volvofinans_logged_in.pem
index 15fde8e..1194d96 100644
--- app/src/main/res/raw/cert_volvofinans_logged_in.pem
+++ app/src/main/res/raw/cert_volvofinans_logged_in.pem
@@ -39,3 +39,4 @@ wnGYQMzvoMT+gG/xJea0iJF1heI8nwL/JXzkiS8Lw1r/V8btd7tyGTZerS3DvYWD
 chekZMEAsfOYWsz4pCjED5P2S1ZnfqCsXerWPX7i+23lnjhpQ8MOzZJF8nXGBpXD
 GxUHutMVEtqW9aCSv5wMdnDd/BKF1qHk
 -----END CERTIFICATE-----
+inloggad.volvofinans.se:443
diff --git app/src/main/res/raw/cert_zidisha.pem app/src/main/res/raw/cert_zidisha.pem
index 1326aa8..91c14c4 100644
--- app/src/main/res/raw/cert_zidisha.pem
+++ app/src/main/res/raw/cert_zidisha.pem
@@ -1,31 +1,32 @@
------BEGIN CERTIFICATE-----

-DpTT/zON250=
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+DpTT/zON250=
+-----END CERTIFICATE-----
+www.zidisha.org:443
diff --git tools/print_expired_certificates tools/print_expired_certificates
deleted file mode 100755
index b233f24..0000000
--- tools/print_expired_certificates
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-for cert in `dirname $0`/../app/src/main/res/raw/*.pem; do
-  EXPIRE_DATE=`openssl x509 -in "$cert" -noout -enddate | sed -e 's/notAfter=\(.*\)/\1/g'`
-  if [ `date --date="$EXPIRE_DATE" "+%s"` -lt `date "+%s"` ]; then
-    echo `basename $cert`: $EXPIRE_DATE
-  fi
-done
diff --git tools/refresh_bank_certificates tools/refresh_bank_certificates
new file mode 100755
index 0000000..c282e59
--- /dev/null
+++ tools/refresh_bank_certificates
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+
+# This script can be used to update bankdroid's bank certificates to
+# match the certificates used by the servers.
+#
+# For this script to understand which server it should contact to
+# refresh a certificate, the server's hostname and port need to be
+# added on the last line of the certificate (after the certificate's
+# pem data).
+#
+# Note: The downloaded certificates are not validated, so you should
+# verify that each updated certificate is really from a trusted
+# server.
+
+import glob
+import os
+import re
+import select
+import socket
+import time
+import OpenSSL.crypto as crypto
+import OpenSSL.SSL as ssl
+
+
+def read_host_information(cert_file):
+    for line in reversed(open(cert_file).readlines()):
+        line = line.strip()
+        if len(line) == 0:
+            continue
+
+        m = re.match("([-.0-9a-z]+):([0-9]{2,5})", line, re.IGNORECASE)
+        if not m:
+            break
+
+        return (m.group(1), int(m.group(2)))
+
+    return None
+
+
+def get_pem_certificate(host):
+    CONNECTION_TIMEOUT = 10.0  # seconds
+
+    for ssl_method in [ssl.TLSv1_METHOD, ssl.SSLv23_METHOD]:
+        s = None
+        ssl_connection = None
+
+        try:
+            s = socket.socket()
+            s.settimeout(CONNECTION_TIMEOUT)
+            s.connect(host)
+            ssl_connection = ssl.Connection(ssl.Context(ssl_method), s)
+            ssl_connection.set_connect_state()
+            # Some servers require "Server Name Indication" to be set
+            # in the client's TLS hello
+            ssl_connection.set_tlsext_host_name(host[0])
+
+            handshake_start_time = time.time()
+            while time.time() - handshake_start_time < CONNECTION_TIMEOUT:
+                try:
+                    ssl_connection.do_handshake()
+                    break
+                except ssl.WantReadError:
+                    select.select([ssl_connection], [], [], 1)
+                except ssl.WantWriteError:
+                    select.select([], [ssl_connection], [], 1)
+            else:
+                continue
+
+            return crypto.dump_certificate(
+                crypto.FILETYPE_PEM, ssl_connection.get_peer_certificate())
+        except (socket.error, ssl.Error):
+            continue
+        finally:
+            if ssl_connection:
+                ssl_connection.close()
+            if s:
+                s.close()
+
+    return None
+
+
+def write_certificate(cert_file, host, cert):
+    f = open(cert_file, "w")
+    f.write(cert)
+    f.write("%s:%d\n" % host)
+    f.close()
+
+
+if __name__ == "__main__":
+    certificate_files_pattern = os.path.normpath(os.path.dirname(
+        os.path.realpath(__file__)) + "/../app/src/main/res/raw/*.pem")
+    for cert_file in glob.glob(certificate_files_pattern):
+        host = read_host_information(cert_file)
+        if host is None:
+            print "Could not find host information in %s." % cert_file
+            print "This script needs to know hostname and port of the server"
+            print "from where the certificate can be retrieved. Please add"
+            print "this information in the last line of the certificate file"
+            print "(after the certificate data). Write the hostname"
+            print "information in the form 'hostname:port'."
+            print
+            continue
+
+        cert = get_pem_certificate(host)
+        if cert is None:
+            print "Failed to get certificate for %s (from %s:%d)" % (
+                cert_file, host[0], host[1])
+            print
+            continue
+
+        write_certificate(cert_file, host, cert)

commit 00ce54cdc6552b8e332a44dc557cac28c302ed94 (tag: v1.9.7.4)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Feb 21 23:06:19 2015 +0100

    Creates release 1.9.7.4

diff --git CHANGES.txt CHANGES.txt
index 0d83ae2..0888538 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,4 +1,4 @@
-v1.9.7.4: (2015-02-20)
+v1.9.7.4: (2015-02-21)
 * Updated certificates for ICA Banken, Västtrafik, Brummer KF, Diners Club, Ikano Bank, Marginalen, Trustbuddy, Zidisha, AmericanExpress, TicketRikskortet
 * Adds support for Coop's MedMera-Före and MedMera-Efter (thanks to fredrike)
 * Adds support for Blekingetrafiken (thanks to fredrike)
diff --git app/build.gradle app/build.gradle
index 1880c66..5c3e519 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 196
-        versionName "1.9.7.4-RC2"
+        versionCode 197
+        versionName "1.9.7.4"
     }
 
     final Console console = System.console();

commit c62ae4a4fa680cd0d6b141aad40ef2e0604ba866 (tag: v1.9.7.4-RC2)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 20 12:03:32 2015 +0100

    Creates release 1.9.7.4-RC2

diff --git CHANGES.txt CHANGES.txt
index 0b463ed..0d83ae2 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,8 +1,8 @@
-v1.9.7.4: (2015-02-18)
-* Updated certificates for ICA Banken, Västtrafik, Brummer KF, Diners Club, Ikano Bank, Marginalen, Trustbuddy, Zidisha
-* Adds support for Coop's MedMera MasterCard (thanks to fredrike)
+v1.9.7.4: (2015-02-20)
+* Updated certificates for ICA Banken, Västtrafik, Brummer KF, Diners Club, Ikano Bank, Marginalen, Trustbuddy, Zidisha, AmericanExpress, TicketRikskortet
+* Adds support for Coop's MedMera-Före and MedMera-Efter (thanks to fredrike)
 * Adds support for Blekingetrafiken (thanks to fredrike)
-* Adds suport for Östgötatrafiken (thanks to robho)
+* Adds support for Östgötatrafiken (thanks to robho)
 * Adds support for point account and transactions for Coop (thanks to fredrike)
 * Adds support for Coop's MedMera Efter credit card (thanks to fredrike)
 * Adds possibility to go back to the account view from the transaction view by clicking on the logotype (thanks to fredrike)
@@ -11,6 +11,7 @@ v1.9.7.4: (2015-02-18)
 * Fix Handshake failed errors for FirstCard and PostGirot
 * Fix for credit card currency error for Nordea (thanks to Ree)
 * Fix for Västtrafik (thanks to jonasgroth) 
+* Fix balance for Avanza (thanks to fredrike)
 
 v1.9.7.3: (2014-11-21)
 * Fix for Nordea balance (thanks to sed)
diff --git app/build.gradle app/build.gradle
index 48d7787..1880c66 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 195
-        versionName "1.9.7.4-RC1"
+        versionCode 196
+        versionName "1.9.7.4-RC2"
     }
 
     final Console console = System.console();

commit 2c05df5a29c46a3895cf7457c18601b099427f5f
Merge: a5ebd08 921db2a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 20 11:57:44 2015 +0100

    Merge pull request #404 from fredrike/coop-patch
    
    Adds support for MedMera-Efter and MedMera-Före

commit a5ebd089b2d98fb80762412dc7392d57b34360a9
Merge: ed55bdf c91b485
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Feb 20 11:56:27 2015 +0100

    Merge pull request #405 from fredrike/avanza-patch
    
    Adds support for account balance for Avanza.

commit 921db2a2eca5f4d8c324b93f8278380781b33ce3
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Feb 20 10:57:40 2015 +0100

    Fixed support for MedMera-Efter (apperntly there are two urls that needs checking), Added MedMera-Före, Char prefix changed for Coop Poäng

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index cf7b577..c011976 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -82,6 +82,8 @@ public class Coop extends Bank {
     enum AccountType {
         MEDMERA_KONTO("konto_", "https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/"),
         MEDMERA_EFTER("efter_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter/"),
+        MEDMERA_EFTER1("efter1_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter1/"),
+        MEDMERA_FORE("fore_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Fore/"),
         MEDMERA_MER("mer_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Mer/"),
         MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 
@@ -231,7 +233,7 @@ public class Coop extends Bank {
         try {
             response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
             Document dResponse = Jsoup.parse(response);
-            Account poang = new Account("Poäng",
+            Account poang = new Account("\u2014  Poäng",
                     Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()),
                     "poang", Account.OTHER, "");
             List<Transaction> transactions = new ArrayList<Transaction>();

commit 92d3734cce9cd814a1a52625474ce368ad40c2c5
Merge: 0330fd8 f37cd74
Author: liato <x@x00.us>
Date:   Thu Feb 19 23:23:05 2015 +0100

    Merge pull request #401 from robho/print_expired_certificates_script
    
    Add basic shell script which prints expired certificates

commit f37cd746c3fef79cc557fdcfb15003e7de4e3fe8
Author: Robert Hogberg <robert.hogberg@gmail.com>
Date:   Thu Feb 19 23:09:15 2015 +0100

    Add basic shell script which prints expired certificates

diff --git tools/print_expired_certificates tools/print_expired_certificates
new file mode 100755
index 0000000..b233f24
--- /dev/null
+++ tools/print_expired_certificates
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+for cert in `dirname $0`/../app/src/main/res/raw/*.pem; do
+  EXPIRE_DATE=`openssl x509 -in "$cert" -noout -enddate | sed -e 's/notAfter=\(.*\)/\1/g'`
+  if [ `date --date="$EXPIRE_DATE" "+%s"` -lt `date "+%s"` ]; then
+    echo `basename $cert`: $EXPIRE_DATE
+  fi
+done

commit ed55bdf95a0413941ab31d31488f8b394b0eb790
Author: Robert Hogberg <robert.hogberg@gmail.com>
Date:   Wed Feb 18 22:52:00 2015 +0100

    Certificate update

diff --git app/src/main/res/raw/cert_ticketrikskortet.pem app/src/main/res/raw/cert_ticketrikskortet.pem
index 0d40b84..f56cd1d 100644
--- app/src/main/res/raw/cert_ticketrikskortet.pem
+++ app/src/main/res/raw/cert_ticketrikskortet.pem
@@ -1,30 +1,30 @@
------BEGIN CERTIFICATE-----

-1psJlnRKDzQWFAj6CZ0oyGA1qHsxHA==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----

commit 81ae6c4060368277f755227195e1227cfaaf29c9
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Feb 19 20:43:30 2015 +0100

    Updates certificate for AmericanExpress Global

diff --git app/src/main/res/raw/cert_americanexpress_global.pem app/src/main/res/raw/cert_americanexpress_global.pem
index 773b769..bc65ec4 100644
--- app/src/main/res/raw/cert_americanexpress_global.pem
+++ app/src/main/res/raw/cert_americanexpress_global.pem
@@ -1,31 +1,32 @@
------BEGIN CERTIFICATE-----

-ZZZmPHKzZcQMXHKr/HckqlRrzxUHdgdryY0=
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+Sh3UmBWpiuWsR+Wp2+geW7Lc2ULeyeTWM9CVCUNUtXskjg==
+-----END CERTIFICATE-----

commit df83e7e035acdfb95a79831331c17ebde67c0962 (tag: v1.9.7.4-RC1)
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 18 19:32:34 2015 +0100

    Updates release notes.

diff --git CHANGES.txt CHANGES.txt
index 84ad935..0b463ed 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -2,6 +2,7 @@ v1.9.7.4: (2015-02-18)
 * Updated certificates for ICA Banken, Västtrafik, Brummer KF, Diners Club, Ikano Bank, Marginalen, Trustbuddy, Zidisha
 * Adds support for Coop's MedMera MasterCard (thanks to fredrike)
 * Adds support for Blekingetrafiken (thanks to fredrike)
+* Adds suport for Östgötatrafiken (thanks to robho)
 * Adds support for point account and transactions for Coop (thanks to fredrike)
 * Adds support for Coop's MedMera Efter credit card (thanks to fredrike)
 * Adds possibility to go back to the account view from the transaction view by clicking on the logotype (thanks to fredrike)
diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index 9d9c5b2..df3dc78 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -41,6 +41,7 @@ Development
   Niclasl                           https://github.com/NiclasI
   Mikael Eriksson                   https://github.com/mikaeler
   Mikael Auno                       https://github.com/auno
+  robho                             https://github.com/robho
 
 
   Stats at:

commit bbb8fe75e4545ffa60db380d0d5e3cc9735be4ff
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 18 15:33:21 2015 +0100

    Create release candidate.

diff --git app/build.gradle app/build.gradle
index f59fdda..48d7787 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 194
-        versionName "1.9.7.3"
+        versionCode 195
+        versionName "1.9.7.4-RC1"
     }
 
     final Console console = System.console();

commit 325795bbdb912a8fdc7a7bdb34d1c886fbea95c2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 18 15:32:14 2015 +0100

    Adds release notes

diff --git CHANGES.txt CHANGES.txt
index fc52190..84ad935 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,16 @@
+v1.9.7.4: (2015-02-18)
+* Updated certificates for ICA Banken, Västtrafik, Brummer KF, Diners Club, Ikano Bank, Marginalen, Trustbuddy, Zidisha
+* Adds support for Coop's MedMera MasterCard (thanks to fredrike)
+* Adds support for Blekingetrafiken (thanks to fredrike)
+* Adds support for point account and transactions for Coop (thanks to fredrike)
+* Adds support for Coop's MedMera Efter credit card (thanks to fredrike)
+* Adds possibility to go back to the account view from the transaction view by clicking on the logotype (thanks to fredrike)
+* Use SvenskaSpel's API (thanks to mikaeler)
+* Fix for null currency for credit cards for Swedbank and Sparbankerna. Defaults to SEK.
+* Fix Handshake failed errors for FirstCard and PostGirot
+* Fix for credit card currency error for Nordea (thanks to Ree)
+* Fix for Västtrafik (thanks to jonasgroth) 
+
 v1.9.7.3: (2014-11-21)
 * Fix for Nordea balance (thanks to sed)
 * Fix for widget sizes

commit 0330fd80810eb0472dae5ca3cdaedba9527908d0
Merge: 7baea8f 0bb3775
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 18 19:07:48 2015 +0100

    Merge pull request #271 from robho/master
    
    Support for Östgötatrafiken's travel cards.

commit 0bb3775d4a7eae6f039bbda05b7d7ab0ec931bf9
Author: Robert Högberg <robert.hogberg@gmail.com>
Date:   Sun Jan 19 20:25:49 2014 +0100

    Add support for Östgötatrafiken's travel cards

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index dcf59da..7948be5 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -57,6 +57,7 @@ import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Opel;
+import com.liato.bankdroid.banking.banks.Ostgotatrafiken;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.PlusGirot;
@@ -268,6 +269,8 @@ public class BankFactory {
             return new Sparbankerna(context);
         case IBankTypes.BLEKINGETRAFIKEN:
             return new BlekingeTrafiken(context);
+        case IBankTypes.OSTGOTATRAFIKEN:
+            return new Ostgotatrafiken(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -353,6 +356,7 @@ public class BankFactory {
         banks.add(new SupremeCard(context));
         banks.add(new Sparbankerna(context));
         banks.add(new BlekingeTrafiken(context));
+        banks.add(new Ostgotatrafiken(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java app/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
new file mode 100644
index 0000000..aba1105
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Ostgotatrafiken.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Ostgotatrafiken extends Bank {
+	private static final String TAG = "Östgötatrafiken";
+	private static final String NAME = "Östgötatrafiken";
+	private static final String NAME_SHORT = "ogt";
+	private static final String URL = "https://www.ostgotatrafiken.se/Priser--biljetter/Mina-sidor/Login/";
+	private static final int BANKTYPE_ID = IBankTypes.OSTGOTATRAFIKEN;
+
+	private Pattern reViewState = Pattern.compile("<input [^>]+ id=\"javax.faces.ViewState\"[^>]* value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+	private Pattern reMoreCards = Pattern.compile("<li><a [^>]+ id=\"(form1cardOverviewTabs[^\"]+)\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+	private Pattern reCardNumber = Pattern.compile(">Kortnummer: (\\d+)<", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+	private Pattern reCardName = Pattern.compile("<li class=\"selected\">.*?>(\\w+?)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+	private Pattern reCardBalance = Pattern.compile(">Saldo<.*?>\\s*(\\d+)\\s*kr\\s*</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+	private String response = null;
+
+	public Ostgotatrafiken(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Ostgotatrafiken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	protected LoginPackage preLogin() throws BankException,
+	ClientProtocolException, IOException {
+		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ostgotatrafiken_login, R.raw.cert_ostgotatrafiken_overview));
+
+		List <NameValuePair> postData = new ArrayList <NameValuePair>();
+		postData.add(new BasicNameValuePair("Username", username));
+		postData.add(new BasicNameValuePair("Password", password));
+		postData.add(new BasicNameValuePair("Login", "Logga in"));
+
+		return new LoginPackage(urlopen, postData, response, URL);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (!response.contains("Logga ut")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+
+		try {
+			String cardOverviewUrl = "https://webtick.ostgotatrafiken.se/webtick/user/pages/CardOverview.iface";
+			response = urlopen.open(cardOverviewUrl);
+			parseTravelCardBalanceFromServerResponse(response);
+
+			Matcher viewStateMatcher = reViewState.matcher(response);
+			if (!viewStateMatcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState");
+			}
+			Matcher moreCardsMatcher = reMoreCards.matcher(response);
+			while (moreCardsMatcher.find()) {
+				List <NameValuePair> postData = new ArrayList <NameValuePair>();
+				postData.add(new BasicNameValuePair("form1cardOverviewTabs:j_idcl", moreCardsMatcher.group(1)));
+				postData.add(new BasicNameValuePair("ice.focus", moreCardsMatcher.group(1)));
+				postData.add(new BasicNameValuePair(moreCardsMatcher.group(1), moreCardsMatcher.group(1)));
+				postData.add(new BasicNameValuePair("form1cardOverviewTabs", "form1cardOverviewTabs"));
+				postData.add(new BasicNameValuePair("ice.event.captured", moreCardsMatcher.group(1)));
+				postData.add(new BasicNameValuePair("javax.faces.source", moreCardsMatcher.group(1)));
+				postData.add(new BasicNameValuePair("javax.faces.ViewState", viewStateMatcher.group(1)));
+
+				postData.add(new BasicNameValuePair("icefacesCssUpdates", ""));
+				postData.add(new BasicNameValuePair("javax.faces.partial.event", "click"));
+				postData.add(new BasicNameValuePair("javax.faces.partial.execute", "@all"));
+				postData.add(new BasicNameValuePair("javax.faces.partial.render", "@all"));
+				postData.add(new BasicNameValuePair("ice.event.type", "onclick"));
+				postData.add(new BasicNameValuePair("ice.event.alt", "false"));
+				postData.add(new BasicNameValuePair("ice.event.ctrl", "false"));
+				postData.add(new BasicNameValuePair("ice.event.shift", "false"));
+				postData.add(new BasicNameValuePair("ice.event.meta", "false"));
+				postData.add(new BasicNameValuePair("ice.event.x", "606"));
+				postData.add(new BasicNameValuePair("ice.event.y", "362"));
+				postData.add(new BasicNameValuePair("ice.event.left", "true"));
+				postData.add(new BasicNameValuePair("ice.event.right", "false"));
+				postData.add(new BasicNameValuePair("ice.submit.type", "ice.s"));
+				postData.add(new BasicNameValuePair("ice.submit.serialization", "form"));
+				postData.add(new BasicNameValuePair("javax.faces.partial.ajax", "true"));
+
+				// ice.event.target is sent by browser, but not needed by
+				// server so don't bother parsing response for its correct value
+				//postData.add(new BasicNameValuePair("ice.event.target", "form1cardOverviewTabs:j_idt240:1:j_idt243"));
+
+				// ice.window and ice.view are sent by browser, but by not sending
+				// these to server we get an HTML response which can be parsed
+				// just like the initial response. If including ice.window and
+				// ice.view in POST the server will give us XML data back which
+				// would need separate parsing.
+				//postData.add(new BasicNameValuePair("ice.window", "p7htbwx9t8"));
+				//postData.add(new BasicNameValuePair("ice.view", "vcuag6esom"));
+
+				urlopen.addHeader("Faces-Request", "partial/ajax");
+				response = urlopen.open(cardOverviewUrl, postData);
+				parseTravelCardBalanceFromServerResponse(response);
+			}
+
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			super.updateComplete();
+		}
+	}
+
+	private void parseTravelCardBalanceFromServerResponse(String response) {
+		Matcher cardNameMatcher = reCardName.matcher(response);
+		Matcher cardNumberMatcher = reCardNumber.matcher(response);
+		Matcher balanceMatcher = reCardBalance.matcher(response);
+
+		if (cardNameMatcher.find() && cardNumberMatcher.find() && balanceMatcher.find()) {
+			String cardName = cardNameMatcher.group(1);
+			String cardNumber = cardNumberMatcher.group(1);
+			String cardBalance = balanceMatcher.group(1);
+
+			accounts.add(new Account(cardName, Helpers.parseBalance(cardBalance), cardNumber));
+			balance = balance.add(Helpers.parseBalance(cardBalance));
+		}
+	}
+}
diff --git app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 70a4640..0c16f43 100644
--- app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -99,4 +99,5 @@ public interface IBankTypes {
     public final static int SUPREMECARD  = 75;
     public final static int SPARBANKERNA = 76;
     public final static int BLEKINGETRAFIKEN = 77;
+    public final static int OSTGOTATRAFIKEN = 78;
 }
diff --git app/src/main/res/drawable/logo_ogt.png app/src/main/res/drawable/logo_ogt.png
new file mode 100644
index 0000000..8232ff8
Binary files /dev/null and app/src/main/res/drawable/logo_ogt.png differ
diff --git app/src/main/res/raw/cert_ostgotatrafiken_login.pem app/src/main/res/raw/cert_ostgotatrafiken_login.pem
new file mode 100644
index 0000000..4776515
--- /dev/null
+++ app/src/main/res/raw/cert_ostgotatrafiken_login.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+MCe7Jchh43bGAvJhOzi706Enkio=
+-----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_ostgotatrafiken_overview.pem app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
new file mode 100644
index 0000000..461e140
--- /dev/null
+++ app/src/main/res/raw/cert_ostgotatrafiken_overview.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+YQuw4+jd
+-----END CERTIFICATE-----

commit 7baea8f88df93543614cf985d08806775c9d78ac
Merge: 438882b 18d66c6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 18 15:02:12 2015 +0100

    Merge pull request #379 from mikaeler/master
    
    Changed API for Svenska Spel. Fixes #376

commit 438882bdd7109bc6b0c1ec396192231afdfa4503
Author: mahsberg <mathias.ahsberg@cloudfinder.com>
Date:   Wed Feb 18 01:00:56 2015 +0100

    Upgrades gradle wrapper

diff --git gradlew gradlew
old mode 100644
new mode 100755

commit 81a0e99942376752e6068309af6c4deec4c4fb7f
Author: mahsberg <mathias.ahsberg@cloudfinder.com>
Date:   Wed Feb 18 00:35:35 2015 +0100

    Removes diamond declaration for List

diff --git app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index ff68fc3..7b856eb 100644
--- app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -176,7 +176,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
         // Fix for supporting old servers.
         // See https://code.google.com/p/android-developer-preview/issues/detail?id=1200#c23
         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
-            List<String> ciphers = new ArrayList<>(Arrays.asList(vSocket.getEnabledCipherSuites()));
+            List<String> ciphers = new ArrayList<String>(Arrays.asList(vSocket.getEnabledCipherSuites()));
             ciphers.remove("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
             ciphers.remove("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
             vSocket.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));

commit d03edc64e1082325dddf1514ef04ad264e2f37bf
Merge: 0f9bd1a 6655edf
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Feb 18 00:28:58 2015 +0100

    Merge pull request #399 from liato/feature/sslv3-fix
    
    Fixes support for old servers and removes SSLv3.

commit 6655edfdb1f84296aee468aa4fb279f8d1b8dba1
Author: mahsberg <mathias.ahsberg@cloudfinder.com>
Date:   Wed Feb 18 00:24:49 2015 +0100

    Fixes support for old servers and removes SSLv3.

diff --git app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index d70759c..ff68fc3 100644
--- app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -19,6 +19,8 @@ package eu.nullbyte.android.urllib;
  * under the License.
  */
 
+import android.os.Build;
+
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.params.HttpConnectionParams;
@@ -35,6 +37,9 @@ import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
@@ -132,7 +137,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
     @Override
     public Socket createSocket() throws IOException {
         //Log.v(TAG, "createSocket()");
-        return getSSLContext().getSocketFactory().createSocket();
+        return secureSocket(getSSLContext().getSocketFactory().createSocket());
     }
 
 
@@ -145,7 +150,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
             throws IOException, UnknownHostException {
         //Log.v(TAG, "createSocket(socket: " + socket + ", host: " + host + ", port: " + port + ", autoClose: " + autoClose);
         lastHost = host;
-        return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
+        return secureSocket(getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose));
     }
 
     public void setHost(String host) {
@@ -154,4 +159,28 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
             mTrustManager.setHost(host);
         }
     }
+
+    private Socket secureSocket(Socket socket) {
+        if(!(socket instanceof SSLSocket)) {
+            return socket;
+        }
+        
+        SSLSocket vSocket = (SSLSocket) socket;
+
+        // Remove SSLv3 support.
+        // See https://code.google.com/p/android/issues/detail?id=78187
+        List<String> supportedProtocols = new ArrayList<String>(Arrays.asList(vSocket.getSupportedProtocols()));
+        supportedProtocols.remove("SSLv3");
+        vSocket.setEnabledProtocols(supportedProtocols.toArray(new String[supportedProtocols.size()]));
+
+        // Fix for supporting old servers.
+        // See https://code.google.com/p/android-developer-preview/issues/detail?id=1200#c23
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
+            List<String> ciphers = new ArrayList<>(Arrays.asList(vSocket.getEnabledCipherSuites()));
+            ciphers.remove("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
+            ciphers.remove("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
+            vSocket.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));
+        }
+        return vSocket;
+    }
 }

commit 0f9bd1ad2a16654eb6c0f072f12e450bf13511d3
Merge: 54392f1 a2e7529
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Feb 16 20:51:27 2015 +0100

    Merge pull request #394 from fredrike/account-back
    
    Support to go back to main view from transaction view

commit 54392f189bab788d6828b741040ce5b6d2a27fc4
Merge: 4508769 8b60f10
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Feb 16 20:51:12 2015 +0100

    Merge pull request #391 from fredrike/toggle-account-view
    
    Better support to hide all accounts

commit 4508769e6ead46e731b679c944a1f3b30bec8401
Merge: ac907e4 bb0b2f7
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Feb 16 20:49:00 2015 +0100

    Merge pull request #392 from fredrike/blekingetrafiken
    
    Change from number input to phone for Blekingetrafiken

commit ac907e4404952a34a66ef686bb93d580323c62cf
Merge: 8da0778 b56a243
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Feb 16 20:48:15 2015 +0100

    Merge pull request #393 from fredrike/coop-patch
    
    Added support for point balance at Coop

commit 8da0778fd8a8de46149dea9098ea4138ce47502f
Merge: ae3d76a 0403b55
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Feb 16 20:47:50 2015 +0100

    Merge pull request #395 from wicol/nordea-desktop
    
    Fixed faulty credit card currency parsing for Nordea

commit ae3d76abd5027c5da634cc03259fbcb4ef9adf08
Merge: bdc3360 1f7fad2
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Feb 16 20:46:41 2015 +0100

    Merge pull request #396 from liato/feature/certificates
    
    Fixes outdated certificates

commit 1f7fad289e410361917fa2311c877c1d401f26d2
Author: mahsberg <mathias.ahsberg@cloudfinder.com>
Date:   Mon Feb 16 20:41:37 2015 +0100

    Fixes outdated certificates

diff --git app/src/main/res/raw/cert_brummer.pem app/src/main/res/raw/cert_brummer.pem
index 5d074ce..09e0d9d 100644
--- app/src/main/res/raw/cert_brummer.pem
+++ app/src/main/res/raw/cert_brummer.pem
@@ -1,33 +1,30 @@
 -----BEGIN CERTIFICATE-----

+kfLSPLGscWmnR6JTBY7mdzkaCBkFXIyqN06pV3kxzxjtCqBwdg==
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_dinersclub.pem app/src/main/res/raw/cert_dinersclub.pem
index d504022..5e7ce2c 100644
--- app/src/main/res/raw/cert_dinersclub.pem
+++ app/src/main/res/raw/cert_dinersclub.pem
@@ -1,35 +1,34 @@
------BEGIN CERTIFICATE-----

-TLZpQwLZfSpf
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+JEoC5a8o3g==
+-----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_ikanobank.pem app/src/main/res/raw/cert_ikanobank.pem
index 03be7ec..e07ed5d 100644
--- app/src/main/res/raw/cert_ikanobank.pem
+++ app/src/main/res/raw/cert_ikanobank.pem
@@ -1,33 +1,38 @@
------BEGIN CERTIFICATE-----

-l+Ov
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_marginalen.pem app/src/main/res/raw/cert_marginalen.pem
index 9f610ac..bde1811 100644
--- app/src/main/res/raw/cert_marginalen.pem
+++ app/src/main/res/raw/cert_marginalen.pem
@@ -1,35 +1,34 @@
------BEGIN CERTIFICATE-----

-yB5UmZXUFg==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_trustbuddy.pem app/src/main/res/raw/cert_trustbuddy.pem
index 7a6d499..fe1a01d 100644
--- app/src/main/res/raw/cert_trustbuddy.pem
+++ app/src/main/res/raw/cert_trustbuddy.pem
@@ -1,33 +1,42 @@
------BEGIN CERTIFICATE-----

-cnUy20d8PvQ+aY1ugUPRBjFHksFAKA==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+NkPZyQ==
+-----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_zidisha.pem app/src/main/res/raw/cert_zidisha.pem
index b11040c..1326aa8 100644
--- app/src/main/res/raw/cert_zidisha.pem
+++ app/src/main/res/raw/cert_zidisha.pem
@@ -1,29 +1,31 @@
------BEGIN CERTIFICATE-----

-nBmNEknwJEEmDsyOF7k=
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+DpTT/zON250=
+-----END CERTIFICATE-----

commit 0403b559e745da1fd82316a309346e8c4cc07146
Author: Ree <ree@unts.se>
Date:   Mon Feb 2 22:38:58 2015 +0100

    Fixed faulty credit card currency parsing
    
    I wrongly assumed the currency column would hold the currency information for credit cards with other native currencies. It turns out it holds the native amount and currency of the /transaction/, when it's not in SEK. This fix fetches the account currency from the table header instead.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 571914d..6db0eb5 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -128,12 +128,16 @@ public class Nordea extends Bank {
             "\\s*([^<]*)\\s*</td>" + // Group 2: (trimmed) Transaction name
             "[^<]*<td[^>]*>" + // Start recipient name col (same as transaction name?)
             "[^<]*</td>" + // Transaction name
-            "[^<]*<td[^>]*>" + // Start currency col
-            "\\s*([^<]*)\\s*</td>" + // Group 3: (trimmed) Currency (Empty when SEK?)
+            "[^<]*<td[^>]*>" + // Start transaction native amount/currency col
+            "\\s*([^<]*)\\s*</td>" + // Group 3: Transaction native amount/currency (Empty when SEK)
             "[^<]*<td[^>]*>" + // Start amount col
             "\\s*([\\d,.-]+)", // Group 4: Transaction amount
             Pattern.DOTALL
     );
+    // Credit card currency
+    private Pattern reCreditCardCurrency = Pattern.compile(
+      "<th[^>]*>Belopp\\s([^<]+)</th>"
+    );
 
     // The link to go to the loans overview page
     private Pattern reLoansLink = Pattern.compile("<a href=\"([^\"#]*)#?\">Lån<");
@@ -478,7 +482,6 @@ public class Nordea extends Bank {
             throws LoginException, BankException, IOException {
         Matcher matcher;
         String link = null;
-        String currency = "";
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 
         if (this.currentPageType != PageType.CREDIT_CARDS) {
@@ -504,7 +507,6 @@ public class Nordea extends Bank {
         while (matcher.find() && transactions.size() < MAX_TRANSACTIONS) {
             String date = matcher.group(1);
             String text = matcher.group(2);
-            currency = matcher.group(3);
             BigDecimal amount = Helpers.parseBalance(matcher.group(4));
             Transaction transaction = new Transaction(date, text, amount);
             transactions.add(transaction);
@@ -512,7 +514,8 @@ public class Nordea extends Bank {
         // Add the transactions to this account
         account.setTransactions(transactions);
         // Set currency for this account
-        if (currency.length() > 0) {
+        matcher = reCreditCardCurrency.matcher(this.lastResponse);
+        if (matcher.find()) {
             account.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
         }
     }

commit c91b48595145b58b1b9ffc67f96e516275704d94
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Feb 1 11:27:34 2015 +0100

    Avanza, added support to show balance. Also, shows all sub-accounts as main accounts

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index ebfde61..4d01e6b 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -58,6 +58,7 @@ public class Avanza extends Bank {
         NAME_SHORT = "avanza";
         URL = "https://www.avanza.se/";
         BANKTYPE_ID = IBankTypes.AVANZA;
+//        STATIC_BALANCE = true;
     }
 
     public Avanza(String username, String password, Context context)
@@ -70,6 +71,7 @@ public class Avanza extends Bank {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+        balance = new BigDecimal(0);
 
         try {
             HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all", new ArrayList<NameValuePair>(), false);
@@ -87,6 +89,12 @@ public class Avanza extends Bank {
                 if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
                     ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount :  account.getCurrencyAccounts()) {
+                        transactions.add(new Transaction(Helpers.formatDate(now),
+                                "\u2014  " + currencyAccount.getCurrency() + "  \u2014",
+                                BigDecimal.valueOf(currencyAccount.getBalance()),
+                                currencyAccount.getCurrency()));
+                    }
                     for (PositionAggregation positionAgList : account.getPositionAggregations()) {
                         if (positionAgList.getPositions().isEmpty()) {
                             continue;
@@ -107,7 +115,40 @@ public class Avanza extends Bank {
                     }
                     a.setTransactions(transactions);
                 }
+                balance = balance.add(a.getBalance());
                 accounts.add(a);
+                // Add subtypes for account as own account.
+                if (!account.getPositionAggregations().isEmpty()) {
+                    Date now = new Date();
+                    for (com.liato.bankdroid.banking.banks.avanza.model.CurrencyAccount currencyAccount :  account.getCurrencyAccounts()) {
+                        accounts.add(new Account("\u2014  " + account.getAccountId() + ",  " +
+                                currencyAccount.getCurrency(),
+                                new BigDecimal(currencyAccount.getBalance()),
+                                account.getAccountId() + currencyAccount.getCurrency(),
+                                Account.OTHER,
+                                currencyAccount.getCurrency()));
+                    }
+                    for (PositionAggregation positionAgList : account.getPositionAggregations()) {
+                        if (positionAgList.getPositions().isEmpty()) {
+                            continue;
+                        }
+                        Account b = new Account("\u2014  " + account.getAccountId() + ",  " +
+                                    positionAgList.getInstrumentTypeName() +
+                                    "  " + positionAgList.getTotalProfitPercent() + "% ",
+                                new BigDecimal(positionAgList.getTotalValue()),
+                                account.getAccountId() + positionAgList.getInstrumentTypeName(),
+                                Account.OTHER, a.getCurrency());
+                        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                        for (Position p : positionAgList.getPositions()) {
+                            transactions.add(new Transaction(Helpers.formatDate(now),
+                                    p.getInstrumentName(),
+                                    BigDecimal.valueOf(p.getProfit()),
+                                    a.getCurrency()));
+                        }
+                        b.setTransactions(transactions);
+                        accounts.add(b);
+                    }
+                }
             }
         } catch (JsonParseException e) {
             e.printStackTrace();

commit a2e752961a40f12506fed5e1888dae2c7e99ff8e
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Jan 29 20:35:51 2015 +0100

    Support to go back to main view from transaction view

diff --git app/src/main/java/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
index 624ad78..c5ca11d 100644
--- app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
+++ app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
@@ -62,6 +62,12 @@ public class TransactionsActivity extends LockableActivity {
             ListView viewTransactionsList = (ListView) findViewById(R.id.lstTransactionsList);
             viewTransactionsList.setAdapter(adapter);
         }
+        findViewById(R.id.layBankHeader).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finish();
+            }
+        });
     }
 
     @Override

commit b56a243c1e955258fc84a3167a2e15f2cec0e316
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Jan 29 20:02:06 2015 +0100

    Fixes for "special" point balance
    
    Added try finally block around the parsing to stop the app from
    crashing.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 1d8b6e0..cf7b577 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -237,10 +237,20 @@ public class Coop extends Bank {
             List<Transaction> transactions = new ArrayList<Transaction>();
             poang.setTransactions(transactions);
             for (Element e : dResponse.select(".Timeline-item")) {
-                transactions.add(new Transaction(
-                    formatDate(e.select(".Timeline-header .u-nbfcAlt span").text()),
-                    e.select(".u-block").text(),
-                    Helpers.parseBalance(e.select(".Timeline-header .Timeline-title").first().ownText()), ""));
+                try {
+                    if (e.parent().hasClass("Timeline-group--emphasized")) {
+                        transactions.add(new Transaction(
+                                formatDate(e.ownText()),
+                                e.select(".Timeline-label").text(),
+                                Helpers.parseBalance(e.select(".Timeline-title").first().text()), ""));
+
+                    } else {
+                        transactions.add(new Transaction(
+                                formatDate(e.select(".Timeline-header .u-nbfcAlt span").text()),
+                                e.select(".u-block").text(),
+                                Helpers.parseBalance(e.select(".Timeline-header .Timeline-title").first().ownText()), ""));
+                    }
+                } finally { continue; }
             }
             accounts.add(poang);
             for (AccountType at : AccountType.values()) {
@@ -386,6 +396,8 @@ public class Coop extends Bank {
 
     private String formatDate(String date) {
         String[] parts = date.split(" ");
+        if( parts.length < 3)
+            return "";
         return String.format("%s-%s-%02d", parts[2], MONTHS.containsKey(parts[1].toLowerCase()) ? MONTHS.get(parts[1].toLowerCase()) : "01", Integer.parseInt(parts[0]));
     }
 

commit 8a4672acfed5414bf042fb410f773c70a9cf8268
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Jan 28 20:53:48 2015 +0100

    Added support for Coop MedMera Efter credit card

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index e0d5b44..1d8b6e0 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -81,6 +81,7 @@ public class Coop extends Bank {
 
     enum AccountType {
         MEDMERA_KONTO("konto_", "https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/"),
+        MEDMERA_EFTER("efter_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Efter/"),
         MEDMERA_MER("mer_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Mer/"),
         MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 

commit bb0b2f7cc888f1ced0f9be26d8ff5741f5e69a06
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Wed Jan 28 20:51:33 2015 +0100

    Support for updated site for Blekingetrafiken
    
    as a side note, they are no longer supporting plain JSON (as the digit
    card number have to be sent as a string)

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index b512b73..f375c49 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -40,7 +40,7 @@ public class BlekingeTrafiken extends Bank {
     private static final String TAG = "Blekingetrafiken";
     private static final String NAME = "Blekingetrafiken";
     private static final String NAME_SHORT = "blekingetrafiken";
-    private static final String URL = "http://www.blekingetrafiken.se/webshop/FService/FBalanceService.svc/card/balance/";
+    private static final String URL = "https://www.blekingetrafiken.se/webshop/card/balance/";
     private static final int BANKTYPE_ID = IBankTypes.BLEKINGETRAFIKEN;
     private String response = null;
 
@@ -77,7 +77,7 @@ public class BlekingeTrafiken extends Bank {
         try {
             LoginPackage lp = preLogin();
             HttpResponse httpResponse = urlopen.openAsHttpResponse(URL,
-                    new StringEntity("{\"cardnr\":" + username + "}"), true);
+                    new StringEntity("{\"cardnr\":\"" + username + "\"}"), true);
             if(httpResponse.getStatusLine().getStatusCode() != 200) {
                 throw new LoginException(res.getText(R.string.invalid_card_number).toString());
             }

commit 8708e7904bd6318fa9782ec47d046b01006c30d8
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Jan 26 14:20:39 2015 +0100

    Added transactions to "Poäng" account at Coop

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index d7c512e..e0d5b44 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -229,9 +229,18 @@ public class Coop extends Bank {
 
         try {
             response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
+            Document dResponse = Jsoup.parse(response);
             Account poang = new Account("Poäng",
-                    Helpers.parseBalance(Jsoup.parse(response).select(".Grid-cell--1 p").text()),
+                    Helpers.parseBalance(dResponse.select(".Grid-cell--1 p").text()),
                     "poang", Account.OTHER, "");
+            List<Transaction> transactions = new ArrayList<Transaction>();
+            poang.setTransactions(transactions);
+            for (Element e : dResponse.select(".Timeline-item")) {
+                transactions.add(new Transaction(
+                    formatDate(e.select(".Timeline-header .u-nbfcAlt span").text()),
+                    e.select(".u-block").text(),
+                    Helpers.parseBalance(e.select(".Timeline-header .Timeline-title").first().ownText()), ""));
+            }
             accounts.add(poang);
             for (AccountType at : AccountType.values()) {
                 response = urlopen.open(at.getUrl());

commit 03368d45c7a50d93f42c9d3d20f6b73134654adc
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Mon Jan 26 11:26:17 2015 +0100

    Added support for point balance at Coop

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index df1d038..d7c512e 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -228,6 +228,11 @@ public class Coop extends Bank {
         login();
 
         try {
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Mina-poang/");
+            Account poang = new Account("Poäng",
+                    Helpers.parseBalance(Jsoup.parse(response).select(".Grid-cell--1 p").text()),
+                    "poang", Account.OTHER, "");
+            accounts.add(poang);
             for (AccountType at : AccountType.values()) {
                 response = urlopen.open(at.getUrl());
                 Document d = Jsoup.parse(response);

commit 2b439f3e6f04ee76a6a4e4935e45160e538bcd30
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Jan 25 15:01:22 2015 +0100

    Change from number input to phone

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
index dcece9c..b512b73 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -51,7 +51,7 @@ public class BlekingeTrafiken extends Bank {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
-        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
         super.INPUT_HINT_USERNAME = "XXXXXXXXXX";
         super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
         super.INPUT_HIDDEN_PASSWORD = true;

commit 8b60f10a03b5cb2eff66f9c0261b4a0257e6aca5
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sun Jan 25 14:27:47 2015 +0100

    Better support to hide accounts

diff --git app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
index e770d4d..1e18ad5 100644
--- app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -55,7 +55,7 @@ public class AccountsAdapter extends BaseAdapter {
 	public void addGroup(Bank bank) {
 		banks.add(bank);
 	}
-	
+
 	public void setGroups(ArrayList<Bank> banks) {
 		this.banks = banks;
 		/*for (Bank b : this.banks) {
@@ -120,11 +120,11 @@ public class AccountsAdapter extends BaseAdapter {
                         account.getBank().getDecimalFormatter()));
 		if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
-            txtBalance.setTextColor(Color.argb(255, 191, 191, 191));		    
+            txtBalance.setTextColor(Color.argb(255, 191, 191, 191));
 		}
 		else {
             txtAccountName.setTextColor(Color.WHITE);
-            txtBalance.setTextColor(Color.WHITE);            
+            txtBalance.setTextColor(Color.WHITE);
 		}
 		return convertView;
 	}
@@ -133,7 +133,10 @@ public class AccountsAdapter extends BaseAdapter {
 	public int getCount() {
 		int c = 0;
 		for(Bank g : banks) {
-			c += g.getAccounts().size()+1;
+			if (g.getHideAccounts())
+				c++;
+ 			else
+				c += g.getAccounts().size()+1;
 		}
 		return c;
 	}
@@ -152,6 +155,10 @@ public class AccountsAdapter extends BaseAdapter {
 			if (position == i) {
 				return g;
 			}
+			else if (g.getHideAccounts()) {
+				i++;
+				continue;
+			}
 			else if (position <= (g.getAccounts().size()+i)) {
 				return g.getAccounts().get(position-i-1);
 			}
@@ -185,7 +192,7 @@ public class AccountsAdapter extends BaseAdapter {
 	    if (getItemViewType(position) == VIEWTYPE_EMPTY) return false;
 	    return true;
 	}
-        
+
 
 	@Override
 	public int getViewTypeCount () {
@@ -205,7 +212,7 @@ public class AccountsAdapter extends BaseAdapter {
 		    }
 		}
 		return VIEWTYPE_ACCOUNT;
-	}	
+	}
 }
 
 

commit bdc33604eb795b41bd41dec87bab0fe22010a8ca
Merge: 2c3da39 0096ca8
Author: liato <x@x00.us>
Date:   Sat Jan 17 00:19:16 2015 +0100

    Merge pull request #390 from fredrike/blekingetrafiken
    
    Added support for BlekingeTrafiken's pre-paid cards

commit 0096ca84be0d6100acb69570d98d4b6330f299d6
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Jan 16 14:04:01 2015 +0100

    Added support for BlekingeTrafiken's pre-paid cards

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index ea1c3c7..dcf59da 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -97,6 +97,7 @@ import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
 import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
+import com.liato.bankdroid.banking.banks.BlekingeTrafiken;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
@@ -265,6 +266,8 @@ public class BankFactory {
             return new SupremeCard(context);
         case IBankTypes.SPARBANKERNA:
             return new Sparbankerna(context);
+        case IBankTypes.BLEKINGETRAFIKEN:
+            return new BlekingeTrafiken(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -349,6 +352,7 @@ public class BankFactory {
         banks.add(new SveaDirekt(context));
         banks.add(new SupremeCard(context));
         banks.add(new Sparbankerna(context));
+        banks.add(new BlekingeTrafiken(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
new file mode 100644
index 0000000..dcece9c
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/BlekingeTrafiken.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONException;
+import org.json.JSONObject;
+import java.io.IOException;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class BlekingeTrafiken extends Bank {
+    private static final String TAG = "Blekingetrafiken";
+    private static final String NAME = "Blekingetrafiken";
+    private static final String NAME_SHORT = "blekingetrafiken";
+    private static final String URL = "http://www.blekingetrafiken.se/webshop/FService/FBalanceService.svc/card/balance/";
+    private static final int BANKTYPE_ID = IBankTypes.BLEKINGETRAFIKEN;
+    private String response = null;
+
+    public BlekingeTrafiken(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+        super.INPUT_HINT_USERNAME = "XXXXXXXXXX";
+        super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
+        super.INPUT_HIDDEN_PASSWORD = true;
+
+    }
+
+    public BlekingeTrafiken(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            IOException {
+        urlopen = new Urllib(context);
+        urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
+        urlopen.addHeader("Accept","application/json");
+        return new LoginPackage(urlopen, null , null, URL);
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(URL,
+                    new StringEntity("{\"cardnr\":" + username + "}"), true);
+            if(httpResponse.getStatusLine().getStatusCode() != 200) {
+                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+            }
+            response = EntityUtils.toString(httpResponse.getEntity());
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || username.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            JSONObject accountJSONObject = new JSONObject(response).optJSONObject("Card");
+            accountJSONObject = accountJSONObject.optJSONObject("Value");
+
+            Account a = new Account(accountJSONObject.getString("Description"),
+                    Helpers.parseBalance(accountJSONObject.getString("Remaining")),
+                    "0");
+            accounts.add(a);
+            balance = balance.add(a.getBalance());
+
+            accountJSONObject = accountJSONObject.optJSONObject("Autoload");
+            if (accountJSONObject !=  null) {
+                a = new Account(" - Kommande -",
+                        Helpers.parseBalance(accountJSONObject.getString("Value")),
+                        "1");
+                accounts.add(a);
+                balance = balance.add(a.getBalance());
+            }
+
+        } catch (JSONException e) {
+            throw new BankException(e.getMessage());
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 73e0601..70a4640 100644
--- app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -98,4 +98,5 @@ public interface IBankTypes {
     public final static int SVEADIREKT  = 74;
     public final static int SUPREMECARD  = 75;
     public final static int SPARBANKERNA = 76;
+    public final static int BLEKINGETRAFIKEN = 77;
 }
diff --git app/src/main/res/drawable/logo_blekingetrafiken.png app/src/main/res/drawable/logo_blekingetrafiken.png
new file mode 100644
index 0000000..6de35a8
Binary files /dev/null and app/src/main/res/drawable/logo_blekingetrafiken.png differ

commit 2c3da398b494c4617ccf47c1f8c1bfcf82c4f8f3
Merge: 947608b 2cc7bcb
Author: liato <x@x00.us>
Date:   Tue Jan 13 23:51:39 2015 +0100

    Merge pull request #387 from jonasgroth/master
    
    Updated Västtrafik. Fixes #141

commit 947608baa7ce4873f16a1017fa89358faa3de0eb
Merge: 5dac646 8928e79
Author: liato <x@x00.us>
Date:   Tue Jan 13 23:46:21 2015 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      added support for Coop's MedMera-Mer MasterCard
      Adds support for Android Studio 1.0

commit 5dac6464cd061076dbd9a516e98fad2f648d82c8
Author: liato <x@x00.us>
Date:   Tue Jan 13 23:46:04 2015 +0100

    Update certificate for ICA Banken.

diff --git app/src/main/res/raw/cert_icabanken.pem app/src/main/res/raw/cert_icabanken.pem
index 2bb925b..5ccc9b0 100644
--- app/src/main/res/raw/cert_icabanken.pem
+++ app/src/main/res/raw/cert_icabanken.pem
@@ -1,34 +1,37 @@
 -----BEGIN CERTIFICATE-----

-w8z6/jIFgTDUeoqdfZrN++iWQjq4DAB6pS4/6nRJeX0wj2iJJw==

 -----END CERTIFICATE-----

commit 8928e79c3fedf9dae79a6ab3402adcd383e69624
Merge: 66abf0b ea4280b
Author: liato <x@x00.us>
Date:   Tue Jan 13 23:34:40 2015 +0100

    Merge pull request #389 from fredrike/coop-patch
    
    added support for Coop's MedMera-Mer MasterCard

commit ea4280b7fbc15009e0c9f3b1edff349de2d3bcec
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Sat Jan 10 20:35:19 2015 +0100

    added support for Coop's MedMera-Mer MasterCard

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 61f10a9..df1d038 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -81,6 +81,7 @@ public class Coop extends Bank {
 
     enum AccountType {
         MEDMERA_KONTO("konto_", "https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/"),
+        MEDMERA_MER("mer_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Mer/"),
         MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 
         String prefix;

commit 2cc7bcbfb50fac3ac7d5b11b1db06d5e2cc083c4
Author: jonasgroth <jonasgroth@users.noreply.github.com>
Date:   Thu Dec 25 20:44:48 2014 +0100

    Update server certificate for Västtrafik.

diff --git app/src/main/res/raw/cert_vasttrafik.pem app/src/main/res/raw/cert_vasttrafik.pem
index 8f18f18..a8c7df3 100644
--- app/src/main/res/raw/cert_vasttrafik.pem
+++ app/src/main/res/raw/cert_vasttrafik.pem
@@ -1,28 +1,29 @@
 -----BEGIN CERTIFICATE-----
-MIIEtjCCA56gAwIBAgIQHOiLLZE9JvnBHwmTN3m1PTANBgkqhkiG9w0BAQUFADBE
+MIIE8zCCA9ugAwIBAgIQUeTHmHB7Xr1CudcxMmVzpjANBgkqhkiG9w0BAQsFADBE
 MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU
-R2VvVHJ1c3QgU1NMIENBIC0gRzIwHhcNMTQwOTE5MDAwMDAwWhcNMTUxMjE5MjM1
+R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTQxMTEyMDAwMDAwWhcNMTYxMjExMjM1
 OTU5WjBvMQswCQYDVQQGEwJTRTEPMA0GA1UECAwGU3dlZGVuMRAwDgYDVQQHDAdT
 S8OWVkRFMRYwFAYDVQQKDA1WYXN0dHJhZmlrIEFCMQswCQYDVQQLDAJJVDEYMBYG
 A1UEAwwPKi52YXN0dHJhZmlrLnNlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB

 Ki52YXN0dHJhZmlrLnNlgg12YXN0dHJhZmlrLnNlMAkGA1UdEwQCMAAwDgYDVR0P

-/o1LuYVBwcNU4Q==

+7lu66yWdSo3BXrk0mpe3BvNNjGY5R0U=
 -----END CERTIFICATE-----

commit 00f71c07cd94041dddb387b94cbc6473c6a92dc0
Author: jonasgroth <jonasgroth@users.noreply.github.com>
Date:   Thu Dec 25 20:43:48 2014 +0100

    Fix for Västtrafik

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
index f712602..f47582e 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -49,9 +49,9 @@ public class Vasttrafik extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("<div class=\"myCardsItemContainer\" data-cardnumber=\"(.*?)\">.*?<h3 class=\"cardName grid_12 clearMargin\">(.*?)</h3>.*?<div class=\"clearfix cardCharges\">(.*?)<div class=\"clearfix paddingBottom grid_12 cardOptions(.*?)\">", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
-	private Pattern reBalance = Pattern.compile("<span class=\"chargeType boldType\">(.*?): (.*?)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
-	private String response = null;
+    private Pattern reAccounts = Pattern.compile("<h3 class=\"cardName\">(.*?)</h3>(.*?)<span class=\"isAccount hidden\">", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+    private Pattern reBalance = Pattern.compile("<span class=\"chargeType\"><span class='col1'>(.*?):</span><span class='col2 boldType'>(.*?)</span></span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+    private String response = null;
 
     public Vasttrafik(Context context) {
         super(context);
@@ -81,10 +81,10 @@ public class Vasttrafik extends Bank {
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
 		postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$TextBoxUserName", username));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$TextBoxPassword", password));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$CheckBoxPersistent", "on"));
-		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$ButtonLogin", "Logga in"));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxUserName", username));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$TextBoxPassword", password));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$CheckBoxPersistent", "on"));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$MainContentRegion$AddContentRegion$ctl00$ButtonLogin", "Logga in"));
 
         return new LoginPackage(urlopen, postData, response, "https://www.vasttrafik.se/mina-sidor/logga-in/?ReturnUrl=/mina-sidor-inloggad/mina-kort/");
     }
@@ -124,16 +124,15 @@ public class Vasttrafik extends Bank {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
-                 * 1: Card number       1111111111
-                 * 2: Name              Nytt
-                 * 3: Balance information
+                 * 1: Name              Nytt
+                 * 2: Balance information
                  */
 
 				if ("".equals(matcher.group(1))) {
 					continue;
 				}
 
-                matcher_b = reBalance.matcher(matcher.group(3));
+                matcher_b = reBalance.matcher(matcher.group(2));
                 if (matcher_b.find()) {
                     /*
                      * Capture groups:
@@ -144,7 +143,7 @@ public class Vasttrafik extends Bank {
 
 					String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
 
-					accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(1)));
+					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(1)));
 					balance = balance.add(Helpers.parseBalance(balanceString));
                 }
             }

commit 66abf0bbcece7cf78864e92b44f220ed62013559
Merge: 9cb8a20 cbce84a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Dec 14 10:13:59 2014 +0100

    Merge pull request #385 from liato/feature/android-studio-1.0
    
    Adds support for Android Studio 1.0

commit cbce84ac2a0996265b153db13005facf882e21f8
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Dec 14 10:12:21 2014 +0100

    Adds support for Android Studio 1.0

diff --git build.gradle build.gradle
index 1ff0b37..15ff55d 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.14.4'
+        classpath 'com.android.tools.build:gradle:1.0.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files

commit 9cb8a2027d68ee1497889096617337cc1e72f4f3
Merge: f3b0336 3cb12a9
Author: liato <x@x00.us>
Date:   Tue Nov 25 00:53:46 2014 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Set SEK as default currency for Swedbank credit cards. Fixes #371

commit f3b03363d8701629680c5db5770c7d480abbc4ed
Author: liato <x@x00.us>
Date:   Tue Nov 25 00:53:26 2014 +0100

    Update gradle. Fix Android Studio RC1 compatibility.

diff --git app/build.gradle app/build.gradle
index 0628d36..f59fdda 100644
--- app/build.gradle
+++ app/build.gradle
@@ -38,7 +38,7 @@ android {
         
     buildTypes {
         release {
-            runProguard false
+            minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
             signingConfig signingConfigs.release
         }
diff --git build.gradle build.gradle
index a1d991f..1ff0b37 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.12.+'
+        classpath 'com.android.tools.build:gradle:0.14.4'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 856ae6d..bac4113 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Jul 10 23:49:07 CEST 2014
+#Tue Nov 25 00:35:41 CET 2014
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip

commit 18d66c6a99d94fca598e609a972f7a543fbe5a10
Author: mikaeler@gmail.com <Evabritt66!>
Date:   Sat Nov 22 22:01:20 2014 +0100

    Changed API for Svenska Spel. Fixes #376

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index e1731ed..f297567 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -22,9 +22,11 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
 
 import android.content.Context;
 import android.text.InputType;
@@ -45,12 +47,12 @@ public class SvenskaSpel extends Bank {
 	private static final String TAG = "SvenskaSpel";
 	private static final String NAME = "Svenska Spel";
 	private static final String NAME_SHORT = "svenskaspel";
-	private static final String URL = "https://m.svenskaspel.se/Customer/Login?returnUrl=/MinaSpel";
+	private static final String URL = "https://api.www.svenskaspel.se/player/sessions";
 	private static final int BANKTYPE_ID = Bank.SVENSKASPEL;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;
+	private static final int INPUT_TITLETEXT_USERNAME = R.string.username;
 
-    private Pattern reBalance = Pattern.compile("Balance\\\":\\\"([^<]+)\\\",", Pattern.CASE_INSENSITIVE);
+	private Pattern reBalance = Pattern.compile("balance\":\"(.*?)\",", Pattern.CASE_INSENSITIVE);
 	private String response = "";
 
 	public SvenskaSpel(Context context) {
@@ -60,7 +62,7 @@ public class SvenskaSpel extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME= INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
 	}
 
@@ -71,58 +73,59 @@ public class SvenskaSpel extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
+		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
 
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("username", username));
-	    postData.add(new BasicNameValuePair("password", password));
-	    postData.add(new BasicNameValuePair("loginbutton", "Logga in"));
-
-		return new LoginPackage(urlopen, postData, response, "https://m.svenskaspel.se/Customer/Login?returnUrl=/MinaSpel");
+		return new LoginPackage(urlopen, postData, response, URL);
 	}
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-        try {
-        	 LoginPackage lp = preLogin();
-             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());    
-             if (response.contains("Felaktigt anv")) {
-                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-             }
-         }
-         catch (ClientProtocolException e) {
-             throw new BankException(e.getMessage());
-         }
-         catch (IOException e) {
-             throw new BankException(e.getMessage());
-         }
-         return urlopen;
+		try {
+			LoginPackage lp = preLogin();
+
+			StringEntity postdata = new StringEntity(
+					"{\"userName\":\"" + username + "\",\"password\":\"" + password + "\"}");
+			HttpResponse httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), postdata, true);
+
+			if (httpResponse.getStatusLine().getStatusCode() != 200) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			response = EntityUtils.toString(httpResponse.getEntity());
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
 	}
 
 	@Override
 	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-        urlopen = login();
-      
-        Matcher matcher = reBalance.matcher(response);
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+
+		Matcher matcher = reBalance.matcher(response);
 		if (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: balance               845
-             * 
-             */    		    
-		   Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "1");
-           balance = Helpers.parseBalance(matcher.group(1));
-           balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-           accounts.add(account);
+			/*
+			 * Capture groups:
+			 * GROUP                    EXAMPLE DATA
+			 * 1: balance               845
+			 *
+			 */
+			Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "1");
+			balance = Helpers.parseBalance(matcher.group(1));
+			balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			accounts.add(account);
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
+		super.updateComplete();
 	}
 }
\ No newline at end of file

commit 3cb12a91e33a3195a936f426b349f71c80ba9595
Merge: d98d6db a56a685
Author: liato <x@x00.us>
Date:   Sat Nov 22 04:11:44 2014 +0100

    Merge pull request #378 from goober/feature/371-swedbank-creditcard-null-currency
    
    Set SEK as default currency for Swedbank credit cards. Fixes #371

commit a56a68502d07c18c2709b27edc3fd50b388f106d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Nov 21 23:58:28 2014 +0100

    Set SEK as default currency for Swedbank credit cards. Fixes #371

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index edbb44a..b101cfc 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -300,7 +300,8 @@ public abstract class AbstractSwedbank extends Bank {
 
     private void addCardAccounts(List<CardAccount> accountList) {
         for(CardAccount account : accountList) {
-            Account bankdroidAccount = new Account(account.getName(),account.getAvailableAmount(),account.getCardNumber(), Account.CCARD,account.getCurrency());
+            String currency = account.getCurrency() == null ? "SEK" : account.getCurrency();
+            Account bankdroidAccount = new Account(account.getName(),account.getAvailableAmount(),account.getCardNumber(), Account.CCARD,currency);
             mIdMap.put(bankdroidAccount.getId(), account.getId());
             this.accounts.add(bankdroidAccount);
         }

commit d98d6db936f63819e78f22397bcd3de5e3a09f91 (tag: v1.9.7.3)
Author: liato <x@x00.us>
Date:   Fri Nov 21 01:40:45 2014 +0100

    Bump version. v1.9.7.3.

diff --git CHANGES.txt CHANGES.txt
index 7e158d7..fc52190 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,8 @@
+v1.9.7.3: (2014-11-21)
+* Fix for Nordea balance (thanks to sed)
+* Fix for widget sizes
+
+
 v1.9.7.2: (2014-11-20)
 * Quickfix for widgets, still work to be done
 * Improved account order for Swedbank (thanks to goober)
diff --git app/build.gradle app/build.gradle
index cdbc623..0628d36 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 193
-        versionName "1.9.7.2"
+        versionCode 194
+        versionName "1.9.7.3"
     }
 
     final Console console = System.console();

commit 7edd3c02a3b61d4ea201009fc86e0a820f3a9562
Author: liato <x@x00.us>
Date:   Fri Nov 21 01:35:42 2014 +0100

    Fix widget sizes.

diff --git app/src/main/res/xml/appwidget_info.xml app/src/main/res/xml/appwidget_info.xml
index bb5ed18..ce432e7 100644
--- app/src/main/res/xml/appwidget_info.xml
+++ app/src/main/res/xml/appwidget_info.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
-    android:minWidth="146dp"
-    android:minHeight="72dp"
+    android:minWidth="110dp"
+    android:minHeight="40dp"
     android:updatePeriodMillis="0"
     android:initialLayout="@layout/widget"
     android:configure="com.liato.bankdroid.appwidget.WidgetConfigureActivity" >
diff --git app/src/main/res/xml/appwidget_info_large.xml app/src/main/res/xml/appwidget_info_large.xml
index d46fc4f..263960c 100644
--- app/src/main/res/xml/appwidget_info_large.xml
+++ app/src/main/res/xml/appwidget_info_large.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
-    android:minWidth="294dp"
-    android:minHeight="72dp"
+    android:minWidth="250dp"
+    android:minHeight="40dp"
     android:updatePeriodMillis="0"
     android:initialLayout="@layout/widget_large"
     android:configure="com.liato.bankdroid.appwidget.WidgetConfigureActivity" >

commit 63ae05e0720de64d59cc3c6b0490994790e35a31
Author: sed03 <stefan.edstrom@gmail.com>
Date:   Thu Nov 20 13:37:50 2014 +0100

    Fix balance

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 68c8d0a..571914d 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -92,7 +92,7 @@ public class Nordea extends Bank {
             ".*?" + // fast forward
             "([*\\d]+)" + // censured account number (account identifier)
             ".*?" + // fast forward
-            "([\\d\\.,]+)", // account balance
+            "<td.*?>(.*?)</td>", // account balance
             Pattern.DOTALL
     );
     private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d+,.-]*)", Pattern.DOTALL);
@@ -268,7 +268,7 @@ public class Nordea extends Bank {
                         // Account name
 						Html.fromHtml(matcher.group(3)).toString().trim(), 
 						// Balance
-                        Helpers.parseBalance(matcher.group(5)),
+                        Helpers.parseBalance(Html.fromHtml(matcher.group(5)).toString()),
                         // Account identifier - half censured account number: "************1234"
 						Html.fromHtml(matcher.group(4)).toString().trim()
 						));

commit 368fe4691644fda1c93b19c295c7ee4452ac5f0d
Merge: 845c296 0715271
Author: sed03 <stefan.edstrom@gmail.com>
Date:   Thu Nov 20 12:59:43 2014 +0100

    Merge pull request #1 from liato/master
    
    Uppdatera

commit 0715271d880d74eea95dc95257975cb7d71c2c3a (tag: v1.9.7.2)
Author: liato <x@x00.us>
Date:   Thu Nov 20 00:51:13 2014 +0100

    Bump version. v1.9.7.2.

diff --git CHANGES.txt CHANGES.txt
index 77fad4b..7e158d7 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,8 @@
+v1.9.7.2: (2014-11-20)
+* Quickfix for widgets, still work to be done
+* Improved account order for Swedbank (thanks to goober)
+
+
 v1.9.7.1: (2014-11-19)
 * Swedbank and Sparbankerna: Show transactions, fix for widget, credit card transactions, various fixes (thanks to goober, cortex, mikaeler)
 * Updated certificate for American Express, Brummer KF, CSN, EasyCard, FirstCard, ICA, Jojo, Meniga, Nordea DK, PlusGirot, Svenskaspel and Västtrafik (thanks to goober, Niclasl, auno)
diff --git app/build.gradle app/build.gradle
index ffd105a..cdbc623 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 192
-        versionName "1.9.7.1"
+        versionCode 193
+        versionName "1.9.7.2"
     }
 
     final Console console = System.console();

commit 2b3cdbc21140e2c3afd8dd03e4789882176d4b12
Merge: 849f194 c5fd442
Author: liato <x@x00.us>
Date:   Thu Nov 20 00:48:20 2014 +0100

    Merge pull request #372 from goober/feature/370-wrong-account-order-swedbank
    
    Update account order for Swedbank. Fixes #370

commit 849f194f6c744ffaec552f73aa23f79e504c65ba
Author: liato <x@x00.us>
Date:   Thu Nov 20 00:48:07 2014 +0100

    Use appcompat theme for widget activity. Closes #369.

diff --git app/src/main/AndroidManifest.xml app/src/main/AndroidManifest.xml
index b5eedb2..7ca05ec 100644
--- app/src/main/AndroidManifest.xml
+++ app/src/main/AndroidManifest.xml
@@ -69,7 +69,7 @@
 			android:name=".lockpattern.ConfirmLockPattern">
 		</activity>
 		<activity
-			android:theme="@android:style/Theme.Dialog"
+			android:theme="@style/Theme.AppCompat.Dialog"
 			android:name=".appwidget.WidgetConfigureActivity">
 			<intent-filter>
 				<action
diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index f0a19d0..3e3a98b 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -16,7 +16,6 @@
 
 package com.liato.bankdroid;
 
-import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
@@ -35,16 +34,7 @@ import android.support.v7.app.ActionBarActivity;
 import android.support.v7.widget.Toolbar;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.Window;
 import android.view.WindowManager;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.Animation.AnimationListener;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
 
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
@@ -82,8 +72,12 @@ public class LockableActivity extends ActionBarActivity {
         super.setContentView(layoutResID);
         Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
         if (toolbar != null) {
-            setSupportActionBar(toolbar);
-            toolbar.setLogo(R.drawable.ic_launcher);
+            if (shouldShowActionBar()) {
+                setSupportActionBar(toolbar);
+                toolbar.setLogo(R.drawable.ic_launcher);
+            } else {
+                toolbar.setVisibility(View.GONE);
+            }
 
         }
 //        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
@@ -331,6 +325,10 @@ public class LockableActivity extends ActionBarActivity {
             }
         }
         return bm;
-    }    
+    }
+
+    public boolean shouldShowActionBar() {
+        return true;
+    }
     
 }
diff --git app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
index fbc4dd5..092bdee 100644
--- app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
+++ app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
@@ -16,18 +16,6 @@
 
 package com.liato.bankdroid.appwidget;
 
-import java.util.ArrayList;
-
-import com.liato.bankdroid.LockableActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
-import com.liato.bankdroid.R.string;
-import com.liato.bankdroid.adapters.AccountsAdapter;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
@@ -39,6 +27,15 @@ import android.widget.AdapterView.OnItemClickListener;
 import android.widget.CheckBox;
 import android.widget.ListView;
 
+import com.liato.bankdroid.LockableActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.adapters.AccountsAdapter;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+
+import java.util.ArrayList;
+
 public class WidgetConfigureActivity extends LockableActivity {
     private static final String WIDGET_PREFIX = "widget_";
 	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
@@ -137,4 +134,8 @@ public class WidgetConfigureActivity extends LockableActivity {
 	}
 
 
+    @Override
+    public boolean shouldShowActionBar() {
+        return false;
+    }
 }

commit c5fd4424129b227b5bdc73bac6c79217d3f844d5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Nov 19 22:36:23 2014 +0100

    Update account order for Swedbank. Fixes #370

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 4130c82..edbb44a 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -152,11 +152,11 @@ public abstract class AbstractSwedbank extends Bank {
 
             OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),OverviewResponse.class);
             addAccounts(overviewResponse.getTransactionAccounts(),Account.REGULAR);
-            addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
             addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
             addAccounts(overviewResponse.getTransactionDisposalAccounts(),Account.REGULAR);
             addAccounts(overviewResponse.getSavingDisposalAccounts(),Account.REGULAR);
             addCardAccounts(overviewResponse.getCardAccounts());
+            addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
             if (this.accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }

commit eae161601c1ea25bc55ff740e92822d8e922a0c1 (tag: v1.9.7.1)
Author: liato <x@x00.us>
Date:   Wed Nov 19 01:36:31 2014 +0100

    Bump version. v1.9.7.1.

diff --git CHANGES.txt CHANGES.txt
index 5f64c48..77fad4b 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,12 @@
+v1.9.7.1: (2014-11-19)
+* Swedbank and Sparbankerna: Show transactions, fix for widget, credit card transactions, various fixes (thanks to goober, cortex, mikaeler)
+* Updated certificate for American Express, Brummer KF, CSN, EasyCard, FirstCard, ICA, Jojo, Meniga, Nordea DK, PlusGirot, Svenskaspel and Västtrafik (thanks to goober, Niclasl, auno)
+* Account balance for Nordea credit cards (thanks to sed03)
+* Fix for Jojo (thanks to sed03)
+* Toggle account visibility by long pressing an account (thanks to fredrike)
+* Show all account types for Avanza (thanks to fredrike)
+
+
 v1.9.7.0: (2014-10-31)
 * Fix for Nordea (thanks to rhoot and wicol)
 * Use Swedbank's API (thanks to goober for the implementation and Swedbank for giving us access to their API)
diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index 693ec4f..9d9c5b2 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -36,6 +36,11 @@ Development
   MathiasBois                       https://github.com/MathiasBois
   Johan Sköld                       https://github.com/rhoot
   Wictor                            https://github.com/wicol
+  sed03                             https://github.com/sed03
+  Fredrik Erlandsson                https://github.com/fredrike
+  Niclasl                           https://github.com/NiclasI
+  Mikael Eriksson                   https://github.com/mikaeler
+  Mikael Auno                       https://github.com/auno
 
 
   Stats at:
diff --git app/build.gradle app/build.gradle
index e74554e..ffd105a 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 21
-        versionCode 191
-        versionName "1.9.7.1-RC1"
+        versionCode 192
+        versionName "1.9.7.1"
     }
 
     final Console console = System.console();

commit 4837803c582a16f09fde56b54548d42b8940b76b
Merge: 040e3df 38b2aa7
Author: liato <x@x00.us>
Date:   Wed Nov 19 01:13:38 2014 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Avoid unnecessary requests to: https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/engagement/transactions/null for accounts without an id.

commit 040e3df84d128e2aae87a107802f7c5ea873dc8c
Author: liato <x@x00.us>
Date:   Wed Nov 19 01:13:24 2014 +0100

    Use actionbar. Set targetSdk to 21. Closes #348.

diff --git app/build.gradle app/build.gradle
index 307de3c..e74554e 100644
--- app/build.gradle
+++ app/build.gradle
@@ -1,13 +1,13 @@
 apply plugin: 'com.android.application'
 
 android {
-    compileSdkVersion 19
-    buildToolsVersion "19.1.0"
+    compileSdkVersion 21
+    buildToolsVersion "21.1.1"
 
     defaultConfig {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
-        targetSdkVersion 10
+        targetSdkVersion 21
         versionCode 191
         versionName "1.9.7.1-RC1"
     }
@@ -52,6 +52,7 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile "com.android.support:appcompat-v7:21.0.+"
     compile 'org.apache.commons:commons-io:1.3.2'
     compile 'com.google.collections:google-collections:1.0'
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
diff --git app/src/main/AndroidManifest.xml app/src/main/AndroidManifest.xml
index 6deb35e..b5eedb2 100644
--- app/src/main/AndroidManifest.xml
+++ app/src/main/AndroidManifest.xml
@@ -3,7 +3,7 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid">
 	<application
-		android:icon="@drawable/icon"
+		android:icon="@drawable/ic_launcher"
 		android:label="@string/app_name"
 	    android:hardwareAccelerated="true"
         android:allowBackup="true">
diff --git app/src/main/java/com/liato/bankdroid/AboutActivity.java app/src/main/java/com/liato/bankdroid/AboutActivity.java
index 1731940..7f7c72e 100644
--- app/src/main/java/com/liato/bankdroid/AboutActivity.java
+++ app/src/main/java/com/liato/bankdroid/AboutActivity.java
@@ -22,17 +22,17 @@ import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
-import android.view.View;
-import android.view.View.OnClickListener;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.widget.TextView;
 
-public class AboutActivity extends LockableActivity implements OnClickListener {
-	final static String TAG = "AboutActivity";
-	
+public class AboutActivity extends LockableActivity {
+
     @Override
-	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-	    setContentView(R.layout.about);
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.about);
         PackageInfo pInfo;
         String version = "v1.x.x";
         try {
@@ -41,29 +41,29 @@ public class AboutActivity extends LockableActivity implements OnClickListener {
         } catch (final NameNotFoundException e) {
             e.printStackTrace();
         }
-        ((TextView)findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));	    
-        this.addTitleButton(R.drawable.title_icon_donate, "donate", this);
-        this.addTitleButton(R.drawable.title_icon_web, "web", this);
- 
+        ((TextView) findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));
+
     }
 
-	@Override
-	protected void onResume() {
-		super.onResume();
-	}
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        final MenuInflater inflater = new MenuInflater(this);
+        inflater.inflate(R.menu.about, menu);
+        return true;
+    }
 
     @Override
-    public void onClick(View v) {
-        String tag = (String)v.getTag();
-        Intent i = new Intent(Intent.ACTION_VIEW);
-        
-        if ("web".equals(tag)) {
-            i.setData(Uri.parse("https://github.com/liato/android-bankdroid"));
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_web:
+                Intent i = new Intent(Intent.ACTION_VIEW);
+                i.setData(Uri.parse("https://github.com/liato/android-bankdroid"));
+                startActivity(i);
+                return true;
         }
-        else if ("donate".equals(tag)) {
-            i.setData(Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KWRCBB4PAA3LC"));
-        }
-        startActivity(i);
+
+        return super.onOptionsItemSelected(item);
     }
-	
+
 }
diff --git app/src/main/java/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
index b42f633..f0a19d0 100644
--- app/src/main/java/com/liato/bankdroid/LockableActivity.java
+++ app/src/main/java/com/liato/bankdroid/LockableActivity.java
@@ -16,7 +16,6 @@
 
 package com.liato.bankdroid;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -32,6 +31,8 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.Toolbar;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -48,7 +49,7 @@ import android.widget.ProgressBar;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
 
-public class LockableActivity extends Activity {
+public class LockableActivity extends ActionBarActivity {
     private static int PATTERNLOCK_UNLOCK = 42;
 	private SharedPreferences mPrefs;
 	private Editor mEditor;
@@ -56,21 +57,21 @@ public class LockableActivity extends Activity {
 	private boolean mHasLoaded = false;
 	protected boolean mSkipLockOnce = false;
 	
-	private LinearLayout mTitlebarButtons;
+//	private LinearLayout mTitlebarButtons;
 	private LayoutInflater mInflater;
-	private ProgressBar mProgressBar;
+//	private ProgressBar mProgressBar;
 	
-    private ImageView mHomeButton;
-    private View mHomeButtonCont;
+//    private ImageView mHomeButton;
+//    private View mHomeButtonCont;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-		mLockPatternUtils = new LockPatternUtils(this);		
+		mLockPatternUtils = new LockPatternUtils(this);
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
-        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+//        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
         }
@@ -79,96 +80,102 @@ public class LockableActivity extends Activity {
 	@Override
     public void setContentView(int layoutResID) {
         super.setContentView(layoutResID);
-        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
-        View titlebar = findViewById(R.id.layTitle);
-        mTitlebarButtons = (LinearLayout)titlebar.findViewById(R.id.layTitleButtons);
-        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        if (toolbar != null) {
+            setSupportActionBar(toolbar);
+            toolbar.setLogo(R.drawable.ic_launcher);
 
-        mHomeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
-        mHomeButtonCont = titlebar.findViewById(R.id.layLogoContainer);
-        mProgressBar = (ProgressBar)titlebar.findViewById(R.id.progressBar);
-        OnClickListener listener = new View.OnClickListener() {
-            public void onClick(View v) {
-                Intent intent = new Intent(LockableActivity.this, MainActivity.class);
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                startActivity(intent);
-                LockableActivity.this.finish();
-            }
-        };
-        mHomeButton.setOnClickListener(listener);
-        mHomeButtonCont.setOnClickListener(listener);
-        setHomeButtonEnabled(true);
-    }
-
-    protected void addTitleButton(int imageResourceId, String tag, OnClickListener listener) {
-        View child = mInflater.inflate(R.layout.title_item, mTitlebarButtons, false);
-        ImageButton button = (ImageButton)child.findViewById(R.id.imgItemIcon);
-        button.setImageResource(imageResourceId);
-        button.setTag(tag);
-        child.setTag("item_"+tag);
-        button.setOnClickListener(listener);
-        mTitlebarButtons.addView(child);
-	}
-
-    protected void hideTitleButton(String tag) {
-        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
-        if (v != null) {
-            v.setVisibility(View.GONE);
-        }
-    }
-    
-    protected void showTitleButton(String tag) {
-        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
-        if (v != null) {
-            v.setVisibility(View.VISIBLE);
-        }
-    }
-
-    protected void setTitleButtonEnabled(String tag, boolean enabled) {
-        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
-        if (v != null) {
-            ImageButton button = (ImageButton)v.findViewById(R.id.imgItemIcon);
-            if (button != null) {
-                v.setEnabled(enabled);
-                v.setFocusable(enabled);
-                button.setEnabled(enabled);
-                button.setAlpha(enabled ? 255 : 50);
-            }
         }
-    }
-    
-    protected void setHomeButtonEnabled(boolean enabled) {
-        mHomeButtonCont.setFocusable(enabled);
-        mHomeButtonCont.setClickable(enabled);
-        mHomeButton.setFocusable(enabled);
-        mHomeButton.setClickable(enabled);
-    }    
-    
-    protected void setProgressBar(int progress) {
-        mProgressBar.setProgress(progress);
+//        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
+//        View titlebar = findViewById(R.id.layTitle);
+//        mTitlebarButtons = (LinearLayout)titlebar.findViewById(R.id.layTitleButtons);
+//        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+//
+//        mHomeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
+//        mHomeButtonCont = titlebar.findViewById(R.id.layLogoContainer);
+//        mProgressBar = (ProgressBar)titlebar.findViewById(R.id.progressBar);
+//        OnClickListener listener = new View.OnClickListener() {
+//            public void onClick(View v) {
+//                Intent intent = new Intent(LockableActivity.this, MainActivity.class);
+//                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+//                startActivity(intent);
+//                LockableActivity.this.finish();
+//            }
+//        };
+//        mHomeButton.setOnClickListener(listener);
+//        mHomeButtonCont.setOnClickListener(listener);
+//        setHomeButtonEnabled(true);
     }
 
-    protected void showProgressBar() {
-        mProgressBar.setVisibility(View.VISIBLE);
-    }
-
-    protected void hideProgressBar() {
-        AlphaAnimation animation = new AlphaAnimation(1, 0);
-        animation.setDuration(350);
-        animation.setAnimationListener(new AnimationListener() {
-            @Override
-            public void onAnimationEnd(Animation animation) {
-                mProgressBar.setVisibility(View.GONE);
-            }
-
-            @Override
-            public void onAnimationRepeat(Animation animation) {}
-
-            @Override
-            public void onAnimationStart(Animation animation) {}
-        });
-        mProgressBar.startAnimation(animation);
-    }
+//    protected void addTitleButton(int imageResourceId, String tag, OnClickListener listener) {
+//        View child = mInflater.inflate(R.layout.title_item, mTitlebarButtons, false);
+//        ImageButton button = (ImageButton)child.findViewById(R.id.imgItemIcon);
+//        button.setImageResource(imageResourceId);
+//        button.setTag(tag);
+//        child.setTag("item_"+tag);
+//        button.setOnClickListener(listener);
+//        mTitlebarButtons.addView(child);
+//	}
+//
+//    protected void hideTitleButton(String tag) {
+//        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
+//        if (v != null) {
+//            v.setVisibility(View.GONE);
+//        }
+//    }
+//
+//    protected void showTitleButton(String tag) {
+//        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
+//        if (v != null) {
+//            v.setVisibility(View.VISIBLE);
+//        }
+//    }
+//
+//    protected void setTitleButtonEnabled(String tag, boolean enabled) {
+//        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
+//        if (v != null) {
+//            ImageButton button = (ImageButton)v.findViewById(R.id.imgItemIcon);
+//            if (button != null) {
+//                v.setEnabled(enabled);
+//                v.setFocusable(enabled);
+//                button.setEnabled(enabled);
+//                button.setAlpha(enabled ? 255 : 50);
+//            }
+//        }
+//    }
+//
+//    protected void setHomeButtonEnabled(boolean enabled) {
+//        mHomeButtonCont.setFocusable(enabled);
+//        mHomeButtonCont.setClickable(enabled);
+//        mHomeButton.setFocusable(enabled);
+//        mHomeButton.setClickable(enabled);
+//    }
+//
+//    protected void setProgressBar(int progress) {
+//        mProgressBar.setProgress(progress);
+//    }
+//
+//    protected void showProgressBar() {
+//        mProgressBar.setVisibility(View.VISIBLE);
+//    }
+//
+//    protected void hideProgressBar() {
+//        AlphaAnimation animation = new AlphaAnimation(1, 0);
+//        animation.setDuration(350);
+//        animation.setAnimationListener(new AnimationListener() {
+//            @Override
+//            public void onAnimationEnd(Animation animation) {
+//                mProgressBar.setVisibility(View.GONE);
+//            }
+//
+//            @Override
+//            public void onAnimationRepeat(Animation animation) {}
+//
+//            @Override
+//            public void onAnimationStart(Animation animation) {}
+//        });
+//        mProgressBar.startAnimation(animation);
+//    }
     
     @Override
 	protected void onPause() {
diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 08aa6d4..2450748 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -29,10 +29,8 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.Uri;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -68,20 +66,6 @@ public class MainActivity extends LockableActivity {
 		PairApplicationsActivity.initialSetupApiKey(this);
 		
 		setContentView(R.layout.main);
-		final OnClickListener listener = new View.OnClickListener() {
-			public void onClick(final View v) {
-				final Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
-				startActivity(intentAccount);
-			}
-		};
-		final OnClickListener listener2 = new View.OnClickListener() {
-			public void onClick(final View v) {
-				new DataRetrieverTask(MainActivity.this).execute();
-			}
-		};
-		this.addTitleButton(R.drawable.title_icon_add, "add", listener);
-		this.addTitleButton(R.drawable.title_icon_refresh, "refresh", listener2);
-
 		adapter = new AccountsAdapter(this, showHidden);
 		final ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
 		adapter.setGroups(banks);
@@ -158,12 +142,12 @@ public class MainActivity extends LockableActivity {
 		final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
 		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-			showTitleButton("refresh");
+//			showTitleButton("refresh");
 			//findViewById(R.id.btnAccountsRefresh).setClickable(true);
 		}
 		else {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
-			hideTitleButton("refresh");
+//			hideTitleButton("refresh");
 			//findViewById(R.id.btnAccountsRefresh).setClickable(false);
 		}
 
@@ -176,7 +160,7 @@ public class MainActivity extends LockableActivity {
 	public boolean onCreateOptionsMenu(final Menu menu) {
 		super.onCreateOptionsMenu(menu);
 		final MenuInflater inflater = new MenuInflater(this);
-		inflater.inflate(R.menu.menu, menu);
+		inflater.inflate(R.menu.main, menu);
 		return true;
 	}
 
@@ -203,30 +187,28 @@ public class MainActivity extends LockableActivity {
 	public boolean onOptionsItemSelected (final MenuItem item){
 		Intent intent;
 		switch (item.getItemId()) {
-		case R.id.toggle_hidden:
+		case R.id.action_toggle_hidden:
 			showHidden = !showHidden;
-			if (showHidden) {
-				item.setTitle(R.string.menu_hide_hidden);
-			}
-			else {
-				item.setTitle(R.string.menu_show_hidden);
-			}
+            item.setTitle(showHidden ? R.string.menu_hide_hidden : R.string.menu_show_hidden);
 			refreshView();
 			return true;
-		case R.id.settings:
+		case R.id.action_settings:
 			intent = new Intent(this, SettingsActivity.class);
 			this.startActivity(intent);
 			//Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
 			return true;
-        case R.id.about:
+        case R.id.action_about:
             intent = new Intent(this, AboutActivity.class);
             startActivity(intent);
             return true;
-        case R.id.donate:
-            intent = new Intent(Intent.ACTION_VIEW);
-            intent.setData(Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KWRCBB4PAA3LC"));
-            startActivity(intent);
+        case R.id.action_refresh:
+            new DataRetrieverTask(MainActivity.this).execute();
             return true;
+        case R.id.action_add:
+            final Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
+            startActivity(intentAccount);
+            return true;
+
         }
 		return false;
 	}
diff --git app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
index d78a77d..e97cc73 100644
--- app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
+++ app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
@@ -49,7 +49,7 @@ public class PairApplicationsActivity extends LockableActivity {
 	protected void onCreate(final Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.pair_applications_layout);
-		setHomeButtonEnabled(false);
+//		setHomeButtonEnabled(false);
 		
 		Bundle bundle = getIntent().getExtras();
 
diff --git app/src/main/java/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
index 17a0591..624ad78 100644
--- app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
+++ app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
@@ -18,11 +18,9 @@ package com.liato.bankdroid;
 
 import android.content.Context;
 import android.os.Bundle;
-import android.view.InflateException;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.Adapter;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.ListView;
@@ -33,156 +31,139 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.Transaction;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
 public class TransactionsActivity extends LockableActivity {
-	final static String TAG = "TransactionActivity";
-	
+    final static String TAG = "TransactionActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.transactions);
+        Bundle extras = getIntent().getExtras();
+        Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
+        Account account = BankFactory.accountFromDb(this, extras.getLong("bank") + "_" + extras.getString("account"), true);
+        TextView viewBankName = (TextView) findViewById(R.id.txtListitemAccountsGroupAccountname);
+        TextView viewAccountName = (TextView) findViewById(R.id.txtListitemAccountsGroupBankname);
+        TextView viewAccountBalance = (TextView) findViewById(R.id.txtListitemAccountsGroupTotal);
+
+        ImageView icon = (ImageView) findViewById(R.id.imgListitemAccountsGroup);
+        viewBankName.setText(bank.getDisplayName());
+        viewAccountName.setText(account.getName());
+        viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        icon.setImageResource(bank.getImageResource());
+        List<Transaction> transactions = account.getTransactions();
+
+        if (transactions.size() > 0) {
+            findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
+            TransactionsAdapter adapter = new TransactionsAdapter(transactions);
+            ListView viewTransactionsList = (ListView) findViewById(R.id.lstTransactionsList);
+            viewTransactionsList.setAdapter(adapter);
+        }
+    }
+
     @Override
-	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-
-		//Use HtcListView if available
-		try {
-		    setContentView(R.layout.transactions_htc);
-		}
-		catch (InflateException e) {
-		    setContentView(R.layout.transactions);
-		}
-		Bundle extras = getIntent().getExtras();
-		Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
-		Account account = BankFactory.accountFromDb(this, extras.getLong("bank")+"_"+extras.getString("account"), true);
-		TextView viewBankName = (TextView)findViewById(R.id.txtListitemAccountsGroupAccountname);
-		TextView viewAccountName = (TextView)findViewById(R.id.txtListitemAccountsGroupBankname);
-		TextView viewAccountBalance = (TextView)findViewById(R.id.txtListitemAccountsGroupTotal);
-
-		ImageView icon = (ImageView)findViewById(R.id.imgListitemAccountsGroup);
-		viewBankName.setText(bank.getDisplayName());
-		viewAccountName.setText(account.getName());
-		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
-		icon.setImageResource(bank.getImageResource());
-		List<Transaction> transactions = account.getTransactions();
-
-		if (transactions.size() > 0) {
-			findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
-			TransactionsAdapter adapter = new TransactionsAdapter(transactions);
-	        try {
-	            Class<?> c = Class.forName("com.htc.widget.HtcListView");
-	            Object viewTransactionsList = c.cast(findViewById(R.id.lstTransactionsList));
-	            Method  method = c.getDeclaredMethod("setAdapter", Adapter.class);
-	            method.invoke(viewTransactionsList, adapter);
-	        }
-	        catch (Exception e) {
-	            ListView viewTransactionsList = (ListView)findViewById(R.id.lstTransactionsList);
-	            viewTransactionsList.setAdapter(adapter);
-	        }
-		}
-	}
-
-	@Override
-	protected void onResume() {
-		super.onResume();
-	}
-
-	private class TransactionsAdapter extends BaseAdapter {
-		private LayoutInflater inflater;
-		private ArrayList<Object> items = new ArrayList<Object>();
-
-		public TransactionsAdapter(List<Transaction> transactions) {
-			inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-			if (!transactions.isEmpty()) {
-				String date = transactions.get(0).getDate();
-				items.add(date);
-				for (Transaction transaction : transactions) {
-					if (!date.equals(transaction.getDate())) {
-						date = transaction.getDate();
-						items.add(date);
-					}
-					items.add(transaction);
-				}
-				
-			}
-		}
-
-		public View newTransactionView(Transaction transaction, ViewGroup parent, View convertView) {
-			if (convertView == null) {
-				convertView = inflater.inflate(R.layout.transaction_item, parent, false);
-			}
-			((TextView)convertView.findViewById(R.id.txtTransaction)).setText(transaction.getTransaction());
-			((TextView)convertView.findViewById(R.id.txtAmount)).setText(Helpers.formatBalance(transaction.getAmount(), transaction.getCurrency()));
-			if (transaction.getAmount().signum() == 1) {
-				((ImageView)convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_positive);
-			}
-			else {
-				((ImageView)convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_negative);
-			}
-			return convertView;
-		}
-
-		public View newDateView(String date, ViewGroup parent, View convertView) {
-			if (convertView == null) {
-				convertView = inflater.inflate(R.layout.transaction_date, parent, false);
-			}
-			((TextView)convertView.findViewById(R.id.txtDate)).setText(date);
-			return convertView;
-		}		
-
-		@Override
-		public int getCount() {
-			return items.size();
-		}
-
-		@Override
-		public Object getItem(int position) {
-			return items.get(position);
-		}
-
-		@Override
-		public long getItemId(int position) {
-			return position;
-		}
-
-		@Override
-		public View getView(int position, View convertView, ViewGroup parent) {
-			Object item = getItem(position);
-			if (item == null) {
-				return null;
-			}
-			if (item instanceof Transaction) {
-				return newTransactionView((Transaction)item, parent, convertView);
-			}
-			else if (item instanceof String) {
-				return newDateView((String)item, parent, convertView);
-			}
-			return null;
-		}
-
-		@Override
-		public boolean areAllItemsEnabled() {
-			return true;
-		}
-
-		@Override
-		public boolean isEnabled(int position) {
-			return true;
-		}
-		
-		@Override
-		public int getViewTypeCount () {
-			return 2;
-		}
-
-		@Override
-		public int getItemViewType(int position) {
-			Object item = getItem(position);
-			if (item instanceof Transaction) {
-				return 0;
-			}
-			return 1;
-		}
-
-	}
-	
+    protected void onResume() {
+        super.onResume();
+    }
+
+    private class TransactionsAdapter extends BaseAdapter {
+        private LayoutInflater inflater;
+        private ArrayList<Object> items = new ArrayList<Object>();
+
+        public TransactionsAdapter(List<Transaction> transactions) {
+            inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            if (!transactions.isEmpty()) {
+                String date = transactions.get(0).getDate();
+                items.add(date);
+                for (Transaction transaction : transactions) {
+                    if (!date.equals(transaction.getDate())) {
+                        date = transaction.getDate();
+                        items.add(date);
+                    }
+                    items.add(transaction);
+                }
+
+            }
+        }
+
+        public View newTransactionView(Transaction transaction, ViewGroup parent, View convertView) {
+            if (convertView == null) {
+                convertView = inflater.inflate(R.layout.transaction_item, parent, false);
+            }
+            ((TextView) convertView.findViewById(R.id.txtTransaction)).setText(transaction.getTransaction());
+            ((TextView) convertView.findViewById(R.id.txtAmount)).setText(Helpers.formatBalance(transaction.getAmount(), transaction.getCurrency()));
+            if (transaction.getAmount().signum() == 1) {
+                ((ImageView) convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_positive);
+            } else {
+                ((ImageView) convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_negative);
+            }
+            return convertView;
+        }
+
+        public View newDateView(String date, ViewGroup parent, View convertView) {
+            if (convertView == null) {
+                convertView = inflater.inflate(R.layout.transaction_date, parent, false);
+            }
+            ((TextView) convertView.findViewById(R.id.txtDate)).setText(date);
+            return convertView;
+        }
+
+        @Override
+        public int getCount() {
+            return items.size();
+        }
+
+        @Override
+        public Object getItem(int position) {
+            return items.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            Object item = getItem(position);
+            if (item == null) {
+                return null;
+            }
+            if (item instanceof Transaction) {
+                return newTransactionView((Transaction) item, parent, convertView);
+            } else if (item instanceof String) {
+                return newDateView((String) item, parent, convertView);
+            }
+            return null;
+        }
+
+        @Override
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return true;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 2;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            Object item = getItem(position);
+            if (item instanceof Transaction) {
+                return 0;
+            }
+            return 1;
+        }
+
+    }
+
 }
diff --git app/src/main/java/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
index e071ccc..5b10dab 100644
--- app/src/main/java/com/liato/bankdroid/WebViewActivity.java
+++ app/src/main/java/com/liato/bankdroid/WebViewActivity.java
@@ -54,12 +54,13 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.webview);
-        this.addTitleButton(R.drawable.title_icon_back, "back", this);
-        this.addTitleButton(R.drawable.title_icon_forward, "forward", this);
-        this.addTitleButton(R.drawable.title_icon_refresh, "refresh", this);
-        this.setTitleButtonEnabled("forward", false);
-        this.setTitleButtonEnabled("back", false);
-        this.setTitleButtonEnabled("refresh", false);
+        //TODO
+//        this.addTitleButton(R.drawable.title_icon_back, "back", this);
+//        this.addTitleButton(R.drawable.title_icon_forward, "forward", this);
+//        this.addTitleButton(R.drawable.title_icon_refresh, "refresh", this);
+//        this.setTitleButtonEnabled("forward", false);
+//        this.setTitleButtonEnabled("back", false);
+//        this.setTitleButtonEnabled("refresh", false);
 
         final CookieSyncManager csm = CookieSyncManager.createInstance(this);
         mWebView = (WebView)findViewById(R.id.wvBank);
@@ -71,12 +72,12 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         
         mWebView.setWebChromeClient(new WebChromeClient() {
             public void onProgressChanged(WebView view, int progress) {
-                activity.setProgressBar(progress);
+//                activity.setProgressBar(progress);
                 if (progress == 100) {
                     Handler handler = new Handler();
                     Runnable runnable = new Runnable() {
                         public void run() {
-                            activity.hideProgressBar();
+//                            activity.hideProgressBar();
                         }
                     };
                     // Let the progress bar hit 100% before we hide it.
@@ -84,7 +85,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                     
                 }
                 else if (mFirstPageLoaded) {
-                    activity.showProgressBar();
+//                    activity.showProgressBar();
                 }
             }
           });
@@ -165,7 +166,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                 //Remove the generated page from history.
                 mWebView.clearHistory();
                 mFirstPageLoaded = true;
-                activity.setTitleButtonEnabled("refresh", true);
+//                activity.setTitleButtonEnabled("refresh", true);
                 return;
             }
         }
@@ -186,8 +187,8 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         }
         
         public void handleHistoryChange() {
-            activity.setTitleButtonEnabled("back", mWebView.canGoBack());
-            activity.setTitleButtonEnabled("forward", mWebView.canGoForward());
+//            activity.setTitleButtonEnabled("back", mWebView.canGoBack());
+//            activity.setTitleButtonEnabled("forward", mWebView.canGoForward());
         }
     }	
 
diff --git app/src/main/res/drawable-hdpi-v4/icon.png app/src/main/res/drawable-hdpi-v4/icon.png
deleted file mode 100644
index be6f807..0000000
Binary files app/src/main/res/drawable-hdpi-v4/icon.png and /dev/null differ
diff --git app/src/main/res/drawable-hdpi/ic_launcher.png app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..4f4ea89
Binary files /dev/null and app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git app/src/main/res/drawable-mdpi/ic_launcher.png app/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..7c5c515
Binary files /dev/null and app/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git app/src/main/res/drawable-xhdpi/ic_launcher.png app/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..a1478e7
Binary files /dev/null and app/src/main/res/drawable-xhdpi/ic_launcher.png differ
diff --git app/src/main/res/drawable-xxhdpi/ic_launcher.png app/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..01f3aa9
Binary files /dev/null and app/src/main/res/drawable-xxhdpi/ic_launcher.png differ
diff --git app/src/main/res/drawable-xxhdpi/ic_menu_refresh.png app/src/main/res/drawable-xxhdpi/ic_menu_refresh.png
new file mode 100644
index 0000000..a513f86
Binary files /dev/null and app/src/main/res/drawable-xxhdpi/ic_menu_refresh.png differ
diff --git app/src/main/res/drawable-xxhdpi/ic_menu_web.png app/src/main/res/drawable-xxhdpi/ic_menu_web.png
new file mode 100644
index 0000000..f49e61e
Binary files /dev/null and app/src/main/res/drawable-xxhdpi/ic_menu_web.png differ
diff --git app/src/main/res/drawable-xxxhdpi/ic_launcher.png app/src/main/res/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..931ec6c
Binary files /dev/null and app/src/main/res/drawable-xxxhdpi/ic_launcher.png differ
diff --git app/src/main/res/drawable/icon.png app/src/main/res/drawable/icon.png
deleted file mode 100644
index 82a54c6..0000000
Binary files app/src/main/res/drawable/icon.png and /dev/null differ
diff --git app/src/main/res/layout/about.xml app/src/main/res/layout/about.xml
index 3120cda..6cd3b73 100644
--- app/src/main/res/layout/about.xml
+++ app/src/main/res/layout/about.xml
@@ -5,6 +5,7 @@
 	android:layout_height="fill_parent"
 	android:layout_width="fill_parent"
 	android:paddingBottom="20dp">
+    <include layout="@layout/toolbar" />
 	<ScrollView
 		android:fillViewport="true"
 		android:layout_width="fill_parent"
diff --git app/src/main/res/layout/bank.xml app/src/main/res/layout/bank.xml
index ce738ee..64a429b 100644
--- app/src/main/res/layout/bank.xml
+++ app/src/main/res/layout/bank.xml
@@ -1,130 +1,151 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat"
-	android:layout_width="fill_parent">
-
-	<ScrollView
-		android:layout_height="fill_parent"
-		android:layout_width="fill_parent"
-		android:fillViewport="true"
-		android:layout_above="@+id/TableLayout01">
-		<LinearLayout
-			android:id="@+id/LinearLayout01"
-			android:layout_height="wrap_content"
-			android:layout_below="@+id/txtErrorDesc"
-			android:layout_width="wrap_content"
-			android:orientation="vertical"
-			android:layout_alignParentTop="true"
-			android:padding="10dp">
-			<TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/bank" />
-			<Spinner
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/spnBankeditBanklist"></Spinner>
-			<TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/username"
-				android:id="@+id/txtBankeditUsername" />
-			<EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditUsername"
-				android:inputType="textEmailAddress"></EditText>
-			<TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/password"
-				android:id="@+id/txtBankeditPassword" />
-			<EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditPassword"
-				android:inputType="textPassword"></EditText>
-			<TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/custom_name" />
-			<EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditCustomName"
-				android:inputType="textCapWords"></EditText>
-			<TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/extras_field"
-				android:id="@+id/txtBankeditExtras"
-				android:visibility="gone" />
-			<EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditExtras"
-				android:inputType="textCapWords"
-				android:visibility="gone"></EditText>
-			<TextView
-				android:layout_width="wrap_content"
-				android:layout_height="wrap_content"
-				android:drawableLeft="@drawable/indicator_input_error"
-				android:text="@string/error_desc"
-				android:textSize="12sp"
-				android:drawablePadding="5dp"
-				android:id="@+id/txtErrorDesc"
-				android:visibility="invisible"></TextView>
-		</LinearLayout>
-	</ScrollView>
-	<TableLayout
-		android:id="@+id/TableLayout01"
-		android:stretchColumns="0,2"
-		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content"
-		android:layout_below="@+id/LinearLayout01"
-		android:gravity="bottom">
-		<TableRow
-			android:id="@+id/TableRow01"
-			android:layout_height="wrap_content"
-			android:gravity="center_vertical|center_horizontal"
-			android:layout_gravity="center_vertical|center_horizontal"
-			android:layout_width="fill_parent">
-			<Button
-				android:text="@string/cancel"
-				android:drawableLeft="@drawable/button_cancel"
-				android:id="@+id/btnSettingsCancel"
-				style="@style/Menu_Button"></Button>
-			<ImageView
-				android:layout_height="wrap_content"
-				android:focusable="false"
-				android:src="@drawable/menu_separator"
-				android:adjustViewBounds="true"
-				android:scaleType="fitXY"
-				android:minWidth="3dp"
-				android:maxWidth="3dp"
-				android:layout_width="wrap_content"></ImageView>
-			<Button
-				android:id="@+id/btnSettingsOk"
-				android:drawableLeft="@drawable/button_save"
-				android:text="@string/save"
-				style="@style/Menu_Button"></Button>
-		</TableRow>
-	</TableLayout>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/RelativeLayout01"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="@drawable/background_repeat">
+
+    <include
+        android:id="@+id/toolbar"
+        layout="@layout/toolbar" />
+
+    <ScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_above="@+id/TableLayout01"
+        android:layout_below="@id/toolbar"
+        android:fillViewport="true">
+
+        <LinearLayout
+            android:id="@+id/LinearLayout01"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:layout_below="@+id/txtErrorDesc"
+            android:orientation="vertical"
+            android:padding="10dp">
+
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/bank"
+                android:textSize="20sp"
+                android:typeface="sans" />
+
+            <Spinner
+                android:id="@+id/spnBankeditBanklist"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"></Spinner>
+
+            <TextView
+                android:id="@+id/txtBankeditUsername"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/username"
+                android:textSize="20sp"
+                android:typeface="sans" />
+
+            <EditText
+                android:id="@+id/edtBankeditUsername"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:inputType="textEmailAddress"></EditText>
+
+            <TextView
+                android:id="@+id/txtBankeditPassword"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/password"
+                android:textSize="20sp"
+                android:typeface="sans" />
+
+            <EditText
+                android:id="@+id/edtBankeditPassword"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:inputType="textPassword"></EditText>
+
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/custom_name"
+                android:textSize="20sp"
+                android:typeface="sans" />
+
+            <EditText
+                android:id="@+id/edtBankeditCustomName"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:inputType="textCapWords"></EditText>
+
+            <TextView
+                android:id="@+id/txtBankeditExtras"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/extras_field"
+                android:textSize="20sp"
+                android:typeface="sans"
+                android:visibility="gone" />
+
+            <EditText
+                android:id="@+id/edtBankeditExtras"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:inputType="textCapWords"
+                android:visibility="gone"></EditText>
+
+            <TextView
+                android:id="@+id/txtErrorDesc"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:drawableLeft="@drawable/indicator_input_error"
+                android:drawablePadding="5dp"
+                android:text="@string/error_desc"
+                android:textSize="12sp"
+                android:visibility="invisible"></TextView>
+        </LinearLayout>
+    </ScrollView>
+
+    <TableLayout
+        android:id="@+id/TableLayout01"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentRight="true"
+        android:layout_below="@+id/LinearLayout01"
+        android:gravity="bottom"
+        android:stretchColumns="0,2">
+
+        <TableRow
+            android:id="@+id/TableRow01"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:gravity="center_vertical|center_horizontal">
+
+            <Button
+                android:id="@+id/btnSettingsCancel"
+                style="@style/Menu_Button"
+                android:drawableLeft="@drawable/button_cancel"
+                android:text="@string/cancel"></Button>
+
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:adjustViewBounds="true"
+                android:focusable="false"
+                android:maxWidth="3dp"
+                android:minWidth="3dp"
+                android:scaleType="fitXY"
+                android:src="@drawable/menu_separator"></ImageView>
+
+            <Button
+                android:id="@+id/btnSettingsOk"
+                style="@style/Menu_Button"
+                android:drawableLeft="@drawable/button_save"
+                android:text="@string/save"></Button>
+        </TableRow>
+    </TableLayout>
 </RelativeLayout>
diff --git app/src/main/res/layout/bank_spinner_dropdown_item.xml app/src/main/res/layout/bank_spinner_dropdown_item.xml
index a043a94..6534ba0 100644
--- app/src/main/res/layout/bank_spinner_dropdown_item.xml
+++ app/src/main/res/layout/bank_spinner_dropdown_item.xml
@@ -6,7 +6,7 @@
 	<ImageView
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
-		android:src="@drawable/icon"
+		android:src="@drawable/ic_launcher"
 		android:id="@+id/imgBank"
 		android:adjustViewBounds="true"
 		android:maxHeight="40dp"
diff --git app/src/main/res/layout/bank_spinner_item.xml app/src/main/res/layout/bank_spinner_item.xml
index c83a5b1..a9beb4a 100644
--- app/src/main/res/layout/bank_spinner_item.xml
+++ app/src/main/res/layout/bank_spinner_item.xml
@@ -6,7 +6,7 @@
 	<ImageView
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
-		android:src="@drawable/icon"
+		android:src="@drawable/ic_launcher"
 		android:id="@+id/imgBank"
 		android:adjustViewBounds="true"
 		android:maxHeight="30dp"
diff --git app/src/main/res/layout/listitem_accounts_group.xml app/src/main/res/layout/listitem_accounts_group.xml
index 62de998..f18d729 100644
--- app/src/main/res/layout/listitem_accounts_group.xml
+++ app/src/main/res/layout/listitem_accounts_group.xml
@@ -23,7 +23,7 @@
         android:minHeight="48dp"
         android:minWidth="48dp"
         android:padding="0dp"
-        android:src="@drawable/icon" />
+        android:src="@drawable/ic_launcher" />
 
     <TextView
         android:id="@+id/txtListitemAccountsGroupBankname"
diff --git app/src/main/res/layout/listitem_banks.xml app/src/main/res/layout/listitem_banks.xml
index 7017dcf..0034a9e 100644
--- app/src/main/res/layout/listitem_banks.xml
+++ app/src/main/res/layout/listitem_banks.xml
@@ -16,7 +16,7 @@
 		android:layout_alignParentBottom="true"
 		android:layout_marginRight="2dp"
 
-		android:src="@drawable/icon"
+		android:src="@drawable/ic_launcher"
 		android:maxHeight="32dp"
 		android:maxWidth="32dp" />
 
diff --git app/src/main/res/layout/main.xml app/src/main/res/layout/main.xml
index 82d716e..baad1e1 100644
--- app/src/main/res/layout/main.xml
+++ app/src/main/res/layout/main.xml
@@ -1,64 +1,82 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_width="wrap_content"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat">
-	<CheckBox
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:id="@+id/chkTransperantBackground"
-		android:visibility="gone"
-		android:layout_margin="10dp"
-		android:text="@string/transparent_background" />
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:id="@+id/txtAccountsDesc"
-		android:visibility="visible"
-		android:layout_margin="10dp"
-		android:text="@string/main_instructions" />
-	<ListView
-		android:layout_width="fill_parent"
-		android:id="@+id/lstAccountsList"
-		android:layout_height="wrap_content"
-		android:cacheColorHint="#00000000"
-		android:layout_above="@+id/layMainMenu"
-		android:layout_below="@+id/chkTransperantBackground" android:layout_alignWithParentIfMissing="true" android:dividerHeight="0dp" android:fadingEdge="vertical"/>
-	<TableLayout
-		android:stretchColumns="0,2"
-		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content"
-		android:id="@+id/layMainMenu" android:visibility="gone">
-		<TableRow
-			android:id="@+id/TableRow01"
-			android:layout_height="wrap_content"
-			android:gravity="center_vertical|center_horizontal"
-			android:layout_gravity="center_vertical|center_horizontal"
-			android:layout_width="fill_parent">
-			<Button
-				android:text="@string/add_new_account"
-				android:drawableLeft="@drawable/button_add"
-				android:id="@+id/btnAddBank"
-				style="@style/Menu_Button"></Button>
-			<ImageView
-				android:layout_height="wrap_content"
-				android:focusable="false"
-				android:src="@drawable/menu_separator"
-				android:adjustViewBounds="true"
-				android:scaleType="fitXY"
-				android:minWidth="3dp"
-				android:maxWidth="3dp"
-				android:layout_width="wrap_content"></ImageView>
-			<Button
-				android:id="@+id/btnAccountsRefresh"
-				android:drawableLeft="@drawable/button_refresh"
-				android:text="@string/refresh_balance"
-				style="@style/Menu_Button"></Button>
-		</TableRow>
-	</TableLayout>
-</RelativeLayout>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="fill_parent"
+    android:background="@drawable/background_repeat"
+    android:orientation="vertical">
+
+    <include layout="@layout/toolbar" />
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <CheckBox
+            android:id="@+id/chkTransperantBackground"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="@string/transparent_background"
+            android:visibility="gone" />
+
+        <TextView
+            android:id="@+id/txtAccountsDesc"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp"
+            android:text="@string/main_instructions"
+            android:visibility="visible" />
+
+        <ListView
+            android:id="@+id/lstAccountsList"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_above="@+id/layMainMenu"
+            android:layout_alignWithParentIfMissing="true"
+            android:layout_below="@+id/chkTransperantBackground"
+            android:cacheColorHint="#00000000"
+            android:dividerHeight="0dp"
+            android:fadingEdge="vertical" />
+
+        <TableLayout
+            android:id="@+id/layMainMenu"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentRight="true"
+            android:stretchColumns="0,2"
+            android:visibility="gone">
+
+            <TableRow
+                android:id="@+id/TableRow01"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|center_horizontal"
+                android:gravity="center_vertical|center_horizontal">
+
+                <Button
+                    android:id="@+id/btnAddBank"
+                    style="@style/Menu_Button"
+                    android:drawableLeft="@drawable/button_add"
+                    android:text="@string/add_new_account"></Button>
+
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:adjustViewBounds="true"
+                    android:focusable="false"
+                    android:maxWidth="3dp"
+                    android:minWidth="3dp"
+                    android:scaleType="fitXY"
+                    android:src="@drawable/menu_separator"></ImageView>
+
+                <Button
+                    android:id="@+id/btnAccountsRefresh"
+                    style="@style/Menu_Button"
+                    android:drawableLeft="@drawable/button_refresh"
+                    android:text="@string/refresh_balance"></Button>
+            </TableRow>
+        </TableLayout>
+    </RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git app/src/main/res/layout/status_bar_latest_event_content.xml app/src/main/res/layout/status_bar_latest_event_content.xml
index 2db0ad1..96d0b0d 100644
--- app/src/main/res/layout/status_bar_latest_event_content.xml
+++ app/src/main/res/layout/status_bar_latest_event_content.xml
@@ -17,7 +17,7 @@
 			android:id="@+id/icon"
 			android:layout_width="25dp"
 			android:layout_height="25dp"
-			android:src="@drawable/icon" android:scaleType="fitXY"/>
+			android:src="@drawable/ic_launcher" android:scaleType="fitXY"/>
 		<TextView
 			android:id="@+id/title"
 			android:layout_width="fill_parent"
diff --git app/src/main/res/layout/title.xml app/src/main/res/layout/title.xml
index 20bfabb..1c9944f 100644
--- app/src/main/res/layout/title.xml
+++ app/src/main/res/layout/title.xml
@@ -23,7 +23,7 @@
 		<ImageView
 			android:layout_height="wrap_content"
 			android:layout_width="wrap_content"
-			android:src="@drawable/icon"
+			android:src="@drawable/ic_launcher"
 			android:scaleType="fitXY"
 			android:adjustViewBounds="true"
 			android:id="@+id/imgLogoIcon"
diff --git app/src/main/res/layout/toolbar.xml app/src/main/res/layout/toolbar.xml
new file mode 100644
index 0000000..7026e5a
--- /dev/null
+++ app/src/main/res/layout/toolbar.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/toolbar"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?attr/colorPrimary"
+    android:minHeight="?attr/actionBarSize"
+    app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
+    tools:showIn="@layout/main" />
\ No newline at end of file
diff --git app/src/main/res/layout/transactions.xml app/src/main/res/layout/transactions.xml
index ed598e2..306ac68 100644
--- app/src/main/res/layout/transactions.xml
+++ app/src/main/res/layout/transactions.xml
@@ -1,22 +1,41 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_width="wrap_content"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat">
-	<include android:id="@+id/layBankHeader" layout="@layout/listitem_accounts_group" />
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:visibility="visible"
-		android:layout_margin="10dp"
-		android:layout_below="@+id/layBankHeader" android:id="@+id/txtTranDesc" android:text="@string/tran_desc"/>
-	<ListView
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:fitsSystemWindows="true"
-		android:background="@drawable/background_repeat"
-		android:cacheColorHint="#00000000" android:layout_below="@+id/layBankHeader" android:layout_alignParentBottom="true" android:id="@+id/lstTransactionsList" android:footerDividersEnabled="true" android:clickable="false" android:scrollbarStyle="outsideInset"/>
-	
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/RelativeLayout01"
+    android:layout_width="wrap_content"
+    android:layout_height="fill_parent"
+    android:background="@drawable/background_repeat">
+
+    <include
+        android:id="@+id/toolbar"
+        layout="@layout/toolbar" />
+
+    <include
+        android:id="@+id/layBankHeader"
+        layout="@layout/listitem_accounts_group"
+        android:layout_width="match_parent"
+        android:layout_height="62dp"
+        android:layout_below="@id/toolbar" />
+
+    <TextView
+        android:id="@+id/txtTranDesc"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/layBankHeader"
+        android:layout_margin="10dp"
+        android:text="@string/tran_desc"
+        android:visibility="visible" />
+
+    <ListView
+        android:id="@+id/lstTransactionsList"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_alignParentBottom="true"
+        android:layout_below="@+id/layBankHeader"
+        android:background="@drawable/background_repeat"
+        android:cacheColorHint="#00000000"
+        android:clickable="false"
+        android:fitsSystemWindows="true"
+        android:footerDividersEnabled="true"
+        android:scrollbarStyle="outsideInset" />
+
 </RelativeLayout>
diff --git app/src/main/res/layout/transactions_htc.xml app/src/main/res/layout/transactions_htc.xml
deleted file mode 100644
index b8e4682..0000000
--- app/src/main/res/layout/transactions_htc.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_width="wrap_content"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat">
-	<include
-		android:id="@+id/layBankHeader"
-		layout="@layout/listitem_accounts_group" />
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:visibility="visible"
-		android:layout_margin="10dp"
-		android:layout_below="@+id/layBankHeader"
-		android:id="@+id/txtTranDesc"
-		android:text="@string/tran_desc" />
-	<com.htc.widget.HtcListView
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:fitsSystemWindows="true"
-		android:background="@drawable/background_repeat"
-		android:cacheColorHint="#00000000"
-		android:layout_below="@+id/layBankHeader"
-		android:layout_alignParentBottom="true"
-		android:id="@+id/lstTransactionsList"
-		android:footerDividersEnabled="true"
-		android:clickable="false"
-		android:scrollbarStyle="outsideInset" />
-
-</RelativeLayout>
diff --git app/src/main/res/layout/widget.xml app/src/main/res/layout/widget.xml
index a2cecef..afa34e3 100644
--- app/src/main/res/layout/widget.xml
+++ app/src/main/res/layout/widget.xml
@@ -24,7 +24,7 @@
 			android:id="@+id/imgWidgetIcon"
 			android:layout_gravity="center_vertical"
 			android:baselineAlignBottom="true"
-			android:src="@drawable/icon"
+			android:src="@drawable/ic_launcher"
 			android:scaleType="fitXY"></ImageView>
 	<TextView
 		android:id="@+id/txtWidgetAccountname"
diff --git app/src/main/res/layout/widget_transparent.xml app/src/main/res/layout/widget_transparent.xml
index cff8b4e..345c3d6 100644
--- app/src/main/res/layout/widget_transparent.xml
+++ app/src/main/res/layout/widget_transparent.xml
@@ -28,7 +28,7 @@
 			android:id="@+id/imgWidgetIcon"
 			android:layout_gravity="center_vertical"
 			android:baselineAlignBottom="true"
-			android:src="@drawable/icon"
+			android:src="@drawable/ic_launcher"
 			android:scaleType="fitXY"></ImageView>
 	<TextView
 		android:id="@+id/txtWidgetAccountname"
diff --git app/src/main/res/menu-sv/menu.xml app/src/main/res/menu-sv/menu.xml
deleted file mode 100644
index f4f6f1e..0000000
--- app/src/main/res/menu-sv/menu.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<item
-		android:id="@+id/settings"
-		android:title="Inställningar"
-		android:icon="@android:drawable/ic_menu_preferences" />
-	<item
-		android:id="@+id/toggle_hidden"
-		android:title="@string/menu_show_hidden"
-		android:icon="@drawable/ic_menu_view"/>
-	<item
-		android:id="@+id/donate"
-		android:title="Donera"
-		android:icon="@drawable/ic_menu_donate" />
-	<item
-		android:id="@+id/about"
-		android:title="Om"
-		android:icon="@drawable/ic_menu_info_details" />
-</menu>
\ No newline at end of file
diff --git app/src/main/res/menu/about.xml app/src/main/res/menu/about.xml
new file mode 100644
index 0000000..2eb305b
--- /dev/null
+++ app/src/main/res/menu/about.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/action_web"
+        android:icon="@drawable/ic_menu_web"
+        android:showAsAction="always"
+        android:title="@string/popup_www"
+        app:showAsAction="always" />
+</menu>
\ No newline at end of file
diff --git app/src/main/res/menu/main.xml app/src/main/res/menu/main.xml
new file mode 100644
index 0000000..e6ac07d
--- /dev/null
+++ app/src/main/res/menu/main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/action_refresh"
+        android:icon="@drawable/ic_menu_refresh"
+        android:showAsAction="always"
+        android:title="@string/refresh"
+        app:showAsAction="always" />
+    <item
+        android:id="@+id/action_add"
+        android:title="@string/add_account"
+        app:showAsAction="never" />
+
+    <item
+        android:id="@+id/action_settings"
+        android:title="@string/settings"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_toggle_hidden"
+        android:title="@string/menu_show_hidden"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/action_about"
+        android:title="@string/about"
+        app:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git app/src/main/res/menu/menu.xml app/src/main/res/menu/menu.xml
deleted file mode 100644
index 14b5e6b..0000000
--- app/src/main/res/menu/menu.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<item
-		android:id="@+id/settings"
-		android:title="Settings"
-		android:icon="@android:drawable/ic_menu_preferences" />
-	<item
-		android:id="@+id/toggle_hidden"
-		android:title="@string/menu_show_hidden"
-		android:icon="@drawable/ic_menu_view"/>
-	<item
-		android:id="@+id/donate"
-		android:title="Donate"
-		android:icon="@drawable/ic_menu_donate" />
-	<item
-		android:id="@+id/about"
-		android:title="About"
-		android:icon="@drawable/ic_menu_info_details" />
-</menu>
\ No newline at end of file
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index f79d5da..0300d55 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -25,6 +25,9 @@
     <string name="account_number">Kontonummer</string>
     <string name="control_code">Kontrollkod</string>
     <string name="server_error_try_again">Serverfel. Var god försök igen om en stund.</string>
+    <string name="settings">Inställningar</string>
+    <string name="refresh">Uppdatera</string>
+    <string name="add_account">Lägg till konto</string>
 
     <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
diff --git app/src/main/res/values-v21/themes.xml app/src/main/res/values-v21/themes.xml
new file mode 100644
index 0000000..c37fa02
--- /dev/null
+++ app/src/main/res/values-v21/themes.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="BankdroidTheme" parent="BaseTheme">
+        <item name="android:windowContentTransitions">true</item>
+        <item name="android:windowAllowEnterTransitionOverlap">true</item>
+        <item name="android:windowAllowReturnTransitionOverlap">true</item>
+        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
+        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git app/src/main/res/values/colors.xml app/src/main/res/values/colors.xml
index 193388c..b70edf6 100644
--- app/src/main/res/values/colors.xml
+++ app/src/main/res/values/colors.xml
@@ -17,5 +17,7 @@
 <resources>
     <color name="black">#000</color>
     <color name="red">#F00</color>
+    <color name="colorPrimary">#212121</color>
+    <color name="colorPrimaryDark">#212121</color>
 </resources>
          
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index 2d89743..b649b81 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -24,6 +24,9 @@
     <string name="account_number">Account number</string>
     <string name="control_code">Control code</string>
     <string name="server_error_try_again">Server error. Please try again later.</string>
+    <string name="settings">Settings</string>
+    <string name="refresh">Refresh</string>
+    <string name="add_account">Add account</string>
 
     <string name="username">Username</string>
     <string name="password">Password</string>
diff --git app/src/main/res/values/themes.xml app/src/main/res/values/themes.xml
index 959c839..71f0665 100644
--- app/src/main/res/values/themes.xml
+++ app/src/main/res/values/themes.xml
@@ -1,17 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-	<style
-		name="BankdroidTheme"
-		parent="android:Theme.Black">
-		<item
-			name="android:windowTitleSize">40dp</item>
-		<item
-			name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item>
-		<item
-			name="android:windowBackground">@drawable/background_repeat</item>
-		<item
-			name="android:listViewStyle">@style/listViewStyle</item>
-		<item
-			name="android:checkboxStyle">@style/checkBoxStyle</item>
-	</style>
+
+    <!--<style name="BankdroidTheme" parent="android:Theme.Black">-->
+        <!--<item name="android:windowTitleSize">40dp</item>-->
+        <!--<item name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item>-->
+    <!--</style>-->
+
+
+        <style name="BankdroidTheme" parent="BaseTheme"/>
+
+        <style name="BaseTheme" parent="Theme.AppCompat">
+            <item name="colorPrimary">@color/colorPrimary</item>
+            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+            <item name="android:windowNoTitle">true</item>
+            <item name="windowActionBar">false</item>
+            <item name="android:windowBackground">@drawable/background_repeat</item>
+            <item name="android:listViewStyle">@style/listViewStyle</item>
+            <!--<item name="android:checkboxStyle">@style/checkBoxStyle</item>-->
+        </style>
+
 </resources>
\ No newline at end of file

commit 38b2aa727fe6bff555391ac59bc85ffbfae08949
Merge: 72d7cc6 fa3378e
Author: liato <x@x00.us>
Date:   Tue Nov 18 14:16:05 2014 +0100

    Merge pull request #368 from mikaeler/master
    
    Avoid unnecessary requests to Swedbank API

commit fa3378e3fe32d5ef36f090c76186c79f4a401cf8
Author: Mikael Eriksson <mikaeler@gmail.com>
Date:   Tue Nov 18 13:10:04 2014 +0100

    Avoid unnecessary requests to:
    https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/engagement/transactions/null
    for accounts without an id.
    
    All of those unnecessary calls gets the error response:
    {"errorMessages":{"general":[{"message":"Kunde inte hitta kontot.","code":"IDENTITY_MISSING"}]}}

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index ac6f30b..4130c82 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -179,6 +179,9 @@ public abstract class AbstractSwedbank extends Bank {
         else if(account.getType() != Account.REGULAR) {
             return;
         }
+        else if(mIdMap.get(account.getId()) == null) {
+            return;
+        }
         try {
 
             HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+mIdMap.get(account.getId())),false);

commit 72d7cc67e9decc30c198f47dc6037bb488667861
Merge: 9b0867c 369577b
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:52:36 2014 +0100

    Merge pull request #342 from fredrike/toggle-account-view
    
    Support for account toggeling

commit 9b0867c7741c3542357b42d8bcd53e117ce5a66d
Merge: 3bfab4e b5eb0dc
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:10:09 2014 +0100

    Merge pull request #343 from fredrike/avanza-patch
    
    Fix for #336 - show all account types @ avanza

commit 3bfab4e21accf379b9121145ad7e92cf96c678a0
Merge: 74def93 845c296
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:09:32 2014 +0100

    Merge pull request #345 from sed03/master
    
    Fix balance Tillgängligt nu for old and new cards

commit 74def93e6d246ab5e4f8568210a81b08e353b23a
Merge: 8d7f02d b0ea153
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:09:03 2014 +0100

    Merge pull request #353 from goober/feature/350-newcertificate-easycard
    
    New certificate for EasyCard. Fixes #350

commit 8d7f02dc196d9d50cf2d519ea34b3f4cd86f6a17
Merge: 9da0ca0 48b2425
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:58 2014 +0100

    Merge pull request #354 from goober/feature/351-new-certificate-meniga
    
    New certificate for Meniga. Fixes #351

commit 9da0ca0a65ed860aad766b119b6bbe1d4273a0e5
Merge: c5115ab 4d0590c
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:52 2014 +0100

    Merge pull request #355 from goober/feature/349-new-certificate-brummer
    
    New certificate for Brummer KF. Fixes #349

commit c5115ab1877d3c5d75bab1d8f8a4d42626526b33
Merge: f2bd2e1 69863ef
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:46 2014 +0100

    Merge pull request #357 from goober/feature/cert-ica
    
    New certificate for Ica. Fixes #356

commit f2bd2e18d8cb9646077efa574f18301ba5fe4ba8
Merge: 76a8f68 8f898aa
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:38 2014 +0100

    Merge pull request #358 from goober/feature/cert-paypal
    
    Removes outdated certificate for Paypal

commit 76a8f68656ac8c6f0affeb3a6098f1e64b50b1f8
Merge: f1e18a1 7c64afd
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:32 2014 +0100

    Merge pull request #360 from goober/feature/cert-icabanken
    
    Removes outdated certificate for ICABanken

commit f1e18a165c1478e9430188af4ff17e74e7c9cecc
Merge: c647136 312a9c3
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:16 2014 +0100

    Merge pull request #361 from goober/feature/cert-plusgirot
    
    New certificate for PlusGirot. Fixes #359

commit c64713669f72f8be1512fea84124e18af6b081a6
Merge: 8f5613f a02ec5a
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:09 2014 +0100

    Merge pull request #363 from goober/feature/cert-firstcard
    
    New certificate for FirstCard. Fixes #362

commit 8f5613f0247c59969ddd831237798fbbc82c28bd
Merge: d992a24 a7134ec
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:08:04 2014 +0100

    Merge pull request #365 from goober/feature/cert-nordea-dk
    
    New certificate for Nordea DK. Fixes #364

commit d992a245359715ea5f5ec57e7d7068833b361c84
Merge: b2acee4 b78b51f
Author: liato <x@x00.us>
Date:   Mon Nov 17 00:07:56 2014 +0100

    Merge pull request #367 from goober/feature/cert-jojo
    
    New certificate for Jojo. Fixes #366

commit b2acee4c53663f864c8d1f06b795d95310595d2a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 23:26:08 2014 +0100

    Update README.rst

diff --git README.rst README.rst
index 2263b5c..f47451d 100644
--- README.rst
+++ README.rst
@@ -12,7 +12,7 @@ More information can be found at:
 * `Bankdroid on Google Play <https://play.google.com/store/apps/details?id=com.liato.bankdroid>`_
 * `Bankdroid thread at the Swedroid Forum <http://goo.gl/9tJeH>`_ (Swedish)
 
-Contribute or reporting broken banks
+Contribute or report broken banks
 ------------------------------------
 The following information is needed for troubleshooting a broken bank or if you want a new bank to be supported 
 by Bankdroid.

commit 5aaa6b4763239775f00dbe1752221988985a8157
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 23:25:40 2014 +0100

    Adds troubleshooting instructions to README

diff --git README.rst README.rst
index d3330b7..2263b5c 100644
--- README.rst
+++ README.rst
@@ -12,6 +12,20 @@ More information can be found at:
 * `Bankdroid on Google Play <https://play.google.com/store/apps/details?id=com.liato.bankdroid>`_
 * `Bankdroid thread at the Swedroid Forum <http://goo.gl/9tJeH>`_ (Swedish)
 
+Contribute or reporting broken banks
+------------------------------------
+The following information is needed for troubleshooting a broken bank or if you want a new bank to be supported 
+by Bankdroid.
+
+1. Address to login page.
+2. Address and html code for the landing page after a successful login.
+3. Address and html code for the page with the accounts overview.
+4. Address and html code for the page with an account's transaction history.
+
+NOTE. Do not forget to replace your personal information in the html code with random 
+information before you send everything to android [at] nullbyte.eu. 
+You can also open an issue here at Github with the required files included as an attachment.
+
 Development environment
 -----------------------
 
@@ -28,4 +42,4 @@ License
 -------
 
 The Bankdroid source code is licensed under the
-`Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
\ No newline at end of file
+`Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.

commit b78b51fdd7b05eda3f2fad4e97da4431856013bf
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:51:00 2014 +0100

    New certificate for Jojo. Fixes #366

diff --git app/src/main/res/raw/cert_jojo.pem app/src/main/res/raw/cert_jojo.pem
index b000c8d..e04d01e 100644
--- app/src/main/res/raw/cert_jojo.pem
+++ app/src/main/res/raw/cert_jojo.pem
@@ -1,34 +1,32 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+8d7oaZCE7jQQ
+-----END CERTIFICATE-----

commit a7134ecf44b2fc3d18cbef4e5dcda1b4ab123494
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:35:14 2014 +0100

    New certificate for Nordea DK. Fixes #364

diff --git app/src/main/res/raw/cert_nordea_dk.pem app/src/main/res/raw/cert_nordea_dk.pem
index 99a9bb4..3aefa0b 100644
--- app/src/main/res/raw/cert_nordea_dk.pem
+++ app/src/main/res/raw/cert_nordea_dk.pem
@@ -1,34 +1,32 @@
------BEGIN CERTIFICATE-----

-wnHAZGWM1O3xF54uWoBxuhg4dTFcK0P/wCwqG72cNyitx2Yd
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+K3OZVKYhUxpbYw==
+-----END CERTIFICATE-----

commit a02ec5a274ab3fbcc44bc8eb1e47880cb34c7a03
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:23:12 2014 +0100

    New certificate for FirstCard. Fixes #362

diff --git app/src/main/res/raw/cert_firstcard.pem app/src/main/res/raw/cert_firstcard.pem
index 7c25deb..792f1c7 100644
--- app/src/main/res/raw/cert_firstcard.pem
+++ app/src/main/res/raw/cert_firstcard.pem
@@ -1,31 +1,31 @@
------BEGIN CERTIFICATE-----

-oUmjrWbulK5DddWqewYyfC0PKc9TPiDYhC/3V4/yQ/wL3g==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+01KidfzMdyRulQ4m6g==
+-----END CERTIFICATE-----

commit 7c64afdd26369c31ca8e4c44845463f2163a495a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:18:29 2014 +0100

    Rename current certificate for ICABanken

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 6b083a2..4034fef 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -80,7 +80,7 @@ public class ICABanken extends Bank {
     }
 
     public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken, R.raw.cert_icabanken2));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken));
         urlopen.addHeader("ApiVersion", API_VERSION);
         urlopen.addHeader("Accept", "application/json");
         urlopen.addHeader("ApiKey", API_KEY);
diff --git app/src/main/res/raw/cert_icabanken2.pem app/src/main/res/raw/cert_icabanken.pem
similarity index 100%
rename from app/src/main/res/raw/cert_icabanken2.pem
rename to app/src/main/res/raw/cert_icabanken.pem

commit 4d1a0ff383c5b3a133a70f9a742c64b9eed73ab7
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:17:00 2014 +0100

    Removes outdated certificate for ICABanken

diff --git app/src/main/res/raw/cert_icabanken.pem app/src/main/res/raw/cert_icabanken.pem
deleted file mode 100644
index e3d0aad..0000000
--- app/src/main/res/raw/cert_icabanken.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----

-u2PDuCEHH9/zksq1dfLTwiDRinMCzw==
------END CERTIFICATE-----

commit 312a9c3da7ae5725e9f2d451822715f494f989de
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:13:34 2014 +0100

    New certificate for PlusGirot. Fixes #359

diff --git app/src/main/res/raw/cert_plusgirot.pem app/src/main/res/raw/cert_plusgirot.pem
index 4849466..f592f65 100644
--- app/src/main/res/raw/cert_plusgirot.pem
+++ app/src/main/res/raw/cert_plusgirot.pem
@@ -1,31 +1,31 @@
------BEGIN CERTIFICATE-----

-dTSCRHZJTC7cHBdc8T6SFBy9uGrIEuOYRfvSvY1emj9lgwKZ
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+fKYgH5kI57BEfo89BUTdKQoCnx4qnYObUJVNsAM+
+-----END CERTIFICATE-----

commit 8f898aa705595ba95eb69e53bc852cde51873324
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:09:29 2014 +0100

    Rename new certificate for PayPal

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
index 8d7f457..7e9aec3 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
@@ -80,7 +80,7 @@ public class PayPal extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal, R.raw.cert_paypal2));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
diff --git app/src/main/res/raw/cert_paypal2.pem app/src/main/res/raw/cert_paypal.pem
similarity index 100%
rename from app/src/main/res/raw/cert_paypal2.pem
rename to app/src/main/res/raw/cert_paypal.pem

commit bcc58a3d449ce59bdfd56de3e8625e77e9f561ae
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:08:43 2014 +0100

    Removes outdated certificate for PayPal

diff --git app/src/main/res/raw/cert_paypal.pem app/src/main/res/raw/cert_paypal.pem
deleted file mode 100644
index 8729515..0000000
--- app/src/main/res/raw/cert_paypal.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----

commit 69863ef473062fbc1534141d64e4175e8521f987
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 14:02:06 2014 +0100

    New certificate for Ica

diff --git app/src/main/res/raw/cert_ica.pem app/src/main/res/raw/cert_ica.pem
index d63b3be..d8e49ca 100644
--- app/src/main/res/raw/cert_ica.pem
+++ app/src/main/res/raw/cert_ica.pem
@@ -1,29 +1,29 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----

commit 4d0590ca3b11a50aa5423dbb585133e5180c9726
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 13:50:41 2014 +0100

    New certificate for Brummer KF. Fixes #349

diff --git app/src/main/res/raw/cert_brummer.pem app/src/main/res/raw/cert_brummer.pem
index 356a688..5d074ce 100644
--- app/src/main/res/raw/cert_brummer.pem
+++ app/src/main/res/raw/cert_brummer.pem
@@ -1,41 +1,33 @@
------BEGIN CERTIFICATE-----

-JO863R2r7jc5
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----

commit 48b2425cbaea99beac65c8255476e95d9a688d0c
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 13:44:00 2014 +0100

    New certificate for Meniga. Fixes #351

diff --git app/src/main/res/raw/cert_meniga.pem app/src/main/res/raw/cert_meniga.pem
index f11893e..cab4773 100644
--- app/src/main/res/raw/cert_meniga.pem
+++ app/src/main/res/raw/cert_meniga.pem
@@ -1,32 +1,30 @@
------BEGIN CERTIFICATE-----

-dUrs
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+83CWGJvQw2hT0OP6EwRKXIESPvxFC269xJdUwAuHrg0=
+-----END CERTIFICATE-----

commit b0ea153da55dc1fa5a0c0a37caae8cf67e0d528a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Nov 16 13:40:35 2014 +0100

    New certificate for EasyCard. Fixes #350

diff --git app/src/main/res/raw/cert_easycard.pem app/src/main/res/raw/cert_easycard.pem
index 14b3d1c..27ac3dc 100644
--- app/src/main/res/raw/cert_easycard.pem
+++ app/src/main/res/raw/cert_easycard.pem
@@ -1,34 +1,32 @@
------BEGIN CERTIFICATE-----

-YMvo8caizM268OdHzj3WQt4biECp/9TWO3wAfGm1PjaY1A==
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+9zMG3j0JdTv4xPZSSQHq
+-----END CERTIFICATE-----

commit 989f531d9c8caf74da3fc698e76202e6b23c298e
Merge: 114657c c39683a
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Nov 12 20:49:00 2014 +0100

    Merge pull request #347 from auno/346-csn-certificate-not-trusted
    
    New certificate for CSN

commit c39683a5982df203593d81e1ae4a4313b4c30eac
Author: Mikael Auno <mikael@auno.se>
Date:   Wed Nov 12 20:44:24 2014 +0100

    New certificate for CSN. Fixes #346.

diff --git app/src/main/res/raw/cert_csn.pem app/src/main/res/raw/cert_csn.pem
index 18fc9b1..2e34bce 100644
--- app/src/main/res/raw/cert_csn.pem
+++ app/src/main/res/raw/cert_csn.pem
@@ -1,33 +1,31 @@
 -----BEGIN CERTIFICATE-----

-PajVUwrdF/h/YCVPwueHfyjYow==

+OFeejCXt98KVdMUSG0s7Zm6eB7pFq1dbYBlS/V30aNo=
 -----END CERTIFICATE-----

commit 845c2963493dbf3b8f0e0442ec90f35136f8e86d
Author: sed03 <stefan.edstrom@gmail.com>
Date:   Tue Nov 11 10:04:58 2014 +0100

    Fix balance Tillgängligt nu for old and new cards

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index 0c79d7e..d6501a3 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -109,8 +109,9 @@ public class Jojo extends Bank {
         Elements es = d.select(".saldo_ok_wrapper > table > tbody tr");
         if (es != null) {
             for (int i = 0; i < 2; i++) {
-                int index = es.size()-5+i;
-                if (index >= 0) {
+
+                int index = 0+i;
+                if (es.size()>=index) {
                     Element e = es.get(index);
                     Element name = e.select(".first").first();
                     Element amount = e.select(".right").first();

commit 114657c37b634cf89b50cfb61e72836040c31d14
Merge: c257fed 5bca604
Author: liato <x@x00.us>
Date:   Tue Nov 11 08:57:09 2014 +0100

    Merge pull request #344 from goober/feature/332-swedbank-credit-card-zero-balance
    
    332 swedbank credit card zero balance

commit 5bca6042689ed10b93aa5af5526604a9ad5ba651
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Nov 10 22:02:13 2014 +0100

    Adds credit card transactions for Swedbank and Sparbankerna. Fixes #339 and #332

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 9f4ed91..ac6f30b 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -14,8 +14,11 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankChoice;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
+import com.liato.bankdroid.banking.banks.swedbank.model.CardTransaction;
 import com.liato.bankdroid.banking.banks.swedbank.model.ErrorMessage;
 import com.liato.bankdroid.banking.banks.swedbank.model.ErrorResponse;
+import com.liato.bankdroid.banking.banks.swedbank.model.engagement.CardAccountResponse;
 import com.liato.bankdroid.banking.banks.swedbank.model.engagement.OverviewResponse;
 import com.liato.bankdroid.banking.banks.swedbank.model.engagement.TransactionsResponse;
 import com.liato.bankdroid.banking.banks.swedbank.model.identification.PersonalCodeRequest;
@@ -153,7 +156,7 @@ public abstract class AbstractSwedbank extends Bank {
             addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
             addAccounts(overviewResponse.getTransactionDisposalAccounts(),Account.REGULAR);
             addAccounts(overviewResponse.getSavingDisposalAccounts(),Account.REGULAR);
-            addAccounts(overviewResponse.getCardAccounts(),Account.CCARD);
+            addCardAccounts(overviewResponse.getCardAccounts());
             if (this.accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
@@ -169,7 +172,11 @@ public abstract class AbstractSwedbank extends Bank {
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
-        if(account.getType() != Account.REGULAR) {
+        if(account.getType() == Account.CCARD) {
+            updateCreditCardTransactions(account, urlopen);
+            return;
+        }
+        else if(account.getType() != Account.REGULAR) {
             return;
         }
         try {
@@ -203,6 +210,24 @@ public abstract class AbstractSwedbank extends Bank {
 
     }
 
+    private void updateCreditCardTransactions(Account account, Urllib urlopen) throws BankException {
+        try {
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/cardaccount/"+mIdMap.get(account.getId())),false);
+            if(httpResponse.getStatusLine().getStatusCode() != 200) {
+                throw new BankException(httpResponse.getStatusLine().toString());
+            }
+            CardAccountResponse response = readJsonValue(httpResponse.getEntity().getContent(),CardAccountResponse.class);
+            List<Transaction> transactions = new ArrayList<Transaction>();
+            transactions.addAll(transformCardTransactions(response.getTransactions()));
+            transactions.addAll(transformCardTransactions(response.getReservedTransactions()));
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+           throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+    }
+
     private List<Transaction> transformTransactions(List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {
         List<Transaction> transactionList = new ArrayList<Transaction>();
         for(com.liato.bankdroid.banking.banks.swedbank.model.Transaction transaction : transactions) {
@@ -211,6 +236,16 @@ public abstract class AbstractSwedbank extends Bank {
         return transactionList;
     }
 
+    private List<Transaction> transformCardTransactions(List<CardTransaction> transactions) {
+        List<Transaction> transactionList = new ArrayList<Transaction>();
+        for(CardTransaction transaction : transactions) {
+            transactionList.add(new Transaction(transaction.getDate(),
+                    transaction.getDescription(),
+                    transaction.getLocalAmount().getAmount(),
+                    transaction.getLocalAmount().getCurrencyCode()));
+        }
+        return transactionList;
+    }
 
     private ProfileResponse getAvailableProfiles() throws IOException, ClientProtocolException, BankException {
         HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/"), false);
@@ -260,6 +295,14 @@ public abstract class AbstractSwedbank extends Bank {
         }
     }
 
+    private void addCardAccounts(List<CardAccount> accountList) {
+        for(CardAccount account : accountList) {
+            Account bankdroidAccount = new Account(account.getName(),account.getAvailableAmount(),account.getCardNumber(), Account.CCARD,account.getCurrency());
+            mIdMap.put(bankdroidAccount.getId(), account.getId());
+            this.accounts.add(bankdroidAccount);
+        }
+    }
+
     private String getAuthenticationHeader() {
         try {
             byte[] data = new StringBuilder(getAppId())
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
index 667e741..7ae62f3 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.liato.bankdroid.banking.banks.swedbank.model.Account;
+import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
 import com.liato.bankdroid.banking.banks.swedbank.model.CreditCard;
 
 import java.util.ArrayList;
@@ -30,7 +31,7 @@ public class OverviewResponse {
     private List<Account> savingDisposalAccounts;
 
     @JsonProperty
-    private List<Account> cardAccounts;
+    private List<CardAccount> cardAccounts;
 
     public CreditCard getCreditCard() {
         return creditCard;
@@ -95,14 +96,14 @@ public class OverviewResponse {
         this.savingDisposalAccounts = savingDisposalAccounts;
     }
 
-    public List<Account> getCardAccounts() {
+    public List<CardAccount> getCardAccounts() {
         if(cardAccounts == null) {
-            cardAccounts = new ArrayList<Account>();
+            cardAccounts = new ArrayList<CardAccount>();
         }
         return cardAccounts;
     }
 
-    public void setCardAccounts(List<Account> cardAccounts) {
+    public void setCardAccounts(List<CardAccount> cardAccounts) {
         this.cardAccounts = cardAccounts;
     }
 }

commit 1281596d4252b4d0d34b5640ca9d001f356fe9c5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Nov 10 21:59:06 2014 +0100

    Adds model classes for credit cards.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
new file mode 100644
index 0000000..26e973e
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Amount.java
@@ -0,0 +1,31 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.math.BigDecimal;
+
+public class Amount {
+
+    @JsonProperty
+    private BigDecimal amount;
+
+    @JsonProperty
+    private String currencyCode;
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public void setAmount(BigDecimal amount) {
+        this.amount = amount;
+    }
+
+    public String getCurrencyCode() {
+        return currencyCode;
+    }
+
+    public void setCurrencyCode(String currencyCode) {
+        this.currencyCode = currencyCode;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
new file mode 100644
index 0000000..7b13cbe
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardAccount.java
@@ -0,0 +1,98 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.math.BigDecimal;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CardAccount {
+
+    @JsonProperty
+    private String id;
+
+    @JsonProperty
+    private String name;
+    
+    @JsonProperty
+    private BigDecimal creditLimit;
+
+    @JsonProperty
+    private BigDecimal currentBalance;
+
+    @JsonProperty
+    private BigDecimal reservedAmount;
+
+    @JsonProperty
+    private BigDecimal availableAmount;
+
+    @JsonProperty
+    private String currency;
+
+    @JsonProperty
+    private String cardNumber;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public BigDecimal getCreditLimit() {
+        return creditLimit;
+    }
+
+    public void setCreditLimit(BigDecimal creditLimit) {
+        this.creditLimit = creditLimit;
+    }
+
+    public BigDecimal getCurrentBalance() {
+        return currentBalance;
+    }
+
+    public void setCurrentBalance(BigDecimal currentBalance) {
+        this.currentBalance = currentBalance;
+    }
+
+    public BigDecimal getReservedAmount() {
+        return reservedAmount;
+    }
+
+    public void setReservedAmount(BigDecimal reservedAmount) {
+        this.reservedAmount = reservedAmount;
+    }
+
+    public BigDecimal getAvailableAmount() {
+        return availableAmount;
+    }
+
+    public void setAvailableAmount(BigDecimal availableAmount) {
+        this.availableAmount = availableAmount;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public String getCardNumber() {
+        return cardNumber;
+    }
+
+    public void setCardNumber(String cardNumber) {
+        this.cardNumber = cardNumber;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
new file mode 100644
index 0000000..b2c4f61
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CardTransaction.java
@@ -0,0 +1,55 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Date;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CardTransaction {
+
+    @JsonProperty
+    private String date;
+
+    @JsonProperty
+    private String description;
+
+    @JsonProperty
+    private Amount foreignAmount;
+
+    @JsonProperty
+    private Amount localAmount;
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Amount getForeignAmount() {
+        return foreignAmount;
+    }
+
+    public void setForeignAmount(Amount foreignAmount) {
+        this.foreignAmount = foreignAmount;
+    }
+
+    public Amount getLocalAmount() {
+        return localAmount;
+    }
+
+    public void setLocalAmount(Amount localAmount) {
+        this.localAmount = localAmount;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
new file mode 100644
index 0000000..9ed2edc
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/CardAccountResponse.java
@@ -0,0 +1,53 @@
+package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.liato.bankdroid.banking.banks.swedbank.model.CardAccount;
+import com.liato.bankdroid.banking.banks.swedbank.model.CardTransaction;
+import com.liato.bankdroid.banking.banks.swedbank.model.Transaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CardAccountResponse {
+
+    @JsonProperty
+    private CardAccount cardAccount;
+
+    @JsonProperty
+    private List<CardTransaction> transactions;
+
+    @JsonProperty
+    private List<CardTransaction> reservedTransactions;
+
+    public CardAccount getCardAccount() {
+        return cardAccount;
+    }
+
+    public void setCardAccount(CardAccount cardAccount) {
+        this.cardAccount = cardAccount;
+    }
+
+    public List<CardTransaction> getTransactions() {
+        if(transactions == null) {
+            transactions = new ArrayList<CardTransaction>();
+        }
+        return transactions;
+    }
+
+    public void setTransactions(List<CardTransaction> transactions) {
+        this.transactions = transactions;
+    }
+
+    public List<CardTransaction> getReservedTransactions() {
+        if(reservedTransactions == null) {
+            reservedTransactions = new ArrayList<CardTransaction>();
+        }
+        return reservedTransactions;
+    }
+
+    public void setReservedTransactions(List<CardTransaction> reservedTransactions) {
+        this.reservedTransactions = reservedTransactions;
+    }
+}

commit 369577be98753e755398814802b27ca64c77f5af
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Nov 7 13:10:16 2014 +0100

    Added menu item for hide all accounts

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 8594286..08aa6d4 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -259,6 +259,18 @@ public class MainActivity extends LockableActivity {
 				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
 			final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
+            final Button btnHide = (Button) root.findViewById(R.id.btnHide);
+            final Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
+            if (selected_bank.getHideAccounts()) {
+                btnHide.setVisibility(View.GONE);
+                btnUnhide.setVisibility(View.VISIBLE);
+                btnUnhide.setOnClickListener(this);
+            }
+            else {
+                btnHide.setVisibility(View.VISIBLE);
+                btnUnhide.setVisibility(View.GONE);
+                btnHide.setOnClickListener(this);
+            }
 			root.findViewById(R.id.btnRefresh).setOnClickListener(this);
 			root.findViewById(R.id.btnWWW).setOnClickListener(this);
 			root.findViewById(R.id.btnEdit).setOnClickListener(this);
@@ -273,6 +285,13 @@ public class MainActivity extends LockableActivity {
 			final Context context = this.anchor.getContext();
 			final int id = v.getId();
 			switch (id) {
+			case R.id.btnHide:
+			case R.id.btnUnhide:
+				this.dismiss();
+				selected_bank.toggleHideAccounts();
+				selected_bank.save();
+				parent.refreshView();
+				return;
 			case R.id.btnWWW:
 				if (selected_bank != null) {
 					//Uri uri = Uri.parse(selected_bank.getURL());
diff --git app/src/main/res/layout/popup_bank.xml app/src/main/res/layout/popup_bank.xml
index 44e7ebf..c4c1ea8 100644
--- app/src/main/res/layout/popup_bank.xml
+++ app/src/main/res/layout/popup_bank.xml
@@ -9,7 +9,12 @@
 	<Button style="@style/Popup_Button"
 		android:id="@+id/btnRefresh"
 		android:drawableTop="@drawable/button_refresh" android:text="@string/popup_refresh"></Button>
-	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<ImageView style="@style/Popup_Separator"></ImageView>
+	<Button style="@style/Popup_Button"
+		android:drawableTop="@drawable/button_hide" android:id="@+id/btnHide" android:text="@string/popup_hide_a"></Button>
+	<Button style="@style/Popup_Button"
+		android:drawableTop="@drawable/button_hide" android:id="@+id/btnUnhide" android:text="@string/popup_unhide_a"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>
 	<Button
 		android:id="@+id/btnEdit"
 		android:drawableTop="@drawable/button_edit"
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 067923c..f79d5da 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -146,7 +146,9 @@
     <string name="popup_remove">Radera</string>
 
     <string name="popup_hide">Dölj</string>
-    <string name="popup_unhide">Dölj ej</string>
+    <string name="popup_unhide">Visa</string>
+    <string name="popup_hide_a">Dölj\nkonton</string>
+    <string name="popup_unhide_a">Visa\nkonton</string>
     <string name="popup_enable_notifications">Aktivera notifieringar</string>
     <string name="popup_disable_notifications">Inaktivera notifieringar</string>
 
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index f532cb2..2d89743 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -149,6 +149,8 @@
 
     <string name="popup_hide">Hide</string>
     <string name="popup_unhide">Unhide</string>
+    <string name="popup_hide_a">Hide\naccounts</string>
+    <string name="popup_unhide_a">Unhide\naccounts</string>
     <string name="popup_enable_notifications">Enable notifications</string>
     <string name="popup_disable_notifications">Disable notifications</string>
         

commit b5eb0dc7af3d135f356071812c8225626d5d4692
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Nov 7 12:34:57 2014 +0100

    Code cleanup

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 6a5a8c5..ebfde61 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -88,7 +88,9 @@ public class Avanza extends Bank {
                     Date now = new Date();
                     ArrayList<Transaction> transactions = new ArrayList<Transaction>();
                     for (PositionAggregation positionAgList : account.getPositionAggregations()) {
-                        if (positionAgList.getPositions().isEmpty()) continue;
+                        if (positionAgList.getPositions().isEmpty()) {
+                            continue;
+                        }
                         List<Position> positions = positionAgList.getPositions();
                         transactions.add(new Transaction(Helpers.formatDate(now),
                                 "\u2014  " + positionAgList.getInstrumentTypeName() +

commit 6125b39787b299fc34a6b8f3c00e5f26f6942d41
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Nov 7 11:59:18 2014 +0100

    Toggle will only activate on longpress,
    
    to keep old functionality of click

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 5c2a236..8594286 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -95,11 +95,12 @@ public class MainActivity extends LockableActivity {
 					pmenu.showLikeQuickAction(0, 12);
 					return true;
 				} else if (adapter.getItem(position) instanceof Bank) {
-                    selected_bank = (Bank) adapter.getItem(position);
-                    final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
-                    pmenu.showLikeQuickAction(0, 12);
-                    return true;
-                }
+					selected_bank = (Bank) adapter.getItem(position);
+					selected_bank.toggleHideAccounts();
+					selected_bank.save();
+					refreshView();
+					return true;
+				}
 				return false;
 			}
 		});
@@ -107,10 +108,9 @@ public class MainActivity extends LockableActivity {
 			public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
 				if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
-                    selected_bank.toggleHideAccounts();
-                    selected_bank.save();
-                    refreshView();
-                }
+					final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
+					pmenu.showLikeQuickAction(0, 12);
+				}
 				else {
 					final Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
 					final Account account = (Account) adapter.getItem(position);

commit c03b1d85c35021d77b2b9d55b7895bbfa88df03f
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Fri Nov 7 11:26:03 2014 +0100

    Fix for #336 - show all account types @ avanza

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 85dc8fc..6a5a8c5 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -29,6 +29,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.banks.avanza.model.AccountOverview;
 import com.liato.bankdroid.banking.banks.avanza.model.Position;
+import com.liato.bankdroid.banking.banks.avanza.model.PositionAggregation;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -41,7 +42,6 @@ import org.apache.http.client.ClientProtocolException;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
@@ -84,13 +84,24 @@ public class Avanza extends Bank {
                 if (!account.getCurrencyAccounts().isEmpty()) {
                     a.setCurrency(account.getCurrencyAccounts().get(0).getCurrency());
                 }
-                if (!account.getPositionAggregations().isEmpty() && !account.getPositionAggregations().get(0).getPositions().isEmpty()) {
-                    List<Position> positions = account.getPositionAggregations().get(0).getPositions();
+                if (!account.getPositionAggregations().isEmpty()) {
                     Date now = new Date();
-                    ArrayList<Transaction> transactions = new ArrayList<Transaction>(positions.size());
-                    for (Position p : positions) {
-                        Transaction t = new Transaction(Helpers.formatDate(now), p.getInstrumentName(), BigDecimal.valueOf(p.getProfit()), a.getCurrency());
-                        transactions.add(t);
+                    ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                    for (PositionAggregation positionAgList : account.getPositionAggregations()) {
+                        if (positionAgList.getPositions().isEmpty()) continue;
+                        List<Position> positions = positionAgList.getPositions();
+                        transactions.add(new Transaction(Helpers.formatDate(now),
+                                "\u2014  " + positionAgList.getInstrumentTypeName() +
+                                        "  " + positionAgList.getTotalProfitPercent() + "%  \u2014",
+                                BigDecimal.valueOf(positionAgList.getTotalValue()),
+                                a.getCurrency()));
+                        for (Position p : positions) {
+                            Transaction t = new Transaction(Helpers.formatDate(now),
+                                    p.getInstrumentName(),
+                                    BigDecimal.valueOf(p.getProfit()),
+                                    a.getCurrency());
+                            transactions.add(t);
+                        }
                     }
                     a.setTransactions(transactions);
                 }

commit f781a5023d379a8fdd165c096b1267a0d2782078
Author: Fredrik Erlandsson <fredrik.e@gmail.com>
Date:   Thu Nov 6 22:31:30 2014 +0100

    Support for account toggeling
    
    By clicking on a “Bank” it is now possible to toggle view of all
    accounts.

diff --git app/src/main/java/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
index 78dd0d9..5c2a236 100644
--- app/src/main/java/com/liato/bankdroid/MainActivity.java
+++ app/src/main/java/com/liato/bankdroid/MainActivity.java
@@ -94,7 +94,12 @@ public class MainActivity extends LockableActivity {
 					final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
 					pmenu.showLikeQuickAction(0, 12);
 					return true;
-				}
+				} else if (adapter.getItem(position) instanceof Bank) {
+                    selected_bank = (Bank) adapter.getItem(position);
+                    final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
+                    pmenu.showLikeQuickAction(0, 12);
+                    return true;
+                }
 				return false;
 			}
 		});
@@ -102,9 +107,10 @@ public class MainActivity extends LockableActivity {
 			public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
 				if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
-					final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
-					pmenu.showLikeQuickAction(0, 12);
-				}
+                    selected_bank.toggleHideAccounts();
+                    selected_bank.save();
+                    refreshView();
+                }
 				else {
 					final Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
 					final Account account = (Account) adapter.getItem(position);
diff --git app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
index 2b86197..e770d4d 100644
--- app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -76,7 +76,7 @@ public class AccountsAdapter extends BaseAdapter {
     public void setShowHidden(boolean showHidden) {
         this.showHidden = showHidden;
     }
-    
+
 	public View newBankView(Bank bank, ViewGroup parent, View convertView) {
 		if (convertView == null) {
 			convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
@@ -102,7 +102,7 @@ public class AccountsAdapter extends BaseAdapter {
 	}
 
 	public View newAccountView(Account account, ViewGroup parent, View convertView) {
-        if (account.isHidden() && !showHidden) {
+        if ((account.isHidden() && !showHidden) || account.getBank().getHideAccounts()) {
             return convertView == null ? inflater.inflate(R.layout.empty, parent, false) : convertView;
         }
 		if (convertView == null) {
@@ -199,7 +199,8 @@ public class AccountsAdapter extends BaseAdapter {
 			return VIEWTYPE_BANK;
 		}
 		else {
-		    if (((Account)item).isHidden() && !showHidden) {
+		    if ((((Account)item).isHidden() && !showHidden) ||
+                    ((Account) item).getBank().getHideAccounts()) {
 		        return VIEWTYPE_EMPTY;
 		    }
 		}
diff --git app/src/main/java/com/liato/bankdroid/banking/Bank.java app/src/main/java/com/liato/bankdroid/banking/Bank.java
index c52c500..a5ae6a2 100644
--- app/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ app/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -78,6 +78,11 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     protected boolean disabled = false;
     protected long dbid = -1;
     protected Urllib urlopen = null;
+    protected boolean hideAccounts = false;
+
+    public boolean toggleHideAccounts() { return hideAccounts = !hideAccounts; }
+
+    public boolean getHideAccounts() { return hideAccounts; }
 
     public Urllib getUrlopen() {
         return urlopen;
@@ -203,7 +208,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public void setData(String username, String password, BigDecimal balance,
-            boolean disabled, long dbid, String currency, String customName, String extras) {
+            boolean disabled, long dbid, String currency, String customName, String extras, int hideAccounts) {
         this.username = username;
         this.password = password;
         this.balance = balance;
@@ -212,6 +217,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.currency = currency;
         this.customName = customName;
         this.extras = extras;
+        this.hideAccounts = hideAccounts==1 ? true : false;
     }
 
     public String getCurrency() {
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index a2db820..ea1c3c7 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -381,7 +381,8 @@ public class BankFactory {
 							 c.getLong(c.getColumnIndex("_id")),
 							 c.getString(c.getColumnIndex("currency")),
 							 c.getString(c.getColumnIndex("custname")),
-							 c.getString(c.getColumnIndex("extras")));
+							 c.getString(c.getColumnIndex("extras")),
+                             c.getInt(c.getColumnIndex("hideAccounts")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -425,7 +426,8 @@ public class BankFactory {
 				             c.getLong(c.getColumnIndex("_id")),
 				             c.getString(c.getColumnIndex("currency")),
 				             c.getString(c.getColumnIndex("custname")),
-                             c.getString(c.getColumnIndex("extras")));
+                             c.getString(c.getColumnIndex("extras")),
+                             c.getInt(c.getColumnIndex("hideAccounts")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
diff --git app/src/main/java/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
index 9269a49..e851c49 100644
--- app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
+++ app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
@@ -41,7 +41,7 @@ public class DBAdapter {
     private SQLiteDatabase mDb;
     
     static final String DATABASE_NAME = "data";
-    static final int DATABASE_VERSION = 10;
+    static final int DATABASE_VERSION = 11;
 
     private final Context mCtx;
 
@@ -114,7 +114,7 @@ public class DBAdapter {
      * @return Cursor over all banks
      */
     public Cursor fetchBanks() {
-        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras"}, null, null, null, null, "_id asc");
+        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"}, null, null, null, null, "_id asc");
     }
 
     
@@ -151,6 +151,7 @@ public class DBAdapter {
         initialValues.put("custname", bank.getCustomName());
         initialValues.put("extras", bank.getExtras());
         initialValues.put("updated", sdf.format(cal.getTime()));
+        initialValues.put("hideAccounts", bank.getHideAccounts() ? 1 : 0);
         
         long bankId = bank.getDbId();
         if (bankId == -1) {
@@ -202,7 +203,7 @@ public class DBAdapter {
     }
     
     public Cursor getBank(String bankId) {
-    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras"}, "_id="+bankId, null, null, null, null);
+    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras", "hideAccounts"}, "_id="+bankId, null, null, null, null);
     	if (c != null) {
     		c.moveToFirst();
     	}
diff --git app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
index 6c86a1b..7127579 100644
--- app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
+++ app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
@@ -44,6 +44,7 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
 				+ "sortorder real, "
 				+ "currency text, "
 				+ "disabled integer, "
+                + "hideAccounts integer,"
 				+ "extras text);");
 		db.execSQL("create table accounts (bankid integer not null, "
 				+ "id text not null, "
@@ -68,10 +69,13 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
 		Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
 				+ " to " + newVersion + ", which will destroy all old data");
         // Version <= 1.7.2 
-		if (oldVersion == 9) {
+		if (oldVersion <= 9) {
 		    // Add an "extras" field to the bank and and "alias for" field to the account.
             db.execSQL("ALTER TABLE banks ADD extras text;");
             db.execSQL("ALTER TABLE accounts ADD aliasfor text;");
 		}
+        if (oldVersion <= 10) {
+            db.execSQL("ALTER TABLE banks ADD hideAccounts interger;");
+        }
 	}
 }
\ No newline at end of file

commit c257fed8407790e7a00aee0d3fbe3693da4e9009
Merge: 2877c07 bc38aa8
Author: liato <x@x00.us>
Date:   Wed Nov 5 22:44:48 2014 +0100

    Merge pull request #341 from goober/feature/340-swedbank-disposal-accounts
    
    Adds support for disposal accounts for Swedbank and Sparbankerna.

commit bc38aa854d40fe784902e527eac84447c656fec1
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Nov 5 22:04:18 2014 +0100

    Adds support for disposal accounts for Swedbank and Sparbankerna. Fixes #340

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 0aaa446..9f4ed91 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -151,6 +151,8 @@ public abstract class AbstractSwedbank extends Bank {
             addAccounts(overviewResponse.getTransactionAccounts(),Account.REGULAR);
             addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
             addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
+            addAccounts(overviewResponse.getTransactionDisposalAccounts(),Account.REGULAR);
+            addAccounts(overviewResponse.getSavingDisposalAccounts(),Account.REGULAR);
             addAccounts(overviewResponse.getCardAccounts(),Account.CCARD);
             if (this.accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 2877c077880245f9db8e68b863071e9f219a9044
Merge: 2d1394a 8469864
Author: liato <x@x00.us>
Date:   Wed Nov 5 11:15:46 2014 +0100

    Merge pull request #337 from sed03/master
    
    Nordea and Jojo updated

commit 846986481864cac08f210515001861fdc26632fb
Author: sed03 <stefan.edstrom@gmail.com>
Date:   Wed Nov 5 10:21:33 2014 +0100

    Update Jojo.java
    
    Updated Tillgängligt nu: balance

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
index e77556d..0c79d7e 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
@@ -109,7 +109,7 @@ public class Jojo extends Bank {
         Elements es = d.select(".saldo_ok_wrapper > table > tbody tr");
         if (es != null) {
             for (int i = 0; i < 2; i++) {
-                int index = es.size()-4+i;
+                int index = es.size()-5+i;
                 if (index >= 0) {
                     Element e = es.get(index);
                     Element name = e.select(".first").first();

commit 1c451f8e52d35db9bb635ca844832d9afbc7d832
Author: sed03 <stefan.edstrom@gmail.com>
Date:   Wed Nov 5 10:20:01 2014 +0100

    Update Nordea.java
    
    Added account balance to credit cards

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index c545639..68c8d0a 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -113,7 +113,11 @@ public class Nordea extends Bank {
             "(.*?)" + // Group 2: Link contents - Credit card type (Eg. "Nordea Gold")
             "</a>" +
             ".*?" + // Fast forward
-            "\\*+(\\d+)", // Group 3: Censured credit card number (account identifier)
+            "\\*+(\\d+)"+ // Group 3: Censured credit card number (account identifier)
+            ".*?" + // Fast forward
+            "<td.*?>([^<]*)</td>" + // Group 4: Expire date **/**
+            ".*?" + // Fast forward
+            "<td.*?>([^<]*)</td>", // Group 5: Account balance
             Pattern.DOTALL
     );
     // Credit card transaction entry
@@ -280,7 +284,7 @@ public class Nordea extends Bank {
                         // Account/Credit card name
                         matcher.group(2),
                         // Balance (not available through simple login)
-                        new BigDecimal(0),
+                        Helpers.parseBalance(matcher.group(5)),
                         // Account/Credit card identifier
                         "c:" + matcher.group(3),
                         -1L,
@@ -522,4 +526,4 @@ public class Nordea extends Bank {
 		public static final int CREDIT_CARDS = 5;
 		public static final int CREDIT_CARD_TRANSACTIONS = 6;
 	}
-}
\ No newline at end of file
+}

commit 2d1394a71cb97ab3bac6ddb4b1d8e407dfa1901a (tag: v1.9.7.1-RC1)
Author: liato <x@x00.us>
Date:   Tue Nov 4 23:24:58 2014 +0100

    Bump version. v1.9.7.1-RC1.

diff --git app/build.gradle app/build.gradle
index 7cf4f2d..307de3c 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 10
-        versionCode 190
-        versionName "1.9.7.0"
+        versionCode 191
+        versionName "1.9.7.1-RC1"
     }
 
     final Console console = System.console();

commit fec20f6b295ece8061a442008790d116ad16a8d8
Author: liato <x@x00.us>
Date:   Tue Nov 4 23:14:37 2014 +0100

    Use BigDecimal.ZERO instead of new BigDecimal(0).

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
index cb73892..d89d625 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
@@ -18,7 +18,7 @@ public class Account {
     private String name;
 
     @JsonProperty
-    private BigDecimal balance = new BigDecimal(0);
+    private BigDecimal balance;
 
     @JsonProperty
     private String currency;
@@ -57,8 +57,7 @@ public class Account {
     }
 
     public BigDecimal getBalance() {
-        if (balance == null) return BigDecimal.ZERO;
-        return balance;
+        return balance != null ? balance : BigDecimal.ZERO;
     }
 
     public void setBalance(BigDecimal balance) {
@@ -66,8 +65,7 @@ public class Account {
     }
 
     public String getCurrency() {
-        if (currency == null) return "-";
-        return currency;
+        return currency != null ? currency : "";
     }
 
     public void setCurrency(String currency) {

commit cfcc24e1e5479b6d132a35b53cf2a8fdabe6821b
Merge: 1b5e524 32afea2
Author: liato <x@x00.us>
Date:   Tue Nov 4 23:11:09 2014 +0100

    Merge pull request #333 from cortex/master
    
    Fix for credit card accounts on Swedbank with null-values for balance and currency

commit 1b5e5242fb5cf0ddd9eb14ef28abbb11d7d0bc48
Merge: 8a7fd73 35b2303
Author: liato <x@x00.us>
Date:   Tue Nov 4 23:08:14 2014 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Nytt certifikat för American Express

commit 8a7fd73155667009638d9af4ef7835422c420cc3
Author: liato <x@x00.us>
Date:   Tue Nov 4 23:08:02 2014 +0100

    Don't sum accounts without balance. Default balance for Swedbank accounts.

diff --git app/src/main/java/com/liato/bankdroid/banking/Bank.java app/src/main/java/com/liato/bankdroid/banking/Bank.java
index 86ee4bd..c52c500 100644
--- app/src/main/java/com/liato/bankdroid/banking/Bank.java
+++ app/src/main/java/com/liato/bankdroid/banking/Bank.java
@@ -159,7 +159,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             BigDecimal bal = new BigDecimal(0); 
             for (Account account : accounts) {
                 if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
-                    if (!account.isHidden() && (account.getAliasfor() == null || account.getAliasfor().length() == 0)) {
+                    if (!account.isHidden() && (account.getAliasfor() == null || account.getAliasfor().length() == 0) && account.getBalance() != null) {
                         bal = bal.add(account.getBalance());
                     }
                 }
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 602744f..0aaa446 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -5,7 +5,6 @@ import android.text.Html;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.Base64;
-import android.view.textservice.TextInfo;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -88,7 +87,7 @@ public abstract class AbstractSwedbank extends Bank {
             LoginPackage lp = preLogin();
             httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), new StringEntity(objectAsJson(new PersonalCodeRequest(username, password)), HTTP.UTF_8), true);
             int responseCode = httpResponse.getStatusLine().getStatusCode();
-            if( responseCode == 201) {
+            if(responseCode == 201) {
                 return urlopen;
             } else if(responseCode == 401 || responseCode == 400) {
                 throw new LoginException(res.getText(
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
index ea51c4b..7e0e476 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
@@ -18,7 +18,7 @@ public class Account {
     private String name;
 
     @JsonProperty
-    private BigDecimal balance;
+    private BigDecimal balance = new BigDecimal(0);
 
     @JsonProperty
     private String currency;

commit 32afea2618cd479e4ba4159529020c20f6ec688e
Merge: 836f5e7 35b2303
Author: Joakim Lundborg <joakim.lundborg@gmail.com>
Date:   Tue Nov 4 22:58:31 2014 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid

commit 836f5e71350084b475044f2c51b32e16bbe131e3
Author: Joakim Lundborg <joakim.lundborg@gmail.com>
Date:   Tue Nov 4 22:58:19 2014 +0100

    Add default values for Swedbank accounts

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
index ea51c4b..639d3b0 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
@@ -57,6 +57,7 @@ public class Account {
     }
 
     public BigDecimal getBalance() {
+        if (balance == null) return BigDecimal.ZERO;
         return balance;
     }
 
@@ -65,6 +66,7 @@ public class Account {
     }
 
     public String getCurrency() {
+        if (currency == null) return "-";
         return currency;
     }
 

commit 35b2303ea05df4b9932b7a639a94da27f6038b08
Merge: 7492685 2d90f69
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Nov 4 16:03:32 2014 +0100

    Merge pull request #331 from NiclasI/master
    
    Updates certificate for American Express

commit 2d90f69daf1564b13ed79d3aa9bd3bfa501bae31
Author: NiclasI <niclas@niclas.net>
Date:   Tue Nov 4 15:32:20 2014 +0100

    Nytt certifikat för American Express

diff --git app/src/main/res/raw/cert_americanexpress.pem app/src/main/res/raw/cert_americanexpress.pem
index bb3bc22..9221fb8 100644
--- app/src/main/res/raw/cert_americanexpress.pem
+++ app/src/main/res/raw/cert_americanexpress.pem
@@ -1,25 +1,37 @@
 -----BEGIN CERTIFICATE-----

-xoL1/mj95xY03lYAEWKwhYQ=

+9TzIzLV/TRFmIpOYgN55mjpSOJoXpiA+pG5n7ZWkn+LiAQ+k
 -----END CERTIFICATE-----

commit 74926858c3c5c49252893d9bda2ef8d6286a90ea
Author: liato <x@x00.us>
Date:   Mon Nov 3 13:17:34 2014 +0100

    Use UTF-8 encoding for StringEntities in Swedbank.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 3abc698..602744f 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -30,6 +30,7 @@ import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HTTP;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -85,7 +86,7 @@ public abstract class AbstractSwedbank extends Bank {
         HttpResponse httpResponse = null;
         try {
             LoginPackage lp = preLogin();
-            httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), new StringEntity(objectAsJson(new PersonalCodeRequest(username, password))), true);
+            httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), new StringEntity(objectAsJson(new PersonalCodeRequest(username, password)), HTTP.UTF_8), true);
             int responseCode = httpResponse.getStatusLine().getStatusCode();
             if( responseCode == 201) {
                 return urlopen;

commit 102106db2c311f38fa1188329319468f067ca3eb
Author: liato <x@x00.us>
Date:   Mon Nov 3 02:52:33 2014 +0100

    Use fullyFormattedNumber as account id for Swedbank accounts. Closes #324.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 2e81f58..3abc698 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -36,7 +36,9 @@ import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import eu.nullbyte.android.urllib.CertificateReader;
@@ -50,6 +52,7 @@ public abstract class AbstractSwedbank extends Bank {
     private static final String API_BASE = "https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/";
 
     private ObjectMapper mObjectMapper = new ObjectMapper();
+    private Map<String, String> mIdMap = new HashMap<String, String>();
 
     public AbstractSwedbank(Context context) {
         super(context);
@@ -169,7 +172,7 @@ public abstract class AbstractSwedbank extends Bank {
         }
         try {
 
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+account.getId()),false);
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+mIdMap.get(account.getId())),false);
 
             TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(), TransactionsResponse.class);
             List<Transaction> transactions = new ArrayList<Transaction>();
@@ -249,7 +252,8 @@ public abstract class AbstractSwedbank extends Bank {
 
     private void addAccounts(List<com.liato.bankdroid.banking.banks.swedbank.model.Account> accountList, int accountType) {
         for(com.liato.bankdroid.banking.banks.swedbank.model.Account account : accountList) {
-            Account bankdroidAccount = new Account(account.getName(),account.getBalance(),account.getId(),accountType,account.getCurrency());
+            Account bankdroidAccount = new Account(account.getName(), account.getBalance(), account.getFullyFormattedNumber(), accountType,account.getCurrency());
+            mIdMap.put(bankdroidAccount.getId(), account.getId());
             this.accounts.add(bankdroidAccount);
         }
     }
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
index ecd2025..ea51c4b 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
@@ -23,6 +23,15 @@ public class Account {
     @JsonProperty
     private String currency;
 
+    @JsonProperty
+    private String fullyFormattedNumber;
+
+    @JsonProperty
+    private String accountNumber;
+
+    @JsonProperty
+    private String clearingNumber;
+
     public boolean isSelectedForQuickBalance() {
         return selectedForQuickBalance;
     }
@@ -62,4 +71,16 @@ public class Account {
     public void setCurrency(String currency) {
         this.currency = currency;
     }
+
+    public String getFullyFormattedNumber() {
+        return fullyFormattedNumber;
+    }
+
+    public String getAccountNumber() {
+        return accountNumber;
+    }
+
+    public String getClearingNumber() {
+        return clearingNumber;
+    }
 }

commit 4b194ef5336073d836bf23615c09e36b0ddbc6ca
Author: liato <x@x00.us>
Date:   Mon Nov 3 02:38:46 2014 +0100

    Add error message handling to Swedbank.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index 7f94490..2e81f58 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -1,8 +1,11 @@
 package com.liato.bankdroid.banking.banks.swedbank;
 
 import android.content.Context;
+import android.text.Html;
 import android.text.InputType;
+import android.text.TextUtils;
 import android.util.Base64;
+import android.view.textservice.TextInfo;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -12,6 +15,8 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankChoice;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.swedbank.model.ErrorMessage;
+import com.liato.bankdroid.banking.banks.swedbank.model.ErrorResponse;
 import com.liato.bankdroid.banking.banks.swedbank.model.engagement.OverviewResponse;
 import com.liato.bankdroid.banking.banks.swedbank.model.engagement.TransactionsResponse;
 import com.liato.bankdroid.banking.banks.swedbank.model.identification.PersonalCodeRequest;
@@ -19,7 +24,6 @@ import com.liato.bankdroid.banking.banks.swedbank.model.profile.ProfileResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
 import com.liato.bankdroid.utils.Installation;
 
 import org.apache.http.HttpEntity;
@@ -81,10 +85,25 @@ public abstract class AbstractSwedbank extends Bank {
             httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), new StringEntity(objectAsJson(new PersonalCodeRequest(username, password))), true);
             int responseCode = httpResponse.getStatusLine().getStatusCode();
             if( responseCode == 201) {
-             return urlopen;
+                return urlopen;
             } else if(responseCode == 401 || responseCode == 400) {
                 throw new LoginException(res.getText(
                         R.string.invalid_username_password).toString());
+            } else if (responseCode == 503) {
+                String errorMessage = null;
+                try {
+                    ErrorResponse er = readJsonValue(httpResponse.getEntity().getContent(), ErrorResponse.class);
+                    StringBuilder sb = new StringBuilder();
+                    for (List<ErrorMessage> ems : er.getErrorMessages().values()) {
+                        for (ErrorMessage em : ems) {
+                            sb.append(Html.fromHtml(em.getMessage()).toString()).append("\n");
+                        }
+                    }
+                    errorMessage = sb.toString().trim();
+                } catch (BankException e) {
+                    //Ignore json parse errors and show generic server error message
+                }
+                throw new BankException(TextUtils.isEmpty(errorMessage) ? context.getString(R.string.server_error_try_again) : errorMessage);
             } else {
                 throw new BankException("");
             }
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
new file mode 100644
index 0000000..ed419dc
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorMessage.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 Nullbyte
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+public class ErrorMessage implements Serializable {
+    private static final long serialVersionUID = 7228754028321179052L;
+    @JsonProperty
+    String title;
+
+    @JsonProperty
+    String code;
+
+    @JsonProperty
+    String message;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
new file mode 100644
index 0000000..bebcc6f
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/ErrorResponse.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Nullbyte
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+
+/*
+{
+    "errorMessages": {
+        "general": [{
+            "title": "Mobilbanken ej tillg&auml;nglig",
+            "code": "SERVICE_UNAVAILABLE",
+            "message": "F&ouml;r n&auml;rvarande &auml;r Mobil- och iPad-apparna otillg&auml;ngliga. V&auml;nligen f&ouml;rs&ouml;k igen senare."
+        }]
+    }
+}
+ */
+//@JsonIgnoreProperties(ignoreUnknown = true)
+public class ErrorResponse implements Serializable {
+    private static final long serialVersionUID = 1971937841087070779L;
+
+    @JsonProperty
+    Map<String, ArrayList<ErrorMessage>> errorMessages = Collections.emptyMap();
+
+    public Map<String, ArrayList<ErrorMessage>> getErrorMessages() {
+        return errorMessages;
+    }
+
+}
+
+
+
diff --git app/src/main/res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
index 1119522..067923c 100644
--- app/src/main/res/values-sv/strings.xml
+++ app/src/main/res/values-sv/strings.xml
@@ -24,6 +24,7 @@
     <string name="unable_to_login">Kunde ej logga in. Var vänlig försök igen senare.</string>
     <string name="account_number">Kontonummer</string>
     <string name="control_code">Kontrollkod</string>
+    <string name="server_error_try_again">Serverfel. Var god försök igen om en stund.</string>
 
     <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
diff --git app/src/main/res/values/strings.xml app/src/main/res/values/strings.xml
index a760f2f..f532cb2 100644
--- app/src/main/res/values/strings.xml
+++ app/src/main/res/values/strings.xml
@@ -23,6 +23,7 @@
     <string name="unable_to_login">Unable to login. Please try again later.</string>
     <string name="account_number">Account number</string>
     <string name="control_code">Control code</string>
+    <string name="server_error_try_again">Server error. Please try again later.</string>
 
     <string name="username">Username</string>
     <string name="password">Password</string>

commit a09266ffb066805e8ec629caa0cdfd274a5057f8
Merge: 8c30234 f09db20
Author: liato <x@x00.us>
Date:   Sun Nov 2 01:52:18 2014 +0100

    Merge pull request #327 from goober/feature/321-certificate-vasttrafik
    
    Update server certificate for Västtrafik.

commit 8c30234871c9dd8b18101a7206538ff6ead9669d
Merge: 2888b47 df8d50e
Author: liato <x@x00.us>
Date:   Sun Nov 2 01:52:11 2014 +0100

    Merge pull request #326 from goober/feature/322-certificate-svenska-spel
    
    Updates server certificate for Svenskaspel

commit 2888b47b0c508ab54cd4038b2ce06eceeb0a5604
Merge: d475613 35856be
Author: liato <x@x00.us>
Date:   Sun Nov 2 01:50:49 2014 +0100

    Merge pull request #325 from goober/feature/323-swedbank-missing-transactions
    
    Fixes missing transactions for Swedbank and Sparbankerna.

commit f09db20586476286d06592f93e46226e3db31789
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Nov 1 14:31:28 2014 +0100

    Update server certificate for Västtrafik.

diff --git app/src/main/res/raw/cert_vasttrafik.pem app/src/main/res/raw/cert_vasttrafik.pem
index 7f471f0..8f18f18 100644
--- app/src/main/res/raw/cert_vasttrafik.pem
+++ app/src/main/res/raw/cert_vasttrafik.pem
@@ -1,30 +1,28 @@
------BEGIN CERTIFICATE-----

-n4sqTE3G
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+/o1LuYVBwcNU4Q==
+-----END CERTIFICATE-----

commit df8d50e2b119f3addc382b225504da54ba836790
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Nov 1 14:28:34 2014 +0100

    Updates server certificate for Svenskaspel

diff --git app/src/main/res/raw/cert_svenskaspel.pem app/src/main/res/raw/cert_svenskaspel.pem
index f7307c5..c541f04 100644
--- app/src/main/res/raw/cert_svenskaspel.pem
+++ app/src/main/res/raw/cert_svenskaspel.pem
@@ -1,31 +1,34 @@
------BEGIN CERTIFICATE-----

-GjFd
------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+orkj7QfRvV5ZNIpCKDJdonffdb+PuSwzWBVLMT/N/g==
+-----END CERTIFICATE-----

commit 35856be140b151ffd9f5589d1274a7d6a148d38f
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Nov 1 13:51:50 2014 +0100

    Fixes missing transactions for Swedbank and Sparbankerna.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
index de6b661..7f94490 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -166,15 +166,17 @@ public abstract class AbstractSwedbank extends Bank {
     }
 
     @Override
-    public void updateComplete() {
-        super.updateComplete();
+    public void closeConnection() {
         try {
             HttpResponse response = urlopen.openAsHttpResponse(getResourceUri("identification/logout"), HttpMethod.PUT);
         } catch(ClientProtocolException e) {
             // Ignore logout exceptions
         } catch(IOException e) {
             //Ignore logout exceptions
+        } finally {
+            super.closeConnection();
         }
+
     }
 
     private List<Transaction> transformTransactions(List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {

commit d475613f6b21c7b8611b021991cf8d4a02d7541d
Author: liato <x@x00.us>
Date:   Fri Oct 31 02:49:27 2014 +0100

    Update contributors and changelog.

diff --git CHANGES.txt CHANGES.txt
index 85911a6..5f64c48 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,10 @@
+v1.9.7.0: (2014-10-31)
+* Fix for Nordea (thanks to rhoot and wicol)
+* Use Swedbank's API (thanks to goober for the implementation and Swedbank for giving us access to their API)
+* Updated SSL certificate for Skandiabanken
+* Fix for Chalmrest balance (thanks to emilan)
+
+
 v1.9.6.16: (2014-09-18)
 * Updated SSL certificates for American Express, Coop, Eurocard, Forex Bank, Ikano Bank, Marginalen Bank, Meniga, Nordnet, Nordnet Direkt, OKQ8, Payson, Rikslunchen, SevenDay, Trustbuddy and Villabanken
 * Improvements to Villabanken account parsing (thanks to knifhen)
diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index 2a57f08..693ec4f 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -34,7 +34,8 @@ Development
   NanoRage                          https://github.com/NanoRage
   Adam Nybäck                       https://github.com/nadam
   MathiasBois                       https://github.com/MathiasBois
-
+  Johan Sköld                       https://github.com/rhoot
+  Wictor                            https://github.com/wicol
 
 
   Stats at:

commit 296130ee5f7949a2963fc661a1aa826435bb04d0 (tag: v1.9.7.0)
Author: liato <x@x00.us>
Date:   Fri Oct 31 02:17:03 2014 +0100

    Bump version. v1.9.7.0

diff --git app/build.gradle app/build.gradle
index bad188f..7cf4f2d 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 10
-        versionCode 189
-        versionName "1.9.6.16"
+        versionCode 190
+        versionName "1.9.7.0"
     }
 
     final Console console = System.console();
diff --git app/src/main/AndroidManifest.xml app/src/main/AndroidManifest.xml
index ed7c54e..6deb35e 100644
--- app/src/main/AndroidManifest.xml
+++ app/src/main/AndroidManifest.xml
@@ -1,11 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid"
-	android:versionName="1.9.6.16" android:versionCode="189">
-    <uses-sdk
-        android:targetSdkVersion="10"
-        android:minSdkVersion="7" />
+	package="com.liato.bankdroid">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 672a89b1d4ead14443b43679be6856a1efb4fcb4
Merge: 3d69df1 249b784
Author: liato <x@x00.us>
Date:   Thu Oct 30 08:41:26 2014 +0100

    Merge pull request #315 from goober/feature/309-mobilbank.swedbank.se-is-being-closed
    
    Feature/309 mobilbank.swedbank.se is being closed

commit 249b7848301f1fc4389c8cf28b8b7fc4301fe0d6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 30 01:30:55 2014 +0100

    Adds Sparbankerna as a separate bank due to requirement form the new Swedbank API.

diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index c6811b3..a2db820 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -95,6 +95,7 @@ import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
+import com.liato.bankdroid.banking.banks.swedbank.Sparbankerna;
 import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
@@ -262,6 +263,8 @@ public class BankFactory {
             return new SveaDirekt(context);
         case IBankTypes.SUPREMECARD:
             return new SupremeCard(context);
+        case IBankTypes.SPARBANKERNA:
+            return new Sparbankerna(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -345,6 +348,7 @@ public class BankFactory {
         banks.add(new EurobonusMastercardDk(context));
         banks.add(new SveaDirekt(context));
         banks.add(new SupremeCard(context));
+        banks.add(new Sparbankerna(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
new file mode 100644
index 0000000..648d950
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Sparbankerna.java
@@ -0,0 +1,37 @@
+package com.liato.bankdroid.banking.banks.swedbank;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+public class Sparbankerna extends AbstractSwedbank {
+
+    private static final String TAG = "Sparbankerna";
+    private static final String NAME = "Sparbankerna";
+    private static final String NAME_SHORT = "sparbankerna";
+    private static final int BANKTYPE_ID = IBankTypes.SPARBANKERNA;
+
+    private static final String APP_ID = "qdorTi1mqZ09Zcyc";
+
+    public Sparbankerna(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+
+    }
+
+    public Sparbankerna(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected String getAppId() {
+        return APP_ID;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
index 909cc96..73e0601 100644
--- app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
+++ app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
@@ -97,4 +97,5 @@ public interface IBankTypes {
     public final static int SASEUROBONUSMASTERCARD_DK = 73;
     public final static int SVEADIREKT  = 74;
     public final static int SUPREMECARD  = 75;
+    public final static int SPARBANKERNA = 76;
 }
diff --git app/src/main/res/drawable/logo_sparbankerna.png app/src/main/res/drawable/logo_sparbankerna.png
new file mode 100644
index 0000000..e7cb3e2
Binary files /dev/null and app/src/main/res/drawable/logo_sparbankerna.png differ

commit 4be63825876694ea08876b8e02bacc2effc586b6
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 30 01:29:56 2014 +0100

    Replaces current Swedbank implementation with their API.

diff --git app/src/main/java/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
index 5409017..4eaeaee 100644
--- app/src/main/java/com/liato/bankdroid/SettingsActivity.java
+++ app/src/main/java/com/liato/bankdroid/SettingsActivity.java
@@ -30,7 +30,7 @@ import android.widget.Toast;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.Swedbank;
+import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.lockpattern.ChooseLockPattern;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
diff --git app/src/main/java/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
index 73cf7a4..c6811b3 100644
--- app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
+++ app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
@@ -77,7 +77,6 @@ import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
-import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.TicketRikskortet;
 import com.liato.bankdroid.banking.banks.TrustBuddy;
@@ -96,6 +95,7 @@ import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
+import com.liato.bankdroid.banking.banks.swedbank.Swedbank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Swedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/Swedbank.java
deleted file mode 100644
index 5199a61..0000000
--- app/src/main/java/com/liato/bankdroid/banking/banks/Swedbank.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankChoice;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Swedbank extends Bank {
-	private static final String TAG = "Swedbank";
-	private static final String NAME = "Swedbank";
-	private static final String NAME_SHORT = "swedbank";
-	private static final String URL = "https://mobilbank.swedbank.se/";
-	private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    
-	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\"[^>]*>\\s*(?:<span\\sclass=\"icon\">[^<]*</span>\\s*)?<span\\s*class=\"name\">([^<]+)</span>\\s*(?:<br/>\\s*)?<span\\s*class=\"amount\">([^<]+)</");
-	private Pattern reLinklessAccounts = Pattern.compile("fix\">\\s*<span\\sclass=\"name\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\sclass=\"amount\">([^<]+)</span>\\s*</div>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("date\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"receiver\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"amount\">([^<]+)</span>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
-	private Pattern reLoanData = Pattern.compile("<li[^>]*>([^<]+)<br/><span\\s*class=\"secondary\">([^<]+)</span></li>");
-	private Pattern reMultipleBanks = Pattern.compile("menu\\.html\\?bank=(\\d{1,})\">([^<]+)</");
-	
-	String response;
-	public Swedbank(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public Swedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-	@Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_swedbank));
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        Matcher matcher;
-        response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
-        matcher = reCSRF.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-        }
-        String csrftoken = matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("xyz", username));
-        postData.add(new BasicNameValuePair("auth-method", "code"));
-        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-        response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loginNext.html", postData);
-
-        matcher = reCSRF.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-        }
-        csrftoken = matcher.group(1);
-        postData.clear();
-        postData.add(new BasicNameValuePair("zyx", password));
-        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-        String banknr = (getExtras() != null && getExtras().length() > 0) ? "?bank="+getExtras() : "";
-        return new LoginPackage(urlopen, postData, response, "https://mobilbank.swedbank.se/banking/swedbank/login.html"+banknr);
-    }
-
-    @Override
-	public Urllib login() throws LoginException, BankException {
-	    
-	    try {
-	        LoginPackage lp = preLogin();
-	        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-			if (response.contains("misslyckats")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-
-		Matcher matcher;
-		if (getExtras() == null || getExtras().length() == 0) {
-    		ArrayList<BankChoice> banks = new ArrayList<BankChoice>();
-    		matcher = reMultipleBanks.matcher(response);
-    		while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: ID                0 | 1 | ..
-                 * 2: Name              Ostlands Sparbank
-                 *  
-                 */ 		    
-    		    banks.add(new BankChoice(Html.fromHtml(matcher.group(2)).toString().trim(), matcher.group(1)));
-    		}
-    		if (!banks.isEmpty()) {
-    		    throw new BankChoiceException("Select a bank.", banks);
-    		}
-		}
-		
-        String banknr = (getExtras() != null && getExtras().length() > 0) ? "?bank="+getExtras() : "";
-		try {
-	        response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/menu.html"+banknr);
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Type              account|loan
-                 * 2: ID                0
-                 * 3: Name              Privatkonto
-                 * 4: Amount            5 678 
-                 *  
-                 */			    
-				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), "loan".equalsIgnoreCase(matcher.group(1).trim()) ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
-				if ("loan".equalsIgnoreCase(matcher.group(1).trim())) {
-				    account.setType(Account.LOANS);
-				}
-				else {
-				    balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-				}
-				accounts.add(account);
-			}
-			matcher = reLinklessAccounts.matcher(response);
-			int accid = 0;
-			while (matcher.find()) {
-				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll:"+accid);
-				account.setType(Account.OTHER);
-                accounts.add(account);
-                accid++;
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		finally {
-	      super.updateComplete();
-		}
-        // Demo account to use with screenshots
-        //accounts.add(new Account("Personkonto", Helpers.parseBalance("8351"), "0"));
-        //accounts.add(new Account("Sparkonto", Helpers.parseBalance("59070"), "1"));
-	}
-	
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		if (account.getType() == Account.OTHER) return;
-
-		String response = null;
-		Matcher matcher;
-		try {
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		    if (account.getType() == Account.LOANS) {
-		        String [] accountId = account.getId().split(":", 2);
-		        if (accountId.length < 2) return;
-	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]);
-	            matcher = reLoanData.matcher(response);
-	            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-	            Calendar cal = Calendar.getInstance(); 
-	            String date = sdf.format(cal.getTime());
-	            while (matcher.find()) {
-	                /*
-	                 * Capture groups:
-	                 * GROUP                    EXAMPLE DATA
-	                 * 1: Title                 Totalt | Clearingnummer
-	                 * 2: Value                 12 345 | 8032-5
-	                 * 
-	                 */
-	                Transaction transaction = new Transaction(date, Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)));
-	                transaction.setCurrency("");
-	                transactions.add(transaction);
-	            }
-		    }
-		    else {
-	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
-	            matcher = reTransactions.matcher(response);
-	            while (matcher.find()) {
-                    /*
-                     * Capture groups:
-                     * GROUP                    EXAMPLE DATA
-                     * 1: Date                  11-04-06
-                     * 2: Specification         Pressbyran
-                     * 3: Amount                -20
-                     * 
-                     */	                
-	                transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-	            }
-		    }
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-
-		// Demo transactions to use with screenshots
-		/*
-		try {
-            response = IOUtils.toString(context.getResources().openRawResource(R.raw.swedbank_transactions));
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-            }
-            account.setTransactions(transactions);
-        }
-        catch (NotFoundException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        */
-	}
-}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
new file mode 100644
index 0000000..de6b661
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/AbstractSwedbank.java
@@ -0,0 +1,281 @@
+package com.liato.bankdroid.banking.banks.swedbank;
+
+import android.content.Context;
+import android.text.InputType;
+import android.util.Base64;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankChoice;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.swedbank.model.engagement.OverviewResponse;
+import com.liato.bankdroid.banking.banks.swedbank.model.engagement.TransactionsResponse;
+import com.liato.bankdroid.banking.banks.swedbank.model.identification.PersonalCodeRequest;
+import com.liato.bankdroid.banking.banks.swedbank.model.profile.ProfileResponse;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+import com.liato.bankdroid.utils.Installation;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.entity.StringEntity;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.HttpMethod;
+import eu.nullbyte.android.urllib.Urllib;
+
+public abstract class AbstractSwedbank extends Bank {
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+
+    private static final String API_BASE = "https://auth.api.swedbank.se/TDE_DAP_Portal_REST_WEB/api/v1/";
+
+    private ObjectMapper mObjectMapper = new ObjectMapper();
+
+    public AbstractSwedbank(Context context) {
+        super(context);
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(BigDecimal.class, new BalanceDeserializer());
+        mObjectMapper.registerModule(module);
+
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+
+    }
+
+    public AbstractSwedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_swedbank));
+        urlopen.addHeader("Authorization",getAuthenticationHeader());
+        urlopen.addHeader("Content-Type","application/json;charset=UTF-8");
+        urlopen.addHeader("Accept","application/json");
+        return new LoginPackage(urlopen,null,null,getResourceUri("identification/personalcode"));
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        HttpResponse httpResponse = null;
+        try {
+            LoginPackage lp = preLogin();
+            httpResponse = urlopen.openAsHttpResponse(lp.getLoginTarget(), new StringEntity(objectAsJson(new PersonalCodeRequest(username, password))), true);
+            int responseCode = httpResponse.getStatusLine().getStatusCode();
+            if( responseCode == 201) {
+             return urlopen;
+            } else if(responseCode == 401 || responseCode == 400) {
+                throw new LoginException(res.getText(
+                        R.string.invalid_username_password).toString());
+            } else {
+                throw new BankException("");
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        } finally {
+            if(httpResponse != null) {
+                HttpEntity httpEntity = httpResponse.getEntity();
+                if (httpEntity != null) {
+                    try {
+                        httpEntity.consumeContent();
+                    } catch (IOException e) {
+                        throw new BankException("");
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        try {
+            ProfileResponse profileResponse = getAvailableProfiles();
+            setDefaultProfile(getBankId(profileResponse.getBanks()));
+
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/overview"), false);
+            if(httpResponse.getStatusLine().getStatusCode() != 200) {
+                throw new BankException("");
+            }
+
+            OverviewResponse overviewResponse = readJsonValue(httpResponse.getEntity().getContent(),OverviewResponse.class);
+            addAccounts(overviewResponse.getTransactionAccounts(),Account.REGULAR);
+            addAccounts(overviewResponse.getLoanAccounts(),Account.LOANS);
+            addAccounts(overviewResponse.getSavingAccounts(),Account.REGULAR);
+            addAccounts(overviewResponse.getCardAccounts(),Account.CCARD);
+            if (this.accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        } finally {
+            updateComplete();
+        }
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        if(account.getType() != Account.REGULAR) {
+            return;
+        }
+        try {
+
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("engagement/transactions/"+account.getId()),false);
+
+            TransactionsResponse response = readJsonValue(httpResponse.getEntity().getContent(), TransactionsResponse.class);
+            List<Transaction> transactions = new ArrayList<Transaction>();
+            transactions.addAll(transformTransactions(response.getTransactions()));
+            transactions.addAll(transformTransactions(response.getReservedTransactions()));
+            account.setTransactions(transactions);
+
+        } catch(ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch(IOException e) {
+            throw new BankException(e.getMessage());
+        }
+    }
+
+    @Override
+    public void updateComplete() {
+        super.updateComplete();
+        try {
+            HttpResponse response = urlopen.openAsHttpResponse(getResourceUri("identification/logout"), HttpMethod.PUT);
+        } catch(ClientProtocolException e) {
+            // Ignore logout exceptions
+        } catch(IOException e) {
+            //Ignore logout exceptions
+        }
+    }
+
+    private List<Transaction> transformTransactions(List<com.liato.bankdroid.banking.banks.swedbank.model.Transaction> transactions) {
+        List<Transaction> transactionList = new ArrayList<Transaction>();
+        for(com.liato.bankdroid.banking.banks.swedbank.model.Transaction transaction : transactions) {
+            transactionList.add(new Transaction(transaction.getDate(),transaction.getDescription(),transaction.getAmount(),transaction.getCurrency()));
+        }
+        return transactionList;
+    }
+
+
+    private ProfileResponse getAvailableProfiles() throws IOException, ClientProtocolException, BankException {
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/"), false);
+        if (httpResponse.getStatusLine().getStatusCode() == 200) {
+            ProfileResponse response = readJsonValue(httpResponse.getEntity().getContent(), ProfileResponse.class);
+            if(response.getBanks().isEmpty()) {
+                String provider = response.isSwedbankProfile() ? "Swedbank" : response.isSavingbankProfile() ? "Sparbankerna" : null;
+                if(provider != null) {
+                    throw new BankException("You are trying to connect an account from " + provider + " to the " + NAME + " bank. Please use the " + provider + " bank instead.");
+                } else {
+                    throw new BankException("No profiles available.");
+                }
+            }
+            return response;
+        }
+        throw new BankException("Could not fetch available profiles.");
+    }
+
+    private void setDefaultProfile(String bankId) throws ClientProtocolException, IOException, BankException {
+        HttpResponse httpResponse = urlopen.openAsHttpResponse(getResourceUri("profile/private/" + bankId), true);
+        httpResponse.getEntity().consumeContent();
+        if (httpResponse.getStatusLine().getStatusCode() != 201) {
+            throw new BankException("Could not set the default profile.");
+        }
+    }
+
+    private String getBankId(List<com.liato.bankdroid.banking.banks.swedbank.model.Bank> bankList) throws BankChoiceException {
+        String bankId = getExtras();
+        if(bankId != null && !bankId.isEmpty()) {
+            return bankId;
+        }
+        if(bankList.size() > 1) {
+            ArrayList<BankChoice> banks = new ArrayList<BankChoice>();
+            for(com.liato.bankdroid.banking.banks.swedbank.model.Bank bank : bankList) {
+                banks.add(new BankChoice(bank.getName(), bank.getBankId()));
+            }
+            throw new BankChoiceException("Select a bank.",banks);
+        }
+        return bankList.get(0).getBankId();
+    }
+
+    private void addAccounts(List<com.liato.bankdroid.banking.banks.swedbank.model.Account> accountList, int accountType) {
+        for(com.liato.bankdroid.banking.banks.swedbank.model.Account account : accountList) {
+            Account bankdroidAccount = new Account(account.getName(),account.getBalance(),account.getId(),accountType,account.getCurrency());
+            this.accounts.add(bankdroidAccount);
+        }
+    }
+
+    private String getAuthenticationHeader() {
+        try {
+            byte[] data = new StringBuilder(getAppId())
+                    .append(':')
+                    .append(Installation.id(context))
+                    .toString().getBytes("UTF-8");
+            return Base64.encodeToString(data,Base64.NO_WRAP);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private String getResourceUri(String resource) {
+        String dsid = "dsid="+UUID.randomUUID().toString();
+        urlopen.addHeader("Cookie",dsid);
+        return API_BASE + resource + '?'+dsid;
+    }
+
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+        try {
+            return mObjectMapper.readValue(is, valueType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+                //Ignore
+            }
+        }
+
+    }
+
+    public String objectAsJson(Object value) {
+        try {
+            return mObjectMapper.writeValueAsString(value);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    protected abstract String getAppId();
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
new file mode 100644
index 0000000..7a84be9
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/BalanceDeserializer.java
@@ -0,0 +1,19 @@
+package com.liato.bankdroid.banking.banks.swedbank;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.liato.bankdroid.Helpers;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+
+public class BalanceDeserializer extends JsonDeserializer<BigDecimal> {
+    @Override
+    public BigDecimal deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+        return Helpers.parseBalance(jp.getValueAsString());
+
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
new file mode 100644
index 0000000..ffe26ee
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/Swedbank.java
@@ -0,0 +1,37 @@
+package com.liato.bankdroid.banking.banks.swedbank;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+public class Swedbank extends AbstractSwedbank {
+
+    private static final String TAG = "Swedbank";
+    private static final String NAME = "Swedbank";
+    private static final String NAME_SHORT = "swedbank";
+    private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
+
+    private static final String APP_ID = "vgmYRMelBJ0Yzujs";
+
+    public Swedbank(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+
+    }
+
+    public Swedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected String getAppId() {
+        return APP_ID;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
new file mode 100644
index 0000000..ecd2025
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Account.java
@@ -0,0 +1,65 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.math.BigDecimal;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Account {
+
+    @JsonProperty
+    private boolean selectedForQuickBalance;
+
+    @JsonProperty
+    private String id;
+
+    @JsonProperty
+    private String name;
+
+    @JsonProperty
+    private BigDecimal balance;
+
+    @JsonProperty
+    private String currency;
+
+    public boolean isSelectedForQuickBalance() {
+        return selectedForQuickBalance;
+    }
+
+    public void setSelectedForQuickBalance(boolean selectedForQuickBalance) {
+        this.selectedForQuickBalance = selectedForQuickBalance;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public BigDecimal getBalance() {
+        return balance;
+    }
+
+    public void setBalance(BigDecimal balance) {
+        this.balance = balance;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
new file mode 100644
index 0000000..05f5b7e
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Bank.java
@@ -0,0 +1,60 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Bank {
+
+    @JsonProperty
+    private String name;
+
+    @JsonProperty
+    private String bankId;
+
+    @JsonProperty
+    private Profile privateProfile;
+
+    @JsonProperty
+    private List<CorporateProfile> corporateProfiles;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBankId() {
+        return bankId;
+    }
+
+    public void setBankId(String bankId) {
+        this.bankId = bankId;
+    }
+
+    public Profile getPrivateProfile() {
+        return privateProfile;
+    }
+
+    public void setPrivateProfile(Profile privateProfile) {
+        this.privateProfile = privateProfile;
+    }
+
+    public List<CorporateProfile> getCorporateProfiles() {
+       if(corporateProfiles == null) {
+           corporateProfiles = new ArrayList<CorporateProfile>();
+       }
+        return corporateProfiles;
+    }
+
+    public void setCorporateProfiles(List<CorporateProfile> corporateProfiles) {
+        this.corporateProfiles = corporateProfiles;
+    }
+}
+
+
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
new file mode 100644
index 0000000..0a7a3ef
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CorporateProfile.java
@@ -0,0 +1,19 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CorporateProfile extends Profile {
+
+    @JsonProperty
+    private String activeProfileName;
+
+    public String getActiveProfileName() {
+        return activeProfileName;
+    }
+
+    public void setActiveProfileName(String activeProfileName) {
+        this.activeProfileName = activeProfileName;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
new file mode 100644
index 0000000..7f79127
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/CreditCard.java
@@ -0,0 +1,58 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CreditCard {
+
+    @JsonProperty
+    private String currency;
+
+    @JsonProperty
+    private String name;
+
+    @JsonProperty
+    private String balance;
+
+    @JsonProperty
+    private List<String> cardNumbers;
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getBalance() {
+        return balance;
+    }
+
+    public void setBalance(String balance) {
+        this.balance = balance;
+    }
+
+    public List<String> getCardNumbers() {
+        if(cardNumbers == null) {
+            cardNumbers = new ArrayList<String>();
+        }
+        return cardNumbers;
+    }
+
+    public void setCardNumbers(List<String> cardNumbers) {
+        this.cardNumbers = cardNumbers;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
new file mode 100644
index 0000000..e07cd43
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/OperationalMessages.java
@@ -0,0 +1,31 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OperationalMessages {
+
+    @JsonProperty
+    private String title;
+
+    @JsonProperty
+    private String message;
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
new file mode 100644
index 0000000..97aa94a
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Profile.java
@@ -0,0 +1,42 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Profile {
+
+    @JsonProperty
+    private String customerName;
+
+    @JsonProperty
+    private String customerNumber;
+
+    @JsonProperty
+    private String id;
+
+    public String getCustomerName() {
+        return customerName;
+    }
+
+    public void setCustomerName(String customerName) {
+        this.customerName = customerName;
+    }
+
+    public String getCustomerNumber() {
+        return customerNumber;
+    }
+
+    public void setCustomerNumber(String customerNumber) {
+        this.customerNumber = customerNumber;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+}
+
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
new file mode 100644
index 0000000..3dbe381
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/Transaction.java
@@ -0,0 +1,55 @@
+package com.liato.bankdroid.banking.banks.swedbank.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Transaction {
+
+    @JsonProperty
+    private String date;
+
+    @JsonProperty
+    private BigDecimal amount;
+
+    @JsonProperty
+    private String description;
+
+    @JsonProperty
+    private String currency;
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public void setAmount(BigDecimal amount) {
+        this.amount = amount;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
new file mode 100644
index 0000000..667e741
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/OverviewResponse.java
@@ -0,0 +1,108 @@
+package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.liato.bankdroid.banking.banks.swedbank.model.Account;
+import com.liato.bankdroid.banking.banks.swedbank.model.CreditCard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OverviewResponse {
+
+    @JsonProperty
+    private CreditCard creditCard;
+
+    @JsonProperty
+    private List<Account> transactionAccounts;
+
+    @JsonProperty
+    private List<Account> savingAccounts;
+
+    @JsonProperty("loanAccounts")
+    private List<Account> loanAccounts;
+
+    @JsonProperty
+    private List<Account> transactionDisposalAccounts;
+
+    @JsonProperty
+    private List<Account> savingDisposalAccounts;
+
+    @JsonProperty
+    private List<Account> cardAccounts;
+
+    public CreditCard getCreditCard() {
+        return creditCard;
+    }
+
+    public void setCreditCard(CreditCard creditCard) {
+        this.creditCard = creditCard;
+    }
+
+    public List<Account> getTransactionAccounts() {
+        if(transactionAccounts == null) {
+            transactionAccounts = new ArrayList<Account>();
+        }
+        return transactionAccounts;
+    }
+
+    public void setTransactionAccounts(List<Account> transactionAccounts) {
+        this.transactionAccounts = transactionAccounts;
+    }
+
+    public List<Account> getSavingAccounts() {
+        if(savingAccounts == null) {
+            savingAccounts = new ArrayList<Account>();
+        }
+        return savingAccounts;
+    }
+
+    public void setSavingAccounts(List<Account> savingAccounts) {
+        this.savingAccounts = savingAccounts;
+    }
+
+    public List<Account> getLoanAccounts() {
+        if(loanAccounts == null) {
+            loanAccounts = new ArrayList<Account>();
+        }
+        return loanAccounts;
+    }
+
+    public void setLoanAccounts(List<Account> loanAccounts) {
+        this.loanAccounts = loanAccounts;
+    }
+
+    public List<Account> getTransactionDisposalAccounts() {
+        if(transactionDisposalAccounts == null) {
+            transactionDisposalAccounts = new ArrayList<Account>();
+        }
+        return transactionDisposalAccounts;
+    }
+
+    public void setTransactionDisposalAccounts(List<Account> transactionDisposalAccounts) {
+        this.transactionDisposalAccounts = transactionDisposalAccounts;
+    }
+
+    public List<Account> getSavingDisposalAccounts() {
+        if(savingDisposalAccounts == null) {
+            savingDisposalAccounts = new ArrayList<Account>();
+        }
+        return savingDisposalAccounts;
+    }
+
+    public void setSavingDisposalAccounts(List<Account> savingDisposalAccounts) {
+        this.savingDisposalAccounts = savingDisposalAccounts;
+    }
+
+    public List<Account> getCardAccounts() {
+        if(cardAccounts == null) {
+            cardAccounts = new ArrayList<Account>();
+        }
+        return cardAccounts;
+    }
+
+    public void setCardAccounts(List<Account> cardAccounts) {
+        this.cardAccounts = cardAccounts;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
new file mode 100644
index 0000000..40a1be4
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/engagement/TransactionsResponse.java
@@ -0,0 +1,40 @@
+package com.liato.bankdroid.banking.banks.swedbank.model.engagement;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.liato.bankdroid.banking.banks.swedbank.model.Transaction;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TransactionsResponse {
+
+    @JsonProperty
+    private List<Transaction> transactions;
+
+    @JsonProperty
+    private List<Transaction> reservedTransactions;
+
+    public List<Transaction> getTransactions() {
+        if(transactions == null) {
+            transactions = new ArrayList<Transaction>();
+        }
+        return transactions;
+    }
+
+    public void setTransactions(List<Transaction> transactions) {
+        this.transactions = transactions;
+    }
+
+    public List<Transaction> getReservedTransactions() {
+        if(reservedTransactions == null) {
+            reservedTransactions = new ArrayList<Transaction>();
+        }
+        return reservedTransactions;
+    }
+
+    public void setReservedTransactions(List<Transaction> reservedTransactions) {
+        this.reservedTransactions = reservedTransactions;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
new file mode 100644
index 0000000..67748c7
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeRequest.java
@@ -0,0 +1,38 @@
+package com.liato.bankdroid.banking.banks.swedbank.model.identification;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PersonalCodeRequest {
+
+    /**
+     * May be a personal number or a fictive personal number. Format YYYYMMDD-NNNN.
+     */
+    @JsonProperty
+    private String userId;
+
+    @JsonProperty
+    private String password;
+
+    public PersonalCodeRequest(String userId, String password) {
+        this.userId = userId;
+        this.password = password;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
new file mode 100644
index 0000000..a862234
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/identification/PersonalCodeResponse.java
@@ -0,0 +1,37 @@
+package com.liato.bankdroid.banking.banks.swedbank.model.identification;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.liato.bankdroid.banking.banks.swedbank.model.OperationalMessages;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class PersonalCodeResponse {
+
+    @JsonProperty
+    private boolean personalCodeChangeRequired;
+
+    @JsonProperty
+    private List<OperationalMessages> operationalMessages;
+
+    public boolean getPersonalCodeChangeRequired() {
+        return personalCodeChangeRequired;
+    }
+
+    public void setPersonalCodeChangeRequired(boolean personalCodeChangeRequired) {
+        this.personalCodeChangeRequired = personalCodeChangeRequired;
+    }
+
+    public List<OperationalMessages> getOperationalMessages() {
+        if(operationalMessages == null) {
+            operationalMessages = new ArrayList<OperationalMessages>();
+        }
+        return operationalMessages;
+    }
+
+    public void setOperationalMessages(List<OperationalMessages> operationalMessages) {
+        this.operationalMessages = operationalMessages;
+    }
+}
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
new file mode 100644
index 0000000..432bca0
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/banking/banks/swedbank/model/profile/ProfileResponse.java
@@ -0,0 +1,48 @@
+package com.liato.bankdroid.banking.banks.swedbank.model.profile;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.liato.bankdroid.banking.banks.swedbank.model.Bank;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ProfileResponse {
+
+    @JsonProperty("hasSwedbankProfile")
+    private boolean swedbankProfile;
+
+    @JsonProperty("hasSavingbankProfile")
+    private boolean savingbankProfile;
+
+    @JsonProperty
+    private List<Bank> banks;
+
+    public boolean isSwedbankProfile() {
+        return swedbankProfile;
+    }
+
+    public void setSwedbankProfile(boolean swedbankProfile) {
+        this.swedbankProfile = swedbankProfile;
+    }
+
+    public boolean isSavingbankProfile() {
+        return savingbankProfile;
+    }
+
+    public void setSavingbankProfile(boolean savingbankProfile) {
+        this.savingbankProfile = savingbankProfile;
+    }
+
+    public List<Bank> getBanks() {
+        if(banks == null) {
+            banks = new ArrayList<Bank>();
+        }
+        return banks;
+    }
+
+    public void setBanks(List<Bank> banks) {
+        this.banks = banks;
+    }
+}
diff --git app/src/main/res/raw/cert_swedbank.pem app/src/main/res/raw/cert_swedbank.pem
index e6fe9e2..fe641c3 100644
--- app/src/main/res/raw/cert_swedbank.pem
+++ app/src/main/res/raw/cert_swedbank.pem
@@ -1,30 +1,31 @@
------BEGIN CERTIFICATE-----

------END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----

+EhN57wT5
+-----END CERTIFICATE-----

commit 3f933c26dcd3a87a6f1b7fc1fda32dd5900241a5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Thu Oct 30 01:25:29 2014 +0100

    Adds possibility to send PUT requests through Urllib

diff --git app/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java app/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java
new file mode 100644
index 0000000..6386efa
--- /dev/null
+++ app/src/main/java/eu/nullbyte/android/urllib/HttpMethod.java
@@ -0,0 +1,8 @@
+package eu.nullbyte.android.urllib;
+
+public enum HttpMethod {
+    GET,
+    POST,
+    PUT,
+    DELETE
+}
diff --git app/src/main/java/eu/nullbyte/android/urllib/Urllib.java app/src/main/java/eu/nullbyte/android/urllib/Urllib.java
index d319ad0..ae10b8a 100644
--- app/src/main/java/eu/nullbyte/android/urllib/Urllib.java
+++ app/src/main/java/eu/nullbyte/android/urllib/Urllib.java
@@ -46,6 +46,7 @@ import org.apache.http.client.UserTokenHandler;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.conn.ClientConnectionManager;
 import org.apache.http.conn.ConnectionKeepAliveStrategy;
@@ -81,6 +82,7 @@ import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.Certificate;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
@@ -154,20 +156,44 @@ public class Urllib {
         return openAsHttpResponse(url, entity, forcePost);
     }
 
+    public HttpResponse openAsHttpResponse(String url, boolean forcePost) throws ClientProtocolException, IOException {
+        return openAsHttpResponse(url, Collections.<NameValuePair>emptyList(),forcePost);
+    }
+
     public HttpResponse openAsHttpResponse(String url, HttpEntity entity, boolean forcePost) throws ClientProtocolException, IOException {
+        if ((entity == null) && !forcePost) {
+           return openAsHttpResponse(url,entity,HttpMethod.GET);
+        }
+        else {
+           return openAsHttpResponse(url,entity,HttpMethod.POST);
+        }
+    }
+
+    public HttpResponse openAsHttpResponse(String url, HttpMethod method) throws ClientProtocolException, IOException {
+        return openAsHttpResponse(url, null, method);
+    }
+
+    public HttpResponse openAsHttpResponse(String url, HttpEntity entity, HttpMethod method) throws ClientProtocolException, IOException {
         this.currentURI = url;
         HttpResponse response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         ResponseHandler<String> responseHandler = new BasicResponseHandler();
         HttpUriRequest request;
-        if ((entity == null) && !forcePost) {
-            //URL urli = new URL(url);
-            request = new HttpGet(url);
-        }
-        else {
-            request = new HttpPost(url);
-            ((HttpPost)request).setEntity(entity);
+        switch(method) {
+            case GET:
+                request = new HttpGet(url);
+                break;
+            case POST:
+                request = new HttpPost(url);
+                ((HttpPost)request).setEntity(entity);
+                break;
+            case PUT:
+                request = new HttpPut(url);
+                ((HttpPut)request).setEntity(entity);
+                break;
+            default:
+                request = new HttpGet(url);
         }
         if (userAgent != null)
             request.addHeader("User-Agent", userAgent);

commit 3d69df180324ae1536845529f8025820db7237a2
Author: liato <x@x00.us>
Date:   Mon Oct 27 03:50:55 2014 +0100

    Update skandiabanken cert. Closes #306.

diff --git app/build.gradle app/build.gradle
index 76eb80c..bad188f 100644
--- app/build.gradle
+++ app/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'android'
+apply plugin: 'com.android.application'
 
 android {
     compileSdkVersion 19
diff --git app/src/main/res/raw/cert_skandiabanken.pem app/src/main/res/raw/cert_skandiabanken.pem
index 67a03c4..5f24435 100644
--- app/src/main/res/raw/cert_skandiabanken.pem
+++ app/src/main/res/raw/cert_skandiabanken.pem
@@ -1,34 +1,31 @@
 -----BEGIN CERTIFICATE-----

-aN+n7CUSNcYXnjgT6Yk3

+xdCATkln5Q==
 -----END CERTIFICATE-----

commit 5273c600e5a6d7da79fb3b5649818077d77358eb
Merge: e26d610 1ee3c4e
Author: liato <x@x00.us>
Date:   Mon Oct 27 03:13:07 2014 +0100

    Merge branch 'nordea-desktop'
    
    * nordea-desktop:
      Adds Installation identifier
      Added support for Nordea credit cards
      Fix for Chalmrest balance.
      Added support for Nordea loans
      Got it up and running
      Updated Nordea to use the non-mobile page instead. The problem with the mobile page is that it shows "Kortköp" for everything, not where the purchase originated. The non-mobile page does not have this issue.

commit 1ee3c4e9ca4048718e4dfe9e569dcef1c54c16a4
Merge: e26d610 0a183b8
Author: liato <x@x00.us>
Date:   Mon Oct 27 03:08:20 2014 +0100

    Merge branch 'desktop' of git://github.com/wicol/android-bankdroid into nordea-desktop
    
    * 'desktop' of git://github.com/wicol/android-bankdroid:
      Adds Installation identifier
      Added support for Nordea credit cards
      Fix for Chalmrest balance.
      Added support for Nordea loans
      Got it up and running
      Updated Nordea to use the non-mobile page instead. The problem with the mobile page is that it shows "Kortköp" for everything, not where the purchase originated. The non-mobile page does not have this issue.

commit e26d610b63fd6a647888d7c618080333a6318469
Author: liato <x@x00.us>
Date:   Mon Oct 27 03:06:37 2014 +0100

    Don't abort build on lint errors.

diff --git .gitignore .gitignore
index cac8f7c..ca0d8c1 100644
--- .gitignore
+++ .gitignore
@@ -44,4 +44,4 @@ out/
 app/src/main/java/com/liato/bankdroid/db/Crypto.*
 app/src/main/java/com/liato/bankdroid/db/Crypto.java.dev
 dev/
-release.keystore
\ No newline at end of file
+app/release.keystore
\ No newline at end of file
diff --git app/build.gradle app/build.gradle
index 34f227a..76eb80c 100644
--- app/build.gradle
+++ app/build.gradle
@@ -43,6 +43,11 @@ android {
             signingConfig signingConfigs.release
         }
     }
+
+    lintOptions {
+        abortOnError false
+    }
+
 }
 
 dependencies {

commit 0a183b8462746a86c8e0921dc80bef2d0235947f
Merge: f67b131 5a1973d
Author: Wictor <wictor@olseryd.se>
Date:   Sat Oct 18 12:41:18 2014 +0200

    Merge branch 'master' of github.com:liato/android-bankdroid into desktop

commit 5a1973d4d1bba04fb4b932704003bb84e74e6b8d
Merge: a0a41e9 91ab56b
Author: liato <x@x00.us>
Date:   Tue Oct 14 09:21:31 2014 +0200

    Merge pull request #311 from goober/feature/310-add-installation-identification
    
    Adds Installation identifier

commit 91ab56b65aa6eaac5a9346e3801ffe2eecc8313d
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Mon Oct 13 22:11:22 2014 +0200

    Adds Installation identifier

diff --git app/src/main/java/com/liato/bankdroid/utils/Installation.java app/src/main/java/com/liato/bankdroid/utils/Installation.java
new file mode 100644
index 0000000..748ed4b
--- /dev/null
+++ app/src/main/java/com/liato/bankdroid/utils/Installation.java
@@ -0,0 +1,59 @@
+package com.liato.bankdroid.utils;
+
+import android.content.Context;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.UUID;
+
+/**
+ * Provides a unique identification for the installation.
+ *
+ * The id is generated the first time the {@link #id(android.content.Context)} is called
+ * and are then persisted until the application is uninstalled.
+ *
+ * @see <a href="http://android-developers.blogspot.se/2011/03/identifying-app-installations.html">Identifying App Installations</a>.
+ */
+public class Installation {
+
+    private static String sID = null;
+
+    private static final String INSTALLATION = "INSTALLATION";
+
+    /**
+     * Get the unique identification for the installation.
+     * A new id will be generated the first time the method is called and are then
+     * persisted until the application is uninstalled.
+     * @return The unique identification for the installed application.
+     */
+    public synchronized static String id(Context context) {
+        if (sID == null) {
+            File installation = new File(context.getFilesDir(), INSTALLATION);
+            try {
+                if (!installation.exists())
+                    writeInstallationFile(installation);
+                sID = readInstallationFile(installation);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+        return sID;
+    }
+
+    private static String readInstallationFile(File installation) throws IOException {
+        RandomAccessFile f = new RandomAccessFile(installation, "r");
+        byte[] bytes = new byte[(int) f.length()];
+        f.readFully(bytes);
+        f.close();
+        return new String(bytes);
+    }
+
+    private static void writeInstallationFile(File installation) throws IOException {
+        FileOutputStream out = new FileOutputStream(installation);
+        String id = UUID.randomUUID().toString();
+        out.write(id.getBytes());
+        out.close();
+    }
+}

commit f67b1312d4b2a23b7f6b988c3b4700d15804595b
Author: Ree <ree@unts.se>
Date:   Tue Sep 23 23:02:56 2014 +0200

    Added support for Nordea credit cards
    
    And a bit of cleanup..

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index f0d10d9..c545639 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -90,14 +90,47 @@ public class Nordea extends Bank {
             "(.*?)" + // Link contents - account name
             "</a>" +
             ".*?" + // fast forward
-            "([*\\d]+)" + // censured account number
+            "([*\\d]+)" + // censured account number (account identifier)
             ".*?" + // fast forward
             "([\\d\\.,]+)", // account balance
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL
+            Pattern.DOTALL
     );
-    private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d-+,.]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d+,.-]*)", Pattern.DOTALL);
     private Pattern reCurrency = Pattern.compile("Saldo:.*?[\\d\\.,-]+[\\s]*</td>[\\s]*<td[^>]*>([^<]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
+    // The link to go to the credit cards overview page
+    private Pattern reCreditCardsLink = Pattern.compile("<a href=\"([^\"#]*)#?\">Kort<");
+    // Link to specific credit card
+    private Pattern reCreditCardLink = Pattern.compile(
+            "href=\"" +
+            "(" + // Start group 1: link url
+            "engine\\?" +
+            "(?=[^\"]*usecase=viewallcards)" +
+            "(?=[^\"]*command=gettransactionscredit)" + // debit cards have "debit" - but we don't need those
+            "[^\"#]*" + // Rest of link url
+            ")" + // End group 1
+            "[^>]*>" + // Rest of link attributes
+            "(.*?)" + // Group 2: Link contents - Credit card type (Eg. "Nordea Gold")
+            "</a>" +
+            ".*?" + // Fast forward
+            "\\*+(\\d+)", // Group 3: Censured credit card number (account identifier)
+            Pattern.DOTALL
+    );
+    // Credit card transaction entry
+    private Pattern reCreditCardTransaction = Pattern.compile(
+            "(\\d{4}-\\d{2}-\\d{2})</a>" + // Group 1: Transaction date
+            "[^<]*</td>" + // End date col
+            "[^<]*<td[^>]*>" + // Start transaction name col
+            "\\s*([^<]*)\\s*</td>" + // Group 2: (trimmed) Transaction name
+            "[^<]*<td[^>]*>" + // Start recipient name col (same as transaction name?)
+            "[^<]*</td>" + // Transaction name
+            "[^<]*<td[^>]*>" + // Start currency col
+            "\\s*([^<]*)\\s*</td>" + // Group 3: (trimmed) Currency (Empty when SEK?)
+            "[^<]*<td[^>]*>" + // Start amount col
+            "\\s*([\\d,.-]+)", // Group 4: Transaction amount
+            Pattern.DOTALL
+    );
+
     // The link to go to the loans overview page
     private Pattern reLoansLink = Pattern.compile("<a href=\"([^\"#]*)#?\">Lån<");
     // Link to specific loan
@@ -114,19 +147,21 @@ public class Nordea extends Bank {
             "(.*?)" + // Group 2: Link contents - Loan type (Eg. "Bolån")
             "</a>" +
             ".*?" + // Fast forward
-            "\\*+(\\d+)" + // Group 3: Censured loan number
+            "\\*+(\\d+)" + // Group 3: Censured loan number (account identifier)
             ".*?" + // Fast forward
             "(\\d{4}-\\d{2}-\\d{2})" + // Group 4: "Transaction date" - Latest interest payment date
             ".*?" + // Fast forward
             "([\\d\\.,]+)", // Group 5: Loan amount
-            Pattern.CASE_INSENSITIVE | Pattern.DOTALL
+            Pattern.DOTALL
     );
     
     private Pattern reAccountSelect = Pattern.compile("<select[^>]+name=\"transactionaccount\"[^>]*>(.*?)</select>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountOption = Pattern.compile("<option[^>]+value=\"([\\d]+)\"[^>]*>.*?([*\\d]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     
-    private String lastResponse;    // Nordea has variables that needs to be sent between every single page
-    private int currentPageType;	// Depending on what kind of page we're currently on, the variables will have to be retrieved differently
+    // Nordea generates unique urls on each page load and serves content from session info,
+    // so we need to find new links in lastResponse after each page load.
+    private String lastResponse;
+    private int currentPageType;
     
 	public Nordea(Context context) {
 		super(context);
@@ -217,41 +252,55 @@ public class Nordea extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		
-		urlopen = login();
-        String link = null;
-        String loanName = null;
+		// This puts us at PageType.ENTRY
+        urlopen = login();
+        String loanName;
 		Matcher matcher;
 		try {
-			matcher = reAccountLink.matcher(this.lastResponse);
+			// Add regular accounts
+            matcher = reAccountLink.matcher(this.lastResponse);
 			while (matcher.find()) {
 				accounts.add(new Account(
+                        // Account name
 						Html.fromHtml(matcher.group(3)).toString().trim(), 
-						Helpers.parseBalance(matcher.group(5)), 
+						// Balance
+                        Helpers.parseBalance(matcher.group(5)),
+                        // Account identifier - half censured account number: "************1234"
 						Html.fromHtml(matcher.group(4)).toString().trim()
 						));
 			}
 
-            // Get loans link
-            matcher = reLoansLink.matcher(this.lastResponse);
-            if (matcher.find()) {
-                link = matcher.group(1);
-                // Go to Loans
-                this.lastResponse = urlopen.open(BASE_URL + link);
-                this.currentPageType = PageType.LOANS;
-                matcher = reLoanLink.matcher(this.lastResponse);
-                // Add loans
-                while (matcher.find()) {
-                    loanName = matcher.group(2) + ' ' + matcher.group(3);
-                    accounts.add(new Account(
-                            loanName,
-                            Helpers.parseBalance(matcher.group(5)),
-                            "l:"+matcher.group(3).trim(),
-                            -1L,
-                            Account.LOANS
-                            ));
-                }
+            // TODO: Code for funds
+
+            goToPage(PageType.CREDIT_CARDS);
+            matcher = reCreditCardLink.matcher(this.lastResponse);
+            // Add credit cards
+            while (matcher.find()) {
+                accounts.add(new Account(
+                        // Account/Credit card name
+                        matcher.group(2),
+                        // Balance (not available through simple login)
+                        new BigDecimal(0),
+                        // Account/Credit card identifier
+                        "c:" + matcher.group(3),
+                        -1L,
+                        Account.CCARD
+                        ));
+            }
+
+            goToPage(PageType.LOANS);
+            matcher = reLoanLink.matcher(this.lastResponse);
+            // Add loans
+            while (matcher.find()) {
+                loanName = matcher.group(2) + ' ' + matcher.group(3);
+                accounts.add(new Account(
+                        loanName,
+                        Helpers.parseBalance(matcher.group(5)),
+                        "l:" + matcher.group(3).trim(),
+                        -1L,
+                        Account.LOANS
+                ));
             }
-			// TODO: Code for funds and credit cards
 
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -277,114 +326,190 @@ public class Nordea extends Bank {
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
 
-		//No transaction history for loans, funds and credit cards.
-		int accType = account.getType();
-		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
+        int accType = account.getType();
 
-		Matcher matcher;
-		try {
-			// We must never browse to a random page without keeping the hashes and stuff from the current page.
-			// Thus, we need to handle it separately depending on if we're still on the entry page or not.
-			
-			String link = null;
-			List<NameValuePair> postData = new ArrayList<NameValuePair>();
-			if(this.currentPageType == PageType.LOANS) {
-                goHome(); // Go to PageType.ENTRY
+        try {
+            switch (accType) {
+                case Account.REGULAR:
+                    updateRegularTransactions(account, urlopen);
+                    break;
+                case Account.CCARD:
+                    updateCreditTransactions(account, urlopen);
+                    break;
+                default:
+                    break;
             }
-            if(currentPageType == PageType.ENTRY) {
-				// Find the link to the transaction page
-				matcher = reAccountLink.matcher(this.lastResponse);
-				while (matcher.find()) {
-					if (Html.fromHtml(matcher.group(4)).toString().trim().equals(account.getId())) {
-						link = matcher.group(1);
-						break;
-					}
-				}
-				if (link == null) {
-					throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions link.");
-				}
-			}
-			else if(currentPageType == PageType.TRANSACTIONS) {
-				// Find the account dropdown form
-				matcher = reTransactionFormContents.matcher(this.lastResponse);
-				if (!matcher.find()) {
-					throw new BankException(res.getText(R.string.unable_to_find).toString()+" account form.");
-				}
-				link = matcher.group(1);
-				matcher = reNonTextInputField.matcher(matcher.group(2));
-				if (!matcher.find()) {
-					throw new BankException(res.getText(R.string.unable_to_find).toString()+" input fields.");
-				}
-				matcher.reset();
-				// Input fields
-				while (matcher.find()) {
-					// For some odd reason, it does not like us sending the submit button... So don't.
-					if (!matcher.group(1).equals("submit")) {
-						postData.add(new BasicNameValuePair(matcher.group(2), matcher.group(3)));
-					}
-				}
-				postData.add(new BasicNameValuePair("transactionPeriod", "0"));
-				// Account id
-				matcher = reAccountSelect.matcher(this.lastResponse);
-				if (!matcher.find()) {
-					throw new BankException(res.getText(R.string.unable_to_find).toString()+" account selection.");
-				}
-				matcher = reAccountOption.matcher(matcher.group(1));
-				String id = null;
-				while (matcher.find()) {
-					if(matcher.group(2).equals(account.getId())) {
-						id = matcher.group(1);
-						break;
-					}
-				}
-				if (id == null) {
-					throw new BankException(res.getText(R.string.unable_to_find).toString()+" account id.");
-				}
-				postData.add(new BasicNameValuePair("transactionaccount", id));
-			}
-			else {
-				throw new BankException("This should never happen. If it does: Grats, you broke it.");
-			}
-			// Navigate to it, and parse the results
-			this.lastResponse = urlopen.open(BASE_URL + link, postData);
-			this.currentPageType = PageType.TRANSACTIONS;
-			matcher = reTransaction.matcher(this.lastResponse);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find() && transactions.size() < MAX_TRANSACTIONS) {
-				String date = Html.fromHtml(matcher.group(1)).toString().trim();
-				String text = Html.fromHtml(matcher.group(2)).toString().trim();
-				BigDecimal amount = Helpers.parseBalance(matcher.group(3));
-				Transaction transaction = new Transaction(date, text, amount);
-				transactions.add(transaction);
-			}
-			account.setTransactions(transactions);
-			// Currency
-			matcher = reCurrency.matcher(this.lastResponse);
-			if (matcher.find()) {
-				account.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
-			}
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
 	}
 
-    private void goHome() {
-        String homeLink;
+    private void goToPage(int pageType) throws ClientProtocolException, IOException {
+        // Convenience method for going to an overview page
+        Matcher matcher;
+        String link;
+        switch (pageType) {
+            case PageType.ENTRY:
+                // Find home link
+                matcher = reHomeLink.matcher(this.lastResponse);
+                break;
+            case PageType.LOANS:
+                // Find loans link
+                matcher = reLoansLink.matcher(this.lastResponse);
+                break;
+            case PageType.CREDIT_CARDS:
+                // Get credit cards link
+                matcher = reCreditCardsLink.matcher(this.lastResponse);
+                break;
+            default:
+                return;
+        }
+        // Find link to page
+        if (matcher.find()) {
+            link = matcher.group(1);
+            // Go to page
+            this.lastResponse = urlopen.open(BASE_URL + link);
+            this.currentPageType = pageType;
+        }
+    }
+
+    public void updateRegularTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException, IOException {
+        // If we're on the entry page it's easy to just find the link to the account and navigate to it,
+        // If we're already on a transaction page we use the account-switching form instead of going
+        // back to the entry page and starting over. This saves us 1 request.
+
         Matcher matcher;
-        // Find home link
-        matcher = reHomeLink.matcher(this.lastResponse);
+        String link = null;
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+
+        if(this.currentPageType != PageType.ENTRY && this.currentPageType != PageType.TRANSACTIONS) {
+            goToPage(PageType.ENTRY);
+        }
+        if(currentPageType == PageType.ENTRY) {
+            // Find the link to the transaction page for this account
+            matcher = reAccountLink.matcher(this.lastResponse);
+            while (matcher.find()) {
+                if (Html.fromHtml(matcher.group(4)).toString().trim().equals(account.getId())) {
+                    link = matcher.group(1);
+                    break;
+                }
+            }
+            if (link == null) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions link.");
+            }
+        }
+        else if(currentPageType == PageType.TRANSACTIONS) {
+            // Find the account dropdown form
+            matcher = reTransactionFormContents.matcher(this.lastResponse);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" account form.");
+            }
+            link = matcher.group(1);
+            matcher = reNonTextInputField.matcher(matcher.group(2));
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" input fields.");
+            }
+            matcher.reset();
+            // Input fields
+            while (matcher.find()) {
+                // For some odd reason, it does not like us sending the submit button... So don't.
+                if (!matcher.group(1).equals("submit")) {
+                    postData.add(new BasicNameValuePair(matcher.group(2), matcher.group(3)));
+                }
+            }
+            postData.add(new BasicNameValuePair("transactionPeriod", "0"));
+            // Account id
+            matcher = reAccountSelect.matcher(this.lastResponse);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" account selection.");
+            }
+            // Find account to switch to in dropdown
+            matcher = reAccountOption.matcher(matcher.group(1));
+            String id = null;
+            while (matcher.find()) {
+                if(matcher.group(2).equals(account.getId())) {
+                    id = matcher.group(1);
+                    break;
+                }
+            }
+            if (id == null) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" account id.");
+            }
+            postData.add(new BasicNameValuePair("transactionaccount", id));
+        }
+        else {
+            throw new BankException("This should never happen. If it does: Grats, you broke it.");
+        }
+
+        // URL established. Either we have a simple URL parsed from ENTRY-page or a base URL +
+        // a populated postData variable. This works with both.
+        this.lastResponse = urlopen.open(BASE_URL + link, postData);
+        this.currentPageType = PageType.TRANSACTIONS;
+
+        // Match up transactions for this account
+        matcher = reTransaction.matcher(this.lastResponse);
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        while (matcher.find() && transactions.size() < MAX_TRANSACTIONS) {
+            String date = Html.fromHtml(matcher.group(1)).toString().trim();
+            String text = Html.fromHtml(matcher.group(2)).toString().trim();
+            BigDecimal amount = Helpers.parseBalance(matcher.group(3));
+            Transaction transaction = new Transaction(date, text, amount);
+            transactions.add(transaction);
+        }
+        // Add the transactions to this account
+        account.setTransactions(transactions);
+        // Set currency for this account
+        matcher = reCurrency.matcher(this.lastResponse);
         if (matcher.find()) {
-            homeLink = matcher.group(1);
-            try {
-                this.lastResponse = urlopen.open(BASE_URL + homeLink);
-            } catch (IOException e) {
-                e.printStackTrace();
+            account.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
+        }
+    }
+
+    public void updateCreditTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException, IOException {
+        Matcher matcher;
+        String link = null;
+        String currency = "";
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+        if (this.currentPageType != PageType.CREDIT_CARDS) {
+            goToPage(PageType.CREDIT_CARDS);
+        }
+
+        // Find the link to the transaction page for this credit card
+        matcher = reCreditCardLink.matcher(this.lastResponse);
+        while (matcher.find()) {
+            if (("c:" + matcher.group(3)).equals(account.getId())) {
+                link = matcher.group(1);
+                break;
             }
-            this.currentPageType = PageType.ENTRY;
+        }
+        if (link == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " transactions link.");
+        }
+
+        this.lastResponse = urlopen.open(BASE_URL + link);
+        this.currentPageType = PageType.CREDIT_CARD_TRANSACTIONS;
+
+        matcher = reCreditCardTransaction.matcher(this.lastResponse);
+        while (matcher.find() && transactions.size() < MAX_TRANSACTIONS) {
+            String date = matcher.group(1);
+            String text = matcher.group(2);
+            currency = matcher.group(3);
+            BigDecimal amount = Helpers.parseBalance(matcher.group(4));
+            Transaction transaction = new Transaction(date, text, amount);
+            transactions.add(transaction);
+        }
+        // Add the transactions to this account
+        account.setTransactions(transactions);
+        // Set currency for this account
+        if (currency.length() > 0) {
+            account.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
         }
     }
 	
@@ -394,5 +519,7 @@ public class Nordea extends Bank {
 		public static final int ENTRY = 2;
 		public static final int TRANSACTIONS = 3;
 		public static final int LOANS = 4;
+		public static final int CREDIT_CARDS = 5;
+		public static final int CREDIT_CARD_TRANSACTIONS = 6;
 	}
 }
\ No newline at end of file

commit a0a41e95aaeec16d0ff7cb3e9a9e68343216d9fe
Merge: af1c553 c77580d
Author: liato <x@x00.us>
Date:   Fri Sep 19 14:10:55 2014 +0200

    Merge pull request #307 from emilan/master
    
    Fix for Chalmrest balance.

commit c77580d89dae5ec95e47aa1bc23ac1c102b25ead
Author: Emil Andersson <emil.jo.andersson@gmail.com>
Date:   Fri Sep 19 09:12:35 2014 +0200

    Fix for Chalmrest balance.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
index 626283a..a0b561c 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -75,13 +75,13 @@ public class Chalmrest extends Bank {
 		    int last = 0;
 		    Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
 		    while (match.find()) {
-		    	sb.append(value.substring(last, Math.max(match.start() - 1, 0)));
+		    	sb.append(value.substring(last, match.start()));
 		    	int i = Integer.parseInt(match.group(1), 16);
 		    	sb.append((char)i);
 		    	last = match.end();
 		    }
 		    sb.append(value.substring(last));
-		    value = sb.toString();
+		    value = sb.toString().replace(',', '.');
 		    
 		    matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
 		    if (!matcher.find())

commit af1c553eb6d1e8dfac549bf1515351225dff5a04 (tag: v1.9.6.16)
Author: liato <x@x00.us>
Date:   Thu Sep 18 00:29:12 2014 +0200

    Bump version. v1.9.6.16

diff --git CHANGES.txt CHANGES.txt
index 5c81f32..85911a6 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,9 @@
+v1.9.6.16: (2014-09-18)
+* Updated SSL certificates for American Express, Coop, Eurocard, Forex Bank, Ikano Bank, Marginalen Bank, Meniga, Nordnet, Nordnet Direkt, OKQ8, Payson, Rikslunchen, SevenDay, Trustbuddy and Villabanken
+* Improvements to Villabanken account parsing (thanks to knifhen)
+* Improvements to Coop
+
+
 v1.9.6.15: (2014-06-07)
 * Fix for Coop MedMedmera Visa and Coop Kort
 * Updated SSL certificate for SEB cards (SAS Eurobonus, SJPrio, Statoil and more)
diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index 0c910ab..2a57f08 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -32,6 +32,9 @@ Development
   ScuttleSE                         https://github.com/ScuttleSE
   Andreas Knifh                     https://github.com/knifhen
   NanoRage                          https://github.com/NanoRage
+  Adam Nybäck                       https://github.com/nadam
+  MathiasBois                       https://github.com/MathiasBois
+
 
 
   Stats at:
diff --git app/build.gradle app/build.gradle
index e6f457a..34f227a 100644
--- app/build.gradle
+++ app/build.gradle
@@ -8,8 +8,8 @@ android {
         applicationId "com.liato.bankdroid"
         minSdkVersion 9
         targetSdkVersion 10
-        versionCode 188
-        versionName "1.9.6.15"
+        versionCode 189
+        versionName "1.9.6.16"
     }
 
     final Console console = System.console();
diff --git app/src/main/AndroidManifest.xml app/src/main/AndroidManifest.xml
index 8b5b626..ed7c54e 100644
--- app/src/main/AndroidManifest.xml
+++ app/src/main/AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.15" android:versionCode="188">
+	android:versionName="1.9.6.16" android:versionCode="189">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />

commit cf8bf0c64f65506d5881366aaeab822c5db221c8
Author: liato <x@x00.us>
Date:   Thu Sep 18 00:12:59 2014 +0200

    Use the new certificates for amex and coop.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 35a745a..c81adfa 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -77,7 +77,7 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress_global));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
diff --git app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
index 72133f7..61f10a9 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -162,7 +162,7 @@ public class Coop extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop, R.raw.cert_coop2));
         urlopen.addHeader("Origin", "https://www.coop.se");
         urlopen.addHeader("Referer", "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
         response = urlopen.open("https://www.coop.se/");

commit 8e82d969e067b6fdcf654899de9f063b95ed2815
Author: liato <x@x00.us>
Date:   Thu Sep 18 00:02:21 2014 +0200

    New SSL certificate for Villabanken.

diff --git app/src/main/res/raw/cert_villabanken.pem app/src/main/res/raw/cert_villabanken.pem
index 14b3d1c..9ebe38c 100644
--- app/src/main/res/raw/cert_villabanken.pem
+++ app/src/main/res/raw/cert_villabanken.pem
@@ -1,34 +1,32 @@
 -----BEGIN CERTIFICATE-----

-YMvo8caizM268OdHzj3WQt4biECp/9TWO3wAfGm1PjaY1A==

+9zMG3j0JdTv4xPZSSQHq
 -----END CERTIFICATE-----

commit b7faddbd7cfd2557917356f3e65b5c2282e45a49
Author: liato <x@x00.us>
Date:   Wed Sep 17 23:54:57 2014 +0200

    New SSL certificate for Meniga.

diff --git app/src/main/res/raw/cert_meniga.pem app/src/main/res/raw/cert_meniga.pem
index 9818831..f11893e 100644
--- app/src/main/res/raw/cert_meniga.pem
+++ app/src/main/res/raw/cert_meniga.pem
@@ -1,35 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIGBjCCBO6gAwIBAgIQZxyHsbE9PB9mdKZw36dy9jANBgkqhkiG9w0BAQUFADCB
+MIIFbzCCBFegAwIBAgIQFW1+Z4QpxBuP+XD/aB3uTTANBgkqhkiG9w0BAQUFADCB
 ujELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE0MDIGA1UEAxMr
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQTAeFw0x

-BXFYr71BrBjmug==

+dUrs
 -----END CERTIFICATE-----

commit c3209510bdbdbf7bbc9961c74b4a77a7ee84af5e
Merge: 445581c 883047e
Author: liato <x@x00.us>
Date:   Wed Sep 17 23:50:39 2014 +0200

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Adds new certificate for forex bank
      New certificate for https://nettbank.edb.com/

commit 445581c18a0a139bcf9b32e00a9518efc2c583d3
Author: liato <x@x00.us>
Date:   Wed Sep 17 23:49:51 2014 +0200

    New SSL certificate for Coop.

diff --git app/src/main/res/raw/cert_coop2.pem app/src/main/res/raw/cert_coop2.pem
new file mode 100644
index 0000000..6ba98c5
--- /dev/null
+++ app/src/main/res/raw/cert_coop2.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----

+jCsIfvDy
+-----END CERTIFICATE-----

commit ddc5028a6369a0142849159895e86230a77c9019
Author: liato <x@x00.us>
Date:   Wed Sep 17 23:47:13 2014 +0200

    New SSL certificate for American Express.

diff --git app/src/main/res/raw/cert_americanexpress2.pem app/src/main/res/raw/cert_americanexpress2.pem
new file mode 100644
index 0000000..9307b5a
--- /dev/null
+++ app/src/main/res/raw/cert_americanexpress2.pem
@@ -0,0 +1,37 @@
+-----BEGIN CERTIFICATE-----

+WU5uJfphUKkLRvc=
+-----END CERTIFICATE-----
\ No newline at end of file

commit 883047e46987de6516a278ed397c4ae8d8bc83f0
Merge: b41efc0 79ba987
Author: liato <x@x00.us>
Date:   Thu Sep 4 10:49:38 2014 +0200

    Merge pull request #302 from goober/master
    
    Adds new certificate for forex bank

commit 79ba987f3bf676d1ff0302889e6a57edaeb8cccd
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Wed Aug 27 13:46:46 2014 +0200

    Adds new certificate for forex bank

diff --git app/src/main/res/raw/cert_forexbank.pem app/src/main/res/raw/cert_forexbank.pem
index 07511e9..77d95ce 100644
--- app/src/main/res/raw/cert_forexbank.pem
+++ app/src/main/res/raw/cert_forexbank.pem
@@ -1,31 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIFbDCCBFSgAwIBAgIQMfatOIDhU/Oa4JGRrfTH0zANBgkqhkiG9w0BAQUFADCB
-vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+MIIFdTCCBF2gAwIBAgIQVkYh85MbXamwHyyAGysrvjANBgkqhkiG9w0BAQUFADCB
+vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug

+JpPqCokWT4kF
 -----END CERTIFICATE-----

commit d4c19cd19bf3d78bc489a243372015b20b936004
Author: Ree <ree@unts.se>
Date:   Tue Aug 26 00:29:54 2014 +0200

    Added support for Nordea loans

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 4203aab..f0d10d9 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -48,7 +48,8 @@ public class Nordea extends Bank {
 	private static final String TAG = "Nordea";
 	private static final String NAME = "Nordea";
 	private static final String NAME_SHORT = "nordea";
-	private static final String URL = "https://internetbanken.privat.nordea.se/nsp/login";
+	private static final String BASE_URL = "https://internetbanken.privat.nordea.se/nsp/";
+	private static final String LOGIN_URL = BASE_URL + "login";
 	private static final int BANKTYPE_ID = IBankTypes.NORDEA;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
@@ -71,6 +72,14 @@ public class Nordea extends Bank {
     private Pattern reNonTextInputField = Pattern.compile("<input(?=[^>]+type=\"((?!text)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
     private Pattern reNonTelInputField = Pattern.compile("<input(?=[^>]+type=\"((?!tel)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
 
+    // Link to home/overview - PageType.ENTRY
+    private Pattern reHomeLink = Pattern.compile(
+            "href=\"(core[^\"#]*)#?\"" + // The actual url (trim the '#')
+            "[^>]*>" +
+            "[^<]*" +
+            "<img[^>]+id=\"home\"" // Identificator
+            );
+
     private Pattern reTransactionFormContents = Pattern.compile("<form(?=[^>]+id=\"accountTransactions\")(?=[^>]+action=\"([^\"]*)\").*?>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountLink = Pattern.compile(
             "href=\"(core\\?" +
@@ -88,6 +97,30 @@ public class Nordea extends Bank {
     );
     private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d-+,.]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reCurrency = Pattern.compile("Saldo:.*?[\\d\\.,-]+[\\s]*</td>[\\s]*<td[^>]*>([^<]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    // The link to go to the loans overview page
+    private Pattern reLoansLink = Pattern.compile("<a href=\"([^\"#]*)#?\">Lån<");
+    // Link to specific loan
+    private Pattern reLoanLink = Pattern.compile(
+            "href=\"" +
+            "(" + // Start group 1: link url
+            "engine\\?" +
+            "(?=[^\"]*usecase=loansoverview)" +
+            "(?=[^\"]*command=get_loan_details_command)" +
+            "[^\"#]*" + // Rest of link url
+            ")" + // End group 1
+            "#?" + // Trim off a padded #
+            "[^>]*>" + // Rest of link attributes
+            "(.*?)" + // Group 2: Link contents - Loan type (Eg. "Bolån")
+            "</a>" +
+            ".*?" + // Fast forward
+            "\\*+(\\d+)" + // Group 3: Censured loan number
+            ".*?" + // Fast forward
+            "(\\d{4}-\\d{2}-\\d{2})" + // Group 4: "Transaction date" - Latest interest payment date
+            ".*?" + // Fast forward
+            "([\\d\\.,]+)", // Group 5: Loan amount
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL
+    );
     
     private Pattern reAccountSelect = Pattern.compile("<select[^>]+name=\"transactionaccount\"[^>]*>(.*?)</select>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountOption = Pattern.compile("<option[^>]+value=\"([\\d]+)\"[^>]*>.*?([*\\d]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -101,7 +134,7 @@ public class Nordea extends Bank {
 		super.NAME = NAME;
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+		super.URL = BASE_URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
@@ -118,14 +151,14 @@ public class Nordea extends Bank {
 		urlopen = new Urllib(context);
 		Matcher matcher;
 		// Find "simple login" link
-		this.lastResponse = urlopen.open("https://internetbanken.privat.nordea.se/nsp/login");
+		this.lastResponse = urlopen.open(LOGIN_URL);
 		this.currentPageType = PageType.LOGIN;
 		matcher = reSimpleLoginLink.matcher(this.lastResponse);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login link.");
 		}
 		// Visit login link
-		String link = "https://internetbanken.privat.nordea.se/nsp/" + matcher.group(1);
+		String link = BASE_URL + matcher.group(1);
 		this.lastResponse = urlopen.open(link);
 		this.currentPageType = PageType.SIMPLE_LOGIN;
 		matcher = reLoginFormContents.matcher(this.lastResponse);
@@ -154,7 +187,7 @@ public class Nordea extends Bank {
 		postData.add(new BasicNameValuePair("pin", password));
 		// Submit button is not contained within the form and thus cannot (should not) be found with the InputField matcher
 		postData.add(new BasicNameValuePair("commonlogin$loginLight", "Logga in"));
-		return new LoginPackage(urlopen, postData, this.lastResponse, "https://internetbanken.privat.nordea.se/nsp/login");
+		return new LoginPackage(urlopen, postData, this.lastResponse, LOGIN_URL);
     }
 
 	@Override
@@ -185,6 +218,8 @@ public class Nordea extends Bank {
 		}
 		
 		urlopen = login();
+        String link = null;
+        String loanName = null;
 		Matcher matcher;
 		try {
 			matcher = reAccountLink.matcher(this.lastResponse);
@@ -195,14 +230,39 @@ public class Nordea extends Bank {
 						Html.fromHtml(matcher.group(4)).toString().trim()
 						));
 			}
-			
-			// TODO(Rhoot): Put code for loan, funds and cards back. I don't have either of them so I cannot do it 
-			//              personally, as I don't know what the pages look like.
+
+            // Get loans link
+            matcher = reLoansLink.matcher(this.lastResponse);
+            if (matcher.find()) {
+                link = matcher.group(1);
+                // Go to Loans
+                this.lastResponse = urlopen.open(BASE_URL + link);
+                this.currentPageType = PageType.LOANS;
+                matcher = reLoanLink.matcher(this.lastResponse);
+                // Add loans
+                while (matcher.find()) {
+                    loanName = matcher.group(2) + ' ' + matcher.group(3);
+                    accounts.add(new Account(
+                            loanName,
+                            Helpers.parseBalance(matcher.group(5)),
+                            "l:"+matcher.group(3).trim(),
+                            -1L,
+                            Account.LOANS
+                            ));
+                }
+            }
+			// TODO: Code for funds and credit cards
 
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 		}
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
 		finally {
 		    super.updateComplete();
 		}
@@ -228,7 +288,10 @@ public class Nordea extends Bank {
 			
 			String link = null;
 			List<NameValuePair> postData = new ArrayList<NameValuePair>();
-			if(currentPageType == PageType.ENTRY) {
+			if(this.currentPageType == PageType.LOANS) {
+                goHome(); // Go to PageType.ENTRY
+            }
+            if(currentPageType == PageType.ENTRY) {
 				// Find the link to the transaction page
 				matcher = reAccountLink.matcher(this.lastResponse);
 				while (matcher.find()) {
@@ -283,7 +346,7 @@ public class Nordea extends Bank {
 				throw new BankException("This should never happen. If it does: Grats, you broke it.");
 			}
 			// Navigate to it, and parse the results
-			this.lastResponse = urlopen.open("https://internetbanken.privat.nordea.se/nsp/" + link, postData);
+			this.lastResponse = urlopen.open(BASE_URL + link, postData);
 			this.currentPageType = PageType.TRANSACTIONS;
 			matcher = reTransaction.matcher(this.lastResponse);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -308,11 +371,28 @@ public class Nordea extends Bank {
 			e.printStackTrace();
 		}
 	}
+
+    private void goHome() {
+        String homeLink;
+        Matcher matcher;
+        // Find home link
+        matcher = reHomeLink.matcher(this.lastResponse);
+        if (matcher.find()) {
+            homeLink = matcher.group(1);
+            try {
+                this.lastResponse = urlopen.open(BASE_URL + homeLink);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            this.currentPageType = PageType.ENTRY;
+        }
+    }
 	
 	private static class PageType {
 		public static final int LOGIN = 0;
 		public static final int SIMPLE_LOGIN = 1;
 		public static final int ENTRY = 2;
 		public static final int TRANSACTIONS = 3;
+		public static final int LOANS = 4;
 	}
 }
\ No newline at end of file

commit b41efc0107b4d2debcc395d87017e856be67ab9d
Merge: edd0e4a 2161065
Author: liato <x@x00.us>
Date:   Fri Aug 22 11:24:59 2014 +0200

    Merge pull request #299 from MathiasBois/master
    
    New certificate for https://nettbank.edb.com/

commit 2161065b801ea75cb58fd47940244eafd51cc18c
Author: bois <mathias@delta.se>
Date:   Thu Aug 21 16:51:38 2014 +0200

    New certificate for https://nettbank.edb.com/

diff --git app/src/main/res/raw/cert_okq8.pem app/src/main/res/raw/cert_okq8.pem
index 07511e9..77d95ce 100644
--- app/src/main/res/raw/cert_okq8.pem
+++ app/src/main/res/raw/cert_okq8.pem
@@ -1,31 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIFbDCCBFSgAwIBAgIQMfatOIDhU/Oa4JGRrfTH0zANBgkqhkiG9w0BAQUFADCB
-vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+MIIFdTCCBF2gAwIBAgIQVkYh85MbXamwHyyAGysrvjANBgkqhkiG9w0BAQUFADCB
+vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug

+JpPqCokWT4kF
 -----END CERTIFICATE-----

commit edd0e4ad0118ec9d849ca27e0c117ca0e093dec7
Merge: 7a947c3 28c1a56
Author: liato <x@x00.us>
Date:   Wed Jul 30 01:48:17 2014 +0200

    Merge branch 'knifhen-master'
    
    * knifhen-master:
      'Villabanken' transactions view is popuplated
      'Villabanken' improved the Accounts parsing, added Köpgräns, made the balance only show the disposable amount.
      Update Rikslunchen certificate.
      Update SevenDay certificate.
      Ignore Coop transactions without dates.

commit 28c1a56f98d4eedd25c32e0b6e7efdd6445db6f9
Merge: 7a947c3 88ca212
Author: liato <x@x00.us>
Date:   Wed Jul 30 01:48:00 2014 +0200

    Resolve merge conflicts.

commit 7a947c3c447a68dc1b966fd7725b6f97bd245f49
Merge: 67e9059 ee6e02b
Author: liato <x@x00.us>
Date:   Wed Jul 30 01:44:15 2014 +0200

    Merge pull request #296 from nadam/master
    
    Fixed README...

commit 36e1bfddacbd101cf3d2b535df82c5e71d9100d3
Author: Ree <ree@unts.se>
Date:   Wed Jul 23 02:55:26 2014 +0200

    Got it up and running

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 4566469..4203aab 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banking.banks;
+package com.liato.bankdroid.banking.banks.nordea;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -48,20 +48,44 @@ public class Nordea extends Bank {
 	private static final String TAG = "Nordea";
 	private static final String NAME = "Nordea";
 	private static final String NAME_SHORT = "nordea";
-	private static final String URL = "https://mobil.nordea.se/";
+	private static final String URL = "https://internetbanken.privat.nordea.se/nsp/login";
 	private static final int BANKTYPE_ID = IBankTypes.NORDEA;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
     
     private static final int MAX_TRANSACTIONS = 50;
 
-    private Pattern reSimpleLoginLink = Pattern.compile("href=\"(engine\\?(?=[^\"]*usecase=commonlogin)(?=[^\"]*command=commonlogintabcommand)(?=[^\"]*commonlogintab=2)(?=[^\"]*guid=([\\w]*))(?=[^\"]*fpid=([\\w]*))(?=[^\"]*hash=([\\w]*))[^\"]*)", Pattern.CASE_INSENSITIVE);
+    private Pattern reSimpleLoginLink = Pattern.compile(
+            "href=\"(login\\?" +
+            "(?=[^\"]*usecase=commonlogin)" +
+            "(?=[^\"]*command=commonlogintabcommand)" +
+            "(?=[^\"]*guid=([\\w]*))" +
+            "(?=[^\"]*fpid=([\\w]*))" +
+            "(?=[^\"]*commonlogintab=2)" +
+            "(?=[^\"]*hash=([\\w]*))" +
+            "[^\"]*)",
+            Pattern.CASE_INSENSITIVE
+    );
     private Pattern reLoginFormContents = Pattern.compile("<form[^>]+id=\"commonlogin\"[^>]*>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reNonTextInputField = Pattern.compile("<input(?=[^>]+type=\"((?!text)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
-    
+    private Pattern reNonTelInputField = Pattern.compile("<input(?=[^>]+type=\"((?!tel)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
+
     private Pattern reTransactionFormContents = Pattern.compile("<form(?=[^>]+id=\"accountTransactions\")(?=[^>]+action=\"([^\"]*)\").*?>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountLink = Pattern.compile("href=\"(engine\\?(?=[^\"]*usecase=accountsoverview)(?=[^\"]*command=getcurrenttransactions)(?=[^\"]*currentaccountsoverviewtable=([\\d]+))[^\"]*)[^>]*>(.*?)</a>.*?([*\\d]+).*?([\\d\\.,]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountLink = Pattern.compile(
+            "href=\"(core\\?" +
+            "(?=[^\"]*usecase=accountsoverview)" +
+            "(?=[^\"]*command=getcurrenttransactions)" +
+            "(?=[^\"]*currentaccountsoverviewtable=([\\d]+))" +
+            "[^\"]*)[^>]*>" + // End of link attributes
+            "(.*?)" + // Link contents - account name
+            "</a>" +
+            ".*?" + // fast forward
+            "([*\\d]+)" + // censured account number
+            ".*?" + // fast forward
+            "([\\d\\.,]+)", // account balance
+            Pattern.CASE_INSENSITIVE | Pattern.DOTALL
+    );
     private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d-+,.]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reCurrency = Pattern.compile("Saldo:.*?[\\d\\.,-]+[\\s]*</td>[\\s]*<td[^>]*>([^<]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     
@@ -91,10 +115,10 @@ public class Nordea extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-		urlopen = new Urllib();
+		urlopen = new Urllib(context);
 		Matcher matcher;
 		// Find "simple login" link
-		this.lastResponse = urlopen.open("https://internetbanken.privat.nordea.se/nsp/engine");
+		this.lastResponse = urlopen.open("https://internetbanken.privat.nordea.se/nsp/login");
 		this.currentPageType = PageType.LOGIN;
 		matcher = reSimpleLoginLink.matcher(this.lastResponse);
 		if (!matcher.find()) {
@@ -110,7 +134,7 @@ public class Nordea extends Bank {
 		}
 		// Extract hidden fields
 		String formContents = matcher.group(1);
-		matcher = reNonTextInputField.matcher(formContents);
+		matcher = reNonTelInputField.matcher(formContents);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login fields.");
 		}
@@ -130,7 +154,7 @@ public class Nordea extends Bank {
 		postData.add(new BasicNameValuePair("pin", password));
 		// Submit button is not contained within the form and thus cannot (should not) be found with the InputField matcher
 		postData.add(new BasicNameValuePair("commonlogin$loginLight", "Logga in"));
-		return new LoginPackage(urlopen, postData, this.lastResponse, "https://internetbanken.privat.nordea.se/nsp/engine");
+		return new LoginPackage(urlopen, postData, this.lastResponse, "https://internetbanken.privat.nordea.se/nsp/login");
     }
 
 	@Override
@@ -139,7 +163,7 @@ public class Nordea extends Bank {
 		    LoginPackage lp = preLogin();
 		    this.lastResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 		    this.currentPageType = PageType.ENTRY;
-			if (this.lastResponse.contains("felaktiga uppgifter")) {
+			if (this.lastResponse.contains("fel uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			

commit 20dd107acac4f5a6fe253fa0ad0ae630c804c03b
Merge: 67e9059 730f699
Author: Ree <ree@unts.se>
Date:   Wed Jul 23 02:52:07 2014 +0200

    Merge remote-tracking branch 'rhoot/master' into desktop
    
    Conflicts:
            app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java

commit ee6e02b25e30ab29e02d17f953a383c8c0c8a0b7
Author: Adam Nybäck <adam@anyro.se>
Date:   Sat Jul 19 09:24:45 2014 +0200

    Fixed README to include information about the project, development environment and license.

diff --git README.rst README.rst
index 7ac9f97..d3330b7 100644
--- README.rst
+++ README.rst
@@ -1 +1,31 @@
-Bankdroid is a an application for android devices... Swedbank, Nordea and ICA Banken.
\ No newline at end of file
+Bankdroid
+=========
+
+Bankdroid is an Android app for Swedish banks, payment cards and similar services. Key features include:
+
+* Automatic updates of your balance and transactions
+* Notifications whenever your balance changes
+* Widgets to show your balance anywhere on your home screen
+
+More information can be found at:
+
+* `Bankdroid on Google Play <https://play.google.com/store/apps/details?id=com.liato.bankdroid>`_
+* `Bankdroid thread at the Swedroid Forum <http://goo.gl/9tJeH>`_ (Swedish)
+
+Development environment
+-----------------------
+
+Bankdroid is written for Android Studio 0.8.2 and Gradle 1.12. Here's how to get the code up and
+running on your computer:
+
+1. Make sure you have `Android Studio 0.8.2 or later <https://developer.android.com/sdk/installing/studio.html>`_
+2. `Clone <https://help.github.com/articles/which-remote-url-should-i-use>`_ the project (if you want to contribute you should `fork <https://help.github.com/articles/fork-a-repo>`_ the project first and then clone your fork)
+3. Open the project's settings.gradle file in Android Studio and select "Use default gradle wrapper (recommended)"
+4. Select "Make project" from the Build menu
+5. Select Run from the Run menu
+
+License
+-------
+
+The Bankdroid source code is licensed under the
+`Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>`_.
\ No newline at end of file

commit 67e905954a392cae14cb61374290c1e8077b8750
Author: liato <x@x00.us>
Date:   Fri Jul 18 19:57:42 2014 +0200

    Move missplaced file.

diff --git src/com/liato/bankdroid/db/Crypto.java app/src/main/java/com/liato/bankdroid/db/Crypto.java
similarity index 100%
rename from src/com/liato/bankdroid/db/Crypto.java
rename to app/src/main/java/com/liato/bankdroid/db/Crypto.java

commit b519b80e4de740ef5af7c38d00d9eafa4222528e
Author: liato <x@x00.us>
Date:   Fri Jul 11 00:30:57 2014 +0200

    Update gradle plugin.

diff --git build.gradle build.gradle
index aadd3db..a1d991f 100644
--- build.gradle
+++ build.gradle
@@ -5,7 +5,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.11.+'
+        classpath 'com.android.tools.build:gradle:0.12.+'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 5de946b..856ae6d 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Thu Jul 10 23:49:07 CEST 2014
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip

commit 8764a81d940ed809819bc131b7660d216cb8f039
Author: liato <x@x00.us>
Date:   Thu Jun 26 00:30:41 2014 +0200

    Update certificate for Eurocard, Ikano Bank, Marginalen Bank, Nordnet. Nordnet Direkt, Payson and Trustbuddy.

diff --git app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
index b678b91..c6c1ee4 100644
--- app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -65,7 +65,7 @@ public class Marginalen extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_marginalen));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_marginalen, R.raw.cert_marginalen2));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open(BASE_URL + "engine");
diff --git app/src/main/res/raw/cert_eurocard.pem app/src/main/res/raw/cert_eurocard.pem
index 88a2b81..967dd2b 100644
--- app/src/main/res/raw/cert_eurocard.pem
+++ app/src/main/res/raw/cert_eurocard.pem
@@ -1,35 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIGADCCBOigAwIBAgIQNaRpSD+K7358HlRrXUy1MjANBgkqhkiG9w0BAQUFADCB
+MIIFvDCCBKSgAwIBAgIQU5j2VqoQZgUZ194LcY0GuzANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew

-SQCaPQ==

+NR3ikmS2NPy8Ftd0TdpyWp8X50dGZbZD7n9ZBBpqRiU=
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_ikanobank.pem app/src/main/res/raw/cert_ikanobank.pem
index e22c19a..03be7ec 100644
--- app/src/main/res/raw/cert_ikanobank.pem
+++ app/src/main/res/raw/cert_ikanobank.pem
@@ -1,32 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIFejCCBGKgAwIBAgISESHNH0XsaP2zD7E0hVpZz9PqMA0GCSqGSIb3DQEBBQUA
+MIIFnzCCBIegAwIBAgISESFaiFqg4Hk599VWZZ/Imyv4MA0GCSqGSIb3DQEBBQUA
 MFkxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMS8wLQYD
 VQQDEyZHbG9iYWxTaWduIEV4dGVuZGVkIFZhbGlkYXRpb24gQ0EgLSBHMjAeFw0x

-fJ+H45cviS+GsER81pQ=

+l+Ov
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_marginalen.pem app/src/main/res/raw/cert_marginalen.pem
index c56eadf..9f610ac 100644
--- app/src/main/res/raw/cert_marginalen.pem
+++ app/src/main/res/raw/cert_marginalen.pem
@@ -1,10 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIIGAzCCBOugAwIBAgIQQ72smCAAo65zr1eq3FXWDTANBgkqhkiG9w0BAQUFADCB
+MIIGAzCCBOugAwIBAgIQL/JD4Q/y+fduEsXjG8NE0DANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTMwMTI0MDAwMDAwWhcNMTQwMTMxMjM1OTU5WjCCAQ0xEzARBgsrBgEEAYI3
+HhcNMTQwMTE2MDAwMDAwWhcNMTUwMTMxMjM1OTU5WjCCAQ0xEzARBgsrBgEEAYI3
 PAIBAxMCU0UxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRQwEgYDVQQF
 Ews1MTY0MDYtMDgwNzELMAkGA1UEBhMCU0UxDzANBgNVBBEUBjExNCAyNzESMBAG
 A1UECBMJU3RvY2tob2xtMRIwEAYDVQQHFAlTdG9ja2hvbG0xGjAYBgNVBAkUEVZh
@@ -17,19 +17,19 @@ op/THP5cX7gYf0qMScmwAeEFMIdW1dmKp42gjab/bytqoCZ+la3YlQmHEBUSkuqK
 B9v8CtVMcGNNuJGVaeeq7Gi9+UoNp3oW9sj75p2oQMFLAVrPoFd0n5Z3KUVS4anT
 oxYL/vYTdn3khts/fFWrhNmnlx7nlGw9v+hM/WuzGfhxD5HTepIxSpMhxwaxS3aR
 mX3Qlo3lgMy8t58hDDSDKFMCAwEAAaOCAakwggGlMCAGA1UdEQQZMBeCFXNlY3Vy

 BgEFBQcBAQRqMGgwKwYIKwYBBQUHMAGGH2h0dHA6Ly9FVkludGwtb2NzcC52ZXJp
 c2lnbi5jb20wOQYIKwYBBQUHMAKGLWh0dHA6Ly9FVkludGwtYWlhLnZlcmlzaWdu
-LmNvbS9FVkludGwyMDA2LmNlcjANBgkqhkiG9w0BAQUFAAOCAQEANIyxMrf4nj4h
-yCZIzC98PKSbE93kFKWT0wrhGbxbbIG2droM2pIZSFGmc2kZo6YRNR0kSxMv8buD
-tVwX2pTEkSmr0PChjVJdAnLZoK78CmjW2SlB5FCbkPZntQlTODj8tJv9lVsIXbce
-wQ+xzq7y2H+WYOJTmHMUMAk8LXAO2zA4+8YTDw8BwX2TTmtWQJr5l129bHsLATlr
-m2a+M8TNMXB4qJMxmNkWghVThmhY7c5bocoXVbu73qlFEmQ79SFlyVBcYaT9Z95+
-dmFfPPjKeGciC1og73elOGo0eySyruR/yxr0/4baCrpLHL4mbrntNaHsGSk4njF8
-zN0LZmKqGQ==
+LmNvbS9FVkludGwyMDA2LmNlcjANBgkqhkiG9w0BAQUFAAOCAQEAlYEbhnPrWDcT
+YUESv4ndpjWd0obTpUobaZehsJKcxnlLFOcZO+x9KgFOnG77VOXCfpsUYSxZEzWF
+bUaWC0VesjxEr6l1xEouESMqvembkcJEFnEJjE/M/hX0F57j+5YXePKdoRa7b8yg
+v30xpf8+FoQ5D3aXrQSPU256udVRgWPCvBEZbVfLq7nnzVRe4XkHcKuLEJ23sbx3
++3FZdH86CuYFY22FGl4NxHkIweHDDwFrVwnBUK9lhOTPhg7+lxVOk3hYgmw66WGV
+KYeBMS7coaBfV+0A1IwsG/7qaZDDBJS7oauombRgmiaBp1RQn7X8lPAhDggi+127
+yB5UmZXUFg==
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_marginalen2.pem app/src/main/res/raw/cert_marginalen2.pem
new file mode 100644
index 0000000..91fceba
--- /dev/null
+++ app/src/main/res/raw/cert_marginalen2.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_nordnet.pem app/src/main/res/raw/cert_nordnet.pem
index 1457151..3e61d16 100644
--- app/src/main/res/raw/cert_nordnet.pem
+++ app/src/main/res/raw/cert_nordnet.pem
@@ -1,34 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIQPiKvs7TqW47bcRMU2ygyjDANBgkqhkiG9w0BAQUFADCB
+MIIFoTCCBImgAwIBAgIQekn3mgSdtIa2ELS0B/Dy9zANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTMwNTIwMDAwMDAwWhcNMTQwNzAyMjM1OTU5WjCB4jETMBEGCysGAQQBgjc8
+HhcNMTQwNjE4MDAwMDAwWhcNMTUwNzAyMjM1OTU5WjCB4jETMBEGCysGAQQBgjc8
 AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgNVBAUT
 CjUxNjQwNjAwMjExCzAJBgNVBAYTAlNFMRIwEAYDVQQRFAlTRS0xNjcgMTQxEjAQ
 BgNVBAgTCVN0b2NraG9sbTEPMA0GA1UEBxQGQnJvbW1hMR4wHAYDVQQJFBVHdXN0
 YXZzbHVuZHN2YWdlbiAxNDExGDAWBgNVBAoUD05vcmRuZXQgQmFuayBBQjEXMBUG
 A1UEAxQOd3d3Lm5vcmRuZXQuc2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK

 d3cubm9yZG5ldC5zZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUE

-zOljAA==

+eUOjBvU=
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_nordnetdirekt.pem app/src/main/res/raw/cert_nordnetdirekt.pem
index fc08c3b..a5da0cd 100644
--- app/src/main/res/raw/cert_nordnetdirekt.pem
+++ app/src/main/res/raw/cert_nordnetdirekt.pem
@@ -1,41 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIHPTCCBiWgAwIBAgIQDuRZx0c7O0x7ZZNS4hC24TANBgkqhkiG9w0BAQUFADBp
+MIIFuTCCBKGgAwIBAgIQDqKAXZL/2WCgqCigR1SfMDANBgkqhkiG9w0BAQUFADBp
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMSgwJgYDVQQDEx9EaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBDQS0xMB4XDTEzMDkwMjAwMDAwMFoXDTE0MDkxMDEyMDAwMFowgecxHTAb
+ZSBFViBDQS0xMB4XDTE0MDYyMzAwMDAwMFoXDTE1MTAxNTEyMDAwMFowgecxHTAb
 BgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAlNF
 MRQwEgYDVQQFEws1MTY0IDA2MDAyMTEfMB0GA1UECQwWR3VzdGF2c2x1bmRzdsOk
-Z2VuIDE0MTEPMA0GA1UEERMGMTY3IDE0MQswCQYDVQQGEwJTRTESMBAGA1UECBMJ
+Z2VuIDE0MTEPMA0GA1UEERMGMTY3IDUxMQswCQYDVQQGEwJTRTESMBAGA1UECBMJ
 U3RvY2tob2xtMQ8wDQYDVQQHEwZCcm9tbWExGDAWBgNVBAoTD05vcmRuZXQgQmFu
 ayBBQjEdMBsGA1UEAxMUd3d3Lm5vcmRuZXRkaXJla3Quc2UwggEiMA0GCSqGSIb3

 c2WCEG5vcmRuZXRkaXJla3Quc2UwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG
 CCsGAQUFBwMBBggrBgEFBQcDAjBjBgNVHR8EXDBaMCugKaAnhiVodHRwOi8vY3Js

-xBCLPXX17IGWWLHb+rZ0YU68b85++9CodblvjKqqCEXG

+jDDzXCaMqI+kp/U034Taez46yNgJp0QDzs2CSNQ=
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_payson.pem app/src/main/res/raw/cert_payson.pem
index 2accfb6..b6a167a 100644
--- app/src/main/res/raw/cert_payson.pem
+++ app/src/main/res/raw/cert_payson.pem
@@ -1,33 +1,32 @@
 -----BEGIN CERTIFICATE-----
-MIIFsDCCBJigAwIBAgIQSVsMq9Q8O26a4JGuv+2mODANBgkqhkiG9w0BAQUFADCB
+MIIFcjCCBFqgAwIBAgIQb06JLHkex4QLALa4cu3EUzANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTQwMTE3MDAwMDAwWhcNMTQwNzA5MjM1OTU5WjCB6TETMBEGCysGAQQBgjc8
+HhcNMTQwNjExMDAwMDAwWhcNMTYwODA5MjM1OTU5WjCBtDETMBEGCysGAQQBgjc8
 AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xFDASBgNVBAUT

-1bmZ1AQg4SGDu8X5MQa+BwRg5/Y=

+NUlgdUKK
 -----END CERTIFICATE-----
diff --git app/src/main/res/raw/cert_trustbuddy.pem app/src/main/res/raw/cert_trustbuddy.pem
index 7d05516..7a6d499 100644
--- app/src/main/res/raw/cert_trustbuddy.pem
+++ app/src/main/res/raw/cert_trustbuddy.pem
@@ -1,29 +1,33 @@
 -----BEGIN CERTIFICATE-----

-a3CPSRzu+D48dh22vCKG7AV7EE47QzaZaYSSgqRHeSmR3ws=

+cnUy20d8PvQ+aY1ugUPRBjFHksFAKA==
 -----END CERTIFICATE-----

commit 1b6d2c6ea24cd9ec5a709190a852fd8d94312487
Author: liato <x@x00.us>
Date:   Wed Jun 25 23:46:40 2014 +0200

    Update project structure and gradle stuff.

diff --git .classpath .classpath
deleted file mode 100644
index 9d6723c..0000000
--- .classpath
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
-	<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
-	<classpathentry kind="lib" path="libs/google-collect-1.0.jar"/>
-	<classpathentry kind="lib" path="libs/jackson-annotations-2.1.0.jar"/>
-	<classpathentry kind="lib" path="libs/jackson-core-2.1.0.jar"/>
-	<classpathentry kind="lib" path="libs/jackson-databind-2.1.0.jar"/>
-	<classpathentry kind="lib" path="libs/jsoup-1.7.2.jar"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="gen"/>
-	<classpathentry kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
-	<classpathentry kind="output" path="bin/classes"/>
-</classpath>
diff --git .gitignore .gitignore
index 8b22f74..cac8f7c 100644
--- .gitignore
+++ .gitignore
@@ -1,27 +1,47 @@
-.metadata
-.settings
-tmp/**
-.DS_Store
-*.tmp
-*.bak
-tmp/**/*
-*.swp
-*~.nib
-Thumbs.db
-Desktop.ini
-*~
+# built application files
 *.apk
-*.java.orig
-bin
-gen
+*.ap_
+
+# files for the dex VM
+*.dex
+
+# Java class files
+*.class
+
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
 local.properties
+
 dev/
-src/com/liato/bankdroid/db/Crypto.*
-src/com/liato/bankdroid/db/Crypto.java.dev
+*.pyc
+.DS_Store
+*.orig
 
-target/
-.idea
+# Local Eclipse files
+.classpath
+.project
+
+# Android studio
 .gradle
-*.iml
 build/
+*.iws
+*.ipr
+*.swp
+out/
+.idea/libraries
+.idea/workspace.xml
+.idea/misc.xml
+.idea/vcs.xml
+.idea/*
+*.iml
+.idea
+
+
+#Project specific
+app/src/main/java/com/liato/bankdroid/db/Crypto.*
+app/src/main/java/com/liato/bankdroid/db/Crypto.java.dev
+dev/
 release.keystore
\ No newline at end of file
diff --git .project .project
deleted file mode 100644
index 93f3488..0000000
--- .project
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>Bankdroid</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git .settings/org.eclipse.core.resources.prefs .settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 37b5c65..0000000
--- .settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Wed May 26 03:27:34 CEST 2010
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git .settings/org.eclipse.ltk.core.refactoring.prefs .settings/org.eclipse.ltk.core.refactoring.prefs
deleted file mode 100644
index 7ba30a7..0000000
--- .settings/org.eclipse.ltk.core.refactoring.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Sun May 02 21:44:53 CEST 2010
-eclipse.preferences.version=1
-org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git app/.gitignore app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git build.gradle app/build.gradle
similarity index 62%
copy from build.gradle
copy to app/build.gradle
index e7bed6a..e6f457a 100644
--- build.gradle
+++ app/build.gradle
@@ -1,59 +1,15 @@
-buildscript {
-    repositories {
-        mavenCentral()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:0.11.+'
-    }
-}
 apply plugin: 'android'
 
-repositories {
-    mavenCentral()
-}
-
-dependencies {
-    compile 'org.apache.commons:commons-io:1.3.2'
-    compile 'com.google.collections:google-collections:1.0'
-    compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
-    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
-    compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
-    compile 'org.jsoup:jsoup:1.7.3'
-    compile('org.simpleframework:simple-xml:2.7.+') {
-        exclude module: 'stax'
-        exclude module: 'stax-api'
-        exclude module: 'xpp3'
-    }
-}
-
-tasks.withType(Compile) {
-    options.encoding = "UTF-8"
-}
-
 android {
-    compileSdkVersion 17
-    buildToolsVersion "17.0.0"
+    compileSdkVersion 19
+    buildToolsVersion "19.1.0"
 
     defaultConfig {
-        versionCode 188
-        versionName '1.9.6.15'
-        minSdkVersion 7
+        applicationId "com.liato.bankdroid"
+        minSdkVersion 9
         targetSdkVersion 10
-        packageName 'com.liato.bankdroid'
-    }
-
-    sourceSets {
-        main {
-            manifest.srcFile 'AndroidManifest.xml'
-            java.srcDirs = ['src']
-            resources.srcDirs = ['src']
-            aidl.srcDirs = ['src']
-            renderscript.srcDirs = ['src']
-            res.srcDirs = ['res']
-            assets.srcDirs = ['assets']
-        }
-
-        instrumentTest.setRoot('tests')
+        versionCode 188
+        versionName "1.9.6.15"
     }
 
     final Console console = System.console();
@@ -79,11 +35,28 @@ android {
         }
 
     }
-
-
+        
     buildTypes {
         release {
+            runProguard false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
             signingConfig signingConfigs.release
         }
     }
 }
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    compile 'org.apache.commons:commons-io:1.3.2'
+    compile 'com.google.collections:google-collections:1.0'
+    compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
+    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
+    compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
+    compile 'org.jsoup:jsoup:1.7.3'
+    compile('org.simpleframework:simple-xml:2.7.+') {
+        exclude module: 'stax'
+        exclude module: 'stax-api'
+        exclude module: 'xpp3'
+    }
+
+}
diff --git app/proguard-rules.pro app/proguard-rules.pro
new file mode 100644
index 0000000..70a3619
--- /dev/null
+++ app/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/liato/bin/android-studio/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git AndroidManifest.xml app/src/main/AndroidManifest.xml
similarity index 100%
rename from AndroidManifest.xml
rename to app/src/main/AndroidManifest.xml
diff --git src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl app/src/main/aidl/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
similarity index 100%
rename from src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
rename to app/src/main/aidl/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
diff --git src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl app/src/main/aidl/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
similarity index 100%
rename from src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
rename to app/src/main/aidl/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
diff --git src/com/ast/util/CookieParser.java app/src/main/java/com/ast/util/CookieParser.java
similarity index 100%
rename from src/com/ast/util/CookieParser.java
rename to app/src/main/java/com/ast/util/CookieParser.java
diff --git src/com/liato/bankdroid/AboutActivity.java app/src/main/java/com/liato/bankdroid/AboutActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/AboutActivity.java
rename to app/src/main/java/com/liato/bankdroid/AboutActivity.java
diff --git src/com/liato/bankdroid/BankEditActivity.java app/src/main/java/com/liato/bankdroid/BankEditActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/BankEditActivity.java
rename to app/src/main/java/com/liato/bankdroid/BankEditActivity.java
diff --git src/com/liato/bankdroid/BetterPopupWindow.java app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
similarity index 100%
rename from src/com/liato/bankdroid/BetterPopupWindow.java
rename to app/src/main/java/com/liato/bankdroid/BetterPopupWindow.java
diff --git src/com/liato/bankdroid/DataRetrieverTask.java app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
similarity index 100%
rename from src/com/liato/bankdroid/DataRetrieverTask.java
rename to app/src/main/java/com/liato/bankdroid/DataRetrieverTask.java
diff --git src/com/liato/bankdroid/Helpers.java app/src/main/java/com/liato/bankdroid/Helpers.java
similarity index 100%
rename from src/com/liato/bankdroid/Helpers.java
rename to app/src/main/java/com/liato/bankdroid/Helpers.java
diff --git src/com/liato/bankdroid/LockableActivity.java app/src/main/java/com/liato/bankdroid/LockableActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/LockableActivity.java
rename to app/src/main/java/com/liato/bankdroid/LockableActivity.java
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/LockablePreferenceActivity.java
rename to app/src/main/java/com/liato/bankdroid/LockablePreferenceActivity.java
diff --git src/com/liato/bankdroid/MainActivity.java app/src/main/java/com/liato/bankdroid/MainActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/MainActivity.java
rename to app/src/main/java/com/liato/bankdroid/MainActivity.java
diff --git src/com/liato/bankdroid/PairApplicationsActivity.java app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/PairApplicationsActivity.java
rename to app/src/main/java/com/liato/bankdroid/PairApplicationsActivity.java
diff --git src/com/liato/bankdroid/SettingsActivity.java app/src/main/java/com/liato/bankdroid/SettingsActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/SettingsActivity.java
rename to app/src/main/java/com/liato/bankdroid/SettingsActivity.java
diff --git src/com/liato/bankdroid/StartupReceiver.java app/src/main/java/com/liato/bankdroid/StartupReceiver.java
similarity index 100%
rename from src/com/liato/bankdroid/StartupReceiver.java
rename to app/src/main/java/com/liato/bankdroid/StartupReceiver.java
diff --git src/com/liato/bankdroid/TimePreference.java app/src/main/java/com/liato/bankdroid/TimePreference.java
similarity index 100%
rename from src/com/liato/bankdroid/TimePreference.java
rename to app/src/main/java/com/liato/bankdroid/TimePreference.java
diff --git src/com/liato/bankdroid/TransactionsActivity.java app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/TransactionsActivity.java
rename to app/src/main/java/com/liato/bankdroid/TransactionsActivity.java
diff --git src/com/liato/bankdroid/WebViewActivity.java app/src/main/java/com/liato/bankdroid/WebViewActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/WebViewActivity.java
rename to app/src/main/java/com/liato/bankdroid/WebViewActivity.java
diff --git src/com/liato/bankdroid/adapters/AccountsAdapter.java app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
similarity index 100%
rename from src/com/liato/bankdroid/adapters/AccountsAdapter.java
rename to app/src/main/java/com/liato/bankdroid/adapters/AccountsAdapter.java
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
similarity index 100%
rename from src/com/liato/bankdroid/appwidget/AutoRefreshService.java
rename to app/src/main/java/com/liato/bankdroid/appwidget/AutoRefreshService.java
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
similarity index 100%
rename from src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
rename to app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
similarity index 100%
rename from src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
rename to app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
similarity index 100%
rename from src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
rename to app/src/main/java/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
diff --git src/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
similarity index 100%
rename from src/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
rename to app/src/main/java/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
diff --git src/com/liato/bankdroid/banking/Account.java app/src/main/java/com/liato/bankdroid/banking/Account.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/Account.java
rename to app/src/main/java/com/liato/bankdroid/banking/Account.java
diff --git src/com/liato/bankdroid/banking/Bank.java app/src/main/java/com/liato/bankdroid/banking/Bank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/Bank.java
rename to app/src/main/java/com/liato/bankdroid/banking/Bank.java
diff --git src/com/liato/bankdroid/banking/BankChoice.java app/src/main/java/com/liato/bankdroid/banking/BankChoice.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/BankChoice.java
rename to app/src/main/java/com/liato/bankdroid/banking/BankChoice.java
diff --git src/com/liato/bankdroid/banking/BankFactory.java app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/BankFactory.java
rename to app/src/main/java/com/liato/bankdroid/banking/BankFactory.java
diff --git src/com/liato/bankdroid/banking/Transaction.java app/src/main/java/com/liato/bankdroid/banking/Transaction.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/Transaction.java
rename to app/src/main/java/com/liato/bankdroid/banking/Transaction.java
diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java app/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusInvest.java
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/AkeliusSpar.java
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
similarity index 98%
rename from src/com/liato/bankdroid/banking/banks/AmericanExpress.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
index a2268b4..35a745a 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ app/src/main/java/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -1,195 +1,195 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.util.Log;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class AmericanExpress extends Bank {
-    private static final String TAG = "AmericanExpress";
-    private static final String NAME = "American Express";
-    private static final String NAME_SHORT = "americanexpress";
-    private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
-    private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
-
-    private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
-    private String response = null;
-
-    public AmericanExpress(Context context) {
-        super(context);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-    }
-
-    public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-        this(context);
-        this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
-        urlopen.setAllowCircularRedirects(true);
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-
-        postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
-        postData.add(new BasicNameValuePair("DestPage", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
-        postData.add(new BasicNameValuePair("Face", "sv_SE"));
-        postData.add(new BasicNameValuePair("brandname", ""));
-        postData.add(new BasicNameValuePair("TARGET", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
-        postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
-        postData.add(new BasicNameValuePair("Logon", "Continue..."));
-        postData.add(new BasicNameValuePair("devicePrint", "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
-        postData.add(new BasicNameValuePair("REMEMBERME", "on"));
-        postData.add(new BasicNameValuePair("manage", "option1"));
-        postData.add(new BasicNameValuePair("UserID", username));
-        postData.add(new BasicNameValuePair("USERID", username));
-        postData.add(new BasicNameValuePair("Password", password));
-        postData.add(new BasicNameValuePair("PWD", password));
-
-        return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
-    }
-
-    @Override
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-
-            if (!response.contains("Your Personal Cards")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-        } catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        } catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
-        super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        Matcher matcher = reAccounts.matcher(response);
-
-        while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Account number        XXX-11111
-             * 2: ID                    0
-             * 3: Name                  SAS EuroBonus American Express&reg; Card
-             * 4: Amount                1.111,11 kr
-             * 
-             */   			    
-            accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
-                    Helpers.parseBalance(matcher.group(4)).negate(),
-                    matcher.group(2).trim()));
-            balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
-        }
-
-        if (accounts.isEmpty()) {
-            throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }
-        super.updateComplete();
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-        super.updateTransactions(account, urlopen);
-
-        try {
-            response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
-            Matcher matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-
-            SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
-            SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
-            Date transactionDate;
-
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Date                  17 jan 2011
-                 * 2: Specification         xx
-                 * 3: Amount                1.582,00&nbsp;kr
-                 * 
-                 */
-                try {
-                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
-                    String strDate = sdfTo.format(transactionDate);
-                    transactions.add(new Transaction(strDate,
-                                                     Html.fromHtml(matcher.group(2)).toString().trim(),
-                                                     Helpers.parseBalance(matcher.group(3).trim()).negate()));
-                }
-                catch (ParseException e) {
-                    Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
-                }
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AmericanExpress extends Bank {
+    private static final String TAG = "AmericanExpress";
+    private static final String NAME = "American Express";
+    private static final String NAME_SHORT = "americanexpress";
+    private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
+    private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
+
+    private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private String response = null;
+
+    public AmericanExpress(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
+        urlopen.setAllowCircularRedirects(true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+
+        postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
+        postData.add(new BasicNameValuePair("DestPage", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("Face", "sv_SE"));
+        postData.add(new BasicNameValuePair("brandname", ""));
+        postData.add(new BasicNameValuePair("TARGET", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
+        postData.add(new BasicNameValuePair("Logon", "Continue..."));
+        postData.add(new BasicNameValuePair("devicePrint", "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
+        postData.add(new BasicNameValuePair("REMEMBERME", "on"));
+        postData.add(new BasicNameValuePair("manage", "option1"));
+        postData.add(new BasicNameValuePair("UserID", username));
+        postData.add(new BasicNameValuePair("USERID", username));
+        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("PWD", password));
+
+        return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+            if (!response.contains("Your Personal Cards")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher = reAccounts.matcher(response);
+
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Account number        XXX-11111
+             * 2: ID                    0
+             * 3: Name                  SAS EuroBonus American Express&reg; Card
+             * 4: Amount                1.111,11 kr
+             * 
+             */   			    
+            accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4)).negate(),
+                    matcher.group(2).trim()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        try {
+            response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
+            Matcher matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+            SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
+            SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
+            Date transactionDate;
+
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Date                  17 jan 2011
+                 * 2: Specification         xx
+                 * 3: Amount                1.582,00&nbsp;kr
+                 * 
+                 */
+                try {
+                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
+                    String strDate = sdfTo.format(transactionDate);
+                    transactions.add(new Transaction(strDate,
+                                                     Html.fromHtml(matcher.group(2)).toString().trim(),
+                                                     Helpers.parseBalance(matcher.group(3).trim()).negate()));
+                }
+                catch (ParseException e) {
+                    Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                }
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/AppeakPoker.java app/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/AppeakPoker.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/AppeakPoker.java
diff --git src/com/liato/bankdroid/banking/banks/Audi.java app/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Audi.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Audi.java
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java app/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/AvanzaMini.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/AvanzaMini.java
diff --git src/com/liato/bankdroid/banking/banks/BetterGlobe.java app/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/BetterGlobe.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/BetterGlobe.java
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Bioklubben.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Bioklubben.java
diff --git src/com/liato/bankdroid/banking/banks/BrummerKF.java app/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/BrummerKF.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/BrummerKF.java
diff --git src/com/liato/bankdroid/banking/banks/CSN.java app/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/CSN.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/CSN.java
diff --git src/com/liato/bankdroid/banking/banks/Chalmrest.java app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Chalmrest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Chalmrest.java
diff --git src/com/liato/bankdroid/banking/banks/Chevrolet.java app/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Chevrolet.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Chevrolet.java
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java app/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/DanskeBank.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/DanskeBank.java
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java app/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/DinersClub.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/DinersClub.java
diff --git src/com/liato/bankdroid/banking/banks/Djurgarden.java app/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Djurgarden.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Djurgarden.java
diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java app/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/EasyCard.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/EasyCard.java
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java app/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Eurocard.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Eurocard.java
diff --git src/com/liato/bankdroid/banking/banks/Everydaycard.java app/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Everydaycard.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Everydaycard.java
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java app/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/FirstCard.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/FirstCard.java
diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java app/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ForexBank.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ForexBank.java
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java app/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Handelsbanken.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Handelsbanken.java
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java app/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Hemkop.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Hemkop.java
diff --git src/com/liato/bankdroid/banking/banks/IKEA.java app/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/IKEA.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/IKEA.java
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java app/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/IkanoBank.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/IkanoBank.java
diff --git src/com/liato/bankdroid/banking/banks/Jojo.java app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Jojo.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Jojo.java
diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Marginalen.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Marginalen.java
diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java app/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/McDonalds.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/McDonalds.java
diff --git src/com/liato/bankdroid/banking/banks/Meniga.java app/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Meniga.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Meniga.java
diff --git src/com/liato/bankdroid/banking/banks/MobilbankenBase.java app/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/MobilbankenBase.java
diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java app/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/NordeaDK.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/NordeaDK.java
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java app/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Nordnet.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Nordnet.java
diff --git src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java app/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java app/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/OKQ8.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/OKQ8.java
diff --git src/com/liato/bankdroid/banking/banks/Opel.java app/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Opel.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Opel.java
diff --git src/com/liato/bankdroid/banking/banks/Osuuspankki.java app/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Osuuspankki.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Osuuspankki.java
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/PayPal.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/PayPal.java
diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java app/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/PlusGirot.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/PlusGirot.java
diff --git src/com/liato/bankdroid/banking/banks/Preem.java app/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Preem.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Preem.java
diff --git src/com/liato/bankdroid/banking/banks/Quintessentially.java app/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Quintessentially.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Quintessentially.java
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java app/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ResursBank.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ResursBank.java
diff --git src/com/liato/bankdroid/banking/banks/SJPrio.java app/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SJPrio.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SJPrio.java
diff --git src/com/liato/bankdroid/banking/banks/Saab.java app/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Saab.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Saab.java
diff --git src/com/liato/bankdroid/banking/banks/Seat.java app/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Seat.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Seat.java
diff --git src/com/liato/bankdroid/banking/banks/SevenDay.java app/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SevenDay.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SevenDay.java
diff --git src/com/liato/bankdroid/banking/banks/Shell.java app/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Shell.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Shell.java
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java app/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Skandiabanken.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Skandiabanken.java
diff --git src/com/liato/bankdroid/banking/banks/Skoda.java app/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Skoda.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Skoda.java
diff --git src/com/liato/bankdroid/banking/banks/SparbankenOresund.java app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenOresund.java
diff --git src/com/liato/bankdroid/banking/banks/SparbankenSyd.java app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SparbankenSyd.java
diff --git src/com/liato/bankdroid/banking/banks/Statoil.java app/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Statoil.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Statoil.java
diff --git src/com/liato/bankdroid/banking/banks/Steam.java app/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Steam.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Steam.java
diff --git src/com/liato/bankdroid/banking/banks/SupremeCard.java app/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SupremeCard.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SupremeCard.java
diff --git src/com/liato/bankdroid/banking/banks/SveaDirekt.java app/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SveaDirekt.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SveaDirekt.java
diff --git src/com/liato/bankdroid/banking/banks/SvenskaSpel.java app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/SvenskaSpel.java
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java app/src/main/java/com/liato/bankdroid/banking/banks/Swedbank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Swedbank.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Swedbank.java
diff --git src/com/liato/bankdroid/banking/banks/TestBank.java app/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/TestBank.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/TestBank.java
diff --git src/com/liato/bankdroid/banking/banks/TicketRikskortet.java app/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/TicketRikskortet.java
diff --git src/com/liato/bankdroid/banking/banks/TrustBuddy.java app/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/TrustBuddy.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/TrustBuddy.java
diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Vasttrafik.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Vasttrafik.java
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java app/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Villabanken.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Villabanken.java
diff --git src/com/liato/bankdroid/banking/banks/Volkswagen.java app/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Volkswagen.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Volkswagen.java
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java app/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Volvofinans.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Volvofinans.java
diff --git src/com/liato/bankdroid/banking/banks/Wallet.java app/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Wallet.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Wallet.java
diff --git src/com/liato/bankdroid/banking/banks/Zidisha.java app/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Zidisha.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/Zidisha.java
diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/avanza/Avanza.java
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/avanza/model/Account.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Account.java
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/Position.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/avanza/model/Position.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/Position.java
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/Coop.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/Coop.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/D.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/web/D.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/D.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/Model.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/Result.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
diff --git src/com/liato/bankdroid/banking/banks/ica/ICA.java app/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ica/ICA.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ica/ICA.java
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ica/model/Account.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Account.java
diff --git src/com/liato/bankdroid/banking/banks/ica/model/LoginError.java app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Overview.java app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Overview.java
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Transaction.java app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
diff --git src/com/liato/bankdroid/banking/banks/ica/model/User.java app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/ica/model/User.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/ica/model/User.java
diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
diff --git src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
diff --git src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
diff --git src/com/liato/bankdroid/banking/banks/nordea/Nordea.java app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/nordea/Nordea.java
diff --git src/com/liato/bankdroid/banking/banks/payson/Payson.java app/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/payson/Payson.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/payson/Payson.java
diff --git src/com/liato/bankdroid/banking/banks/payson/model/Transaction.java app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
diff --git src/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
diff --git src/com/liato/bankdroid/banking/banks/payson/model/User.java app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/payson/model/User.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/payson/model/User.java
diff --git src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
diff --git src/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
diff --git src/com/liato/bankdroid/banking/banks/seb/SEB.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/SEB.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/SEB.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/DEVID.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/Request.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/Request.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/Request.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
diff --git src/com/liato/bankdroid/banking/banks/seb/model/VODB.java app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/seb/model/VODB.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/seb/model/VODB.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/User.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/User.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/User.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
rename to app/src/main/java/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
diff --git src/com/liato/bankdroid/banking/exceptions/BankChoiceException.java app/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
rename to app/src/main/java/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
diff --git src/com/liato/bankdroid/banking/exceptions/BankException.java app/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/exceptions/BankException.java
rename to app/src/main/java/com/liato/bankdroid/banking/exceptions/BankException.java
diff --git src/com/liato/bankdroid/banking/exceptions/LoginException.java app/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/exceptions/LoginException.java
rename to app/src/main/java/com/liato/bankdroid/banking/exceptions/LoginException.java
diff --git src/com/liato/bankdroid/db/DBAdapter.java app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
similarity index 100%
rename from src/com/liato/bankdroid/db/DBAdapter.java
rename to app/src/main/java/com/liato/bankdroid/db/DBAdapter.java
diff --git src/com/liato/bankdroid/db/DatabaseHelper.java app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
similarity index 100%
rename from src/com/liato/bankdroid/db/DatabaseHelper.java
rename to app/src/main/java/com/liato/bankdroid/db/DatabaseHelper.java
diff --git src/com/liato/bankdroid/liveview/LiveViewService.java app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
similarity index 100%
rename from src/com/liato/bankdroid/liveview/LiveViewService.java
rename to app/src/main/java/com/liato/bankdroid/liveview/LiveViewService.java
diff --git src/com/liato/bankdroid/liveview/PluginConstants.java app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
similarity index 100%
rename from src/com/liato/bankdroid/liveview/PluginConstants.java
rename to app/src/main/java/com/liato/bankdroid/liveview/PluginConstants.java
diff --git src/com/liato/bankdroid/liveview/PluginReceiver.java app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
similarity index 100%
rename from src/com/liato/bankdroid/liveview/PluginReceiver.java
rename to app/src/main/java/com/liato/bankdroid/liveview/PluginReceiver.java
diff --git src/com/liato/bankdroid/liveview/PluginUtils.java app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
similarity index 100%
rename from src/com/liato/bankdroid/liveview/PluginUtils.java
rename to app/src/main/java/com/liato/bankdroid/liveview/PluginUtils.java
diff --git src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
diff --git src/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
diff --git src/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
diff --git src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
diff --git src/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java app/src/main/java/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
diff --git src/com/liato/bankdroid/lockpattern/LockPatternUtils.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternUtils.java
diff --git src/com/liato/bankdroid/lockpattern/LockPatternView.java app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
similarity index 100%
rename from src/com/liato/bankdroid/lockpattern/LockPatternView.java
rename to app/src/main/java/com/liato/bankdroid/lockpattern/LockPatternView.java
diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
similarity index 100%
rename from src/com/liato/bankdroid/provider/BankTransactionsProvider.java
rename to app/src/main/java/com/liato/bankdroid/provider/BankTransactionsProvider.java
diff --git src/com/liato/bankdroid/provider/IAccountTypes.java app/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
similarity index 100%
rename from src/com/liato/bankdroid/provider/IAccountTypes.java
rename to app/src/main/java/com/liato/bankdroid/provider/IAccountTypes.java
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java app/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
similarity index 100%
rename from src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
rename to app/src/main/java/com/liato/bankdroid/provider/IBankTransactionsProvider.java
diff --git src/com/liato/bankdroid/provider/IBankTypes.java app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
similarity index 100%
rename from src/com/liato/bankdroid/provider/IBankTypes.java
rename to app/src/main/java/com/liato/bankdroid/provider/IBankTypes.java
diff --git src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
similarity index 100%
rename from src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
rename to app/src/main/java/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java app/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
similarity index 100%
rename from src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
rename to app/src/main/java/eu/nullbyte/android/urllib/CertPinningTrustManager.java
diff --git src/eu/nullbyte/android/urllib/CertificateReader.java app/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
similarity index 100%
rename from src/eu/nullbyte/android/urllib/CertificateReader.java
rename to app/src/main/java/eu/nullbyte/android/urllib/CertificateReader.java
diff --git src/eu/nullbyte/android/urllib/ClientCertificate.java app/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
similarity index 100%
rename from src/eu/nullbyte/android/urllib/ClientCertificate.java
rename to app/src/main/java/eu/nullbyte/android/urllib/ClientCertificate.java
diff --git src/eu/nullbyte/android/urllib/Urllib.java app/src/main/java/eu/nullbyte/android/urllib/Urllib.java
similarity index 100%
rename from src/eu/nullbyte/android/urllib/Urllib.java
rename to app/src/main/java/eu/nullbyte/android/urllib/Urllib.java
diff --git src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
similarity index 100%
rename from src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
rename to app/src/main/java/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
diff --git src/net/margaritov/preference/colorpicker/ColorPickerDialog.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
similarity index 100%
rename from src/net/margaritov/preference/colorpicker/ColorPickerDialog.java
rename to app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerDialog.java
diff --git src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
similarity index 100%
rename from src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
rename to app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
diff --git src/net/margaritov/preference/colorpicker/ColorPickerPreference.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
similarity index 100%
rename from src/net/margaritov/preference/colorpicker/ColorPickerPreference.java
rename to app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerPreference.java
diff --git src/net/margaritov/preference/colorpicker/ColorPickerView.java app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
similarity index 100%
rename from src/net/margaritov/preference/colorpicker/ColorPickerView.java
rename to app/src/main/java/net/margaritov/preference/colorpicker/ColorPickerView.java
diff --git src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
similarity index 100%
rename from src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
rename to app/src/main/java/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
diff --git res/anim/grow_from_bottom.xml app/src/main/res/anim/grow_from_bottom.xml
similarity index 100%
rename from res/anim/grow_from_bottom.xml
rename to app/src/main/res/anim/grow_from_bottom.xml
diff --git res/anim/grow_from_top.xml app/src/main/res/anim/grow_from_top.xml
similarity index 100%
rename from res/anim/grow_from_top.xml
rename to app/src/main/res/anim/grow_from_top.xml
diff --git res/anim/grow_from_topleft_to_bottomright.xml app/src/main/res/anim/grow_from_topleft_to_bottomright.xml
similarity index 100%
rename from res/anim/grow_from_topleft_to_bottomright.xml
rename to app/src/main/res/anim/grow_from_topleft_to_bottomright.xml
diff --git res/anim/shrink_from_bottom.xml app/src/main/res/anim/shrink_from_bottom.xml
similarity index 100%
rename from res/anim/shrink_from_bottom.xml
rename to app/src/main/res/anim/shrink_from_bottom.xml
diff --git res/anim/shrink_from_bottomright_to_topleft.xml app/src/main/res/anim/shrink_from_bottomright_to_topleft.xml
similarity index 100%
rename from res/anim/shrink_from_bottomright_to_topleft.xml
rename to app/src/main/res/anim/shrink_from_bottomright_to_topleft.xml
diff --git res/anim/shrink_from_top.xml app/src/main/res/anim/shrink_from_top.xml
similarity index 100%
rename from res/anim/shrink_from_top.xml
rename to app/src/main/res/anim/shrink_from_top.xml
diff --git res/anim/zoom_enter.xml app/src/main/res/anim/zoom_enter.xml
similarity index 100%
rename from res/anim/zoom_enter.xml
rename to app/src/main/res/anim/zoom_enter.xml
diff --git res/anim/zoom_exit.xml app/src/main/res/anim/zoom_exit.xml
similarity index 100%
rename from res/anim/zoom_exit.xml
rename to app/src/main/res/anim/zoom_exit.xml
diff --git res/drawable-hdpi-v4/background.png app/src/main/res/drawable-hdpi-v4/background.png
similarity index 100%
rename from res/drawable-hdpi-v4/background.png
rename to app/src/main/res/drawable-hdpi-v4/background.png
diff --git res/drawable-hdpi-v4/background_repeat.png app/src/main/res/drawable-hdpi-v4/background_repeat.png
similarity index 100%
rename from res/drawable-hdpi-v4/background_repeat.png
rename to app/src/main/res/drawable-hdpi-v4/background_repeat.png
diff --git res/drawable-hdpi-v4/btn_check_label_background.9.png app/src/main/res/drawable-hdpi-v4/btn_check_label_background.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_label_background.9.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_label_background.9.png
diff --git res/drawable-hdpi-v4/btn_check_off.png app/src/main/res/drawable-hdpi-v4/btn_check_off.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_off.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_off.png
diff --git res/drawable-hdpi-v4/btn_check_off_disable.png app/src/main/res/drawable-hdpi-v4/btn_check_off_disable.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_off_disable.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_off_disable.png
diff --git res/drawable-hdpi-v4/btn_check_off_disable_focused.png app/src/main/res/drawable-hdpi-v4/btn_check_off_disable_focused.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_off_disable_focused.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_off_disable_focused.png
diff --git res/drawable-hdpi-v4/btn_check_off_pressed.png app/src/main/res/drawable-hdpi-v4/btn_check_off_pressed.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_off_pressed.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_off_pressed.png
diff --git res/drawable-hdpi-v4/btn_check_off_selected.png app/src/main/res/drawable-hdpi-v4/btn_check_off_selected.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_off_selected.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_off_selected.png
diff --git res/drawable-hdpi-v4/btn_check_on.png app/src/main/res/drawable-hdpi-v4/btn_check_on.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_on.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_on.png
diff --git res/drawable-hdpi-v4/btn_check_on_disable.png app/src/main/res/drawable-hdpi-v4/btn_check_on_disable.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_on_disable.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_on_disable.png
diff --git res/drawable-hdpi-v4/btn_check_on_disable_focused.png app/src/main/res/drawable-hdpi-v4/btn_check_on_disable_focused.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_on_disable_focused.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_on_disable_focused.png
diff --git res/drawable-hdpi-v4/btn_check_on_pressed.png app/src/main/res/drawable-hdpi-v4/btn_check_on_pressed.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_on_pressed.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_on_pressed.png
diff --git res/drawable-hdpi-v4/btn_check_on_selected.png app/src/main/res/drawable-hdpi-v4/btn_check_on_selected.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_check_on_selected.png
rename to app/src/main/res/drawable-hdpi-v4/btn_check_on_selected.png
diff --git res/drawable-hdpi-v4/btn_code_lock_default.png app/src/main/res/drawable-hdpi-v4/btn_code_lock_default.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_code_lock_default.png
rename to app/src/main/res/drawable-hdpi-v4/btn_code_lock_default.png
diff --git res/drawable-hdpi-v4/btn_code_lock_touched.png app/src/main/res/drawable-hdpi-v4/btn_code_lock_touched.png
similarity index 100%
rename from res/drawable-hdpi-v4/btn_code_lock_touched.png
rename to app/src/main/res/drawable-hdpi-v4/btn_code_lock_touched.png
diff --git res/drawable-hdpi-v4/button_accept.png app/src/main/res/drawable-hdpi-v4/button_accept.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_accept.png
rename to app/src/main/res/drawable-hdpi-v4/button_accept.png
diff --git res/drawable-hdpi-v4/button_add.png app/src/main/res/drawable-hdpi-v4/button_add.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_add.png
rename to app/src/main/res/drawable-hdpi-v4/button_add.png
diff --git res/drawable-hdpi-v4/button_bg.9.png app/src/main/res/drawable-hdpi-v4/button_bg.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_bg.9.png
rename to app/src/main/res/drawable-hdpi-v4/button_bg.9.png
diff --git res/drawable-hdpi-v4/button_bg_pressed.9.png app/src/main/res/drawable-hdpi-v4/button_bg_pressed.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_bg_pressed.9.png
rename to app/src/main/res/drawable-hdpi-v4/button_bg_pressed.9.png
diff --git res/drawable-hdpi-v4/button_cancel.png app/src/main/res/drawable-hdpi-v4/button_cancel.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_cancel.png
rename to app/src/main/res/drawable-hdpi-v4/button_cancel.png
diff --git res/drawable-hdpi-v4/button_edit.png app/src/main/res/drawable-hdpi-v4/button_edit.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_edit.png
rename to app/src/main/res/drawable-hdpi-v4/button_edit.png
diff --git res/drawable-hdpi-v4/button_hide.png app/src/main/res/drawable-hdpi-v4/button_hide.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_hide.png
rename to app/src/main/res/drawable-hdpi-v4/button_hide.png
diff --git res/drawable-hdpi-v4/button_notification.png app/src/main/res/drawable-hdpi-v4/button_notification.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_notification.png
rename to app/src/main/res/drawable-hdpi-v4/button_notification.png
diff --git res/drawable-hdpi-v4/button_refresh.png app/src/main/res/drawable-hdpi-v4/button_refresh.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_refresh.png
rename to app/src/main/res/drawable-hdpi-v4/button_refresh.png
diff --git res/drawable-hdpi-v4/button_save.png app/src/main/res/drawable-hdpi-v4/button_save.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_save.png
rename to app/src/main/res/drawable-hdpi-v4/button_save.png
diff --git res/drawable-hdpi-v4/button_www.png app/src/main/res/drawable-hdpi-v4/button_www.png
similarity index 100%
rename from res/drawable-hdpi-v4/button_www.png
rename to app/src/main/res/drawable-hdpi-v4/button_www.png
diff --git res/drawable-hdpi-v4/date_background.png app/src/main/res/drawable-hdpi-v4/date_background.png
similarity index 100%
rename from res/drawable-hdpi-v4/date_background.png
rename to app/src/main/res/drawable-hdpi-v4/date_background.png
diff --git res/drawable-hdpi-v4/date_bg.9.png app/src/main/res/drawable-hdpi-v4/date_bg.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/date_bg.9.png
rename to app/src/main/res/drawable-hdpi-v4/date_bg.9.png
diff --git res/drawable-hdpi-v4/date_bg_2.9.png app/src/main/res/drawable-hdpi-v4/date_bg_2.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/date_bg_2.9.png
rename to app/src/main/res/drawable-hdpi-v4/date_bg_2.9.png
diff --git res/drawable-hdpi-v4/group_bg.png app/src/main/res/drawable-hdpi-v4/group_bg.png
similarity index 100%
rename from res/drawable-hdpi-v4/group_bg.png
rename to app/src/main/res/drawable-hdpi-v4/group_bg.png
diff --git res/drawable-hdpi-v4/ic_btn_next.png app/src/main/res/drawable-hdpi-v4/ic_btn_next.png
similarity index 100%
rename from res/drawable-hdpi-v4/ic_btn_next.png
rename to app/src/main/res/drawable-hdpi-v4/ic_btn_next.png
diff --git res/drawable-hdpi-v4/ic_menu_donate.png app/src/main/res/drawable-hdpi-v4/ic_menu_donate.png
similarity index 100%
rename from res/drawable-hdpi-v4/ic_menu_donate.png
rename to app/src/main/res/drawable-hdpi-v4/ic_menu_donate.png
diff --git res/drawable-hdpi-v4/ic_menu_info_details.png app/src/main/res/drawable-hdpi-v4/ic_menu_info_details.png
similarity index 100%
rename from res/drawable-hdpi-v4/ic_menu_info_details.png
rename to app/src/main/res/drawable-hdpi-v4/ic_menu_info_details.png
diff --git res/drawable-hdpi-v4/ic_menu_view.png app/src/main/res/drawable-hdpi-v4/ic_menu_view.png
similarity index 100%
rename from res/drawable-hdpi-v4/ic_menu_view.png
rename to app/src/main/res/drawable-hdpi-v4/ic_menu_view.png
diff --git res/drawable-hdpi-v4/icon.png app/src/main/res/drawable-hdpi-v4/icon.png
similarity index 100%
rename from res/drawable-hdpi-v4/icon.png
rename to app/src/main/res/drawable-hdpi-v4/icon.png
diff --git res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png
similarity index 100%
rename from res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png
rename to app/src/main/res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png
diff --git res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png
similarity index 100%
rename from res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png
rename to app/src/main/res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png
similarity index 100%
rename from res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png
rename to app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png
similarity index 100%
rename from res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png
rename to app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png
similarity index 100%
rename from res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png
rename to app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png
similarity index 100%
rename from res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png
rename to app/src/main/res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png
diff --git res/drawable-hdpi-v4/logo_text_big.png app/src/main/res/drawable-hdpi-v4/logo_text_big.png
similarity index 100%
rename from res/drawable-hdpi-v4/logo_text_big.png
rename to app/src/main/res/drawable-hdpi-v4/logo_text_big.png
diff --git res/drawable-hdpi-v4/menu_separator.png app/src/main/res/drawable-hdpi-v4/menu_separator.png
similarity index 100%
rename from res/drawable-hdpi-v4/menu_separator.png
rename to app/src/main/res/drawable-hdpi-v4/menu_separator.png
diff --git res/drawable-hdpi-v4/nullbyte_logo.png app/src/main/res/drawable-hdpi-v4/nullbyte_logo.png
similarity index 100%
rename from res/drawable-hdpi-v4/nullbyte_logo.png
rename to app/src/main/res/drawable-hdpi-v4/nullbyte_logo.png
diff --git res/drawable-hdpi-v4/popup_bg_down.9.png app/src/main/res/drawable-hdpi-v4/popup_bg_down.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_bg_down.9.png
rename to app/src/main/res/drawable-hdpi-v4/popup_bg_down.9.png
diff --git res/drawable-hdpi-v4/popup_bg_down_o.png app/src/main/res/drawable-hdpi-v4/popup_bg_down_o.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_bg_down_o.png
rename to app/src/main/res/drawable-hdpi-v4/popup_bg_down_o.png
diff --git res/drawable-hdpi-v4/popup_bg_regular.png app/src/main/res/drawable-hdpi-v4/popup_bg_regular.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_bg_regular.png
rename to app/src/main/res/drawable-hdpi-v4/popup_bg_regular.png
diff --git res/drawable-hdpi-v4/popup_bg_selected.png app/src/main/res/drawable-hdpi-v4/popup_bg_selected.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_bg_selected.png
rename to app/src/main/res/drawable-hdpi-v4/popup_bg_selected.png
diff --git res/drawable-hdpi-v4/popup_bg_up.9.png app/src/main/res/drawable-hdpi-v4/popup_bg_up.9.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_bg_up.9.png
rename to app/src/main/res/drawable-hdpi-v4/popup_bg_up.9.png
diff --git res/drawable-hdpi-v4/popup_bg_up_o.png app/src/main/res/drawable-hdpi-v4/popup_bg_up_o.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_bg_up_o.png
rename to app/src/main/res/drawable-hdpi-v4/popup_bg_up_o.png
diff --git res/drawable-hdpi-v4/popup_separator.png app/src/main/res/drawable-hdpi-v4/popup_separator.png
similarity index 100%
rename from res/drawable-hdpi-v4/popup_separator.png
rename to app/src/main/res/drawable-hdpi-v4/popup_separator.png
diff --git res/drawable-hdpi-v4/title_icon_add.png app/src/main/res/drawable-hdpi-v4/title_icon_add.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_icon_add.png
rename to app/src/main/res/drawable-hdpi-v4/title_icon_add.png
diff --git res/drawable-hdpi-v4/title_icon_back.png app/src/main/res/drawable-hdpi-v4/title_icon_back.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_icon_back.png
rename to app/src/main/res/drawable-hdpi-v4/title_icon_back.png
diff --git res/drawable-hdpi-v4/title_icon_donate.png app/src/main/res/drawable-hdpi-v4/title_icon_donate.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_icon_donate.png
rename to app/src/main/res/drawable-hdpi-v4/title_icon_donate.png
diff --git res/drawable-hdpi-v4/title_icon_forward.png app/src/main/res/drawable-hdpi-v4/title_icon_forward.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_icon_forward.png
rename to app/src/main/res/drawable-hdpi-v4/title_icon_forward.png
diff --git res/drawable-hdpi-v4/title_icon_refresh.png app/src/main/res/drawable-hdpi-v4/title_icon_refresh.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_icon_refresh.png
rename to app/src/main/res/drawable-hdpi-v4/title_icon_refresh.png
diff --git res/drawable-hdpi-v4/title_icon_web.png app/src/main/res/drawable-hdpi-v4/title_icon_web.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_icon_web.png
rename to app/src/main/res/drawable-hdpi-v4/title_icon_web.png
diff --git res/drawable-hdpi-v4/title_logo_focused.png app/src/main/res/drawable-hdpi-v4/title_logo_focused.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_logo_focused.png
rename to app/src/main/res/drawable-hdpi-v4/title_logo_focused.png
diff --git res/drawable-hdpi-v4/title_logo_normal.png app/src/main/res/drawable-hdpi-v4/title_logo_normal.png
similarity index 100%
rename from res/drawable-hdpi-v4/title_logo_normal.png
rename to app/src/main/res/drawable-hdpi-v4/title_logo_normal.png
diff --git res/drawable-hdpi-v4/transaction_negative.png app/src/main/res/drawable-hdpi-v4/transaction_negative.png
similarity index 100%
rename from res/drawable-hdpi-v4/transaction_negative.png
rename to app/src/main/res/drawable-hdpi-v4/transaction_negative.png
diff --git res/drawable-hdpi-v4/transaction_positive.png app/src/main/res/drawable-hdpi-v4/transaction_positive.png
similarity index 100%
rename from res/drawable-hdpi-v4/transaction_positive.png
rename to app/src/main/res/drawable-hdpi-v4/transaction_positive.png
diff --git res/drawable-hdpi-v4/widget_large_balance_blurred.png app/src/main/res/drawable-hdpi-v4/widget_large_balance_blurred.png
similarity index 100%
rename from res/drawable-hdpi-v4/widget_large_balance_blurred.png
rename to app/src/main/res/drawable-hdpi-v4/widget_large_balance_blurred.png
diff --git res/drawable-hdpi-v4/widget_small_balance_blurred.png app/src/main/res/drawable-hdpi-v4/widget_small_balance_blurred.png
similarity index 100%
rename from res/drawable-hdpi-v4/widget_small_balance_blurred.png
rename to app/src/main/res/drawable-hdpi-v4/widget_small_balance_blurred.png
diff --git res/drawable-nodpi/lock.png app/src/main/res/drawable-nodpi/lock.png
similarity index 100%
rename from res/drawable-nodpi/lock.png
rename to app/src/main/res/drawable-nodpi/lock.png
diff --git res/drawable-xxhdpi/logo_bitcoin.png app/src/main/res/drawable-xxhdpi/logo_bitcoin.png
similarity index 100%
rename from res/drawable-xxhdpi/logo_bitcoin.png
rename to app/src/main/res/drawable-xxhdpi/logo_bitcoin.png
diff --git res/drawable-xxhdpi/logo_supremecard.png app/src/main/res/drawable-xxhdpi/logo_supremecard.png
similarity index 100%
rename from res/drawable-xxhdpi/logo_supremecard.png
rename to app/src/main/res/drawable-xxhdpi/logo_supremecard.png
diff --git res/drawable/applogo_ekonomipuls.png app/src/main/res/drawable/applogo_ekonomipuls.png
similarity index 100%
rename from res/drawable/applogo_ekonomipuls.png
rename to app/src/main/res/drawable/applogo_ekonomipuls.png
diff --git res/drawable/background_repeats.xml app/src/main/res/drawable/background_repeats.xml
similarity index 100%
rename from res/drawable/background_repeats.xml
rename to app/src/main/res/drawable/background_repeats.xml
diff --git res/drawable/btn_check.xml app/src/main/res/drawable/btn_check.xml
similarity index 100%
rename from res/drawable/btn_check.xml
rename to app/src/main/res/drawable/btn_check.xml
diff --git res/drawable/ic_btn_next.png app/src/main/res/drawable/ic_btn_next.png
similarity index 100%
rename from res/drawable/ic_btn_next.png
rename to app/src/main/res/drawable/ic_btn_next.png
diff --git res/drawable/ic_bullet_key_permission.png app/src/main/res/drawable/ic_bullet_key_permission.png
similarity index 100%
rename from res/drawable/ic_bullet_key_permission.png
rename to app/src/main/res/drawable/ic_bullet_key_permission.png
diff --git res/drawable/ic_menu_forward.png app/src/main/res/drawable/ic_menu_forward.png
similarity index 100%
rename from res/drawable/ic_menu_forward.png
rename to app/src/main/res/drawable/ic_menu_forward.png
diff --git res/drawable/ic_menu_info_details.png app/src/main/res/drawable/ic_menu_info_details.png
similarity index 100%
rename from res/drawable/ic_menu_info_details.png
rename to app/src/main/res/drawable/ic_menu_info_details.png
diff --git res/drawable/ic_menu_view.png app/src/main/res/drawable/ic_menu_view.png
similarity index 100%
rename from res/drawable/ic_menu_view.png
rename to app/src/main/res/drawable/ic_menu_view.png
diff --git res/drawable/icon.png app/src/main/res/drawable/icon.png
similarity index 100%
rename from res/drawable/icon.png
rename to app/src/main/res/drawable/icon.png
diff --git res/drawable/icon_large.png app/src/main/res/drawable/icon_large.png
similarity index 100%
rename from res/drawable/icon_large.png
rename to app/src/main/res/drawable/icon_large.png
diff --git res/drawable/indicator_input_error.png app/src/main/res/drawable/indicator_input_error.png
similarity index 100%
rename from res/drawable/indicator_input_error.png
rename to app/src/main/res/drawable/indicator_input_error.png
diff --git res/drawable/lock_anim.xml app/src/main/res/drawable/lock_anim.xml
similarity index 100%
rename from res/drawable/lock_anim.xml
rename to app/src/main/res/drawable/lock_anim.xml
diff --git res/drawable/lock_anim_00.png app/src/main/res/drawable/lock_anim_00.png
similarity index 100%
rename from res/drawable/lock_anim_00.png
rename to app/src/main/res/drawable/lock_anim_00.png
diff --git res/drawable/lock_anim_02.png app/src/main/res/drawable/lock_anim_02.png
similarity index 100%
rename from res/drawable/lock_anim_02.png
rename to app/src/main/res/drawable/lock_anim_02.png
diff --git res/drawable/lock_anim_04.png app/src/main/res/drawable/lock_anim_04.png
similarity index 100%
rename from res/drawable/lock_anim_04.png
rename to app/src/main/res/drawable/lock_anim_04.png
diff --git res/drawable/lock_anim_06.png app/src/main/res/drawable/lock_anim_06.png
similarity index 100%
rename from res/drawable/lock_anim_06.png
rename to app/src/main/res/drawable/lock_anim_06.png
diff --git res/drawable/lock_anim_08.png app/src/main/res/drawable/lock_anim_08.png
similarity index 100%
rename from res/drawable/lock_anim_08.png
rename to app/src/main/res/drawable/lock_anim_08.png
diff --git res/drawable/lock_anim_10.png app/src/main/res/drawable/lock_anim_10.png
similarity index 100%
rename from res/drawable/lock_anim_10.png
rename to app/src/main/res/drawable/lock_anim_10.png
diff --git res/drawable/lock_anim_12.png app/src/main/res/drawable/lock_anim_12.png
similarity index 100%
rename from res/drawable/lock_anim_12.png
rename to app/src/main/res/drawable/lock_anim_12.png
diff --git res/drawable/lock_anim_14.png app/src/main/res/drawable/lock_anim_14.png
similarity index 100%
rename from res/drawable/lock_anim_14.png
rename to app/src/main/res/drawable/lock_anim_14.png
diff --git res/drawable/logo_akeliusinvest.png app/src/main/res/drawable/logo_akeliusinvest.png
similarity index 100%
rename from res/drawable/logo_akeliusinvest.png
rename to app/src/main/res/drawable/logo_akeliusinvest.png
diff --git res/drawable/logo_akeliusspar.png app/src/main/res/drawable/logo_akeliusspar.png
similarity index 100%
rename from res/drawable/logo_akeliusspar.png
rename to app/src/main/res/drawable/logo_akeliusspar.png
diff --git res/drawable/logo_americanexpress.png app/src/main/res/drawable/logo_americanexpress.png
similarity index 100%
rename from res/drawable/logo_americanexpress.png
rename to app/src/main/res/drawable/logo_americanexpress.png
diff --git res/drawable/logo_appeakpoker.png app/src/main/res/drawable/logo_appeakpoker.png
similarity index 100%
rename from res/drawable/logo_appeakpoker.png
rename to app/src/main/res/drawable/logo_appeakpoker.png
diff --git res/drawable/logo_audi.png app/src/main/res/drawable/logo_audi.png
similarity index 100%
rename from res/drawable/logo_audi.png
rename to app/src/main/res/drawable/logo_audi.png
diff --git res/drawable/logo_avanza.png app/src/main/res/drawable/logo_avanza.png
similarity index 100%
rename from res/drawable/logo_avanza.png
rename to app/src/main/res/drawable/logo_avanza.png
diff --git res/drawable/logo_avanzamini.png app/src/main/res/drawable/logo_avanzamini.png
similarity index 100%
rename from res/drawable/logo_avanzamini.png
rename to app/src/main/res/drawable/logo_avanzamini.png
diff --git res/drawable/logo_betterglobe.png app/src/main/res/drawable/logo_betterglobe.png
similarity index 100%
rename from res/drawable/logo_betterglobe.png
rename to app/src/main/res/drawable/logo_betterglobe.png
diff --git res/drawable/logo_bioklubben.png app/src/main/res/drawable/logo_bioklubben.png
similarity index 100%
rename from res/drawable/logo_bioklubben.png
rename to app/src/main/res/drawable/logo_bioklubben.png
diff --git res/drawable/logo_brummer_kf.png app/src/main/res/drawable/logo_brummer_kf.png
similarity index 100%
rename from res/drawable/logo_brummer_kf.png
rename to app/src/main/res/drawable/logo_brummer_kf.png
diff --git res/drawable/logo_chalmrest.png app/src/main/res/drawable/logo_chalmrest.png
similarity index 100%
rename from res/drawable/logo_chalmrest.png
rename to app/src/main/res/drawable/logo_chalmrest.png
diff --git res/drawable/logo_chevrolet.png app/src/main/res/drawable/logo_chevrolet.png
similarity index 100%
rename from res/drawable/logo_chevrolet.png
rename to app/src/main/res/drawable/logo_chevrolet.png
diff --git res/drawable/logo_coop.png app/src/main/res/drawable/logo_coop.png
similarity index 100%
rename from res/drawable/logo_coop.png
rename to app/src/main/res/drawable/logo_coop.png
diff --git res/drawable/logo_csn.png app/src/main/res/drawable/logo_csn.png
similarity index 100%
rename from res/drawable/logo_csn.png
rename to app/src/main/res/drawable/logo_csn.png
diff --git res/drawable/logo_danskebank.png app/src/main/res/drawable/logo_danskebank.png
similarity index 100%
rename from res/drawable/logo_danskebank.png
rename to app/src/main/res/drawable/logo_danskebank.png
diff --git res/drawable/logo_dinersclub.png app/src/main/res/drawable/logo_dinersclub.png
similarity index 100%
rename from res/drawable/logo_dinersclub.png
rename to app/src/main/res/drawable/logo_dinersclub.png
diff --git res/drawable/logo_djurgarden.png app/src/main/res/drawable/logo_djurgarden.png
similarity index 100%
rename from res/drawable/logo_djurgarden.png
rename to app/src/main/res/drawable/logo_djurgarden.png
diff --git res/drawable/logo_easycard.png app/src/main/res/drawable/logo_easycard.png
similarity index 100%
rename from res/drawable/logo_easycard.png
rename to app/src/main/res/drawable/logo_easycard.png
diff --git res/drawable/logo_ebmaster.png app/src/main/res/drawable/logo_ebmaster.png
similarity index 100%
rename from res/drawable/logo_ebmaster.png
rename to app/src/main/res/drawable/logo_ebmaster.png
diff --git res/drawable/logo_ebmaster_dk.png app/src/main/res/drawable/logo_ebmaster_dk.png
similarity index 100%
rename from res/drawable/logo_ebmaster_dk.png
rename to app/src/main/res/drawable/logo_ebmaster_dk.png
diff --git res/drawable/logo_ebmaster_no.png app/src/main/res/drawable/logo_ebmaster_no.png
similarity index 100%
rename from res/drawable/logo_ebmaster_no.png
rename to app/src/main/res/drawable/logo_ebmaster_no.png
diff --git res/drawable/logo_eurocard.png app/src/main/res/drawable/logo_eurocard.png
similarity index 100%
rename from res/drawable/logo_eurocard.png
rename to app/src/main/res/drawable/logo_eurocard.png
diff --git res/drawable/logo_everydaycard.png app/src/main/res/drawable/logo_everydaycard.png
similarity index 100%
rename from res/drawable/logo_everydaycard.png
rename to app/src/main/res/drawable/logo_everydaycard.png
diff --git res/drawable/logo_firstcard.png app/src/main/res/drawable/logo_firstcard.png
similarity index 100%
rename from res/drawable/logo_firstcard.png
rename to app/src/main/res/drawable/logo_firstcard.png
diff --git res/drawable/logo_forex.png app/src/main/res/drawable/logo_forex.png
similarity index 100%
rename from res/drawable/logo_forex.png
rename to app/src/main/res/drawable/logo_forex.png
diff --git res/drawable/logo_handelsbanken.png app/src/main/res/drawable/logo_handelsbanken.png
similarity index 100%
rename from res/drawable/logo_handelsbanken.png
rename to app/src/main/res/drawable/logo_handelsbanken.png
diff --git res/drawable/logo_hemkop.png app/src/main/res/drawable/logo_hemkop.png
similarity index 100%
rename from res/drawable/logo_hemkop.png
rename to app/src/main/res/drawable/logo_hemkop.png
diff --git res/drawable/logo_ica.png app/src/main/res/drawable/logo_ica.png
similarity index 100%
rename from res/drawable/logo_ica.png
rename to app/src/main/res/drawable/logo_ica.png
diff --git res/drawable/logo_icabanken.png app/src/main/res/drawable/logo_icabanken.png
similarity index 100%
rename from res/drawable/logo_icabanken.png
rename to app/src/main/res/drawable/logo_icabanken.png
diff --git res/drawable/logo_ikanobank.png app/src/main/res/drawable/logo_ikanobank.png
similarity index 100%
rename from res/drawable/logo_ikanobank.png
rename to app/src/main/res/drawable/logo_ikanobank.png
diff --git res/drawable/logo_ikea.png app/src/main/res/drawable/logo_ikea.png
similarity index 100%
rename from res/drawable/logo_ikea.png
rename to app/src/main/res/drawable/logo_ikea.png
diff --git res/drawable/logo_jojo.png app/src/main/res/drawable/logo_jojo.png
similarity index 100%
rename from res/drawable/logo_jojo.png
rename to app/src/main/res/drawable/logo_jojo.png
diff --git res/drawable/logo_lansforsakringar.png app/src/main/res/drawable/logo_lansforsakringar.png
similarity index 100%
rename from res/drawable/logo_lansforsakringar.png
rename to app/src/main/res/drawable/logo_lansforsakringar.png
diff --git res/drawable/logo_marginalen.png app/src/main/res/drawable/logo_marginalen.png
similarity index 100%
rename from res/drawable/logo_marginalen.png
rename to app/src/main/res/drawable/logo_marginalen.png
diff --git res/drawable/logo_mcdonalds.png app/src/main/res/drawable/logo_mcdonalds.png
similarity index 100%
rename from res/drawable/logo_mcdonalds.png
rename to app/src/main/res/drawable/logo_mcdonalds.png
diff --git res/drawable/logo_meniga.png app/src/main/res/drawable/logo_meniga.png
similarity index 100%
rename from res/drawable/logo_meniga.png
rename to app/src/main/res/drawable/logo_meniga.png
diff --git res/drawable/logo_moneybookers.png app/src/main/res/drawable/logo_moneybookers.png
similarity index 100%
rename from res/drawable/logo_moneybookers.png
rename to app/src/main/res/drawable/logo_moneybookers.png
diff --git res/drawable/logo_nordea.png app/src/main/res/drawable/logo_nordea.png
similarity index 100%
rename from res/drawable/logo_nordea.png
rename to app/src/main/res/drawable/logo_nordea.png
diff --git res/drawable/logo_nordea_dk.png app/src/main/res/drawable/logo_nordea_dk.png
similarity index 100%
rename from res/drawable/logo_nordea_dk.png
rename to app/src/main/res/drawable/logo_nordea_dk.png
diff --git res/drawable/logo_nordnet.png app/src/main/res/drawable/logo_nordnet.png
similarity index 100%
rename from res/drawable/logo_nordnet.png
rename to app/src/main/res/drawable/logo_nordnet.png
diff --git res/drawable/logo_nordnetdirekt.png app/src/main/res/drawable/logo_nordnetdirekt.png
similarity index 100%
rename from res/drawable/logo_nordnetdirekt.png
rename to app/src/main/res/drawable/logo_nordnetdirekt.png
diff --git res/drawable/logo_okq8.png app/src/main/res/drawable/logo_okq8.png
similarity index 100%
rename from res/drawable/logo_okq8.png
rename to app/src/main/res/drawable/logo_okq8.png
diff --git res/drawable/logo_opel.png app/src/main/res/drawable/logo_opel.png
similarity index 100%
rename from res/drawable/logo_opel.png
rename to app/src/main/res/drawable/logo_opel.png
diff --git res/drawable/logo_osuuspankki.png app/src/main/res/drawable/logo_osuuspankki.png
similarity index 100%
rename from res/drawable/logo_osuuspankki.png
rename to app/src/main/res/drawable/logo_osuuspankki.png
diff --git res/drawable/logo_paypal.png app/src/main/res/drawable/logo_paypal.png
similarity index 100%
rename from res/drawable/logo_paypal.png
rename to app/src/main/res/drawable/logo_paypal.png
diff --git res/drawable/logo_payson.png app/src/main/res/drawable/logo_payson.png
similarity index 100%
rename from res/drawable/logo_payson.png
rename to app/src/main/res/drawable/logo_payson.png
diff --git res/drawable/logo_plusgirot.png app/src/main/res/drawable/logo_plusgirot.png
similarity index 100%
rename from res/drawable/logo_plusgirot.png
rename to app/src/main/res/drawable/logo_plusgirot.png
diff --git res/drawable/logo_preem.png app/src/main/res/drawable/logo_preem.png
similarity index 100%
rename from res/drawable/logo_preem.png
rename to app/src/main/res/drawable/logo_preem.png
diff --git res/drawable/logo_quintessentially.png app/src/main/res/drawable/logo_quintessentially.png
similarity index 100%
rename from res/drawable/logo_quintessentially.png
rename to app/src/main/res/drawable/logo_quintessentially.png
diff --git res/drawable/logo_resursbank.png app/src/main/res/drawable/logo_resursbank.png
similarity index 100%
rename from res/drawable/logo_resursbank.png
rename to app/src/main/res/drawable/logo_resursbank.png
diff --git res/drawable/logo_rikskortet.png app/src/main/res/drawable/logo_rikskortet.png
similarity index 100%
rename from res/drawable/logo_rikskortet.png
rename to app/src/main/res/drawable/logo_rikskortet.png
diff --git res/drawable/logo_rikslunchen.png app/src/main/res/drawable/logo_rikslunchen.png
similarity index 100%
rename from res/drawable/logo_rikslunchen.png
rename to app/src/main/res/drawable/logo_rikslunchen.png
diff --git res/drawable/logo_saab.png app/src/main/res/drawable/logo_saab.png
similarity index 100%
rename from res/drawable/logo_saab.png
rename to app/src/main/res/drawable/logo_saab.png
diff --git res/drawable/logo_seat.png app/src/main/res/drawable/logo_seat.png
similarity index 100%
rename from res/drawable/logo_seat.png
rename to app/src/main/res/drawable/logo_seat.png
diff --git res/drawable/logo_seb.png app/src/main/res/drawable/logo_seb.png
similarity index 100%
rename from res/drawable/logo_seb.png
rename to app/src/main/res/drawable/logo_seb.png
diff --git res/drawable/logo_sevenday.png app/src/main/res/drawable/logo_sevenday.png
similarity index 100%
rename from res/drawable/logo_sevenday.png
rename to app/src/main/res/drawable/logo_sevenday.png
diff --git res/drawable/logo_shell.png app/src/main/res/drawable/logo_shell.png
similarity index 100%
rename from res/drawable/logo_shell.png
rename to app/src/main/res/drawable/logo_shell.png
diff --git res/drawable/logo_sj_prio.png app/src/main/res/drawable/logo_sj_prio.png
similarity index 100%
rename from res/drawable/logo_sj_prio.png
rename to app/src/main/res/drawable/logo_sj_prio.png
diff --git res/drawable/logo_skandiabanken.png app/src/main/res/drawable/logo_skandiabanken.png
similarity index 100%
rename from res/drawable/logo_skandiabanken.png
rename to app/src/main/res/drawable/logo_skandiabanken.png
diff --git res/drawable/logo_skoda.png app/src/main/res/drawable/logo_skoda.png
similarity index 100%
rename from res/drawable/logo_skoda.png
rename to app/src/main/res/drawable/logo_skoda.png
diff --git res/drawable/logo_sparbanken_oresund.png app/src/main/res/drawable/logo_sparbanken_oresund.png
similarity index 100%
rename from res/drawable/logo_sparbanken_oresund.png
rename to app/src/main/res/drawable/logo_sparbanken_oresund.png
diff --git res/drawable/logo_sparbanken_syd.png app/src/main/res/drawable/logo_sparbanken_syd.png
similarity index 100%
rename from res/drawable/logo_sparbanken_syd.png
rename to app/src/main/res/drawable/logo_sparbanken_syd.png
diff --git res/drawable/logo_statoil.png app/src/main/res/drawable/logo_statoil.png
similarity index 100%
rename from res/drawable/logo_statoil.png
rename to app/src/main/res/drawable/logo_statoil.png
diff --git res/drawable/logo_steam.png app/src/main/res/drawable/logo_steam.png
similarity index 100%
rename from res/drawable/logo_steam.png
rename to app/src/main/res/drawable/logo_steam.png
diff --git res/drawable/logo_sveadirekt.png app/src/main/res/drawable/logo_sveadirekt.png
similarity index 100%
rename from res/drawable/logo_sveadirekt.png
rename to app/src/main/res/drawable/logo_sveadirekt.png
diff --git res/drawable/logo_svenskaspel.png app/src/main/res/drawable/logo_svenskaspel.png
similarity index 100%
rename from res/drawable/logo_svenskaspel.png
rename to app/src/main/res/drawable/logo_svenskaspel.png
diff --git res/drawable/logo_swedbank.png app/src/main/res/drawable/logo_swedbank.png
similarity index 100%
rename from res/drawable/logo_swedbank.png
rename to app/src/main/res/drawable/logo_swedbank.png
diff --git res/drawable/logo_trustbuddy.png app/src/main/res/drawable/logo_trustbuddy.png
similarity index 100%
rename from res/drawable/logo_trustbuddy.png
rename to app/src/main/res/drawable/logo_trustbuddy.png
diff --git res/drawable/logo_unknown_app.png app/src/main/res/drawable/logo_unknown_app.png
similarity index 100%
rename from res/drawable/logo_unknown_app.png
rename to app/src/main/res/drawable/logo_unknown_app.png
diff --git res/drawable/logo_vasttrafik.png app/src/main/res/drawable/logo_vasttrafik.png
similarity index 100%
rename from res/drawable/logo_vasttrafik.png
rename to app/src/main/res/drawable/logo_vasttrafik.png
diff --git res/drawable/logo_villabanken.png app/src/main/res/drawable/logo_villabanken.png
similarity index 100%
rename from res/drawable/logo_villabanken.png
rename to app/src/main/res/drawable/logo_villabanken.png
diff --git res/drawable/logo_volkswagen.png app/src/main/res/drawable/logo_volkswagen.png
similarity index 100%
rename from res/drawable/logo_volkswagen.png
rename to app/src/main/res/drawable/logo_volkswagen.png
diff --git res/drawable/logo_volvofinans.png app/src/main/res/drawable/logo_volvofinans.png
similarity index 100%
rename from res/drawable/logo_volvofinans.png
rename to app/src/main/res/drawable/logo_volvofinans.png
diff --git res/drawable/logo_wallet.png app/src/main/res/drawable/logo_wallet.png
similarity index 100%
rename from res/drawable/logo_wallet.png
rename to app/src/main/res/drawable/logo_wallet.png
diff --git res/drawable/logo_zidisha.png app/src/main/res/drawable/logo_zidisha.png
similarity index 100%
rename from res/drawable/logo_zidisha.png
rename to app/src/main/res/drawable/logo_zidisha.png
diff --git res/drawable/menu_button.xml app/src/main/res/drawable/menu_button.xml
similarity index 100%
rename from res/drawable/menu_button.xml
rename to app/src/main/res/drawable/menu_button.xml
diff --git res/drawable/popup_button.xml app/src/main/res/drawable/popup_button.xml
similarity index 100%
rename from res/drawable/popup_button.xml
rename to app/src/main/res/drawable/popup_button.xml
diff --git res/drawable/progress_horizontal.xml app/src/main/res/drawable/progress_horizontal.xml
similarity index 100%
rename from res/drawable/progress_horizontal.xml
rename to app/src/main/res/drawable/progress_horizontal.xml
diff --git res/drawable/title_background.xml app/src/main/res/drawable/title_background.xml
similarity index 100%
rename from res/drawable/title_background.xml
rename to app/src/main/res/drawable/title_background.xml
diff --git res/drawable/title_bar_medium.9.png app/src/main/res/drawable/title_bar_medium.9.png
similarity index 100%
rename from res/drawable/title_bar_medium.9.png
rename to app/src/main/res/drawable/title_bar_medium.9.png
diff --git res/drawable/title_item_background.xml app/src/main/res/drawable/title_item_background.xml
similarity index 100%
rename from res/drawable/title_item_background.xml
rename to app/src/main/res/drawable/title_item_background.xml
diff --git res/drawable/title_item_background_focused.xml app/src/main/res/drawable/title_item_background_focused.xml
similarity index 100%
rename from res/drawable/title_item_background_focused.xml
rename to app/src/main/res/drawable/title_item_background_focused.xml
diff --git res/drawable/title_logo.xml app/src/main/res/drawable/title_logo.xml
similarity index 100%
rename from res/drawable/title_logo.xml
rename to app/src/main/res/drawable/title_logo.xml
diff --git res/drawable/title_separator.xml app/src/main/res/drawable/title_separator.xml
similarity index 100%
rename from res/drawable/title_separator.xml
rename to app/src/main/res/drawable/title_separator.xml
diff --git res/drawable/widget_2x1.9.png app/src/main/res/drawable/widget_2x1.9.png
similarity index 100%
rename from res/drawable/widget_2x1.9.png
rename to app/src/main/res/drawable/widget_2x1.9.png
diff --git res/drawable/widget_4x1.png app/src/main/res/drawable/widget_4x1.png
similarity index 100%
rename from res/drawable/widget_4x1.png
rename to app/src/main/res/drawable/widget_4x1.png
diff --git res/drawable/widget_progress.xml app/src/main/res/drawable/widget_progress.xml
similarity index 100%
rename from res/drawable/widget_progress.xml
rename to app/src/main/res/drawable/widget_progress.xml
diff --git res/drawable/widget_progress_1.png app/src/main/res/drawable/widget_progress_1.png
similarity index 100%
rename from res/drawable/widget_progress_1.png
rename to app/src/main/res/drawable/widget_progress_1.png
diff --git res/drawable/widget_progress_2.png app/src/main/res/drawable/widget_progress_2.png
similarity index 100%
rename from res/drawable/widget_progress_2.png
rename to app/src/main/res/drawable/widget_progress_2.png
diff --git res/drawable/widget_progress_3.png app/src/main/res/drawable/widget_progress_3.png
similarity index 100%
rename from res/drawable/widget_progress_3.png
rename to app/src/main/res/drawable/widget_progress_3.png
diff --git res/drawable/widget_progress_4.png app/src/main/res/drawable/widget_progress_4.png
similarity index 100%
rename from res/drawable/widget_progress_4.png
rename to app/src/main/res/drawable/widget_progress_4.png
diff --git res/layout-land/choose_lock_pattern.xml app/src/main/res/layout-land/choose_lock_pattern.xml
similarity index 100%
rename from res/layout-land/choose_lock_pattern.xml
rename to app/src/main/res/layout-land/choose_lock_pattern.xml
diff --git res/layout-land/confirm_lock_pattern.xml app/src/main/res/layout-land/confirm_lock_pattern.xml
similarity index 100%
rename from res/layout-land/confirm_lock_pattern.xml
rename to app/src/main/res/layout-land/confirm_lock_pattern.xml
diff --git res/layout-land/dialog_color_picker.xml app/src/main/res/layout-land/dialog_color_picker.xml
similarity index 100%
rename from res/layout-land/dialog_color_picker.xml
rename to app/src/main/res/layout-land/dialog_color_picker.xml
diff --git res/layout/about.xml app/src/main/res/layout/about.xml
similarity index 100%
rename from res/layout/about.xml
rename to app/src/main/res/layout/about.xml
diff --git res/layout/bank.xml app/src/main/res/layout/bank.xml
similarity index 100%
rename from res/layout/bank.xml
rename to app/src/main/res/layout/bank.xml
diff --git res/layout/bank_spinner_dropdown_item.xml app/src/main/res/layout/bank_spinner_dropdown_item.xml
similarity index 100%
rename from res/layout/bank_spinner_dropdown_item.xml
rename to app/src/main/res/layout/bank_spinner_dropdown_item.xml
diff --git res/layout/bank_spinner_item.xml app/src/main/res/layout/bank_spinner_item.xml
similarity index 100%
rename from res/layout/bank_spinner_item.xml
rename to app/src/main/res/layout/bank_spinner_item.xml
diff --git res/layout/choose_lock_pattern.xml app/src/main/res/layout/choose_lock_pattern.xml
similarity index 100%
rename from res/layout/choose_lock_pattern.xml
rename to app/src/main/res/layout/choose_lock_pattern.xml
diff --git res/layout/choose_lock_pattern_example.xml app/src/main/res/layout/choose_lock_pattern_example.xml
similarity index 100%
rename from res/layout/choose_lock_pattern_example.xml
rename to app/src/main/res/layout/choose_lock_pattern_example.xml
diff --git res/layout/choose_lock_pattern_tutorial.xml app/src/main/res/layout/choose_lock_pattern_tutorial.xml
similarity index 100%
rename from res/layout/choose_lock_pattern_tutorial.xml
rename to app/src/main/res/layout/choose_lock_pattern_tutorial.xml
diff --git res/layout/confirm_lock_pattern.xml app/src/main/res/layout/confirm_lock_pattern.xml
similarity index 100%
rename from res/layout/confirm_lock_pattern.xml
rename to app/src/main/res/layout/confirm_lock_pattern.xml
diff --git res/layout/dialog_color_picker.xml app/src/main/res/layout/dialog_color_picker.xml
similarity index 100%
rename from res/layout/dialog_color_picker.xml
rename to app/src/main/res/layout/dialog_color_picker.xml
diff --git res/layout/empty.xml app/src/main/res/layout/empty.xml
similarity index 100%
rename from res/layout/empty.xml
rename to app/src/main/res/layout/empty.xml
diff --git res/layout/listitem_accounts_group.xml app/src/main/res/layout/listitem_accounts_group.xml
similarity index 100%
rename from res/layout/listitem_accounts_group.xml
rename to app/src/main/res/layout/listitem_accounts_group.xml
diff --git res/layout/listitem_accounts_item.xml app/src/main/res/layout/listitem_accounts_item.xml
similarity index 100%
rename from res/layout/listitem_accounts_item.xml
rename to app/src/main/res/layout/listitem_accounts_item.xml
diff --git res/layout/listitem_banks.xml app/src/main/res/layout/listitem_banks.xml
similarity index 100%
rename from res/layout/listitem_banks.xml
rename to app/src/main/res/layout/listitem_banks.xml
diff --git res/layout/main.xml app/src/main/res/layout/main.xml
similarity index 100%
rename from res/layout/main.xml
rename to app/src/main/res/layout/main.xml
diff --git res/layout/main_htc.xml app/src/main/res/layout/main_htc.xml
similarity index 100%
rename from res/layout/main_htc.xml
rename to app/src/main/res/layout/main_htc.xml
diff --git res/layout/pair_applications_layout.xml app/src/main/res/layout/pair_applications_layout.xml
similarity index 100%
rename from res/layout/pair_applications_layout.xml
rename to app/src/main/res/layout/pair_applications_layout.xml
diff --git res/layout/popup_account.xml app/src/main/res/layout/popup_account.xml
similarity index 100%
rename from res/layout/popup_account.xml
rename to app/src/main/res/layout/popup_account.xml
diff --git res/layout/popup_bank.xml app/src/main/res/layout/popup_bank.xml
similarity index 100%
rename from res/layout/popup_bank.xml
rename to app/src/main/res/layout/popup_bank.xml
diff --git res/layout/status_bar_latest_event_content.xml app/src/main/res/layout/status_bar_latest_event_content.xml
similarity index 100%
rename from res/layout/status_bar_latest_event_content.xml
rename to app/src/main/res/layout/status_bar_latest_event_content.xml
diff --git res/layout/title.xml app/src/main/res/layout/title.xml
similarity index 100%
rename from res/layout/title.xml
rename to app/src/main/res/layout/title.xml
diff --git res/layout/title_item.xml app/src/main/res/layout/title_item.xml
similarity index 100%
rename from res/layout/title_item.xml
rename to app/src/main/res/layout/title_item.xml
diff --git res/layout/transaction_date.xml app/src/main/res/layout/transaction_date.xml
similarity index 100%
rename from res/layout/transaction_date.xml
rename to app/src/main/res/layout/transaction_date.xml
diff --git res/layout/transaction_item.xml app/src/main/res/layout/transaction_item.xml
similarity index 100%
rename from res/layout/transaction_item.xml
rename to app/src/main/res/layout/transaction_item.xml
diff --git res/layout/transactions.xml app/src/main/res/layout/transactions.xml
similarity index 100%
rename from res/layout/transactions.xml
rename to app/src/main/res/layout/transactions.xml
diff --git res/layout/transactions_htc.xml app/src/main/res/layout/transactions_htc.xml
similarity index 100%
rename from res/layout/transactions_htc.xml
rename to app/src/main/res/layout/transactions_htc.xml
diff --git res/layout/webview.xml app/src/main/res/layout/webview.xml
similarity index 100%
rename from res/layout/webview.xml
rename to app/src/main/res/layout/webview.xml
diff --git res/layout/widget.xml app/src/main/res/layout/widget.xml
similarity index 100%
rename from res/layout/widget.xml
rename to app/src/main/res/layout/widget.xml
diff --git res/layout/widget_large.xml app/src/main/res/layout/widget_large.xml
similarity index 100%
rename from res/layout/widget_large.xml
rename to app/src/main/res/layout/widget_large.xml
diff --git res/layout/widget_large_transparent.xml app/src/main/res/layout/widget_large_transparent.xml
similarity index 100%
rename from res/layout/widget_large_transparent.xml
rename to app/src/main/res/layout/widget_large_transparent.xml
diff --git res/layout/widget_transparent.xml app/src/main/res/layout/widget_transparent.xml
similarity index 100%
rename from res/layout/widget_transparent.xml
rename to app/src/main/res/layout/widget_transparent.xml
diff --git res/menu-sv/menu.xml app/src/main/res/menu-sv/menu.xml
similarity index 100%
rename from res/menu-sv/menu.xml
rename to app/src/main/res/menu-sv/menu.xml
diff --git res/menu/menu.xml app/src/main/res/menu/menu.xml
similarity index 100%
rename from res/menu/menu.xml
rename to app/src/main/res/menu/menu.xml
diff --git res/raw/cert_akeliusinvest.pem app/src/main/res/raw/cert_akeliusinvest.pem
similarity index 100%
rename from res/raw/cert_akeliusinvest.pem
rename to app/src/main/res/raw/cert_akeliusinvest.pem
diff --git res/raw/cert_akeliusspar.pem app/src/main/res/raw/cert_akeliusspar.pem
similarity index 100%
rename from res/raw/cert_akeliusspar.pem
rename to app/src/main/res/raw/cert_akeliusspar.pem
diff --git res/raw/cert_americanexpress.pem app/src/main/res/raw/cert_americanexpress.pem
similarity index 100%
rename from res/raw/cert_americanexpress.pem
rename to app/src/main/res/raw/cert_americanexpress.pem
diff --git res/raw/cert_americanexpress_global.pem app/src/main/res/raw/cert_americanexpress_global.pem
similarity index 100%
rename from res/raw/cert_americanexpress_global.pem
rename to app/src/main/res/raw/cert_americanexpress_global.pem
diff --git res/raw/cert_avanza.pem app/src/main/res/raw/cert_avanza.pem
similarity index 100%
rename from res/raw/cert_avanza.pem
rename to app/src/main/res/raw/cert_avanza.pem
diff --git res/raw/cert_bioklubben.pem app/src/main/res/raw/cert_bioklubben.pem
similarity index 100%
rename from res/raw/cert_bioklubben.pem
rename to app/src/main/res/raw/cert_bioklubben.pem
diff --git res/raw/cert_brummer.pem app/src/main/res/raw/cert_brummer.pem
similarity index 100%
rename from res/raw/cert_brummer.pem
rename to app/src/main/res/raw/cert_brummer.pem
diff --git res/raw/cert_client_seb.p12 app/src/main/res/raw/cert_client_seb.p12
similarity index 100%
rename from res/raw/cert_client_seb.p12
rename to app/src/main/res/raw/cert_client_seb.p12
diff --git res/raw/cert_coop.pem app/src/main/res/raw/cert_coop.pem
similarity index 100%
rename from res/raw/cert_coop.pem
rename to app/src/main/res/raw/cert_coop.pem
diff --git res/raw/cert_csn.pem app/src/main/res/raw/cert_csn.pem
similarity index 100%
rename from res/raw/cert_csn.pem
rename to app/src/main/res/raw/cert_csn.pem
diff --git res/raw/cert_danskebank.pem app/src/main/res/raw/cert_danskebank.pem
similarity index 100%
rename from res/raw/cert_danskebank.pem
rename to app/src/main/res/raw/cert_danskebank.pem
diff --git res/raw/cert_dinersclub.pem app/src/main/res/raw/cert_dinersclub.pem
similarity index 100%
rename from res/raw/cert_dinersclub.pem
rename to app/src/main/res/raw/cert_dinersclub.pem
diff --git res/raw/cert_easycard.pem app/src/main/res/raw/cert_easycard.pem
similarity index 100%
rename from res/raw/cert_easycard.pem
rename to app/src/main/res/raw/cert_easycard.pem
diff --git res/raw/cert_eurocard.pem app/src/main/res/raw/cert_eurocard.pem
similarity index 100%
rename from res/raw/cert_eurocard.pem
rename to app/src/main/res/raw/cert_eurocard.pem
diff --git res/raw/cert_everydaycard.pem app/src/main/res/raw/cert_everydaycard.pem
similarity index 100%
rename from res/raw/cert_everydaycard.pem
rename to app/src/main/res/raw/cert_everydaycard.pem
diff --git res/raw/cert_firstcard.pem app/src/main/res/raw/cert_firstcard.pem
similarity index 100%
rename from res/raw/cert_firstcard.pem
rename to app/src/main/res/raw/cert_firstcard.pem
diff --git res/raw/cert_forexbank.pem app/src/main/res/raw/cert_forexbank.pem
similarity index 100%
rename from res/raw/cert_forexbank.pem
rename to app/src/main/res/raw/cert_forexbank.pem
diff --git res/raw/cert_handelsbanken.pem app/src/main/res/raw/cert_handelsbanken.pem
similarity index 100%
rename from res/raw/cert_handelsbanken.pem
rename to app/src/main/res/raw/cert_handelsbanken.pem
diff --git res/raw/cert_hemkop.pem app/src/main/res/raw/cert_hemkop.pem
similarity index 100%
rename from res/raw/cert_hemkop.pem
rename to app/src/main/res/raw/cert_hemkop.pem
diff --git res/raw/cert_ica.pem app/src/main/res/raw/cert_ica.pem
similarity index 100%
rename from res/raw/cert_ica.pem
rename to app/src/main/res/raw/cert_ica.pem
diff --git res/raw/cert_icabanken.pem app/src/main/res/raw/cert_icabanken.pem
similarity index 100%
rename from res/raw/cert_icabanken.pem
rename to app/src/main/res/raw/cert_icabanken.pem
diff --git res/raw/cert_icabanken2.pem app/src/main/res/raw/cert_icabanken2.pem
similarity index 100%
rename from res/raw/cert_icabanken2.pem
rename to app/src/main/res/raw/cert_icabanken2.pem
diff --git res/raw/cert_ikanobank.pem app/src/main/res/raw/cert_ikanobank.pem
similarity index 100%
rename from res/raw/cert_ikanobank.pem
rename to app/src/main/res/raw/cert_ikanobank.pem
diff --git res/raw/cert_ikanopartner.pem app/src/main/res/raw/cert_ikanopartner.pem
similarity index 100%
rename from res/raw/cert_ikanopartner.pem
rename to app/src/main/res/raw/cert_ikanopartner.pem
diff --git res/raw/cert_jojo.pem app/src/main/res/raw/cert_jojo.pem
similarity index 100%
rename from res/raw/cert_jojo.pem
rename to app/src/main/res/raw/cert_jojo.pem
diff --git res/raw/cert_lansforsakringar.pem app/src/main/res/raw/cert_lansforsakringar.pem
similarity index 100%
rename from res/raw/cert_lansforsakringar.pem
rename to app/src/main/res/raw/cert_lansforsakringar.pem
diff --git res/raw/cert_marginalen.pem app/src/main/res/raw/cert_marginalen.pem
similarity index 100%
rename from res/raw/cert_marginalen.pem
rename to app/src/main/res/raw/cert_marginalen.pem
diff --git res/raw/cert_meniga.pem app/src/main/res/raw/cert_meniga.pem
similarity index 100%
rename from res/raw/cert_meniga.pem
rename to app/src/main/res/raw/cert_meniga.pem
diff --git res/raw/cert_mobilbanken.pem app/src/main/res/raw/cert_mobilbanken.pem
similarity index 100%
rename from res/raw/cert_mobilbanken.pem
rename to app/src/main/res/raw/cert_mobilbanken.pem
diff --git res/raw/cert_nordea.pem app/src/main/res/raw/cert_nordea.pem
similarity index 100%
rename from res/raw/cert_nordea.pem
rename to app/src/main/res/raw/cert_nordea.pem
diff --git res/raw/cert_nordea_dk.pem app/src/main/res/raw/cert_nordea_dk.pem
similarity index 100%
rename from res/raw/cert_nordea_dk.pem
rename to app/src/main/res/raw/cert_nordea_dk.pem
diff --git res/raw/cert_nordnet.pem app/src/main/res/raw/cert_nordnet.pem
similarity index 100%
rename from res/raw/cert_nordnet.pem
rename to app/src/main/res/raw/cert_nordnet.pem
diff --git res/raw/cert_nordnetdirekt.pem app/src/main/res/raw/cert_nordnetdirekt.pem
similarity index 100%
rename from res/raw/cert_nordnetdirekt.pem
rename to app/src/main/res/raw/cert_nordnetdirekt.pem
diff --git res/raw/cert_okq8.pem app/src/main/res/raw/cert_okq8.pem
similarity index 100%
rename from res/raw/cert_okq8.pem
rename to app/src/main/res/raw/cert_okq8.pem
diff --git res/raw/cert_osuuspankki.pem app/src/main/res/raw/cert_osuuspankki.pem
similarity index 100%
rename from res/raw/cert_osuuspankki.pem
rename to app/src/main/res/raw/cert_osuuspankki.pem
diff --git res/raw/cert_osuuspankki_mobile.pem app/src/main/res/raw/cert_osuuspankki_mobile.pem
similarity index 100%
rename from res/raw/cert_osuuspankki_mobile.pem
rename to app/src/main/res/raw/cert_osuuspankki_mobile.pem
diff --git res/raw/cert_paypal.pem app/src/main/res/raw/cert_paypal.pem
similarity index 100%
rename from res/raw/cert_paypal.pem
rename to app/src/main/res/raw/cert_paypal.pem
diff --git res/raw/cert_paypal2.pem app/src/main/res/raw/cert_paypal2.pem
similarity index 100%
rename from res/raw/cert_paypal2.pem
rename to app/src/main/res/raw/cert_paypal2.pem
diff --git res/raw/cert_payson.pem app/src/main/res/raw/cert_payson.pem
similarity index 100%
rename from res/raw/cert_payson.pem
rename to app/src/main/res/raw/cert_payson.pem
diff --git res/raw/cert_plusgirot.pem app/src/main/res/raw/cert_plusgirot.pem
similarity index 100%
rename from res/raw/cert_plusgirot.pem
rename to app/src/main/res/raw/cert_plusgirot.pem
diff --git res/raw/cert_resursbank.pem app/src/main/res/raw/cert_resursbank.pem
similarity index 100%
rename from res/raw/cert_resursbank.pem
rename to app/src/main/res/raw/cert_resursbank.pem
diff --git res/raw/cert_rikslunchen.pem app/src/main/res/raw/cert_rikslunchen.pem
similarity index 100%
rename from res/raw/cert_rikslunchen.pem
rename to app/src/main/res/raw/cert_rikslunchen.pem
diff --git res/raw/cert_seb.pem app/src/main/res/raw/cert_seb.pem
similarity index 100%
rename from res/raw/cert_seb.pem
rename to app/src/main/res/raw/cert_seb.pem
diff --git res/raw/cert_seb_web.pem app/src/main/res/raw/cert_seb_web.pem
similarity index 100%
rename from res/raw/cert_seb_web.pem
rename to app/src/main/res/raw/cert_seb_web.pem
diff --git res/raw/cert_sebkort.pem app/src/main/res/raw/cert_sebkort.pem
similarity index 100%
rename from res/raw/cert_sebkort.pem
rename to app/src/main/res/raw/cert_sebkort.pem
diff --git res/raw/cert_sevenday.pem app/src/main/res/raw/cert_sevenday.pem
similarity index 100%
rename from res/raw/cert_sevenday.pem
rename to app/src/main/res/raw/cert_sevenday.pem
diff --git res/raw/cert_skandiabanken.pem app/src/main/res/raw/cert_skandiabanken.pem
similarity index 100%
rename from res/raw/cert_skandiabanken.pem
rename to app/src/main/res/raw/cert_skandiabanken.pem
diff --git res/raw/cert_steam.pem app/src/main/res/raw/cert_steam.pem
similarity index 100%
rename from res/raw/cert_steam.pem
rename to app/src/main/res/raw/cert_steam.pem
diff --git res/raw/cert_sveadirekt.pem app/src/main/res/raw/cert_sveadirekt.pem
similarity index 100%
rename from res/raw/cert_sveadirekt.pem
rename to app/src/main/res/raw/cert_sveadirekt.pem
diff --git res/raw/cert_svenskaspel.pem app/src/main/res/raw/cert_svenskaspel.pem
similarity index 100%
rename from res/raw/cert_svenskaspel.pem
rename to app/src/main/res/raw/cert_svenskaspel.pem
diff --git res/raw/cert_swedbank.pem app/src/main/res/raw/cert_swedbank.pem
similarity index 100%
rename from res/raw/cert_swedbank.pem
rename to app/src/main/res/raw/cert_swedbank.pem
diff --git res/raw/cert_ticketrikskortet.pem app/src/main/res/raw/cert_ticketrikskortet.pem
similarity index 100%
rename from res/raw/cert_ticketrikskortet.pem
rename to app/src/main/res/raw/cert_ticketrikskortet.pem
diff --git res/raw/cert_trustbuddy.pem app/src/main/res/raw/cert_trustbuddy.pem
similarity index 100%
rename from res/raw/cert_trustbuddy.pem
rename to app/src/main/res/raw/cert_trustbuddy.pem
diff --git res/raw/cert_vasttrafik.pem app/src/main/res/raw/cert_vasttrafik.pem
similarity index 100%
rename from res/raw/cert_vasttrafik.pem
rename to app/src/main/res/raw/cert_vasttrafik.pem
diff --git res/raw/cert_villabanken.pem app/src/main/res/raw/cert_villabanken.pem
similarity index 100%
rename from res/raw/cert_villabanken.pem
rename to app/src/main/res/raw/cert_villabanken.pem
diff --git res/raw/cert_volvofinans.pem app/src/main/res/raw/cert_volvofinans.pem
similarity index 100%
rename from res/raw/cert_volvofinans.pem
rename to app/src/main/res/raw/cert_volvofinans.pem
diff --git res/raw/cert_volvofinans_logged_in.pem app/src/main/res/raw/cert_volvofinans_logged_in.pem
similarity index 100%
rename from res/raw/cert_volvofinans_logged_in.pem
rename to app/src/main/res/raw/cert_volvofinans_logged_in.pem
diff --git res/raw/cert_zidisha.pem app/src/main/res/raw/cert_zidisha.pem
similarity index 100%
rename from res/raw/cert_zidisha.pem
rename to app/src/main/res/raw/cert_zidisha.pem
diff --git res/raw/loading.html app/src/main/res/raw/loading.html
similarity index 100%
rename from res/raw/loading.html
rename to app/src/main/res/raw/loading.html
diff --git res/raw/swedbank_transactions.htm app/src/main/res/raw/swedbank_transactions.htm
similarity index 100%
rename from res/raw/swedbank_transactions.htm
rename to app/src/main/res/raw/swedbank_transactions.htm
diff --git res/values-sv/array.xml app/src/main/res/values-sv/array.xml
similarity index 100%
rename from res/values-sv/array.xml
rename to app/src/main/res/values-sv/array.xml
diff --git res/values-sv/strings.xml app/src/main/res/values-sv/strings.xml
similarity index 100%
rename from res/values-sv/strings.xml
rename to app/src/main/res/values-sv/strings.xml
diff --git res/values/array.xml app/src/main/res/values/array.xml
similarity index 100%
rename from res/values/array.xml
rename to app/src/main/res/values/array.xml
diff --git res/values/colors.xml app/src/main/res/values/colors.xml
similarity index 100%
rename from res/values/colors.xml
rename to app/src/main/res/values/colors.xml
diff --git res/values/config.xml app/src/main/res/values/config.xml
similarity index 100%
rename from res/values/config.xml
rename to app/src/main/res/values/config.xml
diff --git res/values/strings.xml app/src/main/res/values/strings.xml
similarity index 100%
rename from res/values/strings.xml
rename to app/src/main/res/values/strings.xml
diff --git res/values/styles.xml app/src/main/res/values/styles.xml
similarity index 100%
rename from res/values/styles.xml
rename to app/src/main/res/values/styles.xml
diff --git res/values/themes.xml app/src/main/res/values/themes.xml
similarity index 100%
rename from res/values/themes.xml
rename to app/src/main/res/values/themes.xml
diff --git res/xml/appwidget_info.xml app/src/main/res/xml/appwidget_info.xml
similarity index 100%
rename from res/xml/appwidget_info.xml
rename to app/src/main/res/xml/appwidget_info.xml
diff --git res/xml/appwidget_info_large.xml app/src/main/res/xml/appwidget_info_large.xml
similarity index 100%
rename from res/xml/appwidget_info_large.xml
rename to app/src/main/res/xml/appwidget_info_large.xml
diff --git res/xml/settings.xml app/src/main/res/xml/settings.xml
similarity index 100%
rename from res/xml/settings.xml
rename to app/src/main/res/xml/settings.xml
diff --git btn_check.psd assets/btn_check.psd
similarity index 100%
rename from btn_check.psd
rename to assets/btn_check.psd
diff --git icabanken.psd assets/icabanken.psd
similarity index 100%
rename from icabanken.psd
rename to assets/icabanken.psd
diff --git logo_unknown_app.svg assets/logo_unknown_app.svg
similarity index 100%
rename from logo_unknown_app.svg
rename to assets/logo_unknown_app.svg
diff --git logos.psd assets/logos.psd
similarity index 100%
rename from logos.psd
rename to assets/logos.psd
diff --git villabanken.psd assets/villabanken.psd
similarity index 100%
rename from villabanken.psd
rename to assets/villabanken.psd
diff --git widgets.psd assets/widgets.psd
similarity index 100%
rename from widgets.psd
rename to assets/widgets.psd
diff --git build.gradle build.gradle
index e7bed6a..aadd3db 100644
--- build.gradle
+++ build.gradle
@@ -1,89 +1,19 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
 buildscript {
     repositories {
         mavenCentral()
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.11.+'
-    }
-}
-apply plugin: 'android'
 
-repositories {
-    mavenCentral()
-}
-
-dependencies {
-    compile 'org.apache.commons:commons-io:1.3.2'
-    compile 'com.google.collections:google-collections:1.0'
-    compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
-    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
-    compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
-    compile 'org.jsoup:jsoup:1.7.3'
-    compile('org.simpleframework:simple-xml:2.7.+') {
-        exclude module: 'stax'
-        exclude module: 'stax-api'
-        exclude module: 'xpp3'
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
     }
 }
 
-tasks.withType(Compile) {
-    options.encoding = "UTF-8"
-}
-
-android {
-    compileSdkVersion 17
-    buildToolsVersion "17.0.0"
-
-    defaultConfig {
-        versionCode 188
-        versionName '1.9.6.15'
-        minSdkVersion 7
-        targetSdkVersion 10
-        packageName 'com.liato.bankdroid'
-    }
-
-    sourceSets {
-        main {
-            manifest.srcFile 'AndroidManifest.xml'
-            java.srcDirs = ['src']
-            resources.srcDirs = ['src']
-            aidl.srcDirs = ['src']
-            renderscript.srcDirs = ['src']
-            res.srcDirs = ['res']
-            assets.srcDirs = ['assets']
-        }
-
-        instrumentTest.setRoot('tests')
-    }
-
-    final Console console = System.console();
-    if (console != null) {
-
-        // Building from console
-        signingConfigs {
-            release {
-                storeFile file("release.keystore")
-                storePassword console.readLine("\nEnter keystore password: ")
-                keyAlias "andmrkt"
-                keyPassword console.readLine("Enter key password: ")
-            }
-        }
-
-    } else {
-
-        // Building from IDE
-        signingConfigs {
-            release {
-
-            }
-        }
-
-    }
-
-
-    buildTypes {
-        release {
-            signingConfig signingConfigs.release
-        }
+allprojects {
+    repositories {
+        mavenCentral()
     }
 }
diff --git gradle.properties gradle.properties
new file mode 100644
index 0000000..5d08ba7
--- /dev/null
+++ gradle.properties
@@ -0,0 +1,18 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Settings specified in this file will override any Gradle settings
+# configured through the IDE.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
\ No newline at end of file
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index c5495d5..5de946b 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Jun 25 22:50:45 CEST 2014
+#Wed Apr 10 15:27:10 PDT 2013
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git project.properties project.properties
deleted file mode 100644
index fd44ee5..0000000
--- project.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Indicates whether an apk should be generated for each density.
-split.density=false
-# Project target.
-target=android-17
diff --git settings.gradle settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ settings.gradle
@@ -0,0 +1 @@
+include ':app'

commit f4201cfeedbf33c6e2ed45a4b3a2de243690e39e
Author: liato <x@x00.us>
Date:   Wed Jun 25 22:56:48 2014 +0200

    Update gradle wrapper url.

diff --git build.gradle build.gradle
index 1fe360e..e7bed6a 100644
--- build.gradle
+++ build.gradle
@@ -3,7 +3,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.7.+'
+        classpath 'com.android.tools.build:gradle:0.11.+'
     }
 }
 apply plugin: 'android'
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index f3c40e0..c5495d5 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Jan 12 21:49:53 CET 2014
+#Wed Jun 25 22:50:45 CEST 2014
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-all.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip

commit 129ee1076af42b892651d2d05ec6c704e650546d
Author: liato <x@x00.us>
Date:   Sat Jun 7 01:30:44 2014 +0200

    Bump version. v1.9.6.15

diff --git AndroidManifest.xml AndroidManifest.xml
index e153f56..8b5b626 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.15-RC3" android:versionCode="187">
+	android:versionName="1.9.6.15" android:versionCode="188">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index 5582929..5c81f32 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,12 @@
+v1.9.6.15: (2014-06-07)
+* Fix for Coop MedMedmera Visa and Coop Kort
+* Updated SSL certificate for SEB cards (SAS Eurobonus, SJPrio, Statoil and more)
+* Allow all characters when entering username for PlusGirot
+* Updated SevenDay SSL certificate
+* Improvements to ResursBank
+* Login fix for Ikano Partner cards (Ikea, Preem, Shell, Skoda and more)
+
+
 v1.9.6.14: (2014-05-13)
 * Fix for ICA Banken
 * Fix for Payson
diff --git build.gradle build.gradle
index aef019e..1fe360e 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 187
-        versionName '1.9.6.15-RC3'
+        versionCode 188
+        versionName '1.9.6.15'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 1bf421c06bea929fcdc1db69cc82fdf98148cd34
Author: liato <x@x00.us>
Date:   Fri Jun 6 23:14:18 2014 +0200

    Update SEB kort certificate.

diff --git res/raw/cert_sebkort.pem res/raw/cert_sebkort.pem
index 3c36878..fc83a60 100644
--- res/raw/cert_sebkort.pem
+++ res/raw/cert_sebkort.pem
@@ -1,35 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIGATCCBOmgAwIBAgIQepNmMtz4xl/eNW5BjwmTQTANBgkqhkiG9w0BAQUFADCB
+MIIFxzCCBK+gAwIBAgIQV2JeBtshjDgGTfGDa62l7zANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew

-wka6NGg=

 -----END CERTIFICATE-----

commit 9f3520b7c93ddbfda3b39dfc45cac5470d901381
Author: liato <x@x00.us>
Date:   Fri Jun 6 23:09:41 2014 +0200

    Allow all characters for username for plusgirot.

diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java src/com/liato/bankdroid/banking/banks/PlusGirot.java
index 2b6b026..de3ae82 100644
--- src/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ src/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -49,8 +49,7 @@ public class PlusGirot extends Bank {
 	private static final String NAME_SHORT = "plusgirot";
 	private static final String URL = "https://kontoutdrag.plusgirot.se/";
 	private static final int BANKTYPE_ID = IBankTypes.PLUSGIROT;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-	
+
     private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+><font[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</f", Pattern.CASE_INSENSITIVE);
 	private String response = null;
@@ -62,7 +61,6 @@ public class PlusGirot extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public PlusGirot(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {

commit d621db23ab5fcdb0119ddd44968eedbbf7f5c653
Author: liato <x@x00.us>
Date:   Sun Jun 1 23:47:46 2014 +0200

    Update Rikslunchen certificate.

diff --git res/raw/cert_rikslunchen.pem res/raw/cert_rikslunchen.pem
index 0b0ef83..c8c035b 100644
--- res/raw/cert_rikslunchen.pem
+++ res/raw/cert_rikslunchen.pem
@@ -1,28 +1,30 @@
 -----BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIDBlDHMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
+MIIFNjCCBB6gAwIBAgIDEsfnMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
 MRcwFQYDVQQKEw5HZW9UcnVzdCwgSW5jLjEUMBIGA1UEAxMLUmFwaWRTU0wgQ0Ew
-HhcNMTIwNTAxMTEyMjA5WhcNMTYwNTAyMjMzNTU2WjCBvzEpMCcGA1UEBRMgUzAx
-elZOSWd6YW1lMWQveFhubXFITzJUaTVOU1JpME0xEzARBgNVBAsTCkdUMDA5OTk1
+HhcNMTQwNTEzMDAyODEwWhcNMTYwNTAzMTY1MTE2WjCBvzEpMCcGA1UEBRMgU2dB
+N2NWOFdSU2FZWHJFTTBqbUROT051dHRIY1RXcWkxEzARBgNVBAsTCkdUMDA5OTk1
 NTAxMTAvBgNVBAsTKFNlZSB3d3cucmFwaWRzc2wuY29tL3Jlc291cmNlcy9jcHMg
 KGMpMTIxLzAtBgNVBAsTJkRvbWFpbiBDb250cm9sIFZhbGlkYXRlZCAtIFJhcGlk
 U1NMKFIpMRkwFwYDVQQDDBAqLnJpa3NsdW5jaGVuLnNlMIIBIjANBgkqhkiG9w0B

 HwYDVR0jBBgwFoAUa2k9ahhCSt2PAmU5/TUkhniRFjAwDgYDVR0PAQH/BAQDAgWg
 MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjArBgNVHREEJDAighAqLnJp
 a3NsdW5jaGVuLnNlgg5yaWtzbHVuY2hlbi5zZTBDBgNVHR8EPDA6MDigNqA0hjJo
 dHRwOi8vcmFwaWRzc2wtY3JsLmdlb3RydXN0LmNvbS9jcmxzL3JhcGlkc3NsLmNy

-94VaODj3eZ9v1Tguxg==

+UU9mph83MDGlCY1EwuHPGorjoqGjYjXl/63EOvKmXEKYMCd6fb4Dfq2F
 -----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 26a2383..6003b70 100644
--- src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -29,32 +29,15 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.CookieStore;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.cookie.Cookie;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.BasicCookieStore;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
 import org.simpleframework.xml.Serializer;
 import org.simpleframework.xml.core.Persister;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -125,10 +108,13 @@ public class Rikslunchen extends Bank {
             accounts.add(new Account("Rikslunchen", balance, "1"));
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
+            throw new BankException(e.getMessage());
         } catch (ClientProtocolException e) {
             e.printStackTrace();
+            throw new BankException(e.getMessage());
         } catch (IOException e) {
             e.printStackTrace();
+            throw new BankException(e.getMessage());
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found)

commit 8037e8a1a97fe4577ff5e4c7a696df14b60b86b1
Author: liato <x@x00.us>
Date:   Sun Jun 1 23:37:51 2014 +0200

    Update SevenDay certificate.

diff --git res/raw/cert_sevenday.pem res/raw/cert_sevenday.pem
index 0a233b5..89a213c 100644
--- res/raw/cert_sevenday.pem
+++ res/raw/cert_sevenday.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQF7xPHP7AujQPIPj8UKmd6jANBgkqhkiG9w0BAQUFADA8
+MIIEkjCCA3qgAwIBAgIQNHl5jjaIHqGW09M+de7GxDANBgkqhkiG9w0BAQUFADA8
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMuMRYwFAYDVQQDEw1U
-aGF3dGUgU1NMIENBMB4XDTEzMDkxMDAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
+aGF3dGUgU1NMIENBMB4XDTE0MDQxNTAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
 MAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9sbTEOMAwGA1UEBxQFS2lzdGEx
 GzAZBgNVBAoUElNldmVuRGF5IEZpbmFucyBBQjEWMBQGA1UEAxQNKi5zZXZlbmRh

 VR0TBAIwADBCBgNVHSAEOzA5MDcGCmCGSAGG+EUBBzYwKTAnBggrBgEFBQcCARYb
 aHR0cHM6Ly93d3cudGhhd3RlLmNvbS9jcHMvMA4GA1UdDwEB/wQEAwIFoDAfBgNV
 HSMEGDAWgBSnooO7NEVAPfzVME8SuT6hAZ/22zA6BgNVHR8EMzAxMC+gLaArhilo
@@ -18,10 +18,10 @@ dHRwOi8vc3ZyLW92LWNybC50aGF3dGUuY29tL1RoYXd0ZU9WLmNybDAdBgNVHSUE
 FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwaQYIKwYBBQUHAQEEXTBbMCIGCCsGAQUF
 BzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDUGCCsGAQUFBzAChilodHRwOi8v
 c3ZyLW92LWFpYS50aGF3dGUuY29tL1RoYXd0ZU9WLmNlcjANBgkqhkiG9w0BAQUF
-AAOCAQEAElhvDbODrkiNm+RiwpfgLTFc0RiEq/mw0rCU04b1j0JSOhK8ImGYLZEN
-GmUSjuJ7x05T3wYcnkXhyWwntkdUed0cFLkuuHohHFdvuPg/0SYw+n/lgPrIXh0V
-BadG1CjnmX3qhdgoTWEvynXJFf3vck9Dx2scxfwJZ7BoUzEraoZ1i0ZJ/2p5pp11
-w+vx95m1/eMdmaikt2wZGDzOyl0LAP7wREDYMs4HkvNGzZxnDoylLZ+45qEuRhnj
-Xg18o4qqK0PxQademqQCMgGZA/YHEPhowSNz20Fd0QlQ3b0XPQiM5L4/Pj5f3/w0
-PV2hZ7XKpVDd+Q41irJ0O6JluWFl8A==
+AAOCAQEAfxEugYbMxBESO8rPkO7SJoquhqdl++OClvSLYdIq8JGfiBc0otayEMBS
+ooEIjwOY3z2dpra7I9ZOSVprv02egTGNR2cW55QRAs+qQLqzxGI5lj+1RHgcJZHo
+g3ZFoqNEnh2u5hfCtf+cS2hH1VUPxp9Ml09Nk/mLK2WK/xv4yEfQDqANZut4oboB
+wsygjnnUpRyGbrxeY29w6TfChOQwb+7vxxCgRPJBrDTGdJmZ6rhE+ZrSNqcCd1ra
+vB8pWPwNeaFHRPrYrlzUXfkS0xak7GFCU+WW4qPG73VLdPnh/GcidtSjDSZKGSkv
+ETEyMuB5fsINZXXfHm6F2x4e0+b8aQ==
 -----END CERTIFICATE-----

commit 6120b82add66b8bf5815dc6857b5126ee9e394a1
Author: liato <x@x00.us>
Date:   Sun Jun 1 23:35:37 2014 +0200

    Ignore Coop transactions without dates.

diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
index 1f226b8..72133f7 100644
--- src/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -350,7 +350,9 @@ public class Coop extends Bank {
                     if (!TextUtils.isEmpty(r.getCardholder())) {
                         title.append(" (").append(r.getCardholder()).append(")");
                     }
-                    transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
+                    if (r.getDate() != null) {
+                        transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
+                    }
                 }
             }
         } catch (UnsupportedEncodingException e) {

commit 0ab930f88b21cf0f4fc50be098a52fd6567a280e
Author: liato <x@x00.us>
Date:   Wed Jun 25 23:01:50 2014 +0200

    Support for client certs. Some work on SEB api.

diff --git res/raw/cert_client_seb.p12 res/raw/cert_client_seb.p12
new file mode 100644
index 0000000..f12d074
Binary files /dev/null and res/raw/cert_client_seb.p12 differ
diff --git res/raw/cert_seb.pem res/raw/cert_seb.pem
index 15c1a40..f866163 100644
--- res/raw/cert_seb.pem
+++ res/raw/cert_seb.pem
@@ -1,30 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIFKTCCBBGgAwIBAgIQMVXtCg4RnD0vL5LDol7aQzANBgkqhkiG9w0BAQUFADCB
-vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
+MIIFvTCCBKWgAwIBAgIQBKeUVwqPLFPhfB2jrQG16DANBgkqhkiG9w0BAQUFADCB
+vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug

-cgz4UMS+A3qV9vPIs0HH5WQ8wkpYjv85ju7492w=

+YzLm2CrBWbKi6C2uth4xbS4cldJHWWSCimVXLC8xhKzl
 -----END CERTIFICATE-----
diff --git res/raw/cert_seb.pem res/raw/cert_seb_web.pem
similarity index 100%
copy from res/raw/cert_seb.pem
copy to res/raw/cert_seb_web.pem
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 0a01da4..73cf7a4 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -63,7 +63,7 @@ import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.SEB;
+import com.liato.bankdroid.banking.banks.seb.SEB;
 import com.liato.bankdroid.banking.banks.SJPrio;
 import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.Seat;
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
deleted file mode 100644
index 64d7e61..0000000
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class SEB extends Bank {
-	private static final String TAG = "SEB";
-	private static final String NAME = "SEB";
-	private static final String NAME_SHORT = "seb";
-	private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx";
-	private static final int BANKTYPE_ID = IBankTypes.SEB;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-	
-	private Pattern reAccounts = Pattern.compile("/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
-	
-	private String response = null;
-
-	public SEB(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public SEB(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_seb));
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        urlopen.addHeader("Referer", "https://m.seb.se/");
-        urlopen.setKeepAliveTimeout(5);
-        //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("A1", username));
-        postData.add(new BasicNameValuePair("A2", password));
-        postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
-    }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("elaktig inloggning")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen = login();
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=digipassAppl1");
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: ID                    GJmQRqlrOPmM++1zf50d6Q==
-                 * 2: Name                  Personkonto
-                 * 3: Amount                2.208,03
-                 * 
-                 */   			    
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		finally {
-		    super.updateComplete();
-		}
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-
-		//No transaction history for loans, funds and credit cards.
-		int accType = account.getType();
-		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
-
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1102.aspx?M1=show&P2=1&P4=1&P1=" + account.getId());
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Book. date            101214
-                 * 2: Transaction           St1
-                 * 3: Trans. date           10-12-11
-                 * 4: Amount                -200,07  
-                 * 
-                 */
-			    String date;
-			    if (matcher.group(3) == null || matcher.group(3).length() == 0) {
-			        date = Html.fromHtml(matcher.group(1)).toString().trim();
-			        date = String.format("%s-%s-%s", date.substring(0,2), date.substring(2,4), date.substring(4,6));
-			    }
-			    else {
-			        date = Html.fromHtml(matcher.group(3)).toString().trim();
-			    }
-				transactions.add(new Transaction("20"+date, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4))));
-			}
-			Collections.sort(transactions, Collections.reverseOrder());
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}	
-}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/seb/SEB.java src/com/liato/bankdroid/banking/banks/seb/SEB.java
new file mode 100644
index 0000000..5042a9b
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/SEB.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.seb;
+
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.seb.model.DEVID;
+import com.liato.bankdroid.banking.banks.seb.model.HWINFO;
+import com.liato.bankdroid.banking.banks.seb.model.Request;
+import com.liato.bankdroid.banking.banks.seb.model.SEBRequest;
+import com.liato.bankdroid.banking.banks.seb.model.ServiceInput;
+import com.liato.bankdroid.banking.banks.seb.model.UserCredentials;
+import com.liato.bankdroid.banking.banks.seb.model.VODB;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class SEB extends Bank {
+    private static final String TAG = "SEB";
+    private static final String NAME = "SEB";
+    private static final String NAME_SHORT = "seb";
+    private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx";
+    private static final int BANKTYPE_ID = IBankTypes.SEB;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
+    private Pattern reAccounts = Pattern.compile("/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+    private ObjectMapper mObjectMapper;
+
+    public SEB(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public SEB(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_seb_web));
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        urlopen.addHeader("Referer", "https://m.seb.se/");
+        urlopen.setKeepAliveTimeout(5);
+        //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("A1", username));
+        postData.add(new BasicNameValuePair("A2", password));
+        postData.add(new BasicNameValuePair("A3", "4"));
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            urlopen = new Urllib(context, CertificateReader.getClientCertificate(context, R.raw.cert_client_seb, "openbankdata"), CertificateReader.getCertificates(context, R.raw.cert_seb));
+            urlopen.setFollowRedirects(false);
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            postData.add(new BasicNameValuePair("A1", username));
+            postData.add(new BasicNameValuePair("A2", password));
+            HttpResponse hr = urlopen.openAsHttpResponse("https://mP.seb.se/nauth2/Authentication/Auth?SEB_Referer=/priv/ServiceFactory-pw", postData, true);
+            if (hr.getStatusLine().getStatusCode() == 200) {
+                throw new LoginException(res.getString(R.string.invalid_username_password));
+            } else if (hr.getStatusLine().getStatusCode() != 302) {
+                throw new BankException(res.getString(R.string.unable_to_login));
+            }
+            urlopen.setFollowRedirects(true);
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
+        urlopen.addHeader("Accept", "application/json");
+
+        SEBRequest sessionRequest = new SEBRequest();
+        Request r = new Request();
+        r.setUserCredentials(new UserCredentials(username, password));
+        ServiceInput serviceInput = new ServiceInput();
+        serviceInput.setCondition("EQ");
+        serviceInput.setVariableName("CUSTOMERTYPE");
+        serviceInput.setVariableValue("P");
+        r.getServiceInput().add(serviceInput);
+        VODB vodb = new VODB();
+        vodb.setHWINFO01(HWINFO.createDefault());
+        vodb.setDEVID01(DEVID.createDefault());
+        r.setVODB(vodb);
+        sessionRequest.setRequest(r);
+
+        try {
+            HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(sessionRequest));
+            HttpResponse hr = urlopen.openAsHttpResponse("https://mP.seb.se/1000/ServiceFactory/PC_BANK/PC_BankAktivera01Session01.asmx/Execute", e, true);
+            hr.getEntity().getContent();
+
+        } catch (UnsupportedEncodingException e1) {
+            e1.printStackTrace();
+        } catch (JsonProcessingException e1) {
+            e1.printStackTrace();
+        } catch (ClientProtocolException e1) {
+            e1.printStackTrace();
+        } catch (IOException e1) {
+            e1.printStackTrace();
+        }
+
+
+//        {
+//            "request": {
+//            "ResultInfo": null,
+//                    "VODB": {
+//                "USRINF01": null,
+//                        "DBZV160": [],
+//                "DEVID01": {
+//                    "APPLICATION_VERSION": "6.0.0",
+//                            "OS_NAME": "Android",
+//                            "MODEL": "4S",
+//                            "MANUFACTURER": "Apple",
+//                            "OS_VERSION": "5",
+//                            "APPLICATION_NAME": "MASP"
+//                },
+//                "HWINFO01": {
+//                    "LONGITUDE_DECIMAL": "0",
+//                            "LATITUDE_DECIMAL": "0",
+//                            "COUNTRY_PREFIX": 0
+//                },
+//                "CBEW501": [],
+//                "DBZV170": [],
+//                "CBEW502": []
+//            },
+//            "ServiceInput": [{
+//                "Condition": "EQ",
+//                        "VariableNamePossibleValues": [],
+//                "VariableName": "CUSTOMERTYPE",
+//                        "VariableValue": "P"
+//            }],
+//            "UserCredentials": {
+//                "ApplicationName": "RFO",
+//                        "WorkstationID": "",
+//                        "LoggedOnUser": "Mobile",
+//                        "AuthMethod": "0",
+//                        "UserId": "8001019999",
+//                        "Password": "123password"
+//            },
+//            "ServiceInfo": null
+//        }
+//        }
+
+        Log.d("SEB", "Logged in");
+//        Matcher matcher;
+//        try {
+//            response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=digipassAppl1");
+//            matcher = reAccounts.matcher(response);
+//            while (matcher.find()) {
+//                /*
+//                 * Capture groups:
+//                 * GROUP                    EXAMPLE DATA
+//                 * 1: ID                    GJmQRqlrOPmM++1zf50d6Q==
+//                 * 2: Name                  Personkonto
+//                 * 3: Amount                2.208,03
+//                 *
+//                 */
+//                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+//                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+//            }
+//
+//            if (accounts.isEmpty()) {
+//                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+//            }
+//        }
+//        catch (ClientProtocolException e) {
+//            throw new BankException(e.getMessage());
+//        }
+//        catch (IOException e) {
+//            throw new BankException(e.getMessage());
+//        }
+//        finally {
+//            super.updateComplete();
+//        }
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        //No transaction history for loans, funds and credit cards.
+        int accType = account.getType();
+        if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
+
+//        Matcher matcher;
+//        try {
+//            response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1102.aspx?M1=show&P2=1&P4=1&P1=" + account.getId());
+//            matcher = reTransactions.matcher(response);
+//            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+//            while (matcher.find()) {
+//                /*
+//                 * Capture groups:
+//                 * GROUP                    EXAMPLE DATA
+//                 * 1: Book. date            101214
+//                 * 2: Transaction           St1
+//                 * 3: Trans. date           10-12-11
+//                 * 4: Amount                -200,07
+//                 *
+//                 */
+//                String date;
+//                if (matcher.group(3) == null || matcher.group(3).length() == 0) {
+//                    date = Html.fromHtml(matcher.group(1)).toString().trim();
+//                    date = String.format("%s-%s-%s", date.substring(0,2), date.substring(2,4), date.substring(4,6));
+//                }
+//                else {
+//                    date = Html.fromHtml(matcher.group(3)).toString().trim();
+//                }
+//                transactions.add(new Transaction("20"+date, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4))));
+//            }
+//            Collections.sort(transactions, Collections.reverseOrder());
+//            account.setTransactions(transactions);
+//        } catch (ClientProtocolException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        } catch (IOException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        }
+    }
+
+
+    private ObjectMapper getObjectmapper() {
+        if (mObjectMapper == null) {
+            mObjectMapper = new ObjectMapper();
+            mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
+        }
+        return mObjectMapper;
+    }
+
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+        try {
+            return getObjectmapper().readValue(is, valueType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/seb/model/DEVID.java src/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
new file mode 100644
index 0000000..084bdc8
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/DEVID.java
@@ -0,0 +1,103 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+public class DEVID implements Serializable {
+    private static final long serialVersionUID = -8706994448508325149L;
+
+    @JsonProperty("APPLICATION_VERSION")
+    private String applicationVersion;
+    @JsonProperty("OS_NAME")
+    private String osName;
+    @JsonProperty("MODEL")
+    private String model;
+    @JsonProperty("MANUFACTURER")
+    private String manufacturer;
+    @JsonProperty("OS_VERSION")
+    private String osVersion;
+    @JsonProperty("APPLICATION_NAME")
+    private String applicationName;
+
+
+    public DEVID() {
+
+    }
+
+    public DEVID(String model, String applicationName, String applicationVersion, String osName, String osVersion, String manufacturer) {
+        this.model = model;
+        this.applicationName = applicationName;
+        this.osVersion = osVersion;
+        this.manufacturer = manufacturer;
+        this.applicationVersion = applicationVersion;
+        this.osName = osName;
+    }
+
+    public static DEVID createDefault() {
+        return new DEVID("45", "MASP", "6.0.0", "Android", "5", "Apple");
+    }
+
+    @JsonProperty("APPLICATION_VERSION")
+    public String getApplicationVersion() {
+        return applicationVersion;
+    }
+
+    @JsonProperty("APPLICATION_VERSION")
+    public void setApplicationVersion(String applicationVersion) {
+        this.applicationVersion = applicationVersion;
+    }
+
+    @JsonProperty("OS_NAME")
+    public String getOsName() {
+        return osName;
+    }
+
+    @JsonProperty("OS_NAME")
+    public void setOsName(String osName) {
+        this.osName = osName;
+    }
+
+    @JsonProperty("MODEL")
+    public String getModel() {
+        return model;
+    }
+
+    @JsonProperty("MODEL")
+    public void setModel(String model) {
+        this.model = model;
+    }
+
+    @JsonProperty("MANUFACTURER")
+    public String getManufacturer() {
+        return manufacturer;
+    }
+
+    @JsonProperty("MANUFACTURER")
+    public void setManufacturer(String manufacturer) {
+        this.manufacturer = manufacturer;
+    }
+
+    @JsonProperty("OS_VERSION")
+    public String getOsVersion() {
+        return osVersion;
+    }
+
+    @JsonProperty("OS_VERSION")
+    public void setOsVersion(String osVersion) {
+        this.osVersion = osVersion;
+    }
+
+    @JsonProperty("APPLICATION_NAME")
+    public String getApplicationName() {
+        return applicationName;
+    }
+
+    @JsonProperty("APPLICATION_NAME")
+    public void setApplicationName(String applicationName) {
+        this.applicationName = applicationName;
+    }
+
+
+
+}
diff --git src/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java src/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
new file mode 100644
index 0000000..018e5ae
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/HWINFO.java
@@ -0,0 +1,60 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+public class HWINFO implements Serializable {
+
+    @JsonProperty("LONGITUDE_DECIMAL")
+    private String longitudeDecimal;
+    @JsonProperty("LATITUDE_DECIMAL")
+    private String latitudeDecimal;
+    @JsonProperty("COUNTRY_PREFIX")
+    private long countryPrefix;
+
+    public HWINFO() {
+
+    }
+
+    public HWINFO(long countryPrefix, String latitudeDecimal, String longitudeDecimal) {
+        this.countryPrefix = countryPrefix;
+        this.latitudeDecimal = latitudeDecimal;
+        this.longitudeDecimal = longitudeDecimal;
+    }
+
+    public static HWINFO createDefault() {
+        return new HWINFO(0, "0", "0");
+    }
+
+    @JsonProperty("LONGITUDE_DECIMAL")
+    public String getLongitudeDecimal() {
+        return longitudeDecimal;
+    }
+
+    @JsonProperty("LONGITUDE_DECIMAL")
+    public void setLongitudeDecimal(String longitudeDecimal) {
+        this.longitudeDecimal = longitudeDecimal;
+    }
+
+    @JsonProperty("LATITUDE_DECIMAL")
+    public String getLatitudeDecimal() {
+        return latitudeDecimal;
+    }
+
+    @JsonProperty("LATITUDE_DECIMAL")
+    public void setLatitudeDecimal(String latitudeDecimal) {
+        this.latitudeDecimal = latitudeDecimal;
+    }
+
+    @JsonProperty("COUNTRY_PREFIX")
+    public long getCountryPrefix() {
+        return countryPrefix;
+    }
+
+    @JsonProperty("COUNTRY_PREFIX")
+    public void setCountryPrefix(long countryPrefix) {
+        this.countryPrefix = countryPrefix;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/seb/model/Request.java src/com/liato/bankdroid/banking/banks/seb/model/Request.java
new file mode 100644
index 0000000..fe2dddb
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/Request.java
@@ -0,0 +1,76 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Request implements Serializable {
+
+    @JsonProperty("ResultInfo")
+    private Object resultInfo;
+    @JsonProperty("VODB")
+    private VODB vODB;
+    @JsonProperty("ServiceInput")
+    private List<ServiceInput> serviceInput = new ArrayList<ServiceInput>();
+    @JsonProperty("UserCredentials")
+    private UserCredentials userCredentials;
+    @JsonProperty("ServiceInfo")
+    private Object serviceInfo;
+
+    @JsonProperty("ResultInfo")
+    public Object getResultInfo() {
+        return resultInfo;
+    }
+
+    @JsonProperty("ResultInfo")
+    public void setResultInfo(Object resultInfo) {
+        this.resultInfo = resultInfo;
+    }
+
+    @JsonProperty("VODB")
+    public VODB getVODB() {
+        return vODB;
+    }
+
+    @JsonProperty("VODB")
+    public void setVODB(VODB vODB) {
+        this.vODB = vODB;
+    }
+
+    @JsonProperty("ServiceInput")
+    public List<ServiceInput> getServiceInput() {
+        return serviceInput;
+    }
+
+    @JsonProperty("ServiceInput")
+    public void setServiceInput(List<ServiceInput> serviceInput) {
+        this.serviceInput = serviceInput;
+    }
+
+    @JsonProperty("UserCredentials")
+    public UserCredentials getUserCredentials() {
+        return userCredentials;
+    }
+
+    @JsonProperty("UserCredentials")
+    public void setUserCredentials(UserCredentials userCredentials) {
+        this.userCredentials = userCredentials;
+    }
+
+    @JsonProperty("ServiceInfo")
+    public Object getServiceInfo() {
+        return serviceInfo;
+    }
+
+    @JsonProperty("ServiceInfo")
+    public void setServiceInfo(Object serviceInfo) {
+        this.serviceInfo = serviceInfo;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java src/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
new file mode 100644
index 0000000..639c23f
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/SEBRequest.java
@@ -0,0 +1,22 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+public class SEBRequest implements Serializable {
+
+    @JsonProperty("request")
+    private Request request;
+
+    @JsonProperty("request")
+    public Request getRequest() {
+        return request;
+    }
+
+    @JsonProperty("request")
+    public void setRequest(Request request) {
+        this.request = request;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java src/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
new file mode 100644
index 0000000..819d30a
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/ServiceInput.java
@@ -0,0 +1,60 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ServiceInput implements Serializable {
+
+    @JsonProperty("Condition")
+    private String condition;
+    @JsonProperty("VariableNamePossibleValues")
+    private List<Object> variableNamePossibleValues = new ArrayList<Object>();
+    @JsonProperty("VariableName")
+    private String variableName;
+    @JsonProperty("VariableValue")
+    private String variableValue;
+
+    @JsonProperty("Condition")
+    public String getCondition() {
+        return condition;
+    }
+
+    @JsonProperty("Condition")
+    public void setCondition(String condition) {
+        this.condition = condition;
+    }
+
+    @JsonProperty("VariableNamePossibleValues")
+    public List<Object> getVariableNamePossibleValues() {
+        return variableNamePossibleValues;
+    }
+
+    @JsonProperty("VariableNamePossibleValues")
+    public void setVariableNamePossibleValues(List<Object> variableNamePossibleValues) {
+        this.variableNamePossibleValues = variableNamePossibleValues;
+    }
+
+    @JsonProperty("VariableName")
+    public String getVariableName() {
+        return variableName;
+    }
+
+    @JsonProperty("VariableName")
+    public void setVariableName(String variableName) {
+        this.variableName = variableName;
+    }
+
+    @JsonProperty("VariableValue")
+    public String getVariableValue() {
+        return variableValue;
+    }
+
+    @JsonProperty("VariableValue")
+    public void setVariableValue(String variableValue) {
+        this.variableValue = variableValue;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java src/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
new file mode 100644
index 0000000..f9d629f
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/UserCredentials.java
@@ -0,0 +1,93 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class UserCredentials {
+
+    @JsonProperty("ApplicationName")
+    private String applicationName;
+    @JsonProperty("WorkstationID")
+    private String workstationID;
+    @JsonProperty("LoggedOnUser")
+    private String loggedOnUser;
+    @JsonProperty("AuthMethod")
+    private String authMethod;
+    @JsonProperty("UserId")
+    private String userId;
+    @JsonProperty("Password")
+    private String password;
+
+    public UserCredentials() {
+
+    }
+
+    public UserCredentials(String userId, String password) {
+        this.userId = userId;
+        this.password = password;
+        this.applicationName = "RFO";
+        this.loggedOnUser = "Mobile";
+        this.workstationID = "";
+        this.authMethod = "0";
+    }
+
+    @JsonProperty("ApplicationName")
+    public String getApplicationName() {
+        return applicationName;
+    }
+
+    @JsonProperty("ApplicationName")
+    public void setApplicationName(String applicationName) {
+        this.applicationName = applicationName;
+    }
+
+    @JsonProperty("WorkstationID")
+    public String getWorkstationID() {
+        return workstationID;
+    }
+
+    @JsonProperty("WorkstationID")
+    public void setWorkstationID(String workstationID) {
+        this.workstationID = workstationID;
+    }
+
+    @JsonProperty("LoggedOnUser")
+    public String getLoggedOnUser() {
+        return loggedOnUser;
+    }
+
+    @JsonProperty("LoggedOnUser")
+    public void setLoggedOnUser(String loggedOnUser) {
+        this.loggedOnUser = loggedOnUser;
+    }
+
+    @JsonProperty("AuthMethod")
+    public String getAuthMethod() {
+        return authMethod;
+    }
+
+    @JsonProperty("AuthMethod")
+    public void setAuthMethod(String authMethod) {
+        this.authMethod = authMethod;
+    }
+
+    @JsonProperty("UserId")
+    public String getUserId() {
+        return userId;
+    }
+
+    @JsonProperty("UserId")
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    @JsonProperty("Password")
+    public String getPassword() {
+        return password;
+    }
+
+    @JsonProperty("Password")
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/seb/model/VODB.java src/com/liato/bankdroid/banking/banks/seb/model/VODB.java
new file mode 100644
index 0000000..7e0df07
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/seb/model/VODB.java
@@ -0,0 +1,97 @@
+package com.liato.bankdroid.banking.banks.seb.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class VODB implements Serializable {
+    private static final long serialVersionUID = 6084093222386932965L;
+
+    @JsonProperty("USRINF01")
+    private Object usrinf01;
+    @JsonProperty("DBZV160")
+    private List<Object> dbzv160 = new ArrayList<Object>();
+    @JsonProperty("DEVID01")
+    private DEVID devid01;
+    @JsonProperty("HWINFO01")
+    private HWINFO hWINFO01;
+    @JsonProperty("CBEW501")
+    private List<Object> cbew501 = new ArrayList<Object>();
+    @JsonProperty("DBZV170")
+    private List<Object> dbzv170 = new ArrayList<Object>();
+    @JsonProperty("CBEW502")
+    private List<Object> cbew502 = new ArrayList<Object>();
+
+    @JsonProperty("USRINF01")
+    public Object getUSRINF01() {
+        return usrinf01;
+    }
+
+    @JsonProperty("USRINF01")
+    public void setUSRINF01(Object uSRINF01) {
+        this.usrinf01 = uSRINF01;
+    }
+
+    @JsonProperty("DBZV160")
+    public List<Object> getDBZV160() {
+        return dbzv160;
+    }
+
+    @JsonProperty("DBZV160")
+    public void setDBZV160(List<Object> dBZV160) {
+        this.dbzv160 = dBZV160;
+    }
+
+    @JsonProperty("DEVID01")
+    public DEVID getDEVID01() {
+        return devid01;
+    }
+
+    @JsonProperty("DEVID01")
+    public void setDEVID01(DEVID dEVID01) {
+        this.devid01 = dEVID01;
+    }
+
+    @JsonProperty("HWINFO01")
+    public HWINFO getHWINFO01() {
+        return hWINFO01;
+    }
+
+    @JsonProperty("HWINFO01")
+    public void setHWINFO01(HWINFO hWINFO01) {
+        this.hWINFO01 = hWINFO01;
+    }
+
+    @JsonProperty("CBEW501")
+    public List<Object> getCBEW501() {
+        return cbew501;
+    }
+
+    @JsonProperty("CBEW501")
+    public void setCBEW501(List<Object> cBEW501) {
+        this.cbew501 = cBEW501;
+    }
+
+    @JsonProperty("DBZV170")
+    public List<Object> getDBZV170() {
+        return dbzv170;
+    }
+
+    @JsonProperty("DBZV170")
+    public void setDBZV170(List<Object> dBZV170) {
+        this.dbzv170 = dBZV170;
+    }
+
+    @JsonProperty("CBEW502")
+    public List<Object> getCBEW502() {
+        return cbew502;
+    }
+
+    @JsonProperty("CBEW502")
+    public void setCBEW502(List<Object> cBEW502) {
+        this.cbew502 = cBEW502;
+    }
+
+}
diff --git src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index fd3081f..d70759c 100644
--- src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -30,11 +30,14 @@ import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import java.security.KeyManagementException;
+import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.Certificate;
 
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
@@ -45,10 +48,12 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
     private Certificate[] certificates;
     private String lastHost;
     private CertPinningTrustManager mTrustManager;
+    private ClientCertificate mClientCertificate;
 
-    public CertPinningSSLSocketFactory(Certificate[] certificates) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+    public CertPinningSSLSocketFactory(ClientCertificate clientCertificate, Certificate[] certificates) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
         super(null);
         this.certificates = certificates;
+        this.mClientCertificate = clientCertificate;
         setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
     }
 
@@ -57,13 +62,21 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
         try {
             SSLContext context = SSLContext.getInstance("TLS");
             mTrustManager = new CertPinningTrustManager(certificates, lastHost);
-            context.init(null, new TrustManager[] { mTrustManager }, null);
+            KeyManager[] keyManagers = null;
+            if  (mClientCertificate != null) {
+                KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+                kmf.init(mClientCertificate.getKeyStore(), mClientCertificate.getPassword().toCharArray());
+                keyManagers = kmf.getKeyManagers();
+            }
+            context.init(keyManagers, new TrustManager[] { mTrustManager }, null);
             return context;
         } catch (Exception e) {
             throw new IOException(e.getMessage());
         }
     }
 
+//    private static KeyManager2 extends KeyManager
+
     private SSLContext getSSLContext() throws IOException {
         //Log.v(TAG, "getSSLContext()");
         if (this.sslcontext == null) {
diff --git src/eu/nullbyte/android/urllib/CertificateReader.java src/eu/nullbyte/android/urllib/CertificateReader.java
index 5df64d7..d5c2f2c 100644
--- src/eu/nullbyte/android/urllib/CertificateReader.java
+++ src/eu/nullbyte/android/urllib/CertificateReader.java
@@ -5,6 +5,8 @@ import android.content.Context;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
@@ -41,6 +43,34 @@ public class CertificateReader {
         return certificates.toArray(new Certificate[certificates.size()]);
     }
 
+    public static ClientCertificate getClientCertificate(Context context, int rawResCert, String password) {
+        InputStream is = null;
+        try {
+            KeyStore keyStore = KeyStore.getInstance("PKCS12");
+            is = new BufferedInputStream(context.getResources().openRawResource(rawResCert));
+            keyStore.load(is, password.toCharArray());
+            return new ClientCertificate(keyStore, password);
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (CertificateException e) {
+            e.printStackTrace();
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    //noop
+                }
+            }
+        }
+        return null;
+    }
+
+
     public static String[] getPins(Context context, int... rawResCerts) {
         Certificate[] certs = getCertificates(context, rawResCerts);
         if (certs != null && certs.length > 0) {
diff --git src/eu/nullbyte/android/urllib/ClientCertificate.java src/eu/nullbyte/android/urllib/ClientCertificate.java
new file mode 100644
index 0000000..4d3dc16
--- /dev/null
+++ src/eu/nullbyte/android/urllib/ClientCertificate.java
@@ -0,0 +1,21 @@
+package eu.nullbyte.android.urllib;
+
+import java.security.KeyStore;
+
+public class ClientCertificate {
+    private String mPassword;
+    private KeyStore mKeyStore;
+
+    public ClientCertificate(KeyStore keyStore, String password) {
+        mKeyStore = keyStore;
+        mPassword = password;
+    }
+
+    public String getPassword() {
+        return mPassword;
+    }
+
+    public KeyStore getKeyStore() {
+        return mKeyStore;
+    }
+}
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index ff2c98b..d319ad0 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -35,6 +35,7 @@ import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.NameValuePair;
+import org.apache.http.ProtocolException;
 import org.apache.http.client.AuthenticationHandler;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.HttpRequestRetryHandler;
@@ -57,6 +58,7 @@ import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.DefaultRedirectHandler;
 import org.apache.http.impl.client.DefaultRequestDirector;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
 import org.apache.http.params.BasicHttpParams;
@@ -72,6 +74,7 @@ import org.apache.http.util.EntityUtils;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
 import java.security.KeyManagementException;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
@@ -98,6 +101,10 @@ public class Urllib {
     }
 
     public Urllib(Context context, Certificate[] pins) {
+        this(context, null, pins);
+    }
+
+    public Urllib(Context context, ClientCertificate clientCert, Certificate[] pins) {
         mContext = context;
         this.headers = new HashMap<String, String>();
         userAgent = createUserAgentString();
@@ -110,7 +117,7 @@ public class Urllib {
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         boolean trustSystemKeystore = prefs.getBoolean("debug_mode", false) && prefs.getBoolean("no_cert_pinning", false);
         try {
-            mSSLSocketFactory = new CertPinningSSLSocketFactory(pins);
+            mSSLSocketFactory = new CertPinningSSLSocketFactory(clientCert, pins);
             registry.register(new Scheme("https", pins != null && !trustSystemKeystore ? mSSLSocketFactory : SSLSocketFactory.getSocketFactory(), 443));
         } catch (UnrecoverableKeyException e) {
             e.printStackTrace();
@@ -231,7 +238,7 @@ public class Urllib {
         httpclient.getConnectionManager().shutdown();
     }
     
-    public HttpContext getmHttpContext() {
+    public HttpContext getHttpContext() {
         return mHttpContext;
     }
     
@@ -261,7 +268,6 @@ public class Urllib {
         httpclient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { 
             @Override
             public long getKeepAliveDuration(HttpResponse response, HttpContext arg1) {
-                // TODO Auto-generated method stub
                 return seconds;
             }});
     }
@@ -278,6 +284,20 @@ public class Urllib {
         return this.headers;
     }
 
+    public void setFollowRedirects(boolean follow) {
+        httpclient.setRedirectHandler(follow ? new DefaultRedirectHandler() : new RedirectHandler() {
+            public URI getLocationURI(HttpResponse response,
+                                      HttpContext context) throws ProtocolException {
+                return null;
+            }
+
+            public boolean isRedirectRequested(HttpResponse response,
+                                               HttpContext context) {
+                return false;
+            }
+        });
+    }
+
     
     public void setUserAgent(String userAgent) {
         this.userAgent = userAgent;

commit 88ca212bfc562facd3d641012e92064d07985d9a
Author: Andreas Knifh <andreas.knifh@jadestone.se>
Date:   Fri Jun 6 21:47:08 2014 +0200

    'Villabanken' transactions view is popuplated

diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index a909156..c1f5e6f 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -27,12 +27,12 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -48,15 +48,18 @@ public class Villabanken extends Bank {
 	private static final String URL = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
 	private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
 
-    private final Pattern reDisposableAmount = Pattern.compile("<td[^>]+>((?:Kvar att utnyttja:)+)[^>]+>([^<]+)</span>");
-    private final Pattern reBalance = Pattern.compile("<td[^>]+>((?:Utnyttjad kredit:)+)[^>]+>([^<]+)</span>");
-    private final Pattern reCreditLimit = Pattern.compile("<td[^>]+>((?:Beviljad kredit:)+)[^>]+>([^<]+)</span>");
+    private final Pattern reDisposableAmount = Pattern.compile("<[^>]+>((?:Kvar att utnyttja:)+)[^>]+>([^<]+)");
+    private final Pattern reBalance = Pattern.compile("<[^>]+>((?:Utnyttjad kredit:)+)[^>]+>([^<]+)");
+    private final Pattern reCreditLimit = Pattern.compile("<[^>]+>((?:Beviljad kredit:)+)[^>]+>([^<]+)");
+    private final Pattern reTransactions = Pattern.compile("<[^>]+>(\\d{4}-\\d{2}-\\d{2})[^>]+><[^>]*>+([^<]+)<[^>]*><[^>]*>([^<]+) SEK<");
 	private final Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
 	private final Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
 	private final Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
 	private final Pattern reCtl00 = Pattern.compile("\"(ctl00.*?ctl00)\"");
+    private String accountUrl = "https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx";;
+    private String accountResponse = null;
 
-	public Villabanken(Context context) {
+    public Villabanken(Context context) {
 		super(context);
 		super.TAG = TAG;
 		super.NAME = NAME;
@@ -73,26 +76,26 @@ public class Villabanken extends Bank {
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_villabanken));
-		String response = urlopen.open(URL);
-		Matcher matcher = reRequestDigest.matcher(response);
+		String preLoginResponse = urlopen.open(URL);
+		Matcher matcher = reRequestDigest.matcher(preLoginResponse);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find).toString() + " request digest.");
 		}
 		String requestDigest = matcher.group(1);
 
-		matcher = reCtl00.matcher(response);
+		matcher = reCtl00.matcher(preLoginResponse);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl00");
 		}
 		String ctl00 = matcher.group(1);
 
-		matcher = reViewState.matcher(response);
+		matcher = reViewState.matcher(preLoginResponse);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find).toString() + " view state.");
 		}
 		String viewState = matcher.group(1);
 
-		matcher = reEventValidation.matcher(response);
+		matcher = reEventValidation.matcher(preLoginResponse);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find).toString() + " event validation.");
 		}
@@ -130,17 +133,18 @@ public class Villabanken extends Bank {
 		postData.add(new BasicNameValuePair("_wpcmWpid", ""));
 		postData.add(new BasicNameValuePair("wpcmVal", ""));
 
-		return new LoginPackage(urlopen, postData, response, URL);
+		return new LoginPackage(urlopen, postData, preLoginResponse, URL);
 	}
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		try {
 			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("misslyckades")) {
+			String loginResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (loginResponse.contains("misslyckades")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
+            this.accountResponse = urlopen.open(accountUrl);
 
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
@@ -157,45 +161,52 @@ public class Villabanken extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		String response = null;
+
 		Matcher matcher;
-		try {
-			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
-
-            matcher = reDisposableAmount.matcher(response);
-            matcher.find();
-            Account account = new Account("Disponibelt belopp", Helpers.parseBalance(matcher.group(2)), "0");
-            account.setType(Account.CCARD);
-            account.setCurrency(currency);
-            accounts.add(account);
-            balance = balance.add(account.getBalance());
-
-            matcher = reBalance.matcher(response);
-            matcher.find();
-            account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
-            account.setType(Account.OTHER);
-            account.setAliasfor("Saldo alias");
-            account.setCurrency(currency);
-            accounts.add(account);
-
-            matcher = reCreditLimit.matcher(response);
-            matcher.find();
-            account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
-            account.setType(Account.OTHER);
-            account.setAliasfor("Köpgräns alias");
-            account.setCurrency(currency);
-            accounts.add(account);
-
-            if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
 
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		} finally {
-			super.updateComplete();
-		}
+        matcher = reDisposableAmount.matcher(accountResponse);
+        matcher.find();
+        Account account = new Account("Disponibelt belopp", Helpers.parseBalance(matcher.group(2)), "0");
+        account.setType(Account.CCARD);
+        account.setCurrency(currency);
+        accounts.add(account);
+        balance = balance.add(account.getBalance());
+
+        matcher = reBalance.matcher(accountResponse);
+        matcher.find();
+        account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
+        account.setType(Account.OTHER);
+        account.setAliasfor("Saldo alias");
+        account.setCurrency(currency);
+        accounts.add(account);
+
+        matcher = reCreditLimit.matcher(accountResponse);
+        matcher.find();
+        account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
+        account.setType(Account.OTHER);
+        account.setAliasfor("Köpgräns alias");
+        account.setCurrency(currency);
+        accounts.add(account);
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+
+        super.updateComplete();
+
 	}
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        if (account.getType() != Account.CCARD) return;
+
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        Matcher matcher = reTransactions.matcher(accountResponse);
+        while(matcher.find()) {
+            transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate(), account.getCurrency()));
+        }
+        account.setTransactions(transactions);
+
+    }
 }
\ No newline at end of file

commit 748fa850c1930b74a1b4d108a3c4b0254b75f182
Author: Andreas Knifh <andreas.knifh@jadestone.se>
Date:   Fri Jun 6 21:01:48 2014 +0200

    'Villabanken' improved the Accounts parsing, added Köpgräns, made the balance only show the disposable amount.

diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index a178c00..a909156 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -48,7 +48,9 @@ public class Villabanken extends Bank {
 	private static final String URL = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
 	private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
 
-	private final Pattern reAccounts = Pattern.compile("<td[^>]+>((?:utnyttjad|kvar)[^:]+)[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+    private final Pattern reDisposableAmount = Pattern.compile("<td[^>]+>((?:Kvar att utnyttja:)+)[^>]+>([^<]+)</span>");
+    private final Pattern reBalance = Pattern.compile("<td[^>]+>((?:Utnyttjad kredit:)+)[^>]+>([^<]+)</span>");
+    private final Pattern reCreditLimit = Pattern.compile("<td[^>]+>((?:Beviljad kredit:)+)[^>]+>([^<]+)</span>");
 	private final Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
 	private final Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
 	private final Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
@@ -160,15 +162,31 @@ public class Villabanken extends Bank {
 		try {
 			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
 
-			matcher = reAccounts.matcher(response);
-			Integer accountId = 0;
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), accountId.toString()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-				accountId += 1;
-			}
-
-			if (accounts.isEmpty()) {
+            matcher = reDisposableAmount.matcher(response);
+            matcher.find();
+            Account account = new Account("Disponibelt belopp", Helpers.parseBalance(matcher.group(2)), "0");
+            account.setType(Account.CCARD);
+            account.setCurrency(currency);
+            accounts.add(account);
+            balance = balance.add(account.getBalance());
+
+            matcher = reBalance.matcher(response);
+            matcher.find();
+            account = new Account("Saldo", Helpers.parseBalance(matcher.group(2)), "1");
+            account.setType(Account.OTHER);
+            account.setAliasfor("Saldo alias");
+            account.setCurrency(currency);
+            accounts.add(account);
+
+            matcher = reCreditLimit.matcher(response);
+            matcher.find();
+            account = new Account("Köpgräns", Helpers.parseBalance(matcher.group(2)), "2");
+            account.setType(Account.OTHER);
+            account.setAliasfor("Köpgräns alias");
+            account.setCurrency(currency);
+            accounts.add(account);
+
+            if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 

commit b2fd569dd47c25abdc7e7f8d5c482e6fc13a9e3a
Author: liato <x@x00.us>
Date:   Sun Jun 1 23:47:46 2014 +0200

    Update Rikslunchen certificate.

diff --git res/raw/cert_rikslunchen.pem res/raw/cert_rikslunchen.pem
index 0b0ef83..c8c035b 100644
--- res/raw/cert_rikslunchen.pem
+++ res/raw/cert_rikslunchen.pem
@@ -1,28 +1,30 @@
 -----BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIDBlDHMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
+MIIFNjCCBB6gAwIBAgIDEsfnMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
 MRcwFQYDVQQKEw5HZW9UcnVzdCwgSW5jLjEUMBIGA1UEAxMLUmFwaWRTU0wgQ0Ew
-HhcNMTIwNTAxMTEyMjA5WhcNMTYwNTAyMjMzNTU2WjCBvzEpMCcGA1UEBRMgUzAx
-elZOSWd6YW1lMWQveFhubXFITzJUaTVOU1JpME0xEzARBgNVBAsTCkdUMDA5OTk1
+HhcNMTQwNTEzMDAyODEwWhcNMTYwNTAzMTY1MTE2WjCBvzEpMCcGA1UEBRMgU2dB
+N2NWOFdSU2FZWHJFTTBqbUROT051dHRIY1RXcWkxEzARBgNVBAsTCkdUMDA5OTk1
 NTAxMTAvBgNVBAsTKFNlZSB3d3cucmFwaWRzc2wuY29tL3Jlc291cmNlcy9jcHMg
 KGMpMTIxLzAtBgNVBAsTJkRvbWFpbiBDb250cm9sIFZhbGlkYXRlZCAtIFJhcGlk
 U1NMKFIpMRkwFwYDVQQDDBAqLnJpa3NsdW5jaGVuLnNlMIIBIjANBgkqhkiG9w0B

 HwYDVR0jBBgwFoAUa2k9ahhCSt2PAmU5/TUkhniRFjAwDgYDVR0PAQH/BAQDAgWg
 MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjArBgNVHREEJDAighAqLnJp
 a3NsdW5jaGVuLnNlgg5yaWtzbHVuY2hlbi5zZTBDBgNVHR8EPDA6MDigNqA0hjJo
 dHRwOi8vcmFwaWRzc2wtY3JsLmdlb3RydXN0LmNvbS9jcmxzL3JhcGlkc3NsLmNy

-94VaODj3eZ9v1Tguxg==

+UU9mph83MDGlCY1EwuHPGorjoqGjYjXl/63EOvKmXEKYMCd6fb4Dfq2F
 -----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 26a2383..6003b70 100644
--- src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -29,32 +29,15 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.CookieStore;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.cookie.Cookie;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.BasicCookieStore;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
 import org.simpleframework.xml.Serializer;
 import org.simpleframework.xml.core.Persister;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -125,10 +108,13 @@ public class Rikslunchen extends Bank {
             accounts.add(new Account("Rikslunchen", balance, "1"));
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
+            throw new BankException(e.getMessage());
         } catch (ClientProtocolException e) {
             e.printStackTrace();
+            throw new BankException(e.getMessage());
         } catch (IOException e) {
             e.printStackTrace();
+            throw new BankException(e.getMessage());
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found)

commit ec35210eeebd0640940ba67e84d0a09ea01b5bc6
Author: liato <x@x00.us>
Date:   Sun Jun 1 23:37:51 2014 +0200

    Update SevenDay certificate.

diff --git res/raw/cert_sevenday.pem res/raw/cert_sevenday.pem
index 0a233b5..89a213c 100644
--- res/raw/cert_sevenday.pem
+++ res/raw/cert_sevenday.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQF7xPHP7AujQPIPj8UKmd6jANBgkqhkiG9w0BAQUFADA8
+MIIEkjCCA3qgAwIBAgIQNHl5jjaIHqGW09M+de7GxDANBgkqhkiG9w0BAQUFADA8
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMuMRYwFAYDVQQDEw1U
-aGF3dGUgU1NMIENBMB4XDTEzMDkxMDAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
+aGF3dGUgU1NMIENBMB4XDTE0MDQxNTAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
 MAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9sbTEOMAwGA1UEBxQFS2lzdGEx
 GzAZBgNVBAoUElNldmVuRGF5IEZpbmFucyBBQjEWMBQGA1UEAxQNKi5zZXZlbmRh

 VR0TBAIwADBCBgNVHSAEOzA5MDcGCmCGSAGG+EUBBzYwKTAnBggrBgEFBQcCARYb
 aHR0cHM6Ly93d3cudGhhd3RlLmNvbS9jcHMvMA4GA1UdDwEB/wQEAwIFoDAfBgNV
 HSMEGDAWgBSnooO7NEVAPfzVME8SuT6hAZ/22zA6BgNVHR8EMzAxMC+gLaArhilo
@@ -18,10 +18,10 @@ dHRwOi8vc3ZyLW92LWNybC50aGF3dGUuY29tL1RoYXd0ZU9WLmNybDAdBgNVHSUE
 FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwaQYIKwYBBQUHAQEEXTBbMCIGCCsGAQUF
 BzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDUGCCsGAQUFBzAChilodHRwOi8v
 c3ZyLW92LWFpYS50aGF3dGUuY29tL1RoYXd0ZU9WLmNlcjANBgkqhkiG9w0BAQUF
-AAOCAQEAElhvDbODrkiNm+RiwpfgLTFc0RiEq/mw0rCU04b1j0JSOhK8ImGYLZEN
-GmUSjuJ7x05T3wYcnkXhyWwntkdUed0cFLkuuHohHFdvuPg/0SYw+n/lgPrIXh0V
-BadG1CjnmX3qhdgoTWEvynXJFf3vck9Dx2scxfwJZ7BoUzEraoZ1i0ZJ/2p5pp11
-w+vx95m1/eMdmaikt2wZGDzOyl0LAP7wREDYMs4HkvNGzZxnDoylLZ+45qEuRhnj
-Xg18o4qqK0PxQademqQCMgGZA/YHEPhowSNz20Fd0QlQ3b0XPQiM5L4/Pj5f3/w0
-PV2hZ7XKpVDd+Q41irJ0O6JluWFl8A==
+AAOCAQEAfxEugYbMxBESO8rPkO7SJoquhqdl++OClvSLYdIq8JGfiBc0otayEMBS
+ooEIjwOY3z2dpra7I9ZOSVprv02egTGNR2cW55QRAs+qQLqzxGI5lj+1RHgcJZHo
+g3ZFoqNEnh2u5hfCtf+cS2hH1VUPxp9Ml09Nk/mLK2WK/xv4yEfQDqANZut4oboB
+wsygjnnUpRyGbrxeY29w6TfChOQwb+7vxxCgRPJBrDTGdJmZ6rhE+ZrSNqcCd1ra
+vB8pWPwNeaFHRPrYrlzUXfkS0xak7GFCU+WW4qPG73VLdPnh/GcidtSjDSZKGSkv
+ETEyMuB5fsINZXXfHm6F2x4e0+b8aQ==
 -----END CERTIFICATE-----

commit cfc58f4d8fc1fcaef83a5eb73577e2acfe472128
Author: liato <x@x00.us>
Date:   Sun Jun 1 23:35:37 2014 +0200

    Ignore Coop transactions without dates.

diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
index 1f226b8..72133f7 100644
--- src/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -350,7 +350,9 @@ public class Coop extends Bank {
                     if (!TextUtils.isEmpty(r.getCardholder())) {
                         title.append(" (").append(r.getCardholder()).append(")");
                     }
-                    transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
+                    if (r.getDate() != null) {
+                        transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
+                    }
                 }
             }
         } catch (UnsupportedEncodingException e) {

commit 9f595a16b103481779d64efd2f3619f769cf76a9
Author: liato <x@x00.us>
Date:   Sun May 18 11:14:30 2014 +0200

    Nullpointer check for coop transactions.

diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
index f4a7d1f..1f226b8 100644
--- src/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -295,7 +295,7 @@ public class Coop extends Bank {
                     setCurrency(a.getCurrency());
                 }
                 accounts.add(a);
-                a = new Account(String.format("Återbäring för %s", refsumResp.getRefundSummaryResult().getMonthName()), BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getPeriodRefund()), "refsummary_month");
+                a = new Account(String.format("Återbäring för %s", refsumResp.getRefundSummaryResult().getMonthName()), BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getTotalRefund()), "refsummary_month");
                 accounts.add(a);
             }
         } catch (JsonParseException e) {
@@ -342,14 +342,16 @@ public class Coop extends Bank {
             String data = URLEncoder.encode(String.format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}", tp.getMinDate(), tp.getMaxDate()), "utf-8");
             String url = String.format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s", tp.getPageGuid(), data, System.currentTimeMillis());
             WebTransactionHistoryResponse transactionsResponse = getObjectmapper().readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
-            List<Transaction> transactions = new ArrayList<Transaction>();
-            account.setTransactions(transactions);
-            for (Result r : transactionsResponse.getModel().getResults()) {
-                StringBuilder title = new StringBuilder(!TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
-                if (!TextUtils.isEmpty(r.getCardholder())) {
-                    title.append(" (").append(r.getCardholder()).append(")");
+            if (transactionsResponse != null && transactionsResponse.getModel() != null) {
+                List<Transaction> transactions = new ArrayList<Transaction>();
+                account.setTransactions(transactions);
+                for (Result r : transactionsResponse.getModel().getResults()) {
+                    StringBuilder title = new StringBuilder(!TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
+                    if (!TextUtils.isEmpty(r.getCardholder())) {
+                        title.append(" (").append(r.getCardholder()).append(")");
+                    }
+                    transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
                 }
-                transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
             }
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
index a9b1e33..ef44524 100644
--- src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
+++ src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
@@ -21,6 +21,6 @@ public class WebTransactionHistoryResponse {
     }
 
     public Model getModel() {
-        return this.d.getModel();
+        return this.d != null ? this.d.getModel() : null;
     }
 }

commit b3aedbe66cdb4de27c943a77e6ced3bf00f3a356
Author: liato <x@x00.us>
Date:   Sun May 18 02:33:23 2014 +0200

    Change account name for resurs bank.

diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 7edcd28..f1fca98 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -129,7 +129,7 @@ public class ResursBank extends Bank {
             accounts.add(new Account("Reserverat belopp",
                     Helpers.parseBalance(matcher.group(4)),
                     "r_"+accountId));
-            accounts.add(new Account("Kvar att utnyttja",
+            accounts.add(new Account("Disponibelt",
                     Helpers.parseBalance(matcher.group(5)),
                     "k_"+accountId));
         }

commit be5c338b7f7ac27c065854c80e015130a9548a18 (tag: v1.9.6.15-RC3)
Author: liato <x@x00.us>
Date:   Sun May 18 02:28:45 2014 +0200

    Bump version. v1.9.6.15-RC3.

diff --git AndroidManifest.xml AndroidManifest.xml
index 6db97f6..e153f56 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.15-RC2" android:versionCode="186">
+	android:versionName="1.9.6.15-RC3" android:versionCode="187">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 89ea17f..aef019e 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 186
-        versionName '1.9.6.15-RC2'
+        versionCode 187
+        versionName '1.9.6.15-RC3'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit b457133888bdda6f4cec91f4bb968faf8e18d5a4
Author: liato <x@x00.us>
Date:   Sun May 18 02:25:55 2014 +0200

    Fix for Coop MedMera Kort.

diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
index 13e3493..f4a7d1f 100644
--- src/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -79,6 +79,60 @@ public class Coop extends Bank {
         }
     }
 
+    enum AccountType {
+        MEDMERA_KONTO("konto_", "https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/"),
+        MEDMERA_VISA("visa_", "https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
+
+        String prefix;
+        String url;
+        private AccountType(String prefix, String url) {
+            this.prefix = prefix;
+            this.url = url;
+        }
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+    }
+
+    class TransactionParams {
+        String pageGuid;
+        String minDate;
+        String maxDate;
+
+        public String getPageGuid() {
+            return pageGuid;
+        }
+
+        public void setPageGuid(String pageGuid) {
+            this.pageGuid = pageGuid;
+        }
+
+        public String getMinDate() {
+            return minDate;
+        }
+
+        public void setMinDate(String minDate) {
+            this.minDate = minDate;
+        }
+
+        public String getMaxDate() {
+            return maxDate;
+        }
+
+        public void setMaxDate(String maxDate) {
+            this.maxDate = maxDate;
+        }
+
+        public boolean isValid() {
+            return pageGuid != null && minDate != null && maxDate != null;
+        }
+    }
+
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
  //   private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -88,9 +142,7 @@ public class Coop extends Bank {
     private String response;
     private String mToken;
     private String mUserId;
-    private String mPageGuid;
-    private String mDateMin;
-    private String mDateMax;
+    private Map<AccountType, TransactionParams> mTransactionParams = new HashMap<AccountType, TransactionParams>();
 
     public Coop(Context context) {
         super(context);
@@ -134,7 +186,7 @@ public class Coop extends Bank {
     @Override
     public Urllib login() throws LoginException, BankException {
         try {
-            //Coop MedMera Visa information and transactions are not available from the json api
+            //Coop MedMera Kort/Visa information and transactions are not available from the json api
             //so we'll have to login once to the web site and once to the api.
             LoginPackage lp = preLogin();
             if (!lp.isLoggedIn()) {
@@ -175,46 +227,50 @@ public class Coop extends Bank {
         login();
 
         try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
-            Document d = Jsoup.parse(response);
-            Elements historik = d.select("#historik section");
-            if (historik != null && !historik.isEmpty()) {
-                String data = historik.first().attr("data-controller");
-                Matcher m = rePageGuid.matcher(data);
-                if (m.find()) {
-                    mPageGuid = m.group(1);
-                }
-            }
-            Element date = d.getElementById("dateFrom");
-            if (date != null) {
-                mDateMin = date.hasAttr("min") ? date.attr("min") : null;
-                mDateMax = date.hasAttr("max") ? date.attr("max") : null;
-            }
-            Elements es = d.select(".List:contains(Saldo)");
-            if (es != null && !es.isEmpty()) {
-                List<String> names = new ArrayList<String>();
-                List<String> values = new ArrayList<String>();
-                for (Element e : es.first().select("dt")) {
-                    names.add(e.text().replaceAll(":", "").trim());
+            for (AccountType at : AccountType.values()) {
+                response = urlopen.open(at.getUrl());
+                Document d = Jsoup.parse(response);
+                Elements historik = d.select("#historik section");
+                TransactionParams params = new TransactionParams();
+                mTransactionParams.put(at, params);
+                if (historik != null && !historik.isEmpty()) {
+                    String data = historik.first().attr("data-controller");
+                    Matcher m = rePageGuid.matcher(data);
+                    if (m.find()) {
+                        params.setPageGuid(m.group(1));
+                    }
                 }
-                for (Element e : es.first().select("dd")) {
-                    values.add(e.text().trim());
+                Element date = d.getElementById("dateFrom");
+                if (date != null) {
+                    params.setMinDate(date.hasAttr("min") ? date.attr("min") : null);
+                    params.setMaxDate(date.hasAttr("max") ? date.attr("max") : null);
                 }
-                for (int i = 0; i < Math.min(names.size(), values.size()); i++) {
-                    Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)), Integer.toString(i));
-                    a.setCurrency(Helpers.parseCurrency(values.get(i), "SEK"));
-                    if (a.getName().toLowerCase().contains("disponibelt")) {
-                        a.setType(Account.REGULAR);
-                        balance = a.getBalance();
-                        setCurrency(a.getCurrency());
-                    } else {
-                        a.setType(Account.OTHER);
+                Elements es = d.select(".List:contains(Saldo)");
+                if (es != null && !es.isEmpty()) {
+                    List<String> names = new ArrayList<String>();
+                    List<String> values = new ArrayList<String>();
+                    for (Element e : es.first().select("dt")) {
+                        names.add(e.text().replaceAll(":", "").trim());
                     }
+                    for (Element e : es.first().select("dd")) {
+                        values.add(e.text().trim());
+                    }
+                    for (int i = 0; i < Math.min(names.size(), values.size()); i++) {
+                        Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)), String.format("%s%d", at.getPrefix(), i));
+                        a.setCurrency(Helpers.parseCurrency(values.get(i), "SEK"));
+                        if (a.getName().toLowerCase().contains("disponibelt")) {
+                            a.setType(Account.REGULAR);
+                            balance = a.getBalance();
+                            setCurrency(a.getCurrency());
+                        } else {
+                            a.setType(Account.OTHER);
+                        }
 
-                    if (i > 0) {
-                        a.setAliasfor("0");
+                        if (i > 0) {
+                            a.setAliasfor(String.format("%s%d", at.getPrefix(), 0));
+                        }
+                        accounts.add(a);
                     }
-                    accounts.add(a);
                 }
             }
         } catch (ClientProtocolException e) {
@@ -279,15 +335,21 @@ public class Coop extends Bank {
 
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-        if (mPageGuid == null || mDateMin == null || mDateMax == null || !"0".equals(account.getId())) return;
+        AccountType at = getAccuntType(account.getId());
+        TransactionParams tp = mTransactionParams.get(at);
+        if (at == null || tp == null || !tp.isValid() || !isFirstAccountForType(account.getId())) return;
         try {
-            String data = URLEncoder.encode(String.format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}", mDateMin, mDateMax), "utf-8");
-            String url = String.format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s", mPageGuid, data, System.currentTimeMillis());
+            String data = URLEncoder.encode(String.format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}", tp.getMinDate(), tp.getMaxDate()), "utf-8");
+            String url = String.format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s", tp.getPageGuid(), data, System.currentTimeMillis());
             WebTransactionHistoryResponse transactionsResponse = getObjectmapper().readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
             List<Transaction> transactions = new ArrayList<Transaction>();
             account.setTransactions(transactions);
             for (Result r : transactionsResponse.getModel().getResults()) {
-                transactions.add(new Transaction(formatDate(r.getDate()), !TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle(), BigDecimal.valueOf(r.getSum())));
+                StringBuilder title = new StringBuilder(!TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle());
+                if (!TextUtils.isEmpty(r.getCardholder())) {
+                    title.append(" (").append(r.getCardholder()).append(")");
+                }
+                transactions.add(new Transaction(formatDate(r.getDate()), title.toString(), BigDecimal.valueOf(r.getSum())));
             }
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
@@ -306,4 +368,23 @@ public class Coop extends Bank {
         String[] parts = date.split(" ");
         return String.format("%s-%s-%02d", parts[2], MONTHS.containsKey(parts[1].toLowerCase()) ? MONTHS.get(parts[1].toLowerCase()) : "01", Integer.parseInt(parts[0]));
     }
+
+    private boolean isFirstAccountForType(String accountId) {
+        for (AccountType at : AccountType.values()) {
+            if (accountId.equals(String.format("%s%d", at.getPrefix(), 0))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private AccountType getAccuntType(String accountId) {
+        for (AccountType at : AccountType.values()) {
+            if (accountId.startsWith(at.getPrefix())) {
+                return at;
+            }
+        }
+        return null;
+    }
+
 }
\ No newline at end of file

commit ca5d261fe7af6bd418ef23724d10a05f5229016b (tag: v1.9.6.15-RC2)
Author: liato <x@x00.us>
Date:   Fri May 16 01:33:15 2014 +0200

    Bump version. v1.9.6.15-RC2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 380b347..6db97f6 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.15-RC1" android:versionCode="185">
+	android:versionName="1.9.6.15-RC2" android:versionCode="186">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index f4cb7b5..89ea17f 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 185
-        versionName '1.9.6.15-RC1'
+        versionCode 186
+        versionName '1.9.6.15-RC2'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 6036a4e..e071ccc 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -16,17 +16,11 @@
 
 package com.liato.bankdroid;
 
-import java.io.IOException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.client.CookieStore;
-import org.apache.http.cookie.Cookie;
-
 import android.content.res.Resources.NotFoundException;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -40,6 +34,12 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Bank.SessionPackage;
 import com.liato.bankdroid.banking.BankFactory;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.http.client.CookieStore;
+import org.apache.http.cookie.Cookie;
+
+import java.io.IOException;
+
 import eu.nullbyte.android.urllib.Urllib;
 
 public class WebViewActivity extends LockableActivity implements OnClickListener {
@@ -47,6 +47,8 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
     private static WebView mWebView;
     private boolean mFirstPageLoaded = false;
     private final LockableActivity activity = this;
+    private Handler mMainThreadhandler = new Handler(Looper.getMainLooper());
+
     
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -104,7 +106,6 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
             e.printStackTrace();
         }
         mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", preloader, "text/html", "utf-8", null);
-
         Bundle extras = getIntent().getExtras();
         final long bankId = extras.getLong("bankid", -1);
         //final long bankId = -1;
@@ -112,22 +113,27 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
             Runnable generateLoginPage = new Runnable() {
                 public void run() {
                     Bank bank = BankFactory.bankFromDb(bankId, WebViewActivity.this, false);
-                    SessionPackage loginPackage = bank.getSessionPackage(WebViewActivity.this);
-                    CookieStore cookieStore = loginPackage.getCookiestore();
-                    if ((cookieStore != null) && !cookieStore.getCookies().isEmpty()) {
-                        CookieManager cookieManager = CookieManager.getInstance();
-                        String cookieString;
-                        for (Cookie cookie : cookieStore.getCookies()) {
-                            cookieString = String.format("%s=%s;%spath=%s; domain=%s;",
-                                    cookie.getName(), cookie.getValue(),
-                                    cookie.getExpiryDate() == null ? "" : "expires="+cookie.getExpiryDate()+"; ",
-                                    cookie.getPath() == null ? "/" : cookie.getPath(),
-                                    cookie.getDomain());
-                            cookieManager.setCookie(cookie.getDomain(), cookieString);
+                    final SessionPackage loginPackage = bank.getSessionPackage(WebViewActivity.this);
+                    final CookieStore cookieStore = loginPackage.getCookiestore();
+                    mMainThreadhandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            if ((cookieStore != null) && !cookieStore.getCookies().isEmpty()) {
+                                CookieManager cookieManager = CookieManager.getInstance();
+                                String cookieString;
+                                for (Cookie cookie : cookieStore.getCookies()) {
+                                    cookieString = String.format("%s=%s;%spath=%s; domain=%s;",
+                                            cookie.getName(), cookie.getValue(),
+                                            cookie.getExpiryDate() == null ? "" : "expires="+cookie.getExpiryDate()+"; ",
+                                            cookie.getPath() == null ? "/" : cookie.getPath(),
+                                            cookie.getDomain());
+                                    cookieManager.setCookie(cookie.getDomain(), cookieString);
+                                }
+                                csm.sync();
+                            }
+                            mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", loginPackage.getHtml(), "text/html", "utf-8", null);
                         }
-                        csm.sync();
-                    }
-                    mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", loginPackage.getHtml(), "text/html", "utf-8", null);
+                    });
                 }
               };
               new Thread(generateLoginPage).start();

commit c196677c6cf6e2b433bce6e037cfe896ee736d1f
Author: liato <x@x00.us>
Date:   Fri May 16 01:19:34 2014 +0200

    Show all "accounts" for Resurs Bank.

diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 5d10907..7edcd28 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -44,24 +44,24 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ResursBank extends Bank {
-	private Pattern reAccounts = Pattern.compile("kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</", Pattern.CASE_INSENSITIVE);
-	
-	private String response = null;
-
-	public ResursBank(Context context) {
-		super(context);
-		super.TAG = "ResursBank";
-		super.NAME = "Resurs Bank";
-		super.NAME_SHORT = "resursbank";
-		super.BANKTYPE_ID = IBankTypes.RESURSBANK;
-		super.URL = "https://secure.resurs.se/internetbank/default.jsp";
-	}
-
-	public ResursBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+    private Pattern reAccounts = Pattern.compile("kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</", Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    public ResursBank(Context context) {
+        super(context);
+        super.TAG = "ResursBank";
+        super.NAME = "Resurs Bank";
+        super.NAME_SHORT = "resursbank";
+        super.BANKTYPE_ID = IBankTypes.RESURSBANK;
+        super.URL = "https://secure.resurs.se/internetbank/default.jsp";
+    }
+
+    public ResursBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() throws BankException,
@@ -75,33 +75,33 @@ public class ResursBank extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://secure.resurs.se/internetbank/login.jsp");
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			if (response.contains("vid inloggningen")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen = login();
-	    Matcher matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+            if (response.contains("vid inloggningen")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
@@ -112,39 +112,45 @@ public class ResursBank extends Bank {
              * 5: Kvar att utnyttja     0,00 kr
              * 
              */
-		    String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll("[^0-9]*", "");
-			accounts.add(new Account("Beviljad kredit",
-			        Helpers.parseBalance(matcher.group(2)),
-			        "b_"+accountId));
-			
-			BigDecimal utnyttjad = Helpers.parseBalance(matcher.group(3));
-			utnyttjad = utnyttjad.add(Helpers.parseBalance(matcher.group(4)));
-			utnyttjad = utnyttjad.negate();
+            String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll("[^0-9]*", "");
+            accounts.add(new Account("Beviljad kredit",
+                    Helpers.parseBalance(matcher.group(2)),
+                    "b_"+accountId));
+
+            BigDecimal utnyttjad = Helpers.parseBalance(matcher.group(3));
+            utnyttjad = utnyttjad.add(Helpers.parseBalance(matcher.group(4)));
+            utnyttjad = utnyttjad.negate();
             accounts.add(new Account("Utnyttjad kredit",
                     utnyttjad,
                     "u_"+accountId));
-			
+
             balance = balance.add(Helpers.parseBalance(matcher.group(3)));
             balance = balance.add(utnyttjad);
-		}
-		
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	    super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		// Only update transactions for the main account
-		if (!account.getId().startsWith("b_")) return;
-		
-		try {
-			response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
-			Matcher matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
+            accounts.add(new Account("Reserverat belopp",
+                    Helpers.parseBalance(matcher.group(4)),
+                    "r_"+accountId));
+            accounts.add(new Account("Kvar att utnyttja",
+                    Helpers.parseBalance(matcher.group(5)),
+                    "k_"+accountId));
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        // Only update transactions for the main account
+        if (!account.getId().startsWith("b_")) return;
+
+        try {
+            response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
+            Matcher matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
@@ -154,17 +160,17 @@ public class ResursBank extends Bank {
                  * 4: Amount                -95,00 kr 
                  * 
                  */
-				transactions.add(new Transaction(matcher.group(1),
-				        Html.fromHtml(matcher.group(2)).toString().trim(),
-				        Helpers.parseBalance(matcher.group(4))));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}	
+                transactions.add(new Transaction(matcher.group(1),
+                        Html.fromHtml(matcher.group(2)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(4))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 }
\ No newline at end of file

commit 615f0c1810744c2a2c42357c706a2686dceffee6
Author: liato <x@x00.us>
Date:   Fri May 16 01:16:31 2014 +0200

    Fix for Coop MedMera Visa.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 5c24bcb..86ee4bd 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -351,10 +351,18 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             }
             //TODO: Skip the form submission. Login using Bank.login(...) and transfer cookies to webview. The user is now logged in
             //      and can me directed to any page.
-            String html = String.format(preloader,
-                    "function go(){document.getElementById('submitform').submit(); }", // Javascript function
-                    Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
-            );        
+            String html = "";
+            if (!lp.isLoggedIn()) {
+                html = String.format(preloader,
+                        "function go(){document.getElementById('submitform').submit(); }", // Javascript function
+                        Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
+                );
+            } else {
+                html = String.format(preloader,
+                        String.format("function go(){window.location=\"%s\" }", lp.getLoginTarget()), // Javascript function
+                        "<script type=\"text/javascript\">setTimeout('go()', 100);</script>" // HTML
+                );
+            }
 
             CookieStore cookies = urlopen.getHttpclient().getCookieStore();
             return new SessionPackage(html, cookies);
@@ -399,12 +407,17 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         private Urllib urllib;
         private List<NameValuePair> postData;
         private String loginTarget;
+        private boolean isLoggedIn = false;
         public LoginPackage(Urllib urllib, List<NameValuePair> postData, String response, String loginTarget) {
             this.urllib = urllib;
             this.postData = postData;
             this.response = response;
             this.loginTarget = loginTarget;
         }
+
+        public void setIsLoggedIn(boolean loggedIn) {
+            this.isLoggedIn = loggedIn;
+        }
         public String getResponse() {
             return response;
         }
@@ -417,6 +430,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         public String getLoginTarget() {
             return loginTarget;
         }
+        public boolean isLoggedIn() {
+            return this.isLoggedIn;
+        }
     }    
     
     public boolean getDisplayDecimals() {
diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index a8a1266..06a6872 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -202,6 +202,7 @@ public class ForexBank extends Bank {
         catch (IOException e) {
             throw new BankException(e.getMessage());
         }
+        super.updateComplete();
     }
 
     @Override
@@ -225,8 +226,5 @@ public class ForexBank extends Bank {
         } catch (IOException e) {
             e.printStackTrace();
         }
-        finally {
-            super.updateComplete();
-        }
     }
 }
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index df01cdd..1890dca 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -216,8 +216,5 @@ public class IkanoBank extends Bank {
         } catch (IOException e) {
             Log.e(TAG, "IOE: "+ e.getMessage());
         }
-        finally {
-            super.updateComplete();
-        }
-    }       	
+    }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index cf5eefb..85dc8fc 100644
--- src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -35,11 +35,13 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
@@ -70,7 +72,7 @@ public class Avanza extends Bank {
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
 
         try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all", null, false);
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all", new ArrayList<NameValuePair>(), false);
             if (httpResponse.getStatusLine().getStatusCode() == 401) {
                 throw new LoginException(context.getText(
                         R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
index 7db5969..13e3493 100644
--- src/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -17,33 +17,47 @@
 package com.liato.bankdroid.banking.banks.coop;
 
 import android.content.Context;
+import android.text.TextUtils;
 
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.banks.coop.model.AuthenticateRequest;
 import com.liato.bankdroid.banking.banks.coop.model.AuthenticateResponse;
 import com.liato.bankdroid.banking.banks.coop.model.RefundSummaryRequest;
 import com.liato.bankdroid.banking.banks.coop.model.RefundSummaryResponse;
+import com.liato.bankdroid.banking.banks.coop.model.web.Result;
+import com.liato.bankdroid.banking.banks.coop.model.web.WebAuthenticateRequest;
+import com.liato.bankdroid.banking.banks.coop.model.web.WebTransactionHistoryResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.HttpEntity;
-import org.apache.http.NameValuePair;
+import org.apache.http.HttpResponse;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
+import java.net.URLEncoder;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -57,15 +71,26 @@ public class Coop extends Bank {
     private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
     private static final int BANKTYPE_ID = IBankTypes.COOP;
     private static final String APPLICATION_ID = "17B2F3F1-841B-40B5-B91C-A5F33DE73C18";
+    private static final Map<String, String> MONTHS = new HashMap<String, String>();
+    static {
+        String[] ms = new String[] {"januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"};
+        for (int i = 0; i < ms.length; i++) {
+            MONTHS.put(ms[i], String.format("%02d", i+1));
+        }
+    }
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
  //   private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern rePageGuid = Pattern.compile("pageGuid\"\\s*:\\s*\"([^\"]+)", Pattern.CASE_INSENSITIVE);
     private ObjectMapper mObjectMapper;
     private String response;
     private String mToken;
     private String mUserId;
+    private String mPageGuid;
+    private String mDateMin;
+    private String mDateMax;
 
     public Coop(Context context) {
         super(context);
@@ -74,6 +99,7 @@ public class Coop extends Bank {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
+        super.STATIC_BALANCE = true;
     }
 
     public Coop(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -87,28 +113,37 @@ public class Coop extends Bank {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
         urlopen.addHeader("Origin", "https://www.coop.se");
         urlopen.addHeader("Referer", "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
-        response = urlopen.open("https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
-        
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+        response = urlopen.open("https://www.coop.se/");
+        Document d = Jsoup.parse(response);
+        String pageGuid = d.select("input[name=pageGuid]").first().val();
+        WebAuthenticateRequest webAuthReq = new WebAuthenticateRequest(pageGuid, username, password);
+        urlopen.addHeader("Content-Type", "application/json");
+        HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(webAuthReq));
+
+        HttpResponse httpResponse = urlopen.openAsHttpResponse("https://www.coop.se/Services/PlainService.svc/JsonExecute", e, true);
+        if (httpResponse.getStatusLine().getStatusCode() != 200) {
+            throw new BankException(res.getString(R.string.invalid_username_password));
         }
-        String strViewState = matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("TextBoxUserName", username));
-        postData.add(new BasicNameValuePair("TextBoxPassword", password));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ButtonLogin", ""));
-        return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
+
+        LoginPackage lp = new LoginPackage(urlopen, null, response, "https://www.coop.se/Mina-sidor/Oversikt/");
+        lp.setIsLoggedIn(true);
+        return lp;
     }
 
 
     @Override
     public Urllib login() throws LoginException, BankException {
         try {
+            //Coop MedMera Visa information and transactions are not available from the json api
+            //so we'll have to login once to the web site and once to the api.
+            LoginPackage lp = preLogin();
+            if (!lp.isLoggedIn()) {
+                throw new BankException(res.getString(R.string.invalid_username_password));
+            }
+
             AuthenticateRequest authReq = new AuthenticateRequest(username, password, APPLICATION_ID);
             HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(authReq));
-            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
+//            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
             urlopen.addHeader("Content-Type", "application/json");
             InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/UserService.svc/Authenticate", e, true);
             AuthenticateResponse authResponse = readJsonValue(is, AuthenticateResponse.class);
@@ -139,14 +174,72 @@ public class Coop extends Bank {
 
         login();
 
+        try {
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
+            Document d = Jsoup.parse(response);
+            Elements historik = d.select("#historik section");
+            if (historik != null && !historik.isEmpty()) {
+                String data = historik.first().attr("data-controller");
+                Matcher m = rePageGuid.matcher(data);
+                if (m.find()) {
+                    mPageGuid = m.group(1);
+                }
+            }
+            Element date = d.getElementById("dateFrom");
+            if (date != null) {
+                mDateMin = date.hasAttr("min") ? date.attr("min") : null;
+                mDateMax = date.hasAttr("max") ? date.attr("max") : null;
+            }
+            Elements es = d.select(".List:contains(Saldo)");
+            if (es != null && !es.isEmpty()) {
+                List<String> names = new ArrayList<String>();
+                List<String> values = new ArrayList<String>();
+                for (Element e : es.first().select("dt")) {
+                    names.add(e.text().replaceAll(":", "").trim());
+                }
+                for (Element e : es.first().select("dd")) {
+                    values.add(e.text().trim());
+                }
+                for (int i = 0; i < Math.min(names.size(), values.size()); i++) {
+                    Account a = new Account(names.get(i), Helpers.parseBalance(values.get(i)), Integer.toString(i));
+                    a.setCurrency(Helpers.parseCurrency(values.get(i), "SEK"));
+                    if (a.getName().toLowerCase().contains("disponibelt")) {
+                        a.setType(Account.REGULAR);
+                        balance = a.getBalance();
+                        setCurrency(a.getCurrency());
+                    } else {
+                        a.setType(Account.OTHER);
+                    }
+
+                    if (i > 0) {
+                        a.setAliasfor("0");
+                    }
+                    accounts.add(a);
+                }
+            }
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+
+
         try {
             RefundSummaryRequest refsumReq = new RefundSummaryRequest(mUserId, mToken, APPLICATION_ID);
             HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(refsumReq));
             InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/RefundService.svc/RefundSummary", e, true);
             RefundSummaryResponse refsumResp = readJsonValue(is, RefundSummaryResponse.class);
             if (refsumResp != null && refsumResp.getRefundSummaryResult() != null) {
-                Account a = new Account("Återbäring på ditt kort", BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getAccountBalance()), "1");
+                Account a = new Account("Återbäring på ditt kort", BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getAccountBalance()), "refsummary");
                 a.setCurrency("SEK");
+                if (accounts.isEmpty()) {
+                    balance = a.getBalance();
+                    setCurrency(a.getCurrency());
+                }
+                accounts.add(a);
+                a = new Account(String.format("Återbäring för %s", refsumResp.getRefundSummaryResult().getMonthName()), BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getPeriodRefund()), "refsummary_month");
                 accounts.add(a);
             }
         } catch (JsonParseException e) {
@@ -183,4 +276,34 @@ public class Coop extends Bank {
             return null;
         }
     }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        if (mPageGuid == null || mDateMin == null || mDateMax == null || !"0".equals(account.getId())) return;
+        try {
+            String data = URLEncoder.encode(String.format("{\"page\":1,\"pageSize\":15,\"from\":\"%s\",\"to\":\"%s\"}", mDateMin, mDateMax), "utf-8");
+            String url = String.format("https://www.coop.se/Services/PlainService.svc/JsonExecuteGet?pageGuid=%s&method=GetTransactions&data=%s&_=%s", mPageGuid, data, System.currentTimeMillis());
+            WebTransactionHistoryResponse transactionsResponse = getObjectmapper().readValue(urlopen.openStream(url), WebTransactionHistoryResponse.class);
+            List<Transaction> transactions = new ArrayList<Transaction>();
+            account.setTransactions(transactions);
+            for (Result r : transactionsResponse.getModel().getResults()) {
+                transactions.add(new Transaction(formatDate(r.getDate()), !TextUtils.isEmpty(r.getLocation()) ? r.getLocation() : r.getTitle(), BigDecimal.valueOf(r.getSum())));
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (JsonMappingException e) {
+            e.printStackTrace();
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private String formatDate(String date) {
+        String[] parts = date.split(" ");
+        return String.format("%s-%s-%02d", parts[2], MONTHS.containsKey(parts[1].toLowerCase()) ? MONTHS.get(parts[1].toLowerCase()) : "01", Integer.parseInt(parts[0]));
+    }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/D.java src/com/liato/bankdroid/banking/banks/coop/model/web/D.java
new file mode 100644
index 0000000..577476c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/web/D.java
@@ -0,0 +1,35 @@
+
+package com.liato.bankdroid.banking.banks.coop.model.web;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class D {
+
+    @JsonProperty("template")
+    private String template;
+    @JsonProperty("model")
+    private Model model;
+
+    @JsonProperty("template")
+    public String getTemplate() {
+        return template;
+    }
+
+    @JsonProperty("template")
+    public void setTemplate(String template) {
+        this.template = template;
+    }
+
+    @JsonProperty("model")
+    public Model getModel() {
+        return model;
+    }
+
+    @JsonProperty("model")
+    public void setModel(Model model) {
+        this.model = model;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/Model.java src/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
new file mode 100644
index 0000000..17232ad
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/web/Model.java
@@ -0,0 +1,98 @@
+
+package com.liato.bankdroid.banking.banks.coop.model.web;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Model {
+
+    @JsonProperty("results")
+    private List<Result> results = new ArrayList<Result>();
+    @JsonProperty("from")
+    private String from;
+    @JsonProperty("to")
+    private String to;
+    @JsonProperty("id")
+    private String id;
+    @JsonProperty("page")
+    private int page;
+    @JsonProperty("pageCount")
+    private int pageCount;
+    @JsonProperty("pageSize")
+    private int pageSize;
+
+    @JsonProperty("results")
+    public List<Result> getResults() {
+        return results;
+    }
+
+    @JsonProperty("results")
+    public void setResults(List<Result> results) {
+        this.results = results;
+    }
+
+    @JsonProperty("from")
+    public String getFrom() {
+        return from;
+    }
+
+    @JsonProperty("from")
+    public void setFrom(String from) {
+        this.from = from;
+    }
+
+    @JsonProperty("to")
+    public String getTo() {
+        return to;
+    }
+
+    @JsonProperty("to")
+    public void setTo(String to) {
+        this.to = to;
+    }
+
+    @JsonProperty("id")
+    public String getId() {
+        return id;
+    }
+
+    @JsonProperty("id")
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @JsonProperty("page")
+    public int getPage() {
+        return page;
+    }
+
+    @JsonProperty("page")
+    public void setPage(int page) {
+        this.page = page;
+    }
+
+    @JsonProperty("pageCount")
+    public int getPageCount() {
+        return pageCount;
+    }
+
+    @JsonProperty("pageCount")
+    public void setPageCount(int pageCount) {
+        this.pageCount = pageCount;
+    }
+
+    @JsonProperty("pageSize")
+    public int getPageSize() {
+        return pageSize;
+    }
+
+    @JsonProperty("pageSize")
+    public void setPageSize(int pageSize) {
+        this.pageSize = pageSize;
+    }
+
+}
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/Result.java src/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
new file mode 100644
index 0000000..9b5dc62
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/web/Result.java
@@ -0,0 +1,144 @@
+
+package com.liato.bankdroid.banking.banks.coop.model.web;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Result {
+
+    @JsonProperty("date")
+    private String date;
+    @JsonProperty("icon")
+    private boolean icon;
+    @JsonProperty("title")
+    private String title;
+    @JsonProperty("cardholder")
+    private String cardholder;
+    @JsonProperty("location")
+    private String location;
+    @JsonProperty("sum")
+    private double sum;
+    @JsonProperty("charity")
+    private boolean charity;
+    @JsonProperty("hasdetails")
+    private boolean hasdetails;
+    @JsonProperty("detailsurl")
+    private String detailsurl;
+    @JsonProperty("batchnumber")
+    private int batchnumber;
+    @JsonProperty("sequencenumber")
+    private int sequencenumber;
+
+    @JsonProperty("date")
+    public String getDate() {
+        return date;
+    }
+
+    @JsonProperty("date")
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    @JsonProperty("icon")
+    public boolean getIcon() {
+        return icon;
+    }
+
+    @JsonProperty("icon")
+    public void setIcon(boolean icon) {
+        this.icon = icon;
+    }
+
+    @JsonProperty("title")
+    public String getTitle() {
+        return title;
+    }
+
+    @JsonProperty("title")
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @JsonProperty("cardholder")
+    public String getCardholder() {
+        return cardholder;
+    }
+
+    @JsonProperty("cardholder")
+    public void setCardholder(String cardholder) {
+        this.cardholder = cardholder;
+    }
+
+    @JsonProperty("location")
+    public String getLocation() {
+        return location;
+    }
+
+    @JsonProperty("location")
+    public void setLocation(String location) {
+        this.location = location;
+    }
+
+    @JsonProperty("sum")
+    public double getSum() {
+        return sum;
+    }
+
+    @JsonProperty("sum")
+    public void setSum(double sum) {
+        this.sum = sum;
+    }
+
+    @JsonProperty("charity")
+    public boolean getCharity() {
+        return charity;
+    }
+
+    @JsonProperty("charity")
+    public void setCharity(boolean charity) {
+        this.charity = charity;
+    }
+
+    @JsonProperty("hasdetails")
+    public boolean getHasdetails() {
+        return hasdetails;
+    }
+
+    @JsonProperty("hasdetails")
+    public void setHasdetails(boolean hasdetails) {
+        this.hasdetails = hasdetails;
+    }
+
+    @JsonProperty("detailsurl")
+    public String getDetailsurl() {
+        return detailsurl;
+    }
+
+    @JsonProperty("detailsurl")
+    public void setDetailsurl(String detailsurl) {
+        this.detailsurl = detailsurl;
+    }
+
+    @JsonProperty("batchnumber")
+    public int getBatchnumber() {
+        return batchnumber;
+    }
+
+    @JsonProperty("batchnumber")
+    public void setBatchnumber(int batchnumber) {
+        this.batchnumber = batchnumber;
+    }
+
+    @JsonProperty("sequencenumber")
+    public int getSequencenumber() {
+        return sequencenumber;
+    }
+
+    @JsonProperty("sequencenumber")
+    public void setSequencenumber(int sequencenumber) {
+        this.sequencenumber = sequencenumber;
+    }
+
+
+}
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java src/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
new file mode 100644
index 0000000..62d105e
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/web/WebAuthenticateRequest.java
@@ -0,0 +1,83 @@
+package com.liato.bankdroid.banking.banks.coop.model.web;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class WebAuthenticateRequest {
+    @JsonProperty("methodName")
+    private String methodName = "Login";
+    @JsonProperty("pageGuid")
+    private String pageGuid;
+    @JsonProperty("data")
+    private Data data;
+
+    public WebAuthenticateRequest(String pageGuid, String username, String password) {
+        this.pageGuid = pageGuid;
+        data = new Data(username, password);
+    }
+
+    @JsonProperty("methodName")
+    public String getMethodName() {
+        return methodName;
+    }
+
+    @JsonProperty("methodName")
+    public void setMethodName(String methodName) {
+        this.methodName = methodName;
+    }
+
+    @JsonProperty("pageGuid")
+    public String getPageGuid() {
+        return pageGuid;
+    }
+
+    @JsonProperty("pageGuid")
+    public void setPageGuid(String pageGuid) {
+        this.pageGuid = pageGuid;
+    }
+
+    @JsonProperty("data")
+    public Data getData() {
+        return data;
+    }
+
+    @JsonProperty("data")
+    public void setData(Data data) {
+        this.data = data;
+    }
+
+
+    public static class Data {
+
+        @JsonProperty("username")
+        private String username;
+        @JsonProperty("password")
+        private String password;
+
+        public Data(String username, String password) {
+            this.username = username;
+            this.password = password;
+        }
+
+        @JsonProperty("username")
+        public String getUsername() {
+            return username;
+        }
+
+        @JsonProperty("username")
+        public void setUsername(String username) {
+            this.username = username;
+        }
+
+        @JsonProperty("password")
+        public String getPassword() {
+            return password;
+        }
+
+        @JsonProperty("password")
+        public void setPassword(String password) {
+            this.password = password;
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
new file mode 100644
index 0000000..a9b1e33
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/web/WebTransactionHistoryResponse.java
@@ -0,0 +1,26 @@
+
+package com.liato.bankdroid.banking.banks.coop.model.web;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WebTransactionHistoryResponse {
+
+    @JsonProperty("d")
+    private D d;
+
+    @JsonProperty("d")
+    public D getD() {
+        return d;
+    }
+
+    @JsonProperty("d")
+    public void setD(D d) {
+        this.d = d;
+    }
+
+    public Model getModel() {
+        return this.d.getModel();
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/ica/ICA.java src/com/liato/bankdroid/banking/banks/ica/ICA.java
index 548fc32..bf618fd 100644
--- src/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 
 import java.io.IOException;
@@ -85,7 +86,7 @@ public class ICA extends Bank {
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
 
         try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login", null, false);
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login", new ArrayList<NameValuePair>(), false);
             if (httpResponse.getStatusLine().getStatusCode() == 401) {
                 LoginError le = readJsonValue(httpResponse, LoginError.class);
                 if (le != null && "UsernamePassword".equals(le.getMessageCode())) {
@@ -111,7 +112,7 @@ public class ICA extends Bank {
             }
 
             urlopen.addHeader(AUTHENTICATION_TICKET_HEADER, mHeaders.get(AUTHENTICATION_TICKET_HEADER));
-            httpResponse = urlopen.openAsHttpResponse(API_URL + "user/minasidor", null, false);
+            httpResponse = urlopen.openAsHttpResponse(API_URL + "user/minasidor", new ArrayList<NameValuePair>(), false);
             Overview overview = readJsonValue(httpResponse, Overview.class);
 
             if (overview == null) {
@@ -151,7 +152,7 @@ public class ICA extends Bank {
             }
 
             urlopen.addHeader(LOGOUT_KEY_HEADER, mHeaders.get(LOGOUT_KEY_HEADER));
-            httpResponse = urlopen.openAsHttpResponse(API_URL + "logout", null, false);
+            httpResponse = urlopen.openAsHttpResponse(API_URL + "logout", new ArrayList<NameValuePair>(), false);
             httpResponse.getStatusLine();
         } catch (JsonParseException e) {
             e.printStackTrace();
diff --git src/com/liato/bankdroid/banking/banks/payson/Payson.java src/com/liato/bankdroid/banking/banks/payson/Payson.java
index ceb7a1b..baf607c 100644
--- src/com/liato/bankdroid/banking/banks/payson/Payson.java
+++ src/com/liato/bankdroid/banking/banks/payson/Payson.java
@@ -136,9 +136,9 @@ public class Payson extends Bank {
         urlopen = login();
 
         try {
-            HttpResponse httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/User/GetUserInfo?DateTime=%s", System.currentTimeMillis()), null, false);
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/User/GetUserInfo?DateTime=%s", System.currentTimeMillis()), new ArrayList<NameValuePair>(), false);
             User user = readJsonValue(httpResponse, User.class);
-            httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/History/List2?rows=40&page=1&sidx=&sord=asc&freeTextSearchString=&take=40&currency=&timeSpanStartDate=&timeSpanEndDate=&minAmount=&maxAmount=&purchaseType=&purchasePart=&purchaseStatus=&_=%s", System.currentTimeMillis()), null, false);
+            httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/History/List2?rows=40&page=1&sidx=&sord=asc&freeTextSearchString=&take=40&currency=&timeSpanStartDate=&timeSpanEndDate=&minAmount=&maxAmount=&purchaseType=&purchasePart=&purchaseStatus=&_=%s", System.currentTimeMillis()), new ArrayList<NameValuePair>(), false);
             TransactionHistory thistory = readJsonValue(httpResponse, TransactionHistory.class);
 
             Account account = new Account("Saldo", Helpers.parseBalance(user.getBalance()), "1");
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index d3c4565..ff2c98b 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -143,19 +143,24 @@ public class Urllib {
     }
 
     public HttpResponse openAsHttpResponse(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+        HttpEntity entity = (postData == null || postData.isEmpty()) && !forcePost ? null : new UrlEncodedFormEntity(postData, this.charset);
+        return openAsHttpResponse(url, entity, forcePost);
+    }
+
+    public HttpResponse openAsHttpResponse(String url, HttpEntity entity, boolean forcePost) throws ClientProtocolException, IOException {
         this.currentURI = url;
         HttpResponse response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         ResponseHandler<String> responseHandler = new BasicResponseHandler();
         HttpUriRequest request;
-        if ((postData == null || postData.isEmpty()) && !forcePost) {
+        if ((entity == null) && !forcePost) {
             //URL urli = new URL(url);
             request = new HttpGet(url);
         }
         else {
             request = new HttpPost(url);
-            ((HttpPost)request).setEntity(new UrlEncodedFormEntity(postData, this.charset));
+            ((HttpPost)request).setEntity(entity);
         }
         if (userAgent != null)
             request.addHeader("User-Agent", userAgent);

commit 55d5a4cbd90822dc4d0708c6b0cc3469b4b9288a (tag: v1.9.6.15-RC1)
Author: liato <x@x00.us>
Date:   Wed May 14 00:06:17 2014 +0200

    Bump version. v1.9.6.15-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 43dd1a6..380b347 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.14" android:versionCode="184">
+	android:versionName="1.9.6.15-RC1" android:versionCode="185">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index fc20d0e..f4cb7b5 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 184
-        versionName '1.9.6.14'
+        versionCode 185
+        versionName '1.9.6.15-RC1'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit a4def325b5ab232dccc53be46d0c15f15a270f67
Author: liato <x@x00.us>
Date:   Wed May 14 00:03:09 2014 +0200

    Show account balance instead of period refund for Coop.

diff --git src/com/liato/bankdroid/banking/banks/coop/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
index b5237ff..7db5969 100644
--- src/com/liato/bankdroid/banking/banks/coop/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -145,7 +145,7 @@ public class Coop extends Bank {
             InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/RefundService.svc/RefundSummary", e, true);
             RefundSummaryResponse refsumResp = readJsonValue(is, RefundSummaryResponse.class);
             if (refsumResp != null && refsumResp.getRefundSummaryResult() != null) {
-                Account a = new Account("Återbäring på ditt kort", BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getPeriodRefund()), "1");
+                Account a = new Account("Återbäring på ditt kort", BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getAccountBalance()), "1");
                 a.setCurrency("SEK");
                 accounts.add(a);
             }

commit 765ec3f2e4f78418373c2edcb16c3826c7e0fad4
Author: liato <x@x00.us>
Date:   Wed May 14 00:00:12 2014 +0200

    Login fix for Ikano Partner banks.

diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index d48956f..e3fb62c 100644
--- src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -30,6 +30,7 @@ import org.jsoup.select.Elements;
 
 import android.content.Context;
 import android.text.InputType;
+import android.text.TextUtils;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -56,6 +57,7 @@ public abstract class AbsIkanoPartner extends Bank {
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = true;
     }
 
     public AbsIkanoPartner(String username, String password, Context context) throws BankException, LoginException,
@@ -68,35 +70,33 @@ public abstract class AbsIkanoPartner extends Bank {
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+
         Document d = Jsoup.parse(response);
-        Element e = d.getElementById("__VIEWSTATE");
-        if (e == null || e.attr("value") == null) {
+        Element viewstate = d.getElementById("__VIEWSTATE");
+        if (viewstate == null || TextUtils.isEmpty(viewstate.val())) {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
-        String viewState = e.attr("value");
 
-        e = d.getElementById("__EVENTVALIDATION");
-        if (e == null || e.attr("value") == null) {
+        Element eventvalidation = d.getElementById("__EVENTVALIDATION");
+        if (eventvalidation == null || TextUtils.isEmpty(eventvalidation.val())) {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
-        String eventValidation = e.attr("value");
 
-        e = d.select("#LoginCustomerDiv > div").first();
-        if (e == null || e.attr("id") == null || e.attr("id").split("_", 2).length < 2) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl.");
+        Element userField = d.select("#LoginSpan input[type=text]").first();
+        Element passField = d.select("#LoginSpan input[type=password]").first();
+        Element submitField = d.select("#LoginCustomerDiv input[type=submit]").first();
+
+        if (userField == null || passField == null || submitField == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " login fields.");
         }
-        String ctl = e.attr("id").split("_", 2)[0];
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-        postData.add(new BasicNameValuePair(ctl
-                + "$LoginWebUserControl$SSNControl$SSNSimpleValueUsercontrol$editValueTextbox", username));
-        postData.add(new BasicNameValuePair(ctl
-                + "$LoginWebUserControl$passwordSimpleValueControl$passwordSimpleValueControl$editValueTextbox",
-                password));
-        postData.add(new BasicNameValuePair(ctl + "$LoginButton", ""));
-        return new LoginPackage(urlopen, postData, response,
-                "https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewstate.val()));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventvalidation.val()));
+        postData.add(new BasicNameValuePair(userField.attr("name"), username));
+        postData.add(new BasicNameValuePair(passField.attr("name"), password));
+        postData.add(new BasicNameValuePair(submitField.attr("name"), submitField.val()));
+        return new LoginPackage(urlopen, postData, response, "https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+
     }
 
     @Override
@@ -173,13 +173,11 @@ public abstract class AbsIkanoPartner extends Bank {
                 throw new BankException(e.getMessage());
             } catch (IOException e) {
                 throw new BankException(e.getMessage());
-            } finally {
-                super.updateComplete();
             }
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
-
+        super.updateComplete();
     }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/Audi.java src/com/liato/bankdroid/banking/banks/Audi.java
index a75821d..dcae4ce 100644
--- src/com/liato/bankdroid/banking/banks/Audi.java
+++ src/com/liato/bankdroid/banking/banks/Audi.java
@@ -24,11 +24,11 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
 public class Audi extends AbsIkanoPartner {
-	private static final String TAG = "Audi";
-	private static final String NAME = "AudiKortet";
-	private static final String NAME_SHORT = "audi";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2177";
-	private static final int BANKTYPE_ID = Bank.AUDI;
+    private static final String TAG = "Audi";
+    private static final String NAME = "AudiKortet";
+    private static final String NAME_SHORT = "audi";
+    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2177";
+    private static final int BANKTYPE_ID = Bank.AUDI;
 
     public Audi(Context context) {
         super(context);
diff --git src/com/liato/bankdroid/banking/banks/IKEA.java src/com/liato/bankdroid/banking/banks/IKEA.java
index 47e1e2a..009cf16 100644
--- src/com/liato/bankdroid/banking/banks/IKEA.java
+++ src/com/liato/bankdroid/banking/banks/IKEA.java
@@ -23,12 +23,12 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class IKEA extends IkanoPartnerBase {
-	private static final String TAG = "IKEA";
-	private static final String NAME = "IKEA HANDLA kort";
-	private static final String NAME_SHORT = "ikea";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
-	private static final int BANKTYPE_ID = Bank.IKEA;
+public class IKEA extends AbsIkanoPartner {
+    private static final String TAG = "IKEA";
+    private static final String NAME = "IKEA HANDLA kort";
+    private static final String NAME_SHORT = "ikea";
+    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
+    private static final int BANKTYPE_ID = Bank.IKEA;
 
     public IKEA(Context context) {
         super(context);
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
deleted file mode 100644
index b6147a7..0000000
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *  Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public abstract class IkanoPartnerBase extends Bank {
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
-    
-
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reCtl = Pattern.compile("(ctl\\d{1,})_CustomValidationSummary", Pattern.CASE_INSENSITIVE);
-    protected Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Transaktioner</", Pattern.CASE_INSENSITIVE);
-    private Pattern reCreditInfoUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Kredit-? ?uppgifter</", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("captionLabel\">(?:<span></span>)?([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
-    private Pattern reTransactions = Pattern.compile("<td\\s*class=\"TransactionDateRow\">([^>]+)</td><td[^>]+>(.+?)</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>");
-    private String response = null;
-	protected String structId;
-	
-
-	public IkanoPartnerBase(Context context) {
-		super(context);
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public IkanoPartnerBase(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-	
-	@Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
-        response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-        }
-        String viewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-        }
-        String eventValidation = matcher.group(1);
-        matcher = reCtl.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ctl.");
-        }
-        String ctl = matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-        postData.add(new BasicNameValuePair(ctl+"$LoginWebUserControl$SSNControl$SSNSimpleValueUsercontrol$editValueTextbox", username));
-        postData.add(new BasicNameValuePair(ctl+"$LoginWebUserControl$passwordSimpleValueControl$passwordSimpleValueControl$editValueTextbox", password));
-        postData.add(new BasicNameValuePair(ctl+"$LoginButton", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, "https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
-    }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-		
-			if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
-			        || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen = login();
-		Matcher matcher;
-		try {
-            String creditPageUrl = null;
-            String transactionsPageUrl = null;
-		    matcher = reCreditInfoUrl.matcher(response);
-            if (matcher.find()) {
-                creditPageUrl = matcher.group(1);
-            }
-		    
-	        matcher = reTransactionsUrl.matcher(response);
-	        if (!matcher.find() && creditPageUrl == null) {
-	            throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions url.");
-	        }
-	        transactionsPageUrl = matcher.group(1);
-		    
-	        // If a url for the credit page is found we request that page first. If no url for the credit page is
-	        // found we only need to request the transactions page as all the credit info should be available on
-	        // that page.
-            response = urlopen.open("https://partner.ikanobank.se/web/engines/"+(creditPageUrl == null ? transactionsPageUrl : creditPageUrl));
-	            
-			matcher = reAccounts.matcher(response);
-			int accId = 0;
-			while (matcher.find()) {
-	            /*
-	             * Capture groups:
-	             * GROUP                EXAMPLE DATA
-	             * 1: Name              Kvar att handla för
-	             * 2: Amount            17&nbsp;229,85
-	             * 3: Currency          &nbsp;kr 
-	             *   
-	             */
-			    Account account = new Account(
-                        Html.fromHtml(matcher.group(1)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(2)),
-                        Integer.toString(accId));
-			    if (accId > 0) {
-			        account.setAliasfor("0");
-			    }
-				accounts.add(account);
-				accId++;
-			}
-			
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-			 // Use the amount from "Kvar att handla för" which should be the last account in the list.
-		    this.balance = accounts.get(accounts.size()-1).getBalance();
-		    
-		    if (creditPageUrl != null) {
-		        response = urlopen.open("https://partner.ikanobank.se/web/engines/"+transactionsPageUrl);
-		    }
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            matcher = reTransactions.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Date              2011-02-27
-                 * 2: Specification     Best Buy<br>
-                 * 3: Amount            143,07 kr
-                 * 4: Currency          SEK
-                 *   
-                 */                
-                Transaction transaction = new Transaction(
-                        matcher.group(1).trim(),
-                        Html.fromHtml(matcher.group(2).replaceAll("<br>", " ")).toString().trim(),
-                        Helpers.parseBalance(matcher.group(3)));
-                transactions.add(transaction);
-            }
-            accounts.get(0).setTransactions(transactions);
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		finally {
-		    super.updateComplete();
-		}
-	}
-}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/Preem.java src/com/liato/bankdroid/banking/banks/Preem.java
index 4ecfe11..22e88ff 100644
--- src/com/liato/bankdroid/banking/banks/Preem.java
+++ src/com/liato/bankdroid/banking/banks/Preem.java
@@ -16,8 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.util.regex.Pattern;
-
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
@@ -26,13 +24,12 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Preem extends IkanoPartnerBase {
-	private static final String TAG = "Preem";
-	private static final String NAME = "Preem Privatkort";
-	private static final String NAME_SHORT = "preem";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
-	private static final int BANKTYPE_ID = Bank.PREEM;
-	private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Mitt konto</", Pattern.CASE_INSENSITIVE);
+public class Preem extends AbsIkanoPartner {
+    private static final String TAG = "Preem";
+    private static final String NAME = "Preem Privatkort";
+    private static final String NAME_SHORT = "preem";
+    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
+    private static final int BANKTYPE_ID = Bank.PREEM;
 
     public Preem(Context context) {
         super(context);
@@ -41,7 +38,6 @@ public class Preem extends IkanoPartnerBase {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
-        super.reTransactionsUrl = reTransactionsUrl;
         this.structId = "1437";
     }
 
diff --git src/com/liato/bankdroid/banking/banks/Seat.java src/com/liato/bankdroid/banking/banks/Seat.java
index 69e33bf..156eb7f 100644
--- src/com/liato/bankdroid/banking/banks/Seat.java
+++ src/com/liato/bankdroid/banking/banks/Seat.java
@@ -23,12 +23,12 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Seat extends IkanoPartnerBase {
-	private static final String TAG = "Seat";
-	private static final String NAME = "Seatkortet";
-	private static final String NAME_SHORT = "seat";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1301";
-	private static final int BANKTYPE_ID = Bank.SEAT;
+public class Seat extends AbsIkanoPartner {
+    private static final String TAG = "Seat";
+    private static final String NAME = "Seatkortet";
+    private static final String NAME_SHORT = "seat";
+    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1301";
+    private static final int BANKTYPE_ID = Bank.SEAT;
 
     public Seat(Context context) {
         super(context);
diff --git src/com/liato/bankdroid/banking/banks/Shell.java src/com/liato/bankdroid/banking/banks/Shell.java
index a37e9b1..d2fe884 100644
--- src/com/liato/bankdroid/banking/banks/Shell.java
+++ src/com/liato/bankdroid/banking/banks/Shell.java
@@ -23,12 +23,12 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Shell extends IkanoPartnerBase {
-	private static final String TAG = "Shell";
-	private static final String NAME = "Shell MasterCard";
-	private static final String NAME_SHORT = "shell";
-	private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
-	private static final int BANKTYPE_ID = Bank.SHELL;
+public class Shell extends AbsIkanoPartner {
+    private static final String TAG = "Shell";
+    private static final String NAME = "Shell MasterCard";
+    private static final String NAME_SHORT = "shell";
+    private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
+    private static final int BANKTYPE_ID = Bank.SHELL;
 
     public Shell(Context context) {
         super(context);
diff --git src/com/liato/bankdroid/banking/banks/Skoda.java src/com/liato/bankdroid/banking/banks/Skoda.java
index 4f65c4c..23900bc 100644
--- src/com/liato/bankdroid/banking/banks/Skoda.java
+++ src/com/liato/bankdroid/banking/banks/Skoda.java
@@ -24,11 +24,11 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
 public class Skoda extends AbsIkanoPartner {
-	private static final String TAG = "Skoda";
-	private static final String NAME = "Skodakortet";
-	private static final String NAME_SHORT = "skoda";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2461";
-	private static final int BANKTYPE_ID = Bank.SKODA;
+    private static final String TAG = "Skoda";
+    private static final String NAME = "Skodakortet";
+    private static final String NAME_SHORT = "skoda";
+    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2461";
+    private static final int BANKTYPE_ID = Bank.SKODA;
 
     public Skoda(Context context) {
         super(context);
diff --git src/com/liato/bankdroid/banking/banks/Volkswagen.java src/com/liato/bankdroid/banking/banks/Volkswagen.java
index 10c7018..2c33dc5 100644
--- src/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ src/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -23,12 +23,12 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Volkswagen extends IkanoPartnerBase {
-	private static final String TAG = "Volkswagen";
-	private static final String NAME = "Volkswagenkortet";
-	private static final String NAME_SHORT = "volkswagen";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1319";
-	private static final int BANKTYPE_ID = Bank.VOLKSWAGEN;
+public class Volkswagen extends AbsIkanoPartner {
+    private static final String TAG = "Volkswagen";
+    private static final String NAME = "Volkswagenkortet";
+    private static final String NAME_SHORT = "volkswagen";
+    private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1319";
+    private static final int BANKTYPE_ID = Bank.VOLKSWAGEN;
 
     public Volkswagen(Context context) {
         super(context);

commit 69f4513ed0e5c0ba31266c7f1b53c0fb0507396a (tag: v1.9.6.14)
Author: liato <x@x00.us>
Date:   Tue May 13 00:02:47 2014 +0200

    Bump version. v1.9.6.14.

diff --git AndroidManifest.xml AndroidManifest.xml
index db2bc3f..43dd1a6 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.13" android:versionCode="183">
+	android:versionName="1.9.6.14" android:versionCode="184">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index d86b1a1..5582929 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,11 @@
+v1.9.6.14: (2014-05-13)
+* Fix for ICA Banken
+* Fix for Payson
+* Partial fix for Coop
++ Support for Sveadirekt (thanks to goober)
++ Support for Supreme Card
+
+
 v1.9.6.13: (2014-04-30)
 * Prevent recent apps thumbnail for pattern lock and settings
 * Updated SSL certificate for American Express, Coop, CSN, Handelsbanken, Osuuspankki, PayPal, Resurs Bank, Sevenday and Zidisha.
diff --git build.gradle build.gradle
index 3e7c204..fc20d0e 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 183
-        versionName '1.9.6.13'
+        versionCode 184
+        versionName '1.9.6.14'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 36e0496f256c4e6ddb8d042074e1d3a1532f8a57
Author: liato <x@x00.us>
Date:   Mon May 12 23:59:43 2014 +0200

    Add SupremeCard as a separate bank.

diff --git res/drawable-xxhdpi/logo_supremecard.png res/drawable-xxhdpi/logo_supremecard.png
new file mode 100644
index 0000000..da5c480
Binary files /dev/null and res/drawable-xxhdpi/logo_supremecard.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 7446023..1119522 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -22,7 +22,9 @@
     <string name="transparent_background">Transparent bakgrund</string>
     <string name="bank_closed">Banken är för närvarande stängd.</string>
     <string name="unable_to_login">Kunde ej logga in. Var vänlig försök igen senare.</string>
-    
+    <string name="account_number">Kontonummer</string>
+    <string name="control_code">Kontrollkod</string>
+
     <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
     <string name="bank">Bank</string>
diff --git res/values/strings.xml res/values/strings.xml
index 1f9591d..a760f2f 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -21,7 +21,9 @@
     <string name="transparent_background">Transparent background</string>
     <string name="bank_closed">The bank is currently closed.</string>
     <string name="unable_to_login">Unable to login. Please try again later.</string>
-    
+    <string name="account_number">Account number</string>
+    <string name="control_code">Control code</string>
+
     <string name="username">Username</string>
     <string name="password">Password</string>
     <string name="custom_name">Custom Name (optional)</string>
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index fda96e9..0a01da4 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -33,7 +33,6 @@ import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
-import com.liato.bankdroid.banking.banks.coop.Coop;
 import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
@@ -60,7 +59,6 @@ import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
-import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.Quintessentially;
@@ -76,6 +74,7 @@ import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
+import com.liato.bankdroid.banking.banks.SupremeCard;
 import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -90,10 +89,12 @@ import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
+import com.liato.bankdroid.banking.banks.coop.Coop;
 import com.liato.bankdroid.banking.banks.ica.ICA;
 import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.nordea.Nordea;
+import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
@@ -259,6 +260,8 @@ public class BankFactory {
             return new Bitcoin(context);
         case IBankTypes.SVEADIREKT:
             return new SveaDirekt(context);
+        case IBankTypes.SUPREMECARD:
+            return new SupremeCard(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -341,6 +344,7 @@ public class BankFactory {
         banks.add(new Bitcoin(context));
         banks.add(new EurobonusMastercardDk(context));
         banks.add(new SveaDirekt(context));
+        banks.add(new SupremeCard(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 04c88a5..5d10907 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -44,12 +44,6 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ResursBank extends Bank {
-	private static final String TAG = "ResursBank";
-	private static final String NAME = "Resurs Bank";
-	private static final String NAME_SHORT = "resursbank";
-	private static final String URL = "https://secure.resurs.se/internetbank/default.jsp";
-	private static final int BANKTYPE_ID = IBankTypes.RESURSBANK;
-	
 	private Pattern reAccounts = Pattern.compile("kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</", Pattern.CASE_INSENSITIVE);
 	
@@ -57,11 +51,11 @@ public class ResursBank extends Bank {
 
 	public ResursBank(Context context) {
 		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+		super.TAG = "ResursBank";
+		super.NAME = "Resurs Bank";
+		super.NAME_SHORT = "resursbank";
+		super.BANKTYPE_ID = IBankTypes.RESURSBANK;
+		super.URL = "https://secure.resurs.se/internetbank/default.jsp";
 	}
 
 	public ResursBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
diff --git src/com/liato/bankdroid/banking/banks/SupremeCard.java src/com/liato/bankdroid/banking/banks/SupremeCard.java
new file mode 100644
index 0000000..aaa5799
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/SupremeCard.java
@@ -0,0 +1,26 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+public class SupremeCard extends ResursBank {
+
+    public SupremeCard(Context context) {
+        super(context);
+        super.TAG = "SupremeCard";
+        super.NAME = "Supreme Card";
+        super.NAME_SHORT = "supremecard";
+        super.INPUT_TITLETEXT_USERNAME = R.string.account_number;
+        super.INPUT_TITLETEXT_PASSWORD = R.string.control_code;
+        super.BANKTYPE_ID = IBankTypes.SUPREMECARD;
+    }
+
+    public SupremeCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        super(username, password, context);
+    }
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 7d47611..909cc96 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -96,4 +96,5 @@ public interface IBankTypes {
     public final static int BITCOIN = 72;
     public final static int SASEUROBONUSMASTERCARD_DK = 73;
     public final static int SVEADIREKT  = 74;
+    public final static int SUPREMECARD  = 75;
 }

commit 9e22337b535662044e6112e417610943e649e0a3
Author: liato <x@x00.us>
Date:   Mon May 12 23:31:51 2014 +0200

    Fix for Payson. Partial fix for Coop.

diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 4461faa..b53e49d 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -141,6 +141,7 @@ public class Helpers {
     }
 
     public static String parseCurrency(String text, String def) {
+        text = text != null ? text.toLowerCase() : "";
         for (String currency : currencies) {
             if (text.contains(currency)) return currency;
         }
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 2c3ac95..fda96e9 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -33,7 +33,7 @@ import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
-import com.liato.bankdroid.banking.banks.Coop;
+import com.liato.bankdroid.banking.banks.coop.Coop;
 import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
@@ -60,7 +60,7 @@ import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
-import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.payson.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.Quintessentially;
diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
deleted file mode 100644
index fb087cd..0000000
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Payson extends Bank {
-	private static final String TAG = "Payson";
-	private static final String NAME = "Payson";
-	private static final String NAME_SHORT = "payson";
-	private static final String URL = "https://www.payson.se/signin/";
-	private static final int BANKTYPE_ID = IBankTypes.PAYSON;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-	
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reBalance = Pattern.compile("Saldo:\\s*<strong>([^<+]+)[<+]", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("href=\"details/Default\\.aspx\\?\\d{1,}\">\\s*<span\\s*title=\"(\\d{4}-\\d{2}-\\d{2})[^\"]+\">.*?Grid1_0_3_\\d{1,}_Hy[^>]+>([^<]+)<.*?Grid1_0_5_\\d{1,}_Hy[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private String response = null;
-	
-	public Payson(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-	}
-
-	public Payson(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_payson));
-        response = urlopen.open("https://www.payson.se/signin/");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-        }
-        String strViewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-        }
-        String strEventValidation = matcher.group(1);
-
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtEmail", username));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtPassword", password));
-        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$btnLogin", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, "https://www.payson.se/signin/");
-    }
-
-    @Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-            LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktig E-postadress") || response.contains("Lösenord saknas") ||
-			        response.contains("E-postadress saknas"))  {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			e.printStackTrace();
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		try {
-			Matcher matcher;
-			matcher = reBalance.matcher(response);
-			if (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Balance           0,00 kr
-                 *  
-                 */
-			    Account account = new Account("Konto" , Helpers.parseBalance(matcher.group(1)), "1");
-			    String currency = Helpers.parseCurrency(matcher.group(1).trim(), "SEK");
-			    account.setCurrency(currency);
-			    this.setCurrency(currency);
-				accounts.add(account);
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-	
-	
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Date              2010-06-03
-                 * 2: Specification     Best&#228;llning fr&#229;n SPELKONTROLL.SE
-                 * 3: Amount            -228,00 kr
-                 *   
-                 */     
-				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			accounts.get(0).setTransactions(transactions);
-		}		
-        finally {
-            super.updateComplete();
-        }
-	}
-}
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/coop/Coop.java
similarity index 56%
rename from src/com/liato/bankdroid/banking/banks/Coop.java
rename to src/com/liato/bankdroid/banking/banks/coop/Coop.java
index 26c05a0..b5237ff 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/coop/Coop.java
@@ -14,31 +14,39 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
+package com.liato.bankdroid.banking.banks.coop;
 
 import android.content.Context;
-import android.text.Html;
 
-import com.liato.bankdroid.Helpers;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.coop.model.AuthenticateRequest;
+import com.liato.bankdroid.banking.banks.coop.model.AuthenticateResponse;
+import com.liato.bankdroid.banking.banks.coop.model.RefundSummaryRequest;
+import com.liato.bankdroid.banking.banks.coop.model.RefundSummaryResponse;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.HttpEntity;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -48,12 +56,16 @@ public class Coop extends Bank {
     private static final String NAME_SHORT = "coop";
     private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
     private static final int BANKTYPE_ID = IBankTypes.COOP;
+    private static final String APPLICATION_ID = "17B2F3F1-841B-40B5-B91C-A5F33DE73C18";
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
  //   private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
+    private ObjectMapper mObjectMapper;
     private String response;
+    private String mToken;
+    private String mUserId;
 
     public Coop(Context context) {
         super(context);
@@ -82,17 +94,11 @@ public class Coop extends Bank {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
         }
         String strViewState = matcher.group(1);
-//        matcher = reEventValidation.matcher(response);
-//        if (!matcher.find()) {
-//          throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
-//        }
-//        String strEventValidation = matcher.group(1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("TextBoxUserName", username));
         postData.add(new BasicNameValuePair("TextBoxPassword", password));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair("ButtonLogin", ""));
-//        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
         return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
     }
 
@@ -100,11 +106,20 @@ public class Coop extends Bank {
     @Override
     public Urllib login() throws LoginException, BankException {
         try {
-            LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("felaktiga")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            AuthenticateRequest authReq = new AuthenticateRequest(username, password, APPLICATION_ID);
+            HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(authReq));
+            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
+            urlopen.addHeader("Content-Type", "application/json");
+            InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/UserService.svc/Authenticate", e, true);
+            AuthenticateResponse authResponse = readJsonValue(is, AuthenticateResponse.class);
+            if (authResponse == null) {
+                throw new BankException(res.getString(R.string.unable_to_login));
+            }
+            if (authResponse.getAuthenticateResult() == null || authResponse.getErrorid() != null || authResponse.getAuthenticateResult() == null) {
+                throw new LoginException(res.getString(R.string.invalid_username_password));
             }
+            mToken = authResponse.getAuthenticateResult().getToken();
+            mUserId = Integer.toString(authResponse.getAuthenticateResult().getUserID());
         }
         catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
@@ -112,7 +127,7 @@ public class Coop extends Bank {
         catch (IOException e) {
             throw new BankException(e.getMessage());
         }
-        return urlopen;		
+        return urlopen;
     }
 
     @Override
@@ -122,62 +137,27 @@ public class Coop extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
-        urlopen = login();
-        Matcher matcher;
-        Account account;
+        login();
 
-
-        class RequestDetails {
-            public String url, name, id;
-            public RequestDetails(String url, String name, String id) {
-                this.url = url;
-                this.name = name;
-                this.id = id;
-            }
-        }    
-        ArrayList<RequestDetails> arrRD = new ArrayList<RequestDetails>();
-        arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/", "MedMera Visa", "1"));
-        arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/", "MedMera Konto", "2"));
-        arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Faktura/", "MedMera Faktura", "3"));
-
-        for (RequestDetails rd : arrRD) {
-            try {
-                response = urlopen.open(rd.url);
-                matcher = reBalance.matcher(response);
-                if (matcher.find()) {
-                    account = new Account(rd.name, Helpers.parseBalance(matcher.group(1).trim()), rd.id);
-                    balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-                    matcher = reTransactions.matcher(response);
-                    ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                    while (matcher.find()) {
-                        /*
-                         * Capture groups:
-                         * GROUP                EXAMPLE DATA
-                         * 1: Date              2010-11-04
-                         * 2: Activity          Köp
-                         * 3: User              John Doe
-                         * 4: Place             Coop Extra Stenungsund
-                         * 5: Amount            -809,37 kr
-                         *                      * 
-                         */
-
-                        String title = Html.fromHtml(matcher.group(4)).toString().trim().length() > 0 ? Html.fromHtml(matcher.group(4)).toString().trim() : Html.fromHtml(matcher.group(2)).toString().trim();
-                        if (Html.fromHtml(matcher.group(3)).toString().trim().length() > 0) {
-                            title = title + " (" + Html.fromHtml(matcher.group(3)).toString().trim() + ")";
-                        }
-                        transactions.add(new Transaction(matcher.group(1).trim(),
-                                title,
-                                Helpers.parseBalance(matcher.group(5))));
-                    }
-                    account.setTransactions(transactions);
-                    accounts.add(account);
-                }
-            }
-            catch (ClientProtocolException e) {
-                //404 or 500 response
+        try {
+            RefundSummaryRequest refsumReq = new RefundSummaryRequest(mUserId, mToken, APPLICATION_ID);
+            HttpEntity e = new StringEntity(getObjectmapper().writeValueAsString(refsumReq));
+            InputStream is = urlopen.openStream("https://www.coop.se/ExternalServices/RefundService.svc/RefundSummary", e, true);
+            RefundSummaryResponse refsumResp = readJsonValue(is, RefundSummaryResponse.class);
+            if (refsumResp != null && refsumResp.getRefundSummaryResult() != null) {
+                Account a = new Account("Återbäring på ditt kort", BigDecimal.valueOf(refsumResp.getRefundSummaryResult().getPeriodRefund()), "1");
+                a.setCurrency("SEK");
+                accounts.add(a);
             }
-            catch (IOException e) {
-            }                        
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
         }
 
         if (accounts.isEmpty()) {
@@ -185,4 +165,22 @@ public class Coop extends Bank {
         }
         super.updateComplete();
     }
+
+    private ObjectMapper getObjectmapper() {
+        if (mObjectMapper == null) {
+            mObjectMapper = new ObjectMapper();
+            mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
+        }
+        return mObjectMapper;
+    }
+
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+        try {
+            return getObjectmapper().readValue(is, valueType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
new file mode 100644
index 0000000..a970220
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateRequest.java
@@ -0,0 +1,54 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class AuthenticateRequest {
+
+    @JsonProperty("password")
+    private String password;
+    @JsonProperty("username")
+    private String username;
+    @JsonProperty("applicationID")
+    private String applicationID;
+
+    public AuthenticateRequest(String username, String password, String applicationID) {
+        this.username = username;
+        this.password = password;
+        this.applicationID = applicationID;
+    }
+
+    public AuthenticateRequest() {
+
+    }
+
+    @JsonProperty("password")
+    public String getPassword() {
+        return password;
+    }
+
+    @JsonProperty("password")
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    @JsonProperty("username")
+    public String getUsername() {
+        return username;
+    }
+
+    @JsonProperty("username")
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    @JsonProperty("applicationID")
+    public String getApplicationID() {
+        return applicationID;
+    }
+
+    @JsonProperty("applicationID")
+    public void setApplicationID(String applicationID) {
+        this.applicationID = applicationID;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
new file mode 100644
index 0000000..0958a18
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResponse.java
@@ -0,0 +1,22 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AuthenticateResponse extends BaseResponse {
+
+    @JsonProperty("AuthenticateResult")
+    private AuthenticateResult authenticateResult;
+
+    @JsonProperty("AuthenticateResult")
+    public AuthenticateResult getAuthenticateResult() {
+        return authenticateResult;
+    }
+
+    @JsonProperty("AuthenticateResult")
+    public void setAuthenticateResult(AuthenticateResult authenticateResult) {
+        this.authenticateResult = authenticateResult;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
new file mode 100644
index 0000000..15e955d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/AuthenticateResult.java
@@ -0,0 +1,35 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AuthenticateResult {
+
+    @JsonProperty("Token")
+    private String token;
+    @JsonProperty("UserID")
+    private int userID;
+
+    @JsonProperty("Token")
+    public String getToken() {
+        return token;
+    }
+
+    @JsonProperty("Token")
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    @JsonProperty("UserID")
+    public int getUserID() {
+        return userID;
+    }
+
+    @JsonProperty("UserID")
+    public void setUserID(int userID) {
+        this.userID = userID;
+    }
+
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java src/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
new file mode 100644
index 0000000..f13c645
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/BaseResponse.java
@@ -0,0 +1,32 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BaseResponse {
+
+    @JsonProperty("errorid")
+    private String errorid;
+    @JsonProperty("message")
+    private String message;
+
+    @JsonProperty("errorid")
+    public String getErrorid() {
+        return errorid;
+    }
+
+    @JsonProperty("errorid")
+    public void setErrorid(String errorid) {
+        this.errorid = errorid;
+    }
+
+    @JsonProperty("message")
+    public String getMessage() {
+        return message;
+    }
+
+    @JsonProperty("message")
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
new file mode 100644
index 0000000..1e19efc
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryRequest.java
@@ -0,0 +1,54 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class RefundSummaryRequest {
+
+    @JsonProperty("token")
+    private String token;
+    @JsonProperty("userID")
+    private String userID;
+    @JsonProperty("applicationID")
+    private String applicationID;
+
+    public RefundSummaryRequest(String userID, String token, String applicationID) {
+        this.userID = userID;
+        this.token = token;
+        this.applicationID = applicationID;
+    }
+
+    public RefundSummaryRequest() {
+
+    }
+
+    @JsonProperty("token")
+    public String getToken() {
+        return token;
+    }
+
+    @JsonProperty("token")
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    @JsonProperty("userID")
+    public String getUserID() {
+        return userID;
+    }
+
+    @JsonProperty("userID")
+    public void setUserID(String userID) {
+        this.userID = userID;
+    }
+
+    @JsonProperty("applicationID")
+    public String getApplicationID() {
+        return applicationID;
+    }
+
+    @JsonProperty("applicationID")
+    public void setApplicationID(String applicationID) {
+        this.applicationID = applicationID;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
new file mode 100644
index 0000000..d985aa4
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResponse.java
@@ -0,0 +1,22 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RefundSummaryResponse extends BaseResponse {
+
+    @JsonProperty("RefundSummaryResult")
+    private RefundSummaryResult refundSummaryResult;
+
+    @JsonProperty("RefundSummaryResult")
+    public RefundSummaryResult getRefundSummaryResult() {
+        return refundSummaryResult;
+    }
+
+    @JsonProperty("RefundSummaryResult")
+    public void setRefundSummaryResult(RefundSummaryResult refundSummaryResult) {
+        this.refundSummaryResult = refundSummaryResult;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
new file mode 100644
index 0000000..79e9761
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/coop/model/RefundSummaryResult.java
@@ -0,0 +1,82 @@
+package com.liato.bankdroid.banking.banks.coop.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RefundSummaryResult {
+
+    @JsonProperty("AccountBalance")
+    private double accountBalance;
+    @JsonProperty("MonthName")
+    private String monthName;
+    @JsonProperty("PeriodRefund")
+    private int periodRefund;
+    @JsonProperty("ProfileNextRateDistance")
+    private int profileNextRateDistance;
+    @JsonProperty("ProfileRate")
+    private double profileRate;
+    @JsonProperty("TotalRefund")
+    private int totalRefund;
+
+    @JsonProperty("AccountBalance")
+    public double getAccountBalance() {
+        return accountBalance;
+    }
+
+    @JsonProperty("AccountBalance")
+    public void setAccountBalance(double accountBalance) {
+        this.accountBalance = accountBalance;
+    }
+
+    @JsonProperty("MonthName")
+    public String getMonthName() {
+        return monthName;
+    }
+
+    @JsonProperty("MonthName")
+    public void setMonthName(String monthName) {
+        this.monthName = monthName;
+    }
+
+    @JsonProperty("PeriodRefund")
+    public int getPeriodRefund() {
+        return periodRefund;
+    }
+
+    @JsonProperty("PeriodRefund")
+    public void setPeriodRefund(int periodRefund) {
+        this.periodRefund = periodRefund;
+    }
+
+    @JsonProperty("ProfileNextRateDistance")
+    public int getProfileNextRateDistance() {
+        return profileNextRateDistance;
+    }
+
+    @JsonProperty("ProfileNextRateDistance")
+    public void setProfileNextRateDistance(int profileNextRateDistance) {
+        this.profileNextRateDistance = profileNextRateDistance;
+    }
+
+    @JsonProperty("ProfileRate")
+    public double getProfileRate() {
+        return profileRate;
+    }
+
+    @JsonProperty("ProfileRate")
+    public void setProfileRate(double profileRate) {
+        this.profileRate = profileRate;
+    }
+
+    @JsonProperty("TotalRefund")
+    public int getTotalRefund() {
+        return totalRefund;
+    }
+
+    @JsonProperty("TotalRefund")
+    public void setTotalRefund(int totalRefund) {
+        this.totalRefund = totalRefund;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/payson/Payson.java src/com/liato/bankdroid/banking/banks/payson/Payson.java
new file mode 100644
index 0000000..ceb7a1b
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/payson/Payson.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.payson;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.text.TextUtils;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.payson.model.TransactionHistory;
+import com.liato.bankdroid.banking.banks.payson.model.User;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Payson extends Bank {
+    private static final String TAG = "Payson";
+    private static final String NAME = "Payson";
+    private static final String NAME_SHORT = "payson";
+    private static final String URL = "https://www.payson.se/signin/";
+    private static final int BANKTYPE_ID = IBankTypes.PAYSON;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | +InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reCleanText = Pattern.compile("\\s+", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private String response = null;
+    private ObjectMapper mObjectMapper;
+
+    public Payson(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+    }
+
+    public Payson(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_payson));
+        response = urlopen.open("https://www.payson.se/signin/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String strViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+        }
+        String strEventValidation = matcher.group(1);
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtEmail", username));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtPassword", password));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$btnLogin", "Logga in"));
+        return new LoginPackage(urlopen, postData, response, "https://www.payson.se/signin/");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("Felaktig E-postadress") || response.contains("Lösenord saknas") ||
+                    response.contains("E-postadress saknas")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        try {
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/User/GetUserInfo?DateTime=%s", System.currentTimeMillis()), null, false);
+            User user = readJsonValue(httpResponse, User.class);
+            httpResponse = urlopen.openAsHttpResponse(String.format("https://www.payson.se/myaccount/History/List2?rows=40&page=1&sidx=&sord=asc&freeTextSearchString=&take=40&currency=&timeSpanStartDate=&timeSpanEndDate=&minAmount=&maxAmount=&purchaseType=&purchasePart=&purchaseStatus=&_=%s", System.currentTimeMillis()), null, false);
+            TransactionHistory thistory = readJsonValue(httpResponse, TransactionHistory.class);
+
+            Account account = new Account("Saldo", Helpers.parseBalance(user.getBalance()), "1");
+            String currency = Helpers.parseCurrency(user.getBalance(), "SEK");
+            account.setCurrency(currency);
+            setCurrency(currency);
+            accounts.add(account);
+            balance = balance.add(account.getBalance());
+
+            if (thistory != null && thistory.getRows() != null) {
+                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                for (com.liato.bankdroid.banking.banks.payson.model.Transaction transaction : thistory.getRows()) {
+                    String date = transaction.getCreatedDate().substring(0, 10);
+                    String description = !TextUtils.isEmpty(transaction.getMessage()) ? transaction.getMessage() : transaction.getSummary();
+
+                    Transaction t = new Transaction(date, Html.fromHtml(description).toString(), Helpers.parseBalance(transaction.getAmount()));
+                    t.setCurrency(Helpers.parseCurrency(transaction.getCurrencySymbol(), account.getCurrency()));
+                    transactions.add(t);
+                }
+                account.setTransactions(transactions);
+
+            }
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+        super.updateComplete();
+    }
+
+    private <T> T readJsonValue(HttpResponse response, Class<T> valueType) throws BankException {
+        try {
+            return readJsonValue(response.getEntity().getContent(), valueType);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+        try {
+            return getObjectmapper().readValue(is, valueType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private ObjectMapper getObjectmapper() {
+        if (mObjectMapper == null) {
+            mObjectMapper = new ObjectMapper();
+            mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
+        }
+        return mObjectMapper;
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/payson/model/Transaction.java src/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
new file mode 100644
index 0000000..364b661
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/payson/model/Transaction.java
@@ -0,0 +1,214 @@
+package com.liato.bankdroid.banking.banks.payson.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Transaction {
+
+    @JsonProperty("Uri")
+    private String uri;
+    @JsonProperty("CreatedDate")
+    private String createdDate;
+    @JsonProperty("AmountDisplayValue")
+    private String amountDisplayValue;
+    @JsonProperty("CreditedAmountDisplayValue")
+    private String creditedAmountDisplayValue;
+    @JsonProperty("PurchaseId")
+    private String purchaseId;
+    @JsonProperty("Message")
+    private String message;
+    @JsonProperty("Summary")
+    private String summary;
+    @JsonProperty("Status")
+    private String status;
+    @JsonProperty("StatusId")
+    private String statusId;
+    @JsonProperty("PurchaseType")
+    private String purchaseType;
+    @JsonProperty("PurchaseTypeRaw")
+    private String purchaseTypeRaw;
+    @JsonProperty("IsActionable")
+    private String isActionable;
+    @JsonProperty("IsGuarantee")
+    private String isGuarantee;
+    @JsonProperty("ReceiverEmail")
+    private String receiverEmail;
+    @JsonProperty("SenderEmail")
+    private String senderEmail;
+    @JsonProperty("CurrencySymbol")
+    private String currencySymbol;
+    @JsonProperty("Amount")
+    private String amount;
+
+    @JsonProperty("Uri")
+    public String getUri() {
+        return uri;
+    }
+
+    @JsonProperty("Uri")
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    @JsonProperty("CreatedDate")
+    public String getCreatedDate() {
+        return createdDate;
+    }
+
+    @JsonProperty("CreatedDate")
+    public void setCreatedDate(String createdDate) {
+        this.createdDate = createdDate;
+    }
+
+    @JsonProperty("AmountDisplayValue")
+    public String getAmountDisplayValue() {
+        return amountDisplayValue;
+    }
+
+    @JsonProperty("AmountDisplayValue")
+    public void setAmountDisplayValue(String amountDisplayValue) {
+        this.amountDisplayValue = amountDisplayValue;
+    }
+
+    @JsonProperty("CreditedAmountDisplayValue")
+    public String getCreditedAmountDisplayValue() {
+        return creditedAmountDisplayValue;
+    }
+
+    @JsonProperty("CreditedAmountDisplayValue")
+    public void setCreditedAmountDisplayValue(String creditedAmountDisplayValue) {
+        this.creditedAmountDisplayValue = creditedAmountDisplayValue;
+    }
+
+    @JsonProperty("PurchaseId")
+    public String getPurchaseId() {
+        return purchaseId;
+    }
+
+    @JsonProperty("PurchaseId")
+    public void setPurchaseId(String purchaseId) {
+        this.purchaseId = purchaseId;
+    }
+
+    @JsonProperty("Message")
+    public String getMessage() {
+        return message;
+    }
+
+    @JsonProperty("Message")
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    @JsonProperty("Summary")
+    public String getSummary() {
+        return summary;
+    }
+
+    @JsonProperty("Summary")
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    @JsonProperty("Status")
+    public String getStatus() {
+        return status;
+    }
+
+    @JsonProperty("Status")
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    @JsonProperty("StatusId")
+    public String getStatusId() {
+        return statusId;
+    }
+
+    @JsonProperty("StatusId")
+    public void setStatusId(String statusId) {
+        this.statusId = statusId;
+    }
+
+    @JsonProperty("PurchaseType")
+    public String getPurchaseType() {
+        return purchaseType;
+    }
+
+    @JsonProperty("PurchaseType")
+    public void setPurchaseType(String purchaseType) {
+        this.purchaseType = purchaseType;
+    }
+
+    @JsonProperty("PurchaseTypeRaw")
+    public String getPurchaseTypeRaw() {
+        return purchaseTypeRaw;
+    }
+
+    @JsonProperty("PurchaseTypeRaw")
+    public void setPurchaseTypeRaw(String purchaseTypeRaw) {
+        this.purchaseTypeRaw = purchaseTypeRaw;
+    }
+
+    @JsonProperty("IsActionable")
+    public String getIsActionable() {
+        return isActionable;
+    }
+
+    @JsonProperty("IsActionable")
+    public void setIsActionable(String isActionable) {
+        this.isActionable = isActionable;
+    }
+
+    @JsonProperty("IsGuarantee")
+    public String getIsGuarantee() {
+        return isGuarantee;
+    }
+
+    @JsonProperty("IsGuarantee")
+    public void setIsGuarantee(String isGuarantee) {
+        this.isGuarantee = isGuarantee;
+    }
+
+    @JsonProperty("ReceiverEmail")
+    public String getReceiverEmail() {
+        return receiverEmail;
+    }
+
+    @JsonProperty("ReceiverEmail")
+    public void setReceiverEmail(String receiverEmail) {
+        this.receiverEmail = receiverEmail;
+    }
+
+    @JsonProperty("SenderEmail")
+    public String getSenderEmail() {
+        return senderEmail;
+    }
+
+    @JsonProperty("SenderEmail")
+    public void setSenderEmail(String senderEmail) {
+        this.senderEmail = senderEmail;
+    }
+
+    @JsonProperty("CurrencySymbol")
+    public String getCurrencySymbol() {
+        return currencySymbol;
+    }
+
+    @JsonProperty("CurrencySymbol")
+    public void setCurrencySymbol(String currencySymbol) {
+        this.currencySymbol = currencySymbol;
+    }
+
+    @JsonProperty("Amount")
+    public String getAmount() {
+        return amount;
+    }
+
+    @JsonProperty("Amount")
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java src/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
new file mode 100644
index 0000000..ea38877
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/payson/model/TransactionHistory.java
@@ -0,0 +1,61 @@
+package com.liato.bankdroid.banking.banks.payson.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TransactionHistory {
+
+    @JsonProperty("total")
+    private int total;
+    @JsonProperty("TotalUnFilteredCount")
+    private int totalUnFilteredCount;
+    @JsonProperty("rows")
+    private List<Transaction> rows = new ArrayList<Transaction>();
+    @JsonProperty("MaxItemAmount")
+    private double maxItemAmount;
+
+    @JsonProperty("total")
+    public int getTotal() {
+        return total;
+    }
+
+    @JsonProperty("total")
+    public void setTotal(int total) {
+        this.total = total;
+    }
+
+    @JsonProperty("TotalUnFilteredCount")
+    public int getTotalUnFilteredCount() {
+        return totalUnFilteredCount;
+    }
+
+    @JsonProperty("TotalUnFilteredCount")
+    public void setTotalUnFilteredCount(int totalUnFilteredCount) {
+        this.totalUnFilteredCount = totalUnFilteredCount;
+    }
+
+    @JsonProperty("rows")
+    public List<Transaction> getRows() {
+        return rows;
+    }
+
+    @JsonProperty("rows")
+    public void setRows(List<Transaction> rows) {
+        this.rows = rows;
+    }
+
+    @JsonProperty("MaxItemAmount")
+    public double getMaxItemAmount() {
+        return maxItemAmount;
+    }
+
+    @JsonProperty("MaxItemAmount")
+    public void setMaxItemAmount(double maxItemAmount) {
+        this.maxItemAmount = maxItemAmount;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/payson/model/User.java src/com/liato/bankdroid/banking/banks/payson/model/User.java
new file mode 100644
index 0000000..07112eb
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/payson/model/User.java
@@ -0,0 +1,46 @@
+package com.liato.bankdroid.banking.banks.payson.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class User {
+
+    @JsonProperty("userName")
+    private String userName;
+    @JsonProperty("balance")
+    private String balance;
+    @JsonProperty("pending")
+    private String pending;
+
+    @JsonProperty("userName")
+    public String getUserName() {
+        return userName;
+    }
+
+    @JsonProperty("userName")
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    @JsonProperty("balance")
+    public String getBalance() {
+        return balance;
+    }
+
+    @JsonProperty("balance")
+    public void setBalance(String balance) {
+        this.balance = balance;
+    }
+
+    @JsonProperty("pending")
+    public String getPending() {
+        return pending;
+    }
+
+    @JsonProperty("pending")
+    public void setPending(String pending) {
+        this.pending = pending;
+    }
+
+}
\ No newline at end of file

commit 8b1d8a9d6b9c190485fc1d1dfc9ffc5cbc26c93f
Merge: 123a1a5 ab88852
Author: liato <x@x00.us>
Date:   Fri May 9 23:42:57 2014 +0200

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Adds support for SveaDirekt.

commit 123a1a5932204adc208419c1941cb0e985985b48
Author: liato <x@x00.us>
Date:   Fri May 9 23:42:47 2014 +0200

    Ignore unknown json properties for ICA Banken.

diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
index 6cdfeb0..69ff542 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
@@ -3,160 +3,162 @@ package com.liato.bankdroid.banking.banks.icabanken.model;
 import java.math.BigDecimal;
 import java.util.List;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class IcaBankenAccount {
-	private String mAccountId;
+    private String mAccountId;
 
-	private String mAccountNumber;
+    private String mAccountNumber;
 
-	private String mAddress;
+    private String mAddress;
 
-	private BigDecimal mAvailableAmount;
+    private BigDecimal mAvailableAmount;
 
-	private String mBic;
+    private String mBic;
 
-	private BigDecimal mCurrentAmount;
+    private BigDecimal mCurrentAmount;
 
-	private String mGroup;
+    private String mGroup;
 
-	private String mHolder;
+    private String mHolder;
 
-	private String mIban;
+    private String mIban;
 
-	private String mName;
+    private String mName;
 
-	private BigDecimal mOutstandingAmount;
+    private BigDecimal mOutstandingAmount;
 
-	private List<String> mServices;
+    private List<String> mServices;
 
-	private List<IcaBankenTransaction> mTransactions;
+    private List<IcaBankenTransaction> mTransactions;
 
-	private List<String> mValidFor;
+    private List<String> mValidFor;
 
-	@JsonProperty("AccountId")
-	public String getAccountId() {
-		return mAccountId;
-	}
+    @JsonProperty("AccountId")
+    public String getAccountId() {
+        return mAccountId;
+    }
 
-	public void setAccountId(String pAccountId) {
-		this.mAccountId = pAccountId;
-	}
+    public void setAccountId(String pAccountId) {
+        this.mAccountId = pAccountId;
+    }
 
-	@JsonProperty("AccountNumber")
-	public String getAccountNumber() {
-		return mAccountNumber;
-	}
+    @JsonProperty("AccountNumber")
+    public String getAccountNumber() {
+        return mAccountNumber;
+    }
 
-	public void setAccountNumber(String pAccountNumber) {
-		this.mAccountNumber = pAccountNumber;
-	}
+    public void setAccountNumber(String pAccountNumber) {
+        this.mAccountNumber = pAccountNumber;
+    }
 
-	@JsonProperty("Address")
-	public String getAddress() {
-		return mAddress;
-	}
+    @JsonProperty("Address")
+    public String getAddress() {
+        return mAddress;
+    }
 
-	public void setAddress(String pAddress) {
-		this.mAddress = pAddress;
-	}
+    public void setAddress(String pAddress) {
+        this.mAddress = pAddress;
+    }
 
-	@JsonProperty("AvailableAmount")
-	public BigDecimal getAvailableAmount() {
-		return mAvailableAmount;
-	}
+    @JsonProperty("AvailableAmount")
+    public BigDecimal getAvailableAmount() {
+        return mAvailableAmount;
+    }
 
-	public void setAvailableAmount(BigDecimal pAvailableAmount) {
-		this.mAvailableAmount = pAvailableAmount;
-	}
+    public void setAvailableAmount(BigDecimal pAvailableAmount) {
+        this.mAvailableAmount = pAvailableAmount;
+    }
 
-	@JsonProperty("BIC")
-	public String getBic() {
-		return mBic;
-	}
+    @JsonProperty("BIC")
+    public String getBic() {
+        return mBic;
+    }
 
-	public void setBic(String pBic) {
-		this.mBic = pBic;
-	}
+    public void setBic(String pBic) {
+        this.mBic = pBic;
+    }
 
-	@JsonProperty("CurrentAmount")
-	public BigDecimal getCurrentAmount() {
-		return mCurrentAmount;
-	}
+    @JsonProperty("CurrentAmount")
+    public BigDecimal getCurrentAmount() {
+        return mCurrentAmount;
+    }
 
-	public void setCurrentAmount(BigDecimal pCurrentAmount) {
-		this.mCurrentAmount = pCurrentAmount;
-	}
+    public void setCurrentAmount(BigDecimal pCurrentAmount) {
+        this.mCurrentAmount = pCurrentAmount;
+    }
 
-	@JsonProperty("Group")
-	public String getGroup() {
-		return mGroup;
-	}
+    @JsonProperty("Group")
+    public String getGroup() {
+        return mGroup;
+    }
 
-	public void setGroup(String pGroup) {
-		this.mGroup = pGroup;
-	}
+    public void setGroup(String pGroup) {
+        this.mGroup = pGroup;
+    }
 
-	@JsonProperty("Holder")
-	public String getHolder() {
-		return mHolder;
-	}
+    @JsonProperty("Holder")
+    public String getHolder() {
+        return mHolder;
+    }
 
-	public void setHolder(String pHolder) {
-		this.mHolder = pHolder;
-	}
+    public void setHolder(String pHolder) {
+        this.mHolder = pHolder;
+    }
 
-	@JsonProperty("IBAN")
-	public String getIban() {
-		return mIban;
-	}
+    @JsonProperty("IBAN")
+    public String getIban() {
+        return mIban;
+    }
 
-	public void setIban(String pIban) {
-		this.mIban = pIban;
-	}
+    public void setIban(String pIban) {
+        this.mIban = pIban;
+    }
 
-	@JsonProperty("Name")
-	public String getName() {
-		return mName;
-	}
+    @JsonProperty("Name")
+    public String getName() {
+        return mName;
+    }
 
-	public void setName(String pName) {
-		this.mName = pName;
-	}
-
-	@JsonProperty("OutstandingAmount")
-	public BigDecimal getOutstandingAmount() {
-		return mOutstandingAmount;
-	}
-
-	public void setOutstandingAmount(BigDecimal pOutstandingAmount) {
-		this.mOutstandingAmount = pOutstandingAmount;
-	}
-
-	@JsonProperty("Services")
-	public List<String> getServices() {
-		return mServices;
-	}
-
-	public void setServices(List<String> pServices) {
-		this.mServices = pServices;
-	}
-
-	@JsonProperty("Transactions")
-	public List<IcaBankenTransaction> getTransactions() {
-		return mTransactions;
-	}
-
-	public void setTransactions(List<IcaBankenTransaction> pTransactions) {
-		this.mTransactions = pTransactions;
-	}
-
-	@JsonProperty("ValidFor")
-	public List<String> getValidFor() {
-		return mValidFor;
-	}
-
-	public void setValidFor(List<String> pValidFor) {
-		this.mValidFor = pValidFor;
-	}
+    public void setName(String pName) {
+        this.mName = pName;
+    }
+
+    @JsonProperty("OutstandingAmount")
+    public BigDecimal getOutstandingAmount() {
+        return mOutstandingAmount;
+    }
+
+    public void setOutstandingAmount(BigDecimal pOutstandingAmount) {
+        this.mOutstandingAmount = pOutstandingAmount;
+    }
+
+    @JsonProperty("Services")
+    public List<String> getServices() {
+        return mServices;
+    }
+
+    public void setServices(List<String> pServices) {
+        this.mServices = pServices;
+    }
+
+    @JsonProperty("Transactions")
+    public List<IcaBankenTransaction> getTransactions() {
+        return mTransactions;
+    }
+
+    public void setTransactions(List<IcaBankenTransaction> pTransactions) {
+        this.mTransactions = pTransactions;
+    }
+
+    @JsonProperty("ValidFor")
+    public List<String> getValidFor() {
+        return mValidFor;
+    }
+
+    public void setValidFor(List<String> pValidFor) {
+        this.mValidFor = pValidFor;
+    }
 }
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
index c08aca1..2eb03e7 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
@@ -3,118 +3,120 @@ package com.liato.bankdroid.banking.banks.icabanken.model;
 import java.math.BigDecimal;
 import java.util.List;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class IcaBankenAccountList {
 
-	private List<IcaBankenAccount> mAccounts;
-
-	private String mDefaultAccountIdForEgiros;
-	private String mDefaultAccountIdForPayments;
-	private String mDefaultAccountIdForTransfers;
-	private BigDecimal mJointAccountsTotalAvailableAmount;
-
-	private BigDecimal mJointAccountsTotalCurrentAmount;
-	private BigDecimal mMinorsAccountsTotalAvailableAmount;
-	private BigDecimal mMinorsAccountsTotalCurrentAmount;
-	private BigDecimal mOwnAccountsTotalAvailableAmount;
-	private BigDecimal mOwnAccountsTotalCurrentAmount;
-
-	@JsonProperty("Accounts")
-	public List<IcaBankenAccount> getAccounts() {
-		return mAccounts;
-	}
-
-	public void setAccounts(List<IcaBankenAccount> pAccounts) {
-		this.mAccounts = pAccounts;
-	}
-
-	@JsonProperty("DefaultAccountIdForEgiros")
-	public String getDefaultAccountIdForEgiros() {
-		return mDefaultAccountIdForEgiros;
-	}
-
-	public void setDefaultAccountIdForEgiros(String pDefaultAccountIdForEgiros) {
-		this.mDefaultAccountIdForEgiros = pDefaultAccountIdForEgiros;
-	}
-
-	@JsonProperty("DefaultAccountIdForPayments")
-	public String getDefaultAccountIdForPayments() {
-		return mDefaultAccountIdForPayments;
-	}
-
-	public void setDefaultAccountIdForPayments(
-			String pDefaultAccountIdForPayments) {
-		this.mDefaultAccountIdForPayments = pDefaultAccountIdForPayments;
-	}
-
-	@JsonProperty("DefaultAccountIdForTransfers")
-	public String getDefaultAccountIdForTransfers() {
-		return mDefaultAccountIdForTransfers;
-	}
-
-	public void setDefaultAccountIdForTransfers(
-			String pDefaultAccountIdForTransfers) {
-		this.mDefaultAccountIdForTransfers = pDefaultAccountIdForTransfers;
-	}
-
-	@JsonProperty("JointAccountsTotalAvailableAmount")
-	public BigDecimal getJointAccountsTotalAvailableAmount() {
-		return mJointAccountsTotalAvailableAmount;
-	}
-
-	public void setJointAccountsTotalAvailableAmount(
-			BigDecimal pJointAccountsTotalAvailableAmount) {
-		this.mJointAccountsTotalAvailableAmount = pJointAccountsTotalAvailableAmount;
-	}
-
-	@JsonProperty("JointAccountsTotalCurrentAmount")
-	public BigDecimal getJointAccountsTotalCurrentAmount() {
-		return mJointAccountsTotalCurrentAmount;
-	}
-
-	public void setJointAccountsTotalCurrentAmount(
-			BigDecimal pJointAccountsTotalCurrentAmount) {
-		this.mJointAccountsTotalCurrentAmount = pJointAccountsTotalCurrentAmount;
-	}
-
-	@JsonProperty("MinorsAccountsTotalAvailableAmount")
-	public BigDecimal getMinorsAccountsTotalAvailableAmount() {
-		return mMinorsAccountsTotalAvailableAmount;
-	}
-
-	public void setMinorsAccountsTotalAvailableAmount(
-			BigDecimal pMinorsAccountsTotalAvailableAmount) {
-		this.mMinorsAccountsTotalAvailableAmount = pMinorsAccountsTotalAvailableAmount;
-	}
-
-	@JsonProperty("MinorsAccountsTotalCurrentAmount")
-	public BigDecimal getMinorsAccountsTotalCurrentAmount() {
-		return mMinorsAccountsTotalCurrentAmount;
-	}
-
-	public void setMinorsAccountsTotalCurrentAmount(
-			BigDecimal pMinorsAccountsTotalCurrentAmount) {
-		this.mMinorsAccountsTotalCurrentAmount = pMinorsAccountsTotalCurrentAmount;
-	}
-
-	@JsonProperty("OwnAccountsTotalAvailableAmount")
-	public BigDecimal getOwnAccountsTotalAvailableAmount() {
-		return mOwnAccountsTotalAvailableAmount;
-	}
-
-	public void setOwnAccountsTotalAvailableAmount(
-			BigDecimal pOwnAccountsTotalAvailableAmount) {
-		this.mOwnAccountsTotalAvailableAmount = pOwnAccountsTotalAvailableAmount;
-	}
-
-	@JsonProperty("OwnAccountsTotalCurrentAmount")
-	public BigDecimal getOwnAccountsTotalCurrentAmount() {
-		return mOwnAccountsTotalCurrentAmount;
-	}
-
-	public void setOwnAccountsTotalCurrentAmount(
-			BigDecimal pOwnAccountsTotalCurrentAmount) {
-		this.mOwnAccountsTotalCurrentAmount = pOwnAccountsTotalCurrentAmount;
-	}
+    private List<IcaBankenAccount> mAccounts;
+
+    private String mDefaultAccountIdForEgiros;
+    private String mDefaultAccountIdForPayments;
+    private String mDefaultAccountIdForTransfers;
+    private BigDecimal mJointAccountsTotalAvailableAmount;
+
+    private BigDecimal mJointAccountsTotalCurrentAmount;
+    private BigDecimal mMinorsAccountsTotalAvailableAmount;
+    private BigDecimal mMinorsAccountsTotalCurrentAmount;
+    private BigDecimal mOwnAccountsTotalAvailableAmount;
+    private BigDecimal mOwnAccountsTotalCurrentAmount;
+
+    @JsonProperty("Accounts")
+    public List<IcaBankenAccount> getAccounts() {
+        return mAccounts;
+    }
+
+    public void setAccounts(List<IcaBankenAccount> pAccounts) {
+        this.mAccounts = pAccounts;
+    }
+
+    @JsonProperty("DefaultAccountIdForEgiros")
+    public String getDefaultAccountIdForEgiros() {
+        return mDefaultAccountIdForEgiros;
+    }
+
+    public void setDefaultAccountIdForEgiros(String pDefaultAccountIdForEgiros) {
+        this.mDefaultAccountIdForEgiros = pDefaultAccountIdForEgiros;
+    }
+
+    @JsonProperty("DefaultAccountIdForPayments")
+    public String getDefaultAccountIdForPayments() {
+        return mDefaultAccountIdForPayments;
+    }
+
+    public void setDefaultAccountIdForPayments(
+            String pDefaultAccountIdForPayments) {
+        this.mDefaultAccountIdForPayments = pDefaultAccountIdForPayments;
+    }
+
+    @JsonProperty("DefaultAccountIdForTransfers")
+    public String getDefaultAccountIdForTransfers() {
+        return mDefaultAccountIdForTransfers;
+    }
+
+    public void setDefaultAccountIdForTransfers(
+            String pDefaultAccountIdForTransfers) {
+        this.mDefaultAccountIdForTransfers = pDefaultAccountIdForTransfers;
+    }
+
+    @JsonProperty("JointAccountsTotalAvailableAmount")
+    public BigDecimal getJointAccountsTotalAvailableAmount() {
+        return mJointAccountsTotalAvailableAmount;
+    }
+
+    public void setJointAccountsTotalAvailableAmount(
+            BigDecimal pJointAccountsTotalAvailableAmount) {
+        this.mJointAccountsTotalAvailableAmount = pJointAccountsTotalAvailableAmount;
+    }
+
+    @JsonProperty("JointAccountsTotalCurrentAmount")
+    public BigDecimal getJointAccountsTotalCurrentAmount() {
+        return mJointAccountsTotalCurrentAmount;
+    }
+
+    public void setJointAccountsTotalCurrentAmount(
+            BigDecimal pJointAccountsTotalCurrentAmount) {
+        this.mJointAccountsTotalCurrentAmount = pJointAccountsTotalCurrentAmount;
+    }
+
+    @JsonProperty("MinorsAccountsTotalAvailableAmount")
+    public BigDecimal getMinorsAccountsTotalAvailableAmount() {
+        return mMinorsAccountsTotalAvailableAmount;
+    }
+
+    public void setMinorsAccountsTotalAvailableAmount(
+            BigDecimal pMinorsAccountsTotalAvailableAmount) {
+        this.mMinorsAccountsTotalAvailableAmount = pMinorsAccountsTotalAvailableAmount;
+    }
+
+    @JsonProperty("MinorsAccountsTotalCurrentAmount")
+    public BigDecimal getMinorsAccountsTotalCurrentAmount() {
+        return mMinorsAccountsTotalCurrentAmount;
+    }
+
+    public void setMinorsAccountsTotalCurrentAmount(
+            BigDecimal pMinorsAccountsTotalCurrentAmount) {
+        this.mMinorsAccountsTotalCurrentAmount = pMinorsAccountsTotalCurrentAmount;
+    }
+
+    @JsonProperty("OwnAccountsTotalAvailableAmount")
+    public BigDecimal getOwnAccountsTotalAvailableAmount() {
+        return mOwnAccountsTotalAvailableAmount;
+    }
+
+    public void setOwnAccountsTotalAvailableAmount(
+            BigDecimal pOwnAccountsTotalAvailableAmount) {
+        this.mOwnAccountsTotalAvailableAmount = pOwnAccountsTotalAvailableAmount;
+    }
+
+    @JsonProperty("OwnAccountsTotalCurrentAmount")
+    public BigDecimal getOwnAccountsTotalCurrentAmount() {
+        return mOwnAccountsTotalCurrentAmount;
+    }
+
+    public void setOwnAccountsTotalCurrentAmount(
+            BigDecimal pOwnAccountsTotalCurrentAmount) {
+        this.mOwnAccountsTotalCurrentAmount = pOwnAccountsTotalCurrentAmount;
+    }
 }
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
index f126dbd..e405c9d 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
@@ -3,51 +3,53 @@ package com.liato.bankdroid.banking.banks.icabanken.model;
 import java.math.BigDecimal;
 import java.util.Date;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class IcaBankenTransaction {
 
-	private BigDecimal mAccountBalance;
+    private BigDecimal mAccountBalance;
 
-	private BigDecimal mAmount;
+    private BigDecimal mAmount;
 
-	private String mMemoText;
+    private String mMemoText;
 
-	private Date mPostedDate;
+    private Date mPostedDate;
 
-	@JsonProperty("AccountBalance")
-	public BigDecimal getAccountBalance() {
-		return mAccountBalance;
-	}
+    @JsonProperty("AccountBalance")
+    public BigDecimal getAccountBalance() {
+        return mAccountBalance;
+    }
 
-	public void setAccountBalance(BigDecimal pAccountBalance) {
-		this.mAccountBalance = pAccountBalance;
-	}
+    public void setAccountBalance(BigDecimal pAccountBalance) {
+        this.mAccountBalance = pAccountBalance;
+    }
 
-	@JsonProperty("Amount")
-	public BigDecimal getAmount() {
-		return mAmount;
-	}
+    @JsonProperty("Amount")
+    public BigDecimal getAmount() {
+        return mAmount;
+    }
 
-	public void setAmount(BigDecimal pAmount) {
-		this.mAmount = pAmount;
-	}
+    public void setAmount(BigDecimal pAmount) {
+        this.mAmount = pAmount;
+    }
 
-	@JsonProperty("MemoText")
-	public String getMemoText() {
-		return mMemoText;
-	}
+    @JsonProperty("MemoText")
+    public String getMemoText() {
+        return mMemoText;
+    }
 
-	public void setMemoText(String pMemoText) {
-		this.mMemoText = pMemoText;
-	}
+    public void setMemoText(String pMemoText) {
+        this.mMemoText = pMemoText;
+    }
 
-	@JsonProperty("PostedDate")
-	public Date getPostedDate() {
-		return mPostedDate;
-	}
+    @JsonProperty("PostedDate")
+    public Date getPostedDate() {
+        return mPostedDate;
+    }
 
-	public void setPostedDate(Date pPostedDate) {
-		this.mPostedDate = pPostedDate;
-	}
+    public void setPostedDate(Date pPostedDate) {
+        this.mPostedDate = pPostedDate;
+    }
 }

commit ab88852ca0cf7d49150563914b07c8f16dd8ebc4
Merge: f7e8d48 d40961e
Author: liato <x@x00.us>
Date:   Wed May 7 23:30:47 2014 +0200

    Merge pull request #287 from goober/feature/sveadirekt
    
    Adds support for SveaDirekt.

commit d40961ef1e63dcef44e5aed5e4e92fd9210ec4d3
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 4 22:03:40 2014 +0200

    Adds support for SveaDirekt.

diff --git res/drawable/logo_sveadirekt.png res/drawable/logo_sveadirekt.png
new file mode 100644
index 0000000..bc60a35
Binary files /dev/null and res/drawable/logo_sveadirekt.png differ
diff --git res/raw/cert_sveadirekt.pem res/raw/cert_sveadirekt.pem
new file mode 100644
index 0000000..7046bec
--- /dev/null
+++ res/raw/cert_sveadirekt.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 73bcd69..2c3ac95 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -76,6 +76,7 @@ import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
+import com.liato.bankdroid.banking.banks.SveaDirekt;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
@@ -256,6 +257,8 @@ public class BankFactory {
             return new ForexBank(context);
         case IBankTypes.BITCOIN:
             return new Bitcoin(context);
+        case IBankTypes.SVEADIREKT:
+            return new SveaDirekt(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -337,6 +340,7 @@ public class BankFactory {
         banks.add(new EurobonusMastercardNo(context));
         banks.add(new Bitcoin(context));
         banks.add(new EurobonusMastercardDk(context));
+        banks.add(new SveaDirekt(context));
 
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/SveaDirekt.java src/com/liato/bankdroid/banking/banks/SveaDirekt.java
new file mode 100644
index 0000000..8791338
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/SveaDirekt.java
@@ -0,0 +1,215 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Currency;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class SveaDirekt extends Bank {
+    private static final String TAG = "SveaDirekt";
+    private static final String NAME = "Svea Direkt";
+    private static final String NAME_SHORT = "sveadirekt";
+    private static final String URL = "https://http://www.sveadirekt.com/sv/swe//";
+    private static final int BANKTYPE_ID = IBankTypes.SVEADIREKT;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "YYMMDDXXXX";
+
+
+    private static final String BASE_URL = "https://services.sveadirekt.se/mypages/sv/";
+    private static final String LOGIN_URL = "https://services.sveadirekt.se/mypages/sv/j_security_check";
+    private static final String ACCOUNTS_URL = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/home.jsp";
+    private static final String TRANSACTIONS_URL = "https://services.sveadirekt.se/faces/WEB-INF/britney_jsp_s/balance.jsp";
+
+    private String response;
+
+    public SveaDirekt(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.URL = URL;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public SveaDirekt(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        if (urlopen == null) {
+            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sveadirekt));
+            urlopen.getHttpclient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
+        }
+        response = urlopen
+                .open(BASE_URL);
+
+        Document doc = Jsoup.parse(response);
+        if (!"Logga in".equals(doc.title())) {
+            throw new BankException(res.getText(R.string.unable_to_find)
+                    .toString() + " login url.");
+        }
+        String strLoginUrl = LOGIN_URL;
+
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("j_username", username));
+        postData.add(new BasicNameValuePair("j_password", password));
+        return new LoginPackage(urlopen, postData, response, strLoginUrl);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(LOGIN_URL, lp.getPostData());
+            if (response.contains("error-failed-to-login")) {
+                throw new LoginException(res.getText(
+                        R.string.invalid_username_password).toString());
+            }
+
+        } catch (ClientProtocolException e) {
+            Log.e(TAG, "ClientProtocolException: " + e.getMessage());
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            Log.e(TAG, "IOException: " + e.getMessage());
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        try {
+            List<NameValuePair> postData = new ArrayList<NameValuePair>();
+            postData.add(new BasicNameValuePair("homeForm:balance","Saldo"));
+            postData.add(new BasicNameValuePair("homeForm","homeForm"));
+            response = urlopen.open(ACCOUNTS_URL,postData);
+            Document doc = Jsoup.parse(response);
+            ArrayList<Account> accounts = parseAccounts(doc);
+
+            if (!accounts.isEmpty()) {
+                Account firstAccount = accounts.get(0);
+                // Get account details for first account
+                addAccountDetails(firstAccount, doc);
+                firstAccount.setTransactions(parseTransactions(response));
+
+            }
+
+            // Fetch additional accounts transaction pages to get their balance.
+            for (int i = 1; i < accounts.size(); i++) {
+                Account account = accounts.get(i);
+                response = urlopen.open(TRANSACTIONS_URL, createTransactionParams(account));
+                addAccountDetails(account, Jsoup.parse(response));
+                account.setTransactions(parseTransactions(response));
+            }
+            this.setAccounts(accounts);
+        }
+        catch (ClientProtocolException e) {
+          throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        finally {
+          super.updateComplete();
+        }
+
+    }
+
+    private ArrayList<Account> parseAccounts(Document pDocument) {
+        ArrayList<Account> accountList = new ArrayList<Account>();
+        Element element = pDocument.getElementById("balanceForm:accountsList");
+        Elements accounts = element.select("td a[href=#]");
+        for (int i = 0; i<accounts.size(); i++) {
+            Account account = new Account("",BigDecimal.ZERO,Integer.toString(i));
+            accountList.add(account);
+        }
+        return accountList;
+    }
+
+    private Account addAccountDetails(Account pAccount, Document pDocument) {
+        Elements vAccountDetails = pDocument
+                .select("strong:contains(Saldo och transaktioner) ~ table")
+                .first().select("tr td:last-child");
+        String vAccountType = vAccountDetails.first().text();
+        String vBalance = vAccountDetails.last().text();
+        pAccount.setName(vAccountType);
+        pAccount.setCurrency("SEK");
+        BigDecimal balance = new BigDecimal(vBalance.replaceAll("[^\\d]", ""));
+        pAccount.setBalance(balance);
+        return pAccount;
+    }
+
+    private List<Transaction> parseTransactions(String pResponse) {
+        List<Transaction> vTransactions = new ArrayList<Transaction>();
+        Document doc = Jsoup.parse(pResponse);
+        Elements vTransactionElements =
+                doc.getElementById("balanceForm:transactionPostList").select("tbody tr");
+
+        for (Element element : vTransactionElements) {
+
+            Elements vTransactionElement = element.select("td");
+
+           BigDecimal amount = new BigDecimal(vTransactionElement.get(1).text()
+                    .replaceAll("[^\\d-]", ""));
+            String description = vTransactionElement.get(2).text();
+            if (description == null || description.isEmpty()) {
+               description = amount.compareTo(BigDecimal.ZERO) > 0 ? "Insättning"
+                                : "Uttag";
+            }
+            String date = vTransactionElement.first().text();
+            vTransactions.add(new Transaction(date,description,amount));
+        }
+        return vTransactions;
+    }
+
+    List<NameValuePair>  createTransactionParams(Account pAccount) {
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("balanceForm", "balanceForm"));
+        postData.add(new BasicNameValuePair("balanceForm:_idcl","balanceForm:accountsList:"+pAccount.getId()+":_id15"));
+        return postData;
+    }
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index b39922c..7d47611 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -95,4 +95,5 @@ public interface IBankTypes {
     public final static int SASEUROBONUSMASTERCARD_NO = 71;
     public final static int BITCOIN = 72;
     public final static int SASEUROBONUSMASTERCARD_DK = 73;
+    public final static int SVEADIREKT  = 74;
 }

commit f7e8d4872a0d1be08f12d80069cb35743659fd9a (tag: v1.9.6.13)
Author: liato <x@x00.us>
Date:   Wed Apr 30 01:29:39 2014 +0200

    Update changelog.

diff --git CHANGES.txt CHANGES.txt
index 2f3dc43..d86b1a1 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,8 @@
+v1.9.6.13: (2014-04-30)
+* Prevent recent apps thumbnail for pattern lock and settings
+* Updated SSL certificate for American Express, Coop, CSN, Handelsbanken, Osuuspankki, PayPal, Resurs Bank, Sevenday and Zidisha.
+
+
 v1.9.6.12: (2014-04-14)
 * Updated SSL certificate for Nordea
 

commit 17dee1c413f537d773585ba685700f42c1b47f58
Author: liato <x@x00.us>
Date:   Wed Apr 30 01:25:06 2014 +0200

    Bump version. v1.9.6.13.

diff --git AndroidManifest.xml AndroidManifest.xml
index cbd002e..db2bc3f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.12" android:versionCode="182">
+	android:versionName="1.9.6.13" android:versionCode="183">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 2c9a197..3e7c204 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 182
-        versionName '1.9.6.12'
+        versionCode 183
+        versionName '1.9.6.13'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 20431d7a7aa860805412c09fa5792a799a4ff126
Author: liato <x@x00.us>
Date:   Wed Apr 30 01:23:24 2014 +0200

    Prevent recent apps thumbnail for lockpattern and lockablepreference.

diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index ee1e53c..89392e6 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -22,6 +22,7 @@ import com.liato.bankdroid.lockpattern.LockPatternUtils;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceActivity;
@@ -44,6 +45,9 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		mLockPatternUtils = new LockPatternUtils(this);
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+        }
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
index a1f49ff..1f96cf6 100644
--- src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
+++ src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
@@ -28,9 +28,11 @@ import com.liato.bankdroid.lockpattern.LockPatternView.OnPatternListener;
 
 import android.app.Activity;
 import android.content.Intent;
+import android.os.Build;
 import android.os.CountDownTimer;
 import android.os.SystemClock;
 import android.os.Bundle;
+import android.view.WindowManager;
 import android.widget.TextView;
 import android.view.KeyEvent;
 import android.view.Window;
@@ -126,6 +128,9 @@ public class ConfirmLockPattern extends Activity {
                 finish();
             }
         }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+        }
     }
 
     @Override

commit c73e711e4b0251a88a2b204f2d7744ac3eefccc8
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:59:30 2014 +0200

    Update zidisha certificate.

diff --git res/raw/cert_zidisha.pem res/raw/cert_zidisha.pem
index d6ff6a3..b11040c 100644
--- res/raw/cert_zidisha.pem
+++ res/raw/cert_zidisha.pem
@@ -1,30 +1,29 @@
 -----BEGIN CERTIFICATE-----
-MIIFFTCCA/2gAwIBAgIQSkXT6jtBHkSdoxC37DMciTANBgkqhkiG9w0BAQUFADBz
+MIIE6jCCA9KgAwIBAgIQPbl2N2hb7Opg8+Bs5UKYuTANBgkqhkiG9w0BAQUFADBw
 MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD

-XpV9MUJd99mF

+nBmNEknwJEEmDsyOF7k=
 -----END CERTIFICATE-----

commit f7de5bf29f98d4bdf36e6c9dc3fd96ac2e00c1f8
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:58:50 2014 +0200

    Update certificate for sevenday.

diff --git res/raw/cert_sevenday.pem res/raw/cert_sevenday.pem
index 89a213c..0a233b5 100644
--- res/raw/cert_sevenday.pem
+++ res/raw/cert_sevenday.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQNHl5jjaIHqGW09M+de7GxDANBgkqhkiG9w0BAQUFADA8
+MIIEkjCCA3qgAwIBAgIQF7xPHP7AujQPIPj8UKmd6jANBgkqhkiG9w0BAQUFADA8
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMuMRYwFAYDVQQDEw1U
-aGF3dGUgU1NMIENBMB4XDTE0MDQxNTAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
+aGF3dGUgU1NMIENBMB4XDTEzMDkxMDAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
 MAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9sbTEOMAwGA1UEBxQFS2lzdGEx
 GzAZBgNVBAoUElNldmVuRGF5IEZpbmFucyBBQjEWMBQGA1UEAxQNKi5zZXZlbmRh

 VR0TBAIwADBCBgNVHSAEOzA5MDcGCmCGSAGG+EUBBzYwKTAnBggrBgEFBQcCARYb
 aHR0cHM6Ly93d3cudGhhd3RlLmNvbS9jcHMvMA4GA1UdDwEB/wQEAwIFoDAfBgNV
 HSMEGDAWgBSnooO7NEVAPfzVME8SuT6hAZ/22zA6BgNVHR8EMzAxMC+gLaArhilo
@@ -18,10 +18,10 @@ dHRwOi8vc3ZyLW92LWNybC50aGF3dGUuY29tL1RoYXd0ZU9WLmNybDAdBgNVHSUE
 FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwaQYIKwYBBQUHAQEEXTBbMCIGCCsGAQUF
 BzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDUGCCsGAQUFBzAChilodHRwOi8v
 c3ZyLW92LWFpYS50aGF3dGUuY29tL1RoYXd0ZU9WLmNlcjANBgkqhkiG9w0BAQUF
-AAOCAQEAfxEugYbMxBESO8rPkO7SJoquhqdl++OClvSLYdIq8JGfiBc0otayEMBS
-ooEIjwOY3z2dpra7I9ZOSVprv02egTGNR2cW55QRAs+qQLqzxGI5lj+1RHgcJZHo
-g3ZFoqNEnh2u5hfCtf+cS2hH1VUPxp9Ml09Nk/mLK2WK/xv4yEfQDqANZut4oboB
-wsygjnnUpRyGbrxeY29w6TfChOQwb+7vxxCgRPJBrDTGdJmZ6rhE+ZrSNqcCd1ra
-vB8pWPwNeaFHRPrYrlzUXfkS0xak7GFCU+WW4qPG73VLdPnh/GcidtSjDSZKGSkv
-ETEyMuB5fsINZXXfHm6F2x4e0+b8aQ==
+AAOCAQEAElhvDbODrkiNm+RiwpfgLTFc0RiEq/mw0rCU04b1j0JSOhK8ImGYLZEN
+GmUSjuJ7x05T3wYcnkXhyWwntkdUed0cFLkuuHohHFdvuPg/0SYw+n/lgPrIXh0V
+BadG1CjnmX3qhdgoTWEvynXJFf3vck9Dx2scxfwJZ7BoUzEraoZ1i0ZJ/2p5pp11
+w+vx95m1/eMdmaikt2wZGDzOyl0LAP7wREDYMs4HkvNGzZxnDoylLZ+45qEuRhnj
+Xg18o4qqK0PxQademqQCMgGZA/YHEPhowSNz20Fd0QlQ3b0XPQiM5L4/Pj5f3/w0
+PV2hZ7XKpVDd+Q41irJ0O6JluWFl8A==
 -----END CERTIFICATE-----

commit 2c188e592fa2d0492e9f51b2a001bcf5500266e0
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:57:47 2014 +0200

    Update certificate for sevenday.

diff --git res/raw/cert_resursbank.pem res/raw/cert_resursbank.pem
index 4f2f9bd..b92f70c 100644
--- res/raw/cert_resursbank.pem
+++ res/raw/cert_resursbank.pem
@@ -1,38 +1,38 @@
 -----BEGIN CERTIFICATE-----
-MIIGrDCCBZSgAwIBAgIQCBYO+xyGr6CbyFlADpbakTANBgkqhkiG9w0BAQUFADBm
+MIIGrTCCBZWgAwIBAgIQDDVxfXJTkm35k7iF9dHJrjANBgkqhkiG9w0BAQUFADBm
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBDQS0zMB4XDTEzMDIwNjAwMDAwMFoXDTE0MDQxNjEyMDAwMFowdDELMAkGA1UE
+ZSBDQS0zMB4XDTEzMDQyNTAwMDAwMFoXDTE1MDYyOTEyMDAwMFowbzELMAkGA1UE
 BhMCU0UxDjAMBgNVBAgTBVNrYW5lMRQwEgYDVQQHEwtIZWxzaW5nYm9yZzEXMBUG

-PFLkY3zo7wY1C4ZwgXLQsb0QPc6eSdeg6C7rEa8XgS4=

+e+GhpRTaPL2e1wlLsHt3Pg4I8V2VikbNJwfPgscs5BeW
 -----END CERTIFICATE-----

commit ca661e79f8d0c8f09fbb1a1b8cf0f66c2d255d5d
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:57:07 2014 +0200

    Update osuuspankki certificate.

diff --git res/raw/cert_osuuspankki.pem res/raw/cert_osuuspankki.pem
index 4660fce..d0df8a2 100644
--- res/raw/cert_osuuspankki.pem
+++ res/raw/cert_osuuspankki.pem
@@ -1,33 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIFuTCCBKGgAwIBAgIQZ7ZTJqRLyTPglwwMCfb/zjANBgkqhkiG9w0BAQUFADCB
+MIIFuTCCBKGgAwIBAgIQSFd0JRQuvKdPF8+re8lhAzANBgkqhkiG9w0BAQUFADCB
 ujELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE0MDIGA1UEAxMr
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQTAeFw0x
-MjEwMzAwMDAwMDBaFw0xMzEyMTEyMzU5NTlaMIHVMRMwEQYLKwYBBAGCNzwCAQMT
+MzEyMTEwMDAwMDBaFw0xNDEyMTIyMzU5NTlaMIHVMRMwEQYLKwYBBAGCNzwCAQMT
 AkZJMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjESMBAGA1UEBRMJMDI0
 MjUyMi0xMQswCQYDVQQGEwJGSTEOMAwGA1UEERQFMDA1MTAxETAPBgNVBAgTCEhl
 bHNpbmtpMREwDwYDVQQHFAhIZWxzaW5raTEbMBkGA1UECRQSVGVvbGxpc3V1c2th
 dHUgMSBCMRcwFQYDVQQKFA5PUC1Qb2hqb2xhIG9zazESMBAGA1UEAxQJd3d3Lm9w

 RVZTZWN1cmUtb2NzcC52ZXJpc2lnbi5jb20wPQYIKwYBBQUHMAKGMWh0dHA6Ly9F
 VlNlY3VyZS1haWEudmVyaXNpZ24uY29tL0VWU2VjdXJlMjAwNi5jZXIwDQYJKoZI
-hvcNAQEFBQADggEBABIiTqUsfMdj0iShTHti3ysfHCxyGMo2HAlhUy9OIg8QUwRi
-FHZ59sraurzO03cG429AzDPq1mvRR6sf/SDiL6rGSZXAOnDMySPzEDNcP2RdbKka
-Q3WzYMOfZ1VsKOGqSvG3SaHIzezMVSNIR5wX01eZ/8df5cbgs7SJQk2oeHH2jCkp
-LUD7jRtwqvYHi8VoK33iJPqfg5TITRegJTAoXAdDOCHSWdg6BxOqNl53objGj5Nm
-AlJrMx9XQeRjfxpI0y1bqMueQfyoe+geDP5TPwZZ1rCSTTyga8tQ0zHwv/1xfCUM
-/Cad9TAS2uv1yg4nZDwIeQzWXXfxRrK0scbZpVU=
+hvcNAQEFBQADggEBAI0gQH2ygQnVwYCh+SMUyqi2q6K/mtBbyzEks73qVkCnp8/M
+Xa82I54jirpr/IKjdpi8ulNbee+d4WFbGyVY38/hbdEOwWlJSZy2CvpHByJalf3W
+ocdc8/VgG09yKi8/ubgbvl+f49vlHcfPQjlUob6cH9WKuavFTmBoFFVA2vfq2Nh5
+wvm281vm07muGjRm3dT7IXgNP8gSy9zYdclmQsniAFJzE1QAZhxIoZhID7HVrR0u
+r8mhyhIS5ICRPMcMPewXbmrMTxrDNuvGyYN1loyJ0RW5pymiE1w68kfF4b7KOqO4
+7C+vTCxnNpaIBNdzQ7uSIQTVJQSWx2cHjYxVlrg=
 -----END CERTIFICATE-----

commit 1dd4687b17c886818b8961c7976860e6f91f2cb7
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:56:30 2014 +0200

    Update coop certificate.

diff --git res/raw/cert_csn.pem res/raw/cert_csn.pem
index 61ad639..18fc9b1 100644
--- res/raw/cert_csn.pem
+++ res/raw/cert_csn.pem
@@ -1,36 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIGODCCBSCgAwIBAgIQJ4DoKVGcZEmmqvumoRjNdjANBgkqhkiG9w0BAQUFADCB
+MIIFrzCCBJegAwIBAgIQYdKDZNXQ/Zoy9XLzEHrPcDANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTIwNDIwMDAwMDAwWhcNMTQwNDIxMjM1OTU5WjCB+DETMBEGCysGAQQBgjc8
+HhcNMTQwNDE3MDAwMDAwWhcNMTYwNDIwMjM1OTU5WjCB9DETMBEGCysGAQQBgjc8
 AgEDEwJTRTEaMBgGA1UEDxMRR292ZXJubWVudCBFbnRpdHkxFDASBgNVBAUTCzIw

-8VE5wSZttMXr17Me

+PajVUwrdF/h/YCVPwueHfyjYow==
 -----END CERTIFICATE-----

commit f6d1cca805e3039294c6116fcced01f8a2e0d0b6
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:55:55 2014 +0200

    Update coop certificate.

diff --git res/raw/cert_coop.pem res/raw/cert_coop.pem
index 851aba5..5f64262 100644
--- res/raw/cert_coop.pem
+++ res/raw/cert_coop.pem
@@ -1,10 +1,10 @@
 -----BEGIN CERTIFICATE-----
-MIIGNzCCBR+gAwIBAgIQCXm9ZEIUxodhg4fL6v6yDjANBgkqhkiG9w0BAQUFADCB
+MIIF4jCCBMqgAwIBAgIQV41QDgarpEDFqCdMcVvpaTANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTExMTE2MDAwMDAwWhcNMTMxMTE2MjM1OTU5WjCB6zETMBEGCysGAQQBgjc8
+HhcNMTMxMTE1MDAwMDAwWhcNMTUxMTE3MjM1OTU5WjCB6zETMBEGCysGAQQBgjc8
 AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgNVBAUT
 CjU1NjExODUzNzExCzAJBgNVBAYTAlNFMQ8wDQYDVQQRFAYxMTYgNDUxEjAQBgNV
 BAgTCVN0b2NraG9sbTESMBAGA1UEBxQJU3RvY2tob2xtMRcwFQYDVQQJFA5TdGFk
@@ -15,22 +15,20 @@ EZuDw2y6wJAgn4GOO2W45lnWurZYmJCDDhkWj2ga6iVjwO/DC7tAh99bnGZWL9YQ
 o60koEkFQI0Qhd2PrMJ7zHHrVsjsNTeDR27KbaKbw4692v+463a1KbDoC6NjCTSy
 LXvUaQHRrLRpeM9fR/z+2qul7dtXU9HRftq7yUERPIlPwrQf71Tw44vo520oD8pY
 p01XL8doD3TEYS1P0llYynd3Q9lRgSWbQ/klJXVgV1i/CIp5SHFtXWvDer1BYl9v

-g9inbt1p3SfEqes=

++UX0heR9QWX+dqsYLQBl7dK2geZcww==
 -----END CERTIFICATE-----

commit 65186ab1845551f220dd6a0dd8459b6196cc9ba8
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:55:11 2014 +0200

    Update PayPal certificate.

diff --git res/raw/cert_paypal2.pem res/raw/cert_paypal2.pem
index 5407ef2..accd937 100644
--- res/raw/cert_paypal2.pem
+++ res/raw/cert_paypal2.pem
@@ -1,36 +1,35 @@
 -----BEGIN CERTIFICATE-----
-MIIGQTCCBSmgAwIBAgIQEjukq09sXK3m1jQzsXbWDzANBgkqhkiG9w0BAQUFADCB
+MIIGCDCCBPCgAwIBAgIQCDTkU9Q6aFcjr/uxM85FfDANBgkqhkiG9w0BAQUFADCB
 ujELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE0MDIGA1UEAxMr
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQTAeFw0x
-NDAyMTkwMDAwMDBaFw0xNTA0MDIyMzU5NTlaMIIBCTETMBEGCysGAQQBgjc8AgED
+NDA0MTUwMDAwMDBaFw0xNTA0MDIyMzU5NTlaMIIBCTETMBEGCysGAQQBgjc8AgED
 EwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xEDAOBgNVBAUTBzMwMTQyNjcxCzAJBgNVBAYTAlVTMRMw
 EQYDVQQRFAo5NTEzMS0yMDIxMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQH
 FAhTYW4gSm9zZTEWMBQGA1UECRQNMjIxMSBOIDFzdCBTdDEVMBMGA1UEChQMUGF5
 UGFsLCBJbmMuMRQwEgYDVQQLFAtDRE4gU3VwcG9ydDEXMBUGA1UEAxQOd3d3LnBh

-pA5cRcJCTj+6x7nfpV3x84/iyfX5

+XPfzzQCJDYWaonDa
 -----END CERTIFICATE-----

commit 43821ad8371679038ac6179279fe74b8d2e16e52
Author: liato <x@x00.us>
Date:   Wed Apr 30 00:54:32 2014 +0200

    Update american express certificate.

diff --git res/raw/cert_americanexpress.pem res/raw/cert_americanexpress.pem
index 74d1921..bb3bc22 100644
--- res/raw/cert_americanexpress.pem
+++ res/raw/cert_americanexpress.pem
@@ -1,25 +1,25 @@
 -----BEGIN CERTIFICATE-----
-MIIELTCCAxWgAwIBAgIOAQAAAAABQ8WUqMqCd7MwDQYJKoZIhvcNAQEFBQAwRjEX
+MIIELTCCAxWgAwIBAgIOAgAAAAABRWqFrmBLiVIwDQYJKoZIhvcNAQEFBQAwRjEX
 MBUGA1UEChMOQ3liZXJ0cnVzdCBJbmMxKzApBgNVBAMTIkN5YmVydHJ1c3QgUHVi
-bGljIFN1cmVTZXJ2ZXIgU1YgQ0EwHhcNMTQwMTI0MTg1NDM3WhcNMTUwMTI0MTg1
-NDM3WjCBjDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEDAOBgNVBAcT
+bGljIFN1cmVTZXJ2ZXIgU1YgQ0EwHhcNMTQwNDE2MTIzMTU5WhcNMTUwNDE2MTIz
+MTU5WjCBjDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEDAOBgNVBAcT
 B1Bob2VuaXgxJjAkBgNVBAoTHUFtZXJpY2FuIEV4cHJlc3MgVGVjaG5vbG9naWVz
 MREwDwYDVQQLEwhDb25zdW1lcjEeMBwGA1UEAxQVKi5hbWVyaWNhbmV4cHJlc3Mu

 MD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6Ly9jcmwub21uaXJvb3QuY29tL1B1Ymxp
-Y1N1cmVTZXJ2ZXJTVi5jcmwwHQYDVR0OBBYEFIxc+a8hiFsVTqFGQ6tCXewLhbQs
+Y1N1cmVTZXJ2ZXJTVi5jcmwwHQYDVR0OBBYEFPJg1uztAbygtiXMpSYnEX5ESzmf
 MAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
 BggrBgEFBQcDAjARBglghkgBhvhCAQEEBAMCBsAwDQYJKoZIhvcNAQEFBQADggEB
-ABFk0k0P1UY71hv4s7WRs+k9B/fYYvtMmUJGGPqTswb9YM2xcX7ImiOElhjOrPuB
-t0Jf0Mb3TGU04pO0ga7LfVAnGctPCdYftUORYxwqcn/KPxPiAh+k1sqQWVdDTe/q
-0JKEyMDSBy/uMcoryzqVjuV6E0YDFnGN+JglEnOf4slGKpquxfwJIUXGRYeCbYHR
-CVcMkJM/2gOZkZUblTVPsjt5w1Yb4UYXiDnrvjrpEBAyZpx4Poy66u3uUERIDL93
-m7m75XwRId/HZk+j6aFCq1HQGRl0KGDKMFC8RJvPSgJ6KEo6CZ8y0DT98YJJ3ew5
-RErQgv+9W9k+KaFKzX5TpTM=
+ABbGhsYOXJHBCo7gvTKP/jQ8lMhr2CpHzNEdensn8yKAlYFFT0mcQx45rS5k0yoG
+Lfhd2iiler0DTd92UkJ7MYa6sXEmmZAzygMWCGhFG5BMbpAkvW/DDOjfXsvbkC1T
+wFj2UZS0IBEdHJiHmNcYYljPYu1QJxh57Z5A9YdRqzqdYBqA4MLDOYV/8c3ynU8Z
+m5nmUolxkhSOaFv9TFfRF2UypA0mNFpY58od1lTR3V0dCWifvdY3OzxcjL3JGuWX
+ZZmLtoF+UZUurqUKrU25sRFWfl7kvDa9cEKNKuemPyQ70qR7GvnZ2cC0Xfad7bHH
+xoL1/mj95xY03lYAEWKwhYQ=
 -----END CERTIFICATE-----

commit 22a72c5605ac93ea3c6a0c6feb07a85d7023b042
Merge: 9ebb20f 71ecf3f
Author: liato <x@x00.us>
Date:   Tue Apr 29 00:21:35 2014 +0200

    Merge pull request #286 from Fogelholk/patch-1
    
    Update cert_handelsbanken.pem

commit 71ecf3ff6bbd75ad0b72d59594a371a0616290ae
Author: Linus <linus@fogelholk.se>
Date:   Sat Apr 26 15:28:02 2014 +0200

    Update cert_handelsbanken.pem
    
    New certificate, valid from 2014-04-23 to 2015-05-07

diff --git res/raw/cert_handelsbanken.pem res/raw/cert_handelsbanken.pem
index d21d1cf..9ceba5c 100644
--- res/raw/cert_handelsbanken.pem
+++ res/raw/cert_handelsbanken.pem
@@ -1,34 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIF6zCCBNOgAwIBAgIQA9gqVP+4uY+osd6kb2oF9DANBgkqhkiG9w0BAQUFADCB
+MIIFvDCCBKSgAwIBAgIQBXzPkQLJW90ocS0O8LNeXDANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTMwNDAyMDAwMDAwWhcNMTQwNTA2MjM1OTU5WjCB+TETMBEGCysGAQQBgjc8
+HhcNMTQwNDIzMDAwMDAwWhcNMTUwNTA2MjM1OTU5WjCB+TETMBEGCysGAQQBgjc8
 AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgNVBAUT
 CjUwMjAwNzc4NjIxCzAJBgNVBAYTAlNFMQ4wDAYDVQQRFAUxMTU0MDESMBAGA1UE
 CBMJU1RPQ0tIT0xNMRIwEAYDVQQHFAlTVE9DS0hPTE0xGjAYBgNVBAkUEVRlZ2Vs
 dWRkc3ZhZ2VuIDEwMSEwHwYDVQQKFBhTdmVuc2thIEhhbmRlbHNiYW5rZW4gQUIx
 DTALBgNVBAsUBEhJTlQxGzAZBgNVBAMUEm0uaGFuZGVsc2Jhbmtlbi5zZTCCASIw

 AjAAMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBggrBgEFBQcDAQYIKwYBBQUH

-ItVlHNP6y6DtxuQ+m6iUovm7eJNG5Y8bhcTh5+sEOQ==

+91AySnUbhs2yRijm12ZF8CAgfEPhK8Hu++/IdlffFhE=
 -----END CERTIFICATE-----

commit 9ebb20fd7647d94e38352d4c5550dc84be711248
Author: liato <x@x00.us>
Date:   Sun Apr 20 11:33:47 2014 +0200

    Update SevenDay certificate.

diff --git res/raw/cert_sevenday.pem res/raw/cert_sevenday.pem
index 0a233b5..89a213c 100644
--- res/raw/cert_sevenday.pem
+++ res/raw/cert_sevenday.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQF7xPHP7AujQPIPj8UKmd6jANBgkqhkiG9w0BAQUFADA8
+MIIEkjCCA3qgAwIBAgIQNHl5jjaIHqGW09M+de7GxDANBgkqhkiG9w0BAQUFADA8
 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMuMRYwFAYDVQQDEw1U
-aGF3dGUgU1NMIENBMB4XDTEzMDkxMDAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
+aGF3dGUgU1NMIENBMB4XDTE0MDQxNTAwMDAwMFoXDTE1MTIxMDIzNTk1OVowZjEL
 MAkGA1UEBhMCU0UxEjAQBgNVBAgTCVN0b2NraG9sbTEOMAwGA1UEBxQFS2lzdGEx
 GzAZBgNVBAoUElNldmVuRGF5IEZpbmFucyBBQjEWMBQGA1UEAxQNKi5zZXZlbmRh

 VR0TBAIwADBCBgNVHSAEOzA5MDcGCmCGSAGG+EUBBzYwKTAnBggrBgEFBQcCARYb
 aHR0cHM6Ly93d3cudGhhd3RlLmNvbS9jcHMvMA4GA1UdDwEB/wQEAwIFoDAfBgNV
 HSMEGDAWgBSnooO7NEVAPfzVME8SuT6hAZ/22zA6BgNVHR8EMzAxMC+gLaArhilo
@@ -18,10 +18,10 @@ dHRwOi8vc3ZyLW92LWNybC50aGF3dGUuY29tL1RoYXd0ZU9WLmNybDAdBgNVHSUE
 FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwaQYIKwYBBQUHAQEEXTBbMCIGCCsGAQUF
 BzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDUGCCsGAQUFBzAChilodHRwOi8v
 c3ZyLW92LWFpYS50aGF3dGUuY29tL1RoYXd0ZU9WLmNlcjANBgkqhkiG9w0BAQUF
-AAOCAQEAElhvDbODrkiNm+RiwpfgLTFc0RiEq/mw0rCU04b1j0JSOhK8ImGYLZEN
-GmUSjuJ7x05T3wYcnkXhyWwntkdUed0cFLkuuHohHFdvuPg/0SYw+n/lgPrIXh0V
-BadG1CjnmX3qhdgoTWEvynXJFf3vck9Dx2scxfwJZ7BoUzEraoZ1i0ZJ/2p5pp11
-w+vx95m1/eMdmaikt2wZGDzOyl0LAP7wREDYMs4HkvNGzZxnDoylLZ+45qEuRhnj
-Xg18o4qqK0PxQademqQCMgGZA/YHEPhowSNz20Fd0QlQ3b0XPQiM5L4/Pj5f3/w0
-PV2hZ7XKpVDd+Q41irJ0O6JluWFl8A==
+AAOCAQEAfxEugYbMxBESO8rPkO7SJoquhqdl++OClvSLYdIq8JGfiBc0otayEMBS
+ooEIjwOY3z2dpra7I9ZOSVprv02egTGNR2cW55QRAs+qQLqzxGI5lj+1RHgcJZHo
+g3ZFoqNEnh2u5hfCtf+cS2hH1VUPxp9Ml09Nk/mLK2WK/xv4yEfQDqANZut4oboB
+wsygjnnUpRyGbrxeY29w6TfChOQwb+7vxxCgRPJBrDTGdJmZ6rhE+ZrSNqcCd1ra
+vB8pWPwNeaFHRPrYrlzUXfkS0xak7GFCU+WW4qPG73VLdPnh/GcidtSjDSZKGSkv
+ETEyMuB5fsINZXXfHm6F2x4e0+b8aQ==
 -----END CERTIFICATE-----

commit 3af900f6936836bcf9093772c2045eb7f4451b43
Author: liato <x@x00.us>
Date:   Mon Apr 14 17:37:58 2014 +0200

    Bump version. v1.9.6.12.

diff --git AndroidManifest.xml AndroidManifest.xml
index 92017b0..cbd002e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.11" android:versionCode="181">
+	android:versionName="1.9.6.12" android:versionCode="182">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index 76d4fe8..2f3dc43 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,7 @@
+v1.9.6.12: (2014-04-14)
+* Updated SSL certificate for Nordea
+
+
 v1.9.6.11: (2014-04-10)
 * Updated SSL certificate for Swedbank
 * Transactions working for ICA accounts
diff --git build.gradle build.gradle
index a85c09b..2c9a197 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 181
-        versionName '1.9.6.11'
+        versionCode 182
+        versionName '1.9.6.12'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 8a86113c459a5b5b3c082e24438229f908d0f930
Author: liato <x@x00.us>
Date:   Mon Apr 14 17:19:56 2014 +0200

    Update Nordea certificate.

diff --git res/raw/cert_nordea.pem res/raw/cert_nordea.pem
index 1378da3..2679590 100644
--- res/raw/cert_nordea.pem
+++ res/raw/cert_nordea.pem
@@ -1,34 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIF3zCCBMegAwIBAgIQK5jXmW+s8dBcGH/mFhEKdDANBgkqhkiG9w0BAQUFADCB
+MIIFvDCCBKSgAwIBAgIQes5Iu1DfQAHhzRlTTflXQDANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTMwMzE4MDAwMDAwWhcNMTUwNTMwMjM1OTU5WjCB8DETMBEGCysGAQQBgjc8
+HhcNMTQwNDExMDAwMDAwWhcNMTYwNDEwMjM1OTU5WjCB/DETMBEGCysGAQQBgjc8
 AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgNVBAUT
 CjUxNjQwNjAxMjAxCzAJBgNVBAYTAlNFMQ8wDQYDVQQRFAYxMTEgNDcxEjAQBgNV
 BAgTCVN0b2NraG9sbTESMBAGA1UEBxQJU3RvY2tob2xtMRgwFgYDVQQJFA9IYW1u

-H52hgaaXFsWiJlfFdynJgqvbwA==

+Um/nnOXcEdoRBnDG1vPBe3X0/p2Po6Cv0EKn5lb1UC8=
 -----END CERTIFICATE-----

commit 550e810ce237a50e5653318f44e133b9a81dc45b (tag: v1.9.6.11)
Author: liato <x@x00.us>
Date:   Thu Apr 10 00:13:37 2014 +0200

    Bump version. v1.9.6.11.

diff --git AndroidManifest.xml AndroidManifest.xml
index 722222d..92017b0 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.10" android:versionCode="180">
+	android:versionName="1.9.6.11" android:versionCode="181">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index d2e8dcb..76d4fe8 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,4 +1,10 @@
-v1.9.6.10: (2014-03-24)
+v1.9.6.11: (2014-04-10)
+* Updated SSL certificate for Swedbank
+* Transactions working for ICA accounts
+* Fix for ICA Banken
+
+
+v1.9.6.10: (2014-03-26)
 * Updated SSL certificate for Akelius Invest
 * Fix ICA for accounts with transactions
 
diff --git build.gradle build.gradle
index d2fe6b8..a85c09b 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 180
-        versionName '1.9.6.10'
+        versionCode 181
+        versionName '1.9.6.11'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit d6795f564705c25d5c0670851cef249f45f52e31
Author: liato <x@x00.us>
Date:   Thu Apr 10 00:09:47 2014 +0200

    Handle null values when parsing balances.

diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 8f5d355..4461faa 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -87,6 +87,9 @@ public class Helpers {
     private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
     public static BigDecimal parseBalance(String balance) {
+        if (balance == null) {
+            return new BigDecimal(0);
+        }
         balance = balance.replaceAll("[^0-9,.-]*", "");
         balance = balance.replace(",", ".");
         if (balance.indexOf(".") != balance.lastIndexOf(".")) {
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 7ee4295..15397ee 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -265,43 +265,54 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 	public static class WidgetService extends Service {
 
-		@Override
-		public void onStart(Intent intent, int startId) {
-			int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-			Context context = getApplicationContext();
-			String action = intent.getAction();
-			if (action == null) return; 
-			if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) {
-				new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId).execute();
-			}
-	        else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR)) {
+        @Override
+        public void onStart(Intent intent, int startId) {
+            handleStart(intent, startId);
+        }
+
+        @Override
+        public int onStartCommand(Intent intent, int flags, int startId) {
+            handleStart(intent, startId);
+            return START_NOT_STICKY;
+        }
+
+        public void handleStart(Intent intent, int startId) {
+            if (intent == null) return;
+            int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
+            Context context = getApplicationContext();
+            String action = intent.getAction();
+            if (action == null) return;
+            if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) {
+                new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId).execute();
+            }
+            else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR)) {
                 unblurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId);
-                
+
                 Handler blurHandler = new Handler();
                 class BlurRunnable implements Runnable {
                     private int mAppWidgetId;
-                    
+
                     public BlurRunnable(int appWidgetId) {
                         this.mAppWidgetId = appWidgetId;
                     }
-    
+
                     @Override
                     public void run() {
                         Context context = getApplicationContext();
                         blurAppWidget(context, AppWidgetManager.getInstance(context), mAppWidgetId);
                     }
-                     
-                 }
-                
+
+                }
+
 
                 SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
-                Integer unblurTimeout = 1000*Integer.parseInt(defprefs.getString("widget_blur_balance_timeout", "5"));                 
+                Integer unblurTimeout = 1000*Integer.parseInt(defprefs.getString("widget_blur_balance_timeout", "5"));
                 blurHandler.postDelayed(new BlurRunnable(appWidgetId), unblurTimeout);
-	        }
+            }
             else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_BLUR)) {
                 blurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId);
             }
-		}
+        }
 
 		@Override
 		public IBinder onBind(Intent arg0) {

commit c2eb1b53b9e2b51930f4f1133b909874368792a7
Author: liato <x@x00.us>
Date:   Thu Apr 10 00:09:09 2014 +0200

    Add transactions to ICA accounts.

diff --git src/com/liato/bankdroid/banking/banks/ica/ICA.java src/com/liato/bankdroid/banking/banks/ica/ICA.java
index d4fc399..548fc32 100644
--- src/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.banks.ica.model.LoginError;
 import com.liato.bankdroid.banking.banks.ica.model.Overview;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
@@ -40,7 +41,9 @@ import org.apache.http.client.ClientProtocolException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import eu.nullbyte.android.urllib.CertificateReader;
@@ -119,11 +122,21 @@ public class ICA extends Bank {
                 Account account = new Account(overview.getAccountName(), BigDecimal.valueOf(overview.getAvailableAmount()), overview.getAccountNumber());
                 balance = balance.add(account.getBalance());
                 accounts.add(account);
+                List<Transaction> transactions = new ArrayList<Transaction>();
+                for (com.liato.bankdroid.banking.banks.ica.model.Transaction t : overview.getTransactions()) {
+                    transactions.add(new Transaction(t.getTransactionDate(), t.getDescription(), BigDecimal.valueOf(t.getAmount())));
+                }
+                account.setTransactions(transactions);
             }
             for (com.liato.bankdroid.banking.banks.ica.model.Account a : overview.getAccounts()) {
                 Account account = new Account(a.getName(), BigDecimal.valueOf(a.getAvailableAmount()), a.getAccountNumber());
                 balance = balance.add(account.getBalance());
                 accounts.add(account);
+                List<Transaction> transactions = new ArrayList<Transaction>();
+                for (com.liato.bankdroid.banking.banks.ica.model.Transaction t : a.getTransactions()) {
+                    transactions.add(new Transaction(t.getTransactionDate(), t.getDescription(), BigDecimal.valueOf(t.getAmount())));
+                }
+                account.setTransactions(transactions);
             }
 
             Account account  = new Account("Erhållen bonus i år", BigDecimal.valueOf(overview.getAcquiredBonus()), "bonus");
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Overview.java src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
index 2cec93c..29d6b1a 100644
--- src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
+++ src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
@@ -39,6 +39,8 @@ public class Overview {
     private double creditLimit;
     @JsonProperty("Accounts")
     private List<Account> accounts = new ArrayList<Account>();
+    @JsonProperty("Transactions")
+    private List<Transaction> transactions = new ArrayList<Transaction>();
 
     @JsonProperty("Saldo")
     public double getSaldo() {
@@ -190,4 +192,14 @@ public class Overview {
         this.accounts = accounts;
     }
 
+    @JsonProperty("Transactions")
+    public List<Transaction> getTransactions() {
+        return transactions;
+    }
+
+    @JsonProperty("Transactions")
+    public void setTransactions(List<Transaction> transactions) {
+        this.transactions = transactions;
+    }
+
 }
\ No newline at end of file

commit e381ca5a2de0e63d11e865486020b298a49234fa
Author: liato <x@x00.us>
Date:   Wed Apr 9 23:31:11 2014 +0200

    Display error message after too many login attempts to Nordea.

diff --git src/com/liato/bankdroid/banking/banks/nordea/Nordea.java src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 3ec4f83..9afb8d0 100644
--- src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -16,22 +16,12 @@
 
 package com.liato.bankdroid.banking.banks.nordea;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.text.Html;
 import android.text.InputType;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
@@ -44,6 +34,20 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -107,8 +111,15 @@ public class Nordea extends Bank {
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("felaktiga uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			else if (response.contains("nloggningar med ditt personnummer idag")) {
+			} else if (response.contains("nyligen skett till din mobilbank")) {
+                Document d = Jsoup.parse(response);
+                Element e = d.select("div.infoContent").first();
+                if (e != null && !TextUtils.isEmpty(e.text().trim())) {
+                    throw new BankException(e.text().trim());
+                } else {
+                    throw new BankException(res.getText(R.string.unable_to_login).toString());
+                }
+            } else if (response.contains("nloggningar med ditt personnummer idag")) {
 		        Matcher matcher = reCSRF.matcher(response);
 		        if (!matcher.find()) {
 		            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");

commit 4b6fb24c7d7779c065b5155200064557d8e506c5
Author: liato <x@x00.us>
Date:   Wed Apr 9 23:21:18 2014 +0200

    Fix api url and headers for ICA Banken.

diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index d863898..6b083a2 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -56,7 +56,7 @@ public class ICABanken extends Bank {
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
     private static final boolean STATIC_BALANCE = false;
 
-    private static final String API_KEY = "E063BAEF-F87B-40A6-A309-3A6CC0F1174E";
+    private static final String API_KEY = "8987B80B-A708-4C61-B8CF-350D4BA289F0";
     private static final String API_URL = "https://appserver.icabanken.se";
     private static final String API_VERSION = "1.0";
 
@@ -87,10 +87,10 @@ public class ICABanken extends Bank {
         urlopen.addHeader("ClientHardware", Build.MODEL);
         urlopen.addHeader("ClientOS", "Android");
         urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
+        urlopen.addHeader("ClientAppVersion", "777");
 
         try {
-            String response = urlopen.open(API_URL + "/login?customerId="
-                    + username + "&password=" + password);
+            String response = urlopen.open(String.format("%s/login/passwordlogin?customerId=%s&password=%s", API_URL, username, password));
             if(response == null || "".equals(response)) {
                 throw new LoginException(res.getText(
                         R.string.invalid_username_password).toString());

commit e89be3757a702d4ea772d4d06653abea99922267
Author: liato <x@x00.us>
Date:   Wed Apr 9 22:58:43 2014 +0200

    Update Swedbank certificate.

diff --git res/raw/cert_swedbank.pem res/raw/cert_swedbank.pem
index 321b0d0..e6fe9e2 100644
--- res/raw/cert_swedbank.pem
+++ res/raw/cert_swedbank.pem
@@ -1,31 +1,30 @@
 -----BEGIN CERTIFICATE-----
-MIIFSTCCBDGgAwIBAgIQMDmESSXZfdIWMfXp3SGzTjANBgkqhkiG9w0BAQUFADCB
+MIIFOjCCBCKgAwIBAgIQXfRGamoEZvcx2Qu2g4nB1jANBgkqhkiG9w0BAQUFADCB
 vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMt
 VmVyaVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMB4X
-DTE0MDIxMzAwMDAwMFoXDTE1MDMwNDIzNTk1OVoweDELMAkGA1UEBhMCU0UxEjAQ
+DTE0MDQwOTAwMDAwMFoXDTE1MDMwNDIzNTk1OVoweDELMAkGA1UEBhMCU0UxEjAQ
 BgNVBAgTCVN0b2NraG9sbTESMBAGA1UEBxQJU3RvY2tob2xtMRQwEgYDVQQKFAtT
 V0VEQkFOSyBBQjELMAkGA1UECxQCSVQxHjAcBgNVBAMUFW1vYmlsYmFuay5zd2Vk

 YmFuay5zZTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBggr

-F26ZS8MiRZ8WWW1yGg==

 -----END CERTIFICATE-----

commit d8ebfabe2fc99c3248f8e48667b9d436af69b60b (tag: v1.9.6.10)
Author: liato <x@x00.us>
Date:   Wed Mar 26 00:16:09 2014 +0100

    Bump version. v1.9.6.10.

diff --git AndroidManifest.xml AndroidManifest.xml
index a6de913..722222d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.9" android:versionCode="179">
+	android:versionName="1.9.6.10" android:versionCode="180">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index 01d3089..d2e8dcb 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,7 +1,12 @@
+v1.9.6.10: (2014-03-24)
+* Updated SSL certificate for Akelius Invest
+* Fix ICA for accounts with transactions
+
+
 v1.9.6.9: (2014-03-24)
 * Updated SSL certificate for Avanza
-* Use Avanza implementation for Avanza Mini.
-* Update ICA implementation to use internal ICA API.
+* Use Avanza implementation for Avanza Mini
+* Update ICA implementation to use internal ICA API
 
 
 v1.9.6.8: (2014-03-20)
diff --git build.gradle build.gradle
index c3d8f86..d2fe6b8 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 179
-        versionName '1.9.6.9'
+        versionCode 180
+        versionName '1.9.6.10'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 1695f845be0045598d38318383f1401809c88b29
Author: liato <x@x00.us>
Date:   Wed Mar 26 00:10:03 2014 +0100

    Fix ICA for accounts with transactions.

diff --git src/com/liato/bankdroid/banking/banks/ica/ICA.java src/com/liato/bankdroid/banking/banks/ica/ICA.java
index 0da1148..d4fc399 100644
--- src/com/liato/bankdroid/banking/banks/ica/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -85,10 +85,15 @@ public class ICA extends Bank {
             HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login", null, false);
             if (httpResponse.getStatusLine().getStatusCode() == 401) {
                 LoginError le = readJsonValue(httpResponse, LoginError.class);
-                if (le != null && !TextUtils.isEmpty(le.getMessage())) {
-                    throw new LoginException(le.getMessage());
+                if (le != null && "UsernamePassword".equals(le.getMessageCode())) {
+                    if (!TextUtils.isEmpty(le.getMessage())) {
+                        throw new LoginException(le.getMessage());
+                    } else  {
+                        throw new LoginException(context.getText(
+                                R.string.invalid_username_password).toString());
+                    }
                 } else {
-                    throw new LoginException(context.getText(
+                    throw new BankException(context.getText(
                             R.string.invalid_username_password).toString());
                 }
             }
@@ -107,11 +112,16 @@ public class ICA extends Bank {
             Overview overview = readJsonValue(httpResponse, Overview.class);
 
             if (overview == null) {
-                throw new BankException(context.getString(R.string.unable_to_find) + "overview.");
+                throw new BankException(context.getString(R.string.unable_to_find) + " overview.");
             }
 
+            if (!TextUtils.isEmpty(overview.getAccountName())) {
+                Account account = new Account(overview.getAccountName(), BigDecimal.valueOf(overview.getAvailableAmount()), overview.getAccountNumber());
+                balance = balance.add(account.getBalance());
+                accounts.add(account);
+            }
             for (com.liato.bankdroid.banking.banks.ica.model.Account a : overview.getAccounts()) {
-                Account account  = new Account(a.getName(), BigDecimal.valueOf(a.getAvailableAmount()), a.getAccountNumber());
+                Account account = new Account(a.getName(), BigDecimal.valueOf(a.getAvailableAmount()), a.getAccountNumber());
                 balance = balance.add(account.getBalance());
                 accounts.add(account);
             }
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Account.java src/com/liato/bankdroid/banking/banks/ica/model/Account.java
index bfcfebd..67b85ef 100644
--- src/com/liato/bankdroid/banking/banks/ica/model/Account.java
+++ src/com/liato/bankdroid/banking/banks/ica/model/Account.java
@@ -24,7 +24,7 @@ public class Account {
     @JsonProperty("CreditLimit")
     private double creditLimit;
     @JsonProperty("Transactions")
-    private List<Object> transactions = new ArrayList<Object>();
+    private List<Transaction> transactions = new ArrayList<Transaction>();
     private Map<String, Object> additionalProperties = new HashMap<String, Object>();
 
     @JsonProperty("Name")
@@ -88,12 +88,12 @@ public class Account {
     }
 
     @JsonProperty("Transactions")
-    public List<Object> getTransactions() {
+    public List<Transaction> getTransactions() {
         return transactions;
     }
 
     @JsonProperty("Transactions")
-    public void setTransactions(List<Object> transactions) {
+    public void setTransactions(List<Transaction> transactions) {
         this.transactions = transactions;
     }
 
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Overview.java src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
index 0fa94c3..2cec93c 100644
--- src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
+++ src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
@@ -1,29 +1,55 @@
 package com.liato.bankdroid.banking.banks.ica.model;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import java.util.ArrayList;
 import java.util.List;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class Overview {
 
+    @JsonProperty("Saldo")
+    private double saldo;
     @JsonProperty("YearlyTotalPurchased")
     private double yearlyTotalPurchased;
+    @JsonProperty("PurchaseToDate")
+    private String purchaseToDate;
     @JsonProperty("AcquiredDiscount")
     private double acquiredDiscount;
     @JsonProperty("AmountSinceLastBonusCheck")
     private double amountSinceLastBonusCheck;
     @JsonProperty("AmountLeftUntilNextBonusCheck")
     private double amountLeftUntilNextBonusCheck;
+    @JsonProperty("NextBonusCheckValue")
+    private double nextBonusCheckValue;
     @JsonProperty("AcquiredBonus")
     private double acquiredBonus;
-    @JsonProperty("IcaBankUrl")
-    private String icaBankUrl;
     @JsonProperty("BonusToDate")
     private String bonusToDate;
+    @JsonProperty("IcaBankUrl")
+    private String icaBankUrl;
+    @JsonProperty("AccountNumber")
+    private String accountNumber;
+    @JsonProperty("AccountName")
+    private String accountName;
+    @JsonProperty("AvailableAmount")
+    private double availableAmount;
+    @JsonProperty("CreditLimit")
+    private double creditLimit;
     @JsonProperty("Accounts")
     private List<Account> accounts = new ArrayList<Account>();
 
+    @JsonProperty("Saldo")
+    public double getSaldo() {
+        return saldo;
+    }
+
+    @JsonProperty("Saldo")
+    public void setSaldo(double saldo) {
+        this.saldo = saldo;
+    }
+
     @JsonProperty("YearlyTotalPurchased")
     public double getYearlyTotalPurchased() {
         return yearlyTotalPurchased;
@@ -34,6 +60,16 @@ public class Overview {
         this.yearlyTotalPurchased = yearlyTotalPurchased;
     }
 
+    @JsonProperty("PurchaseToDate")
+    public String getPurchaseToDate() {
+        return purchaseToDate;
+    }
+
+    @JsonProperty("PurchaseToDate")
+    public void setPurchaseToDate(String purchaseToDate) {
+        this.purchaseToDate = purchaseToDate;
+    }
+
     @JsonProperty("AcquiredDiscount")
     public double getAcquiredDiscount() {
         return acquiredDiscount;
@@ -64,6 +100,16 @@ public class Overview {
         this.amountLeftUntilNextBonusCheck = amountLeftUntilNextBonusCheck;
     }
 
+    @JsonProperty("NextBonusCheckValue")
+    public double getNextBonusCheckValue() {
+        return nextBonusCheckValue;
+    }
+
+    @JsonProperty("NextBonusCheckValue")
+    public void setNextBonusCheckValue(double nextBonusCheckValue) {
+        this.nextBonusCheckValue = nextBonusCheckValue;
+    }
+
     @JsonProperty("AcquiredBonus")
     public double getAcquiredBonus() {
         return acquiredBonus;
@@ -74,6 +120,16 @@ public class Overview {
         this.acquiredBonus = acquiredBonus;
     }
 
+    @JsonProperty("BonusToDate")
+    public String getBonusToDate() {
+        return bonusToDate;
+    }
+
+    @JsonProperty("BonusToDate")
+    public void setBonusToDate(String bonusToDate) {
+        this.bonusToDate = bonusToDate;
+    }
+
     @JsonProperty("IcaBankUrl")
     public String getIcaBankUrl() {
         return icaBankUrl;
@@ -84,14 +140,44 @@ public class Overview {
         this.icaBankUrl = icaBankUrl;
     }
 
-    @JsonProperty("BonusToDate")
-    public String getBonusToDate() {
-        return bonusToDate;
+    @JsonProperty("AccountNumber")
+    public String getAccountNumber() {
+        return accountNumber;
     }
 
-    @JsonProperty("BonusToDate")
-    public void setBonusToDate(String bonusToDate) {
-        this.bonusToDate = bonusToDate;
+    @JsonProperty("AccountNumber")
+    public void setAccountNumber(String accountNumber) {
+        this.accountNumber = accountNumber;
+    }
+
+    @JsonProperty("AccountName")
+    public String getAccountName() {
+        return accountName;
+    }
+
+    @JsonProperty("AccountName")
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    @JsonProperty("AvailableAmount")
+    public double getAvailableAmount() {
+        return availableAmount;
+    }
+
+    @JsonProperty("AvailableAmount")
+    public void setAvailableAmount(double availableAmount) {
+        this.availableAmount = availableAmount;
+    }
+
+    @JsonProperty("CreditLimit")
+    public double getCreditLimit() {
+        return creditLimit;
+    }
+
+    @JsonProperty("CreditLimit")
+    public void setCreditLimit(double creditLimit) {
+        this.creditLimit = creditLimit;
     }
 
     @JsonProperty("Accounts")
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Transaction.java src/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
new file mode 100644
index 0000000..3d90d65
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ica/model/Transaction.java
@@ -0,0 +1,46 @@
+package com.liato.bankdroid.banking.banks.ica.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Transaction {
+
+    @JsonProperty("TransactionDate")
+    private String transactionDate;
+    @JsonProperty("Amount")
+    private double amount;
+    @JsonProperty("Description")
+    private String description;
+
+    @JsonProperty("TransactionDate")
+    public String getTransactionDate() {
+        return transactionDate;
+    }
+
+    @JsonProperty("TransactionDate")
+    public void setTransactionDate(String transactionDate) {
+        this.transactionDate = transactionDate;
+    }
+
+    @JsonProperty("Amount")
+    public double getAmount() {
+        return amount;
+    }
+
+    @JsonProperty("Amount")
+    public void setAmount(double amount) {
+        this.amount = amount;
+    }
+
+    @JsonProperty("Description")
+    public String getDescription() {
+        return description;
+    }
+
+    @JsonProperty("Description")
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+}
\ No newline at end of file

commit 5f520c0f71b24a3fb9d79c99115ef42c296672d2
Author: liato <x@x00.us>
Date:   Wed Mar 26 00:09:32 2014 +0100

    Update Akelius Invest cert.

diff --git res/raw/cert_akeliusinvest.pem res/raw/cert_akeliusinvest.pem
index 6e4f345..ed553be 100644
--- res/raw/cert_akeliusinvest.pem
+++ res/raw/cert_akeliusinvest.pem
@@ -1,34 +1,30 @@
 -----BEGIN CERTIFICATE-----

-5RCwjnQllRzWF+dCwDvLi1mbFOW7

+EeinVbKw
 -----END CERTIFICATE-----

commit 233f87663780fca4005ed932470752e2df1b947a
Author: liato <x@x00.us>
Date:   Mon Mar 24 23:16:38 2014 +0100

    Bump version. v1.9.6.9.

diff --git AndroidManifest.xml AndroidManifest.xml
index dce0581..a6de913 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.8" android:versionCode="178">
+	android:versionName="1.9.6.9" android:versionCode="179">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index 60dd83e..01d3089 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,9 @@
+v1.9.6.9: (2014-03-24)
+* Updated SSL certificate for Avanza
+* Use Avanza implementation for Avanza Mini.
+* Update ICA implementation to use internal ICA API.
+
+
 v1.9.6.8: (2014-03-20)
 * Updated SSL certificate for American Express
 * Fix for PayPal
diff --git build.gradle build.gradle
index ef6273f..c3d8f86 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 178
-        versionName '1.9.6.8'
+        versionCode 179
+        versionName '1.9.6.9'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit fe5870883d4630a0c35400fe305d4a39eedc216d
Author: liato <x@x00.us>
Date:   Sat Mar 22 02:33:48 2014 +0100

    Use internal ICA API for ICA implementation.

diff --git res/raw/cert_ica.pem res/raw/cert_ica.pem
index c789350..d63b3be 100644
--- res/raw/cert_ica.pem
+++ res/raw/cert_ica.pem
@@ -1,30 +1,29 @@
 -----BEGIN CERTIFICATE-----
-MIIFGzCCBAOgAwIBAgISESGW9wF3z3HvrpHMLtbE6jNNMA0GCSqGSIb3DQEBBQUA
+MIIFDDCCA/SgAwIBAgISESEwPVsCmeO5Q+OLhXPhTCyQMA0GCSqGSIb3DQEBBQUA
 MF0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTMwMQYD
 VQQDEypHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gRzIw

-wgsukWiO3rus98dCxpFI

 -----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 3f9bb63..5409017 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -16,8 +16,6 @@
 
 package com.liato.bankdroid;
 
-import java.math.BigDecimal;
-
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
@@ -33,11 +31,13 @@ import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.banks.Swedbank;
-import com.liato.bankdroid.banking.banks.Nordea.Nordea;
+import com.liato.bankdroid.banking.banks.nordea.Nordea;
 import com.liato.bankdroid.lockpattern.ChooseLockPattern;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
 
+import java.math.BigDecimal;
+
 public class SettingsActivity extends LockablePreferenceActivity implements OnPreferenceClickListener, OnPreferenceChangeListener {
 	private final static String TAG = "SettingsActivity";
 	private final static int DISABLE_LOCKPATTERN = 1;
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index f184327..73bcd69 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,10 +16,6 @@
 
 package com.liato.bankdroid.banking;
 
-import java.math.BigDecimal;
-import java.util.ArrayList;
-
-import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.database.Cursor;
@@ -51,7 +47,6 @@ import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.ForexBank;
 import com.liato.bankdroid.banking.banks.Handelsbanken;
 import com.liato.bankdroid.banking.banks.Hemkop;
-import com.liato.bankdroid.banking.banks.ICA;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
@@ -70,7 +65,6 @@ import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
 import com.liato.bankdroid.banking.banks.SJPrio;
 import com.liato.bankdroid.banking.banks.Saab;
@@ -93,16 +87,23 @@ import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Zidisha;
-import com.liato.bankdroid.banking.banks.Nordea.Nordea;
 import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
+import com.liato.bankdroid.banking.banks.ica.ICA;
 import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.nordea.Nordea;
+import com.liato.bankdroid.banking.banks.rikslunchen.Rikslunchen;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+
 public class BankFactory {
 
 	public static Bank fromBanktypeId(int id, Context context) throws BankException {
diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
deleted file mode 100644
index 96b5be9..0000000
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class ICA extends Bank {
-	private static final String TAG = "ICA";
-	private static final String NAME = "ICA";
-	private static final String NAME_SHORT = "ica";
-	private static final String URL = "http://mobil.ica.se/";
-	private static final int BANKTYPE_ID = IBankTypes.ICA;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-
-	private Pattern reAccounts = Pattern.compile("<td><span>Saldo</span></td>\\s*<td class=\"td_right\"><span>([^\\s]+)\\s*kr", Pattern.CASE_INSENSITIVE);
-	private Pattern rePreTransactions = Pattern.compile("<h2>Transaktioner</h2>(.*?)<h2>Information om kredit</h2>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<td><span>(\\d{4}-\\d{2}-\\d{2})</span></td>\\s*<td><span>([^<]+)</span></td>\\s*<td class=\"td_right\"><span>([^<]+)</span></td>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
-	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-	private Pattern reLoginError = Pattern.compile("loginError\">([^<]+)</span>");
-	
-	public ICA(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public ICA(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ica));
-        urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
-        String response = urlopen.open("https://www.ica.se/logga-in/");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
-        }
-        String strViewState = matcher.group(1);
-        
-        // Find __EVENTVALIDATION
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-        	throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation");
-        }
-        String strEventValidation = matcher.group(1);
-        
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("__EVENTTARGET", "LoginView1$btnModalLogin"));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        postData.add(new BasicNameValuePair("LoginView1$userName", username));
-        postData.add(new BasicNameValuePair("LoginView1$passWord", password));
-        postData.add(new BasicNameValuePair("LoginView1$RememberMe", "on"));
-        return new LoginPackage(urlopen, postData, response, "https://www.ica.se/logga-in/");
-    }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			Matcher matcher = reLoginError.matcher(response);
-			if (matcher.find()) {
-				throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.ica.se/mina-sidor/");
-			matcher = reAccounts.matcher(response);
-			if (matcher.find()) {
-				Account account = new Account("ICA Kort", Helpers.parseBalance(matcher.group(1)), "1");
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-				matcher = rePreTransactions.matcher(response);
-				if (matcher.find()) {
-					String temp = matcher.group(1);
-					matcher = reTransactions.matcher(temp);
-					ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-					while (matcher.find()) {
-						transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-					}
-					account.setTransactions(transactions);
-					accounts.add(account);
-				}
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-        finally {
-            super.updateComplete();
-        }
-	}
-}
diff --git src/com/liato/bankdroid/banking/banks/ica/ICA.java src/com/liato/bankdroid/banking/banks/ica/ICA.java
new file mode 100644
index 0000000..0da1148
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ica/ICA.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.ica;
+
+import android.content.Context;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Base64;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.ica.model.LoginError;
+import com.liato.bankdroid.banking.banks.ica.model.Overview;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class ICA extends Bank {
+    private static final String API_URL = "https://api.ica.se/api/";
+    private static final String AUTHENTICATION_TICKET_HEADER = "AuthenticationTicket";
+    private static final String SESSION_TICKET_HEADER = "SessionTicket";
+    private static final String LOGOUT_KEY_HEADER = "LogoutKey";
+    private ObjectMapper mObjectMapper = new ObjectMapper();
+    private Map<String, String> mHeaders = new HashMap<String, String>();
+
+    public ICA(Context context) {
+        super(context);
+        TAG = "ICA";
+        NAME = "ICA";
+        NAME_SHORT = "ica";
+        URL = "http://mobil.ica.se/";
+        BANKTYPE_ID = IBankTypes.ICA;
+        INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+        INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+        INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+        mHeaders.put(AUTHENTICATION_TICKET_HEADER, null);
+        mHeaders.put(SESSION_TICKET_HEADER, null);
+        mHeaders.put(LOGOUT_KEY_HEADER, null);
+    }
+
+    public ICA(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ica));
+        urlopen.addHeader("Accept", "application/json;charset=UTF-8");
+        urlopen.addHeader("Content-Type", "application/json;charset=UTF-8");
+        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+
+        try {
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "login", null, false);
+            if (httpResponse.getStatusLine().getStatusCode() == 401) {
+                LoginError le = readJsonValue(httpResponse, LoginError.class);
+                if (le != null && !TextUtils.isEmpty(le.getMessage())) {
+                    throw new LoginException(le.getMessage());
+                } else {
+                    throw new LoginException(context.getText(
+                            R.string.invalid_username_password).toString());
+                }
+            }
+
+            for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
+                Header header = httpResponse.getFirstHeader(entry.getKey());
+                if (header == null || TextUtils.isEmpty(header.getValue())) {
+                    throw new BankException(context.getString(
+                            R.string.unable_to_find).toString() + " " + entry.getKey());
+                }
+                mHeaders.put(entry.getKey(), header.getValue());
+            }
+
+            urlopen.addHeader(AUTHENTICATION_TICKET_HEADER, mHeaders.get(AUTHENTICATION_TICKET_HEADER));
+            httpResponse = urlopen.openAsHttpResponse(API_URL + "user/minasidor", null, false);
+            Overview overview = readJsonValue(httpResponse, Overview.class);
+
+            if (overview == null) {
+                throw new BankException(context.getString(R.string.unable_to_find) + "overview.");
+            }
+
+            for (com.liato.bankdroid.banking.banks.ica.model.Account a : overview.getAccounts()) {
+                Account account  = new Account(a.getName(), BigDecimal.valueOf(a.getAvailableAmount()), a.getAccountNumber());
+                balance = balance.add(account.getBalance());
+                accounts.add(account);
+            }
+
+            Account account  = new Account("Erhållen bonus i år", BigDecimal.valueOf(overview.getAcquiredBonus()), "bonus");
+            account.setType(Account.OTHER);
+            accounts.add(account);
+            account  = new Account("Årets totala inköp på ICA", BigDecimal.valueOf(overview.getYearlyTotalPurchased()), "totalpurchased");
+            account.setType(Account.OTHER);
+            accounts.add(account);
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+
+            urlopen.addHeader(LOGOUT_KEY_HEADER, mHeaders.get(LOGOUT_KEY_HEADER));
+            httpResponse = urlopen.openAsHttpResponse(API_URL + "logout", null, false);
+            httpResponse.getStatusLine();
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException,
+            BankChoiceException {
+        super.update();
+        if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_username_password).toString());
+        }
+        login();
+        super.updateComplete();
+    }
+
+    private <T> T readJsonValue(HttpResponse response, Class<T> valueType) throws BankException {
+        try {
+            return readJsonValue(response.getEntity().getContent(), valueType);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+        try {
+            return mObjectMapper.readValue(is, valueType);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Account.java src/com/liato/bankdroid/banking/banks/ica/model/Account.java
new file mode 100644
index 0000000..bfcfebd
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ica/model/Account.java
@@ -0,0 +1,100 @@
+package com.liato.bankdroid.banking.banks.ica.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Account {
+
+    @JsonProperty("Name")
+    private String name;
+    @JsonProperty("AccountNumber")
+    private String accountNumber;
+    @JsonProperty("AvailableAmount")
+    private double availableAmount;
+    @JsonProperty("ReservedAmount")
+    private double reservedAmount;
+    @JsonProperty("Saldo")
+    private double saldo;
+    @JsonProperty("CreditLimit")
+    private double creditLimit;
+    @JsonProperty("Transactions")
+    private List<Object> transactions = new ArrayList<Object>();
+    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+    @JsonProperty("Name")
+    public String getName() {
+        return name;
+    }
+
+    @JsonProperty("Name")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @JsonProperty("AccountNumber")
+    public String getAccountNumber() {
+        return accountNumber;
+    }
+
+    @JsonProperty("AccountNumber")
+    public void setAccountNumber(String accountNumber) {
+        this.accountNumber = accountNumber;
+    }
+
+    @JsonProperty("AvailableAmount")
+    public double getAvailableAmount() {
+        return availableAmount;
+    }
+
+    @JsonProperty("AvailableAmount")
+    public void setAvailableAmount(double availableAmount) {
+        this.availableAmount = availableAmount;
+    }
+
+    @JsonProperty("ReservedAmount")
+    public double getReservedAmount() {
+        return reservedAmount;
+    }
+
+    @JsonProperty("ReservedAmount")
+    public void setReservedAmount(double reservedAmount) {
+        this.reservedAmount = reservedAmount;
+    }
+
+    @JsonProperty("Saldo")
+    public double getSaldo() {
+        return saldo;
+    }
+
+    @JsonProperty("Saldo")
+    public void setSaldo(double saldo) {
+        this.saldo = saldo;
+    }
+
+    @JsonProperty("CreditLimit")
+    public double getCreditLimit() {
+        return creditLimit;
+    }
+
+    @JsonProperty("CreditLimit")
+    public void setCreditLimit(double creditLimit) {
+        this.creditLimit = creditLimit;
+    }
+
+    @JsonProperty("Transactions")
+    public List<Object> getTransactions() {
+        return transactions;
+    }
+
+    @JsonProperty("Transactions")
+    public void setTransactions(List<Object> transactions) {
+        this.transactions = transactions;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/ica/model/LoginError.java src/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
new file mode 100644
index 0000000..972316a
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ica/model/LoginError.java
@@ -0,0 +1,58 @@
+package com.liato.bankdroid.banking.banks.ica.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LoginError {
+
+    @JsonProperty("Title")
+    private String title;
+    @JsonProperty("MessageCode")
+    private String messageCode;
+    @JsonProperty("PhoneNumber")
+    private String phoneNumber;
+    @JsonProperty("Message")
+    private String message;
+
+    @JsonProperty("Title")
+    public String getTitle() {
+        return title;
+    }
+
+    @JsonProperty("Title")
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @JsonProperty("MessageCode")
+    public String getMessageCode() {
+        return messageCode;
+    }
+
+    @JsonProperty("MessageCode")
+    public void setMessageCode(String messageCode) {
+        this.messageCode = messageCode;
+    }
+
+    @JsonProperty("PhoneNumber")
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    @JsonProperty("PhoneNumber")
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    @JsonProperty("Message")
+    public String getMessage() {
+        return message;
+    }
+
+    @JsonProperty("Message")
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/ica/model/Overview.java src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
new file mode 100644
index 0000000..0fa94c3
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ica/model/Overview.java
@@ -0,0 +1,107 @@
+package com.liato.bankdroid.banking.banks.ica.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Overview {
+
+    @JsonProperty("YearlyTotalPurchased")
+    private double yearlyTotalPurchased;
+    @JsonProperty("AcquiredDiscount")
+    private double acquiredDiscount;
+    @JsonProperty("AmountSinceLastBonusCheck")
+    private double amountSinceLastBonusCheck;
+    @JsonProperty("AmountLeftUntilNextBonusCheck")
+    private double amountLeftUntilNextBonusCheck;
+    @JsonProperty("AcquiredBonus")
+    private double acquiredBonus;
+    @JsonProperty("IcaBankUrl")
+    private String icaBankUrl;
+    @JsonProperty("BonusToDate")
+    private String bonusToDate;
+    @JsonProperty("Accounts")
+    private List<Account> accounts = new ArrayList<Account>();
+
+    @JsonProperty("YearlyTotalPurchased")
+    public double getYearlyTotalPurchased() {
+        return yearlyTotalPurchased;
+    }
+
+    @JsonProperty("YearlyTotalPurchased")
+    public void setYearlyTotalPurchased(double yearlyTotalPurchased) {
+        this.yearlyTotalPurchased = yearlyTotalPurchased;
+    }
+
+    @JsonProperty("AcquiredDiscount")
+    public double getAcquiredDiscount() {
+        return acquiredDiscount;
+    }
+
+    @JsonProperty("AcquiredDiscount")
+    public void setAcquiredDiscount(double acquiredDiscount) {
+        this.acquiredDiscount = acquiredDiscount;
+    }
+
+    @JsonProperty("AmountSinceLastBonusCheck")
+    public double getAmountSinceLastBonusCheck() {
+        return amountSinceLastBonusCheck;
+    }
+
+    @JsonProperty("AmountSinceLastBonusCheck")
+    public void setAmountSinceLastBonusCheck(double amountSinceLastBonusCheck) {
+        this.amountSinceLastBonusCheck = amountSinceLastBonusCheck;
+    }
+
+    @JsonProperty("AmountLeftUntilNextBonusCheck")
+    public double getAmountLeftUntilNextBonusCheck() {
+        return amountLeftUntilNextBonusCheck;
+    }
+
+    @JsonProperty("AmountLeftUntilNextBonusCheck")
+    public void setAmountLeftUntilNextBonusCheck(double amountLeftUntilNextBonusCheck) {
+        this.amountLeftUntilNextBonusCheck = amountLeftUntilNextBonusCheck;
+    }
+
+    @JsonProperty("AcquiredBonus")
+    public double getAcquiredBonus() {
+        return acquiredBonus;
+    }
+
+    @JsonProperty("AcquiredBonus")
+    public void setAcquiredBonus(double acquiredBonus) {
+        this.acquiredBonus = acquiredBonus;
+    }
+
+    @JsonProperty("IcaBankUrl")
+    public String getIcaBankUrl() {
+        return icaBankUrl;
+    }
+
+    @JsonProperty("IcaBankUrl")
+    public void setIcaBankUrl(String icaBankUrl) {
+        this.icaBankUrl = icaBankUrl;
+    }
+
+    @JsonProperty("BonusToDate")
+    public String getBonusToDate() {
+        return bonusToDate;
+    }
+
+    @JsonProperty("BonusToDate")
+    public void setBonusToDate(String bonusToDate) {
+        this.bonusToDate = bonusToDate;
+    }
+
+    @JsonProperty("Accounts")
+    public List<Account> getAccounts() {
+        return accounts;
+    }
+
+    @JsonProperty("Accounts")
+    public void setAccounts(List<Account> accounts) {
+        this.accounts = accounts;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/ica/model/User.java src/com/liato/bankdroid/banking/banks/ica/model/User.java
new file mode 100644
index 0000000..d1386d9
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ica/model/User.java
@@ -0,0 +1,46 @@
+package com.liato.bankdroid.banking.banks.ica.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class User {
+
+    @JsonProperty("FirstName")
+    private String firstName;
+    @JsonProperty("LastName")
+    private String lastName;
+    @JsonProperty("Ttl")
+    private int ttl;
+
+    @JsonProperty("FirstName")
+    public String getFirstName() {
+        return firstName;
+    }
+
+    @JsonProperty("FirstName")
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    @JsonProperty("LastName")
+    public String getLastName() {
+        return lastName;
+    }
+
+    @JsonProperty("LastName")
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    @JsonProperty("Ttl")
+    public int getTtl() {
+        return ttl;
+    }
+
+    @JsonProperty("Ttl")
+    public void setTtl(int ttl) {
+        this.ttl = ttl;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreaker.java src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
similarity index 98%
rename from src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreaker.java
rename to src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
index f3b9503..41a3db9 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreaker.java
+++ src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreaker.java
@@ -1,4 +1,4 @@
-package com.liato.bankdroid.banking.banks.Nordea;
+package com.liato.bankdroid.banking.banks.nordea;
 
 import java.util.ArrayList;
 
diff --git src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreakerNumbers.java src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
similarity index 99%
rename from src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreakerNumbers.java
rename to src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
index f292edd..b169406 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreakerNumbers.java
+++ src/com/liato/bankdroid/banking/banks/nordea/CaptchaBreakerNumbers.java
@@ -1,4 +1,4 @@
-package com.liato.bankdroid.banking.banks.Nordea;
+package com.liato.bankdroid.banking.banks.nordea;
 
 /**
  * Autogenerated captcha numbers for Nordea.
diff --git src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
similarity index 99%
rename from src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
rename to src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
index 08eec39..3ec4f83 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/nordea/Nordea.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banking.banks.Nordea;
+package com.liato.bankdroid.banking.banks.nordea;
 
 import java.io.IOException;
 import java.util.ArrayList;
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
similarity index 99%
rename from src/com/liato/bankdroid/banking/banks/Rikslunchen.java
rename to src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
index 17ec257..26a2383 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/rikslunchen/Rikslunchen.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.liato.bankdroid.banking.banks;
+package com.liato.bankdroid.banking.banks.rikslunchen;
 
 import android.content.Context;
 import android.text.InputType;
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
index 7f3b29c..9fdf215 100644
--- src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
+++ src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -20,15 +20,15 @@ public class CertPinningTrustManager implements X509TrustManager {
         return new X509Certificate[0];
     }
 
-	@Override
-	public void checkClientTrusted(X509Certificate[] chain, String authType)
-			throws CertificateException {
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
         throw new CertificateException("Client authentication not implemented.");
-	}
+    }
 
-	@Override
-	public void checkServerTrusted(X509Certificate[] chain, String authType)
-			throws java.security.cert.CertificateException {
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType)
+            throws java.security.cert.CertificateException {
         for (X509Certificate certificate : chain) {
             byte[] publicKey = certificate.getPublicKey().getEncoded();
             for (Certificate pinnedCert : certificates) {
@@ -38,7 +38,7 @@ public class CertPinningTrustManager implements X509TrustManager {
             }
         }
         throw new CertificateException(host == null ? "Server certificate not trusted." : String.format("Server certificate not trusted for host: %s.", host));
-	}
+    }
 
     public void setHost(String host) {
         this.host = host;

commit 4f51d06d19db6e738b974c55955d6befec51bafe
Author: liato <x@x00.us>
Date:   Sat Mar 22 00:56:07 2014 +0100

    Use Avanza implementation for Avanza Mini. Update Avanza cert.

diff --git CHANGES.txt CHANGES.txt
index 94167e6..60dd83e 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,5 +1,5 @@
-v1.9.6.8: (2014-03-21)
-* Updated SSL certificates for American Express
+v1.9.6.8: (2014-03-20)
+* Updated SSL certificate for American Express
 * Fix for PayPal
 * Fix for ICA Banken (new api-key)
 
diff --git res/raw/cert_avanza_mini.pem res/raw/cert_avanza_mini.pem
deleted file mode 100644
index ff45953..0000000
--- res/raw/cert_avanza_mini.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----

-ckqfiJM8yNuuHA==
------END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index cf1d245..97fc37c 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,136 +16,18 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-
 import android.content.Context;
-import android.text.Html;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class AvanzaMini extends Bank {
-	private static final String TAG = "AvanzaMini";
-	private static final String NAME = "Avanza Mini";
-	private static final String NAME_SHORT = "avanzamini";
-	private static final String URL = "https://www.avanza.se/mini/hem/";
-	private static final int BANKTYPE_ID = IBankTypes.AVANZAMINI;
-	
-    private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tbody>\\s*(.*)</tbody>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern accountsAvanzaMini = Pattern.compile("<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	public AvanzaMini(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public AvanzaMini(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza_mini));
-        urlopen.setAllowCircularRedirects(true);
-        String response = urlopen.open("https://www.avanza.se/mini/logga_in/");
-        Document d = Jsoup.parse(response);
-        Element e = d.getElementById("javax.faces.ViewState");
-        if (e == null || e.attr("value") == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
-        }
-        String viewState = e.attr("value");
-        e = d.select("input[type=submit]").first();
-        if (e == null || e.attr("value") == null || e.attr("name") == null) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString() + " SubmitValue.");
-        }
-        String submitButtonName = e.attr("name");
-        String submitButtonValue = e.attr("value");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("login", "login"));
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
-        postData.add(new BasicNameValuePair("conversationPropagation", "none"));
-        postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
-        postData.add(new BasicNameValuePair(submitButtonName, submitButtonValue));
-        return new LoginPackage(urlopen, postData, null, "https://www.avanza.se/mini/logga_in/");
+public class AvanzaMini extends Avanza {
+    public AvanzaMini(Context context) {
+        super(context);
+        TAG = "AvanzaMini";
+        NAME = "Avanza Mini";
+        NAME_SHORT = "avanzamini";
+        URL = "https://www.avanza.se/mini/hem/";
+        BANKTYPE_ID = IBankTypes.AVANZAMINI;
     }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		String response = null;
-		try {
-			LoginPackage lp = preLogin();
-			urlopen.addHeader("Referer", "https://www.avanza.se/mini/logga_in/");
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktigt") && response.contains("Logga in")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.avanza.se/mini/mitt_konto/");
-			matcher = reAvanzaMini.matcher(response);
-	        if (matcher.find()) {
-	            int count = 1;
-	            Matcher submatcher = accountsAvanzaMini.matcher(matcher.group(1));
-	            while (submatcher.find()){
-	                accounts.add(new Account(Html.fromHtml(submatcher.group(1)).toString().trim(), Helpers.parseBalance(submatcher.group(2)), Integer.toString(count)));
-	                balance = balance.add(Helpers.parseBalance(submatcher.group(2)));
-	                count++;
-	            }
-	        }
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-        finally {
-            super.updateComplete();
-        }
-	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 236c4af..cf5eefb 100644
--- src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,21 +47,15 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Avanza extends Bank {
-    private static final String TAG = "Avanza";
-    private static final String NAME = "Avanza";
-    private static final String NAME_SHORT = "avanza";
-    private static final String URL = "https://www.avanza.se/";
-    private static final int BANKTYPE_ID = IBankTypes.AVANZA;
-
     private static final String API_URL = "https://iphone.avanza.se/iphone-ws/";
 
     public Avanza(Context context) {
         super(context);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
+        TAG = "Avanza";
+        NAME = "Avanza";
+        NAME_SHORT = "avanza";
+        URL = "https://www.avanza.se/";
+        BANKTYPE_ID = IBankTypes.AVANZA;
     }
 
     public Avanza(String username, String password, Context context)

commit b7901339398823e708f8f671566ff88057c8a280 (tag: v1.9.6.8)
Author: liato <x@x00.us>
Date:   Thu Mar 20 01:12:37 2014 +0100

    Bump version. v1.9.6.8.

diff --git AndroidManifest.xml AndroidManifest.xml
index f7f07ae..dce0581 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.7" android:versionCode="177">
+	android:versionName="1.9.6.8" android:versionCode="178">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index c757fff..94167e6 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,9 @@
+v1.9.6.8: (2014-03-21)
+* Updated SSL certificates for American Express
+* Fix for PayPal
+* Fix for ICA Banken (new api-key)
+
+
 v1.9.6.7: (2014-02-21)
 * Fix login fields parsing for Nordnet
 * Fix for regular Jojo cards
diff --git build.gradle build.gradle
index 8879c9a..ef6273f 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 177
-        versionName '1.9.6.7'
+        versionCode 178
+        versionName '1.9.6.8'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit b4e3a00d23dede4e456cb0775726d762144c0c83
Author: liato <x@x00.us>
Date:   Thu Mar 20 01:11:38 2014 +0100

    Fix indentation in PayPal.

diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 75f489b..8d7f457 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -48,33 +48,33 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PayPal extends Bank {
-	private static final String TAG = "PayPal";
-	private static final String NAME = "PayPal";
-	private static final String NAME_SHORT = "paypal";
-	private static final String URL = "https://www.paypal.com/";
-	private static final int BANKTYPE_ID = IBankTypes.PAYPAL;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-	private static final boolean STATIC_BALANCE = true;
-	
-	private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>", Pattern.CASE_INSENSITIVE);
-	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
-	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	public PayPal(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-	}
+    private static final String TAG = "PayPal";
+    private static final String NAME = "PayPal";
+    private static final String NAME_SHORT = "paypal";
+    private static final String URL = "https://www.paypal.com/";
+    private static final int BANKTYPE_ID = IBankTypes.PAYPAL;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+    private static final boolean STATIC_BALANCE = true;
 
-	public PayPal(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+    private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>", Pattern.CASE_INSENSITIVE);
+    private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
+    private String response = null;
+    public PayPal(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public PayPal(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
     
     @Override
@@ -112,37 +112,37 @@ public class PayPal extends Bank {
         return new LoginPackage(urlopen, postData, response, strPostUrl);
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			if (response.contains("your last action could not be completed")) {
-			    throw new BankException("Error: PPL92");
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		try {
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+            if (response.contains("your last action could not be completed")) {
+                throw new BankException("Error: PPL92");
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
             response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
-    		Matcher matcher = reAccounts.matcher(response);
-    		int accId = 1;
-    		while (matcher.find()) {
+            Matcher matcher = reAccounts.matcher(response);
+            int accId = 1;
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
@@ -151,11 +151,11 @@ public class PayPal extends Bank {
                  * 3: currency          SEK
                  * 
                  */
-    		    Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ""+accId);
-    		    account.setCurrency(matcher.group(3).trim());
-    		    accounts.add(account);
-    		    accId++;
-    		}
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ""+accId);
+                account.setCurrency(matcher.group(3).trim());
+                accounts.add(account);
+                accId++;
+            }
             matcher = reBalance.matcher(response);
             if (matcher.find()) {
                 /*
@@ -174,9 +174,9 @@ public class PayPal extends Bank {
                     accounts.add(account);                }
             }
 
-    		if (accounts.isEmpty()) {
-    			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-    		}
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
         }
         catch (ClientProtocolException e) {
             // TODO Auto-generated catch block
@@ -189,6 +189,6 @@ public class PayPal extends Bank {
         finally {
             super.updateComplete();
         }
-	}
-	
+    }
+
 }
\ No newline at end of file

commit 8ac5a740271cb1edfb8861464104dfc55f501661
Author: liato <x@x00.us>
Date:   Thu Mar 20 01:04:00 2014 +0100

    Fix for American Express and PayPal.

diff --git res/raw/cert_americanexpress.pem res/raw/cert_americanexpress.pem
index 7787e79..74d1921 100644
--- res/raw/cert_americanexpress.pem
+++ res/raw/cert_americanexpress.pem
@@ -1,25 +1,25 @@
 -----BEGIN CERTIFICATE-----
-MIIELTCCAxWgAwIBAgIOAQAAAAABPV8zvQhdKIwwDQYJKoZIhvcNAQEFBQAwRjEX
+MIIELTCCAxWgAwIBAgIOAQAAAAABQ8WUqMqCd7MwDQYJKoZIhvcNAQEFBQAwRjEX
 MBUGA1UEChMOQ3liZXJ0cnVzdCBJbmMxKzApBgNVBAMTIkN5YmVydHJ1c3QgUHVi
-bGljIFN1cmVTZXJ2ZXIgU1YgQ0EwHhcNMTMwMzEyMTQ1OTA5WhcNMTQwMzEyMTQ1
-OTA5WjCBjDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEDAOBgNVBAcT
+bGljIFN1cmVTZXJ2ZXIgU1YgQ0EwHhcNMTQwMTI0MTg1NDM3WhcNMTUwMTI0MTg1
+NDM3WjCBjDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEDAOBgNVBAcT
 B1Bob2VuaXgxJjAkBgNVBAoTHUFtZXJpY2FuIEV4cHJlc3MgVGVjaG5vbG9naWVz
 MREwDwYDVQQLEwhDb25zdW1lcjEeMBwGA1UEAxQVKi5hbWVyaWNhbmV4cHJlc3Mu

 MD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6Ly9jcmwub21uaXJvb3QuY29tL1B1Ymxp
-Y1N1cmVTZXJ2ZXJTVi5jcmwwHQYDVR0OBBYEFPUDiB8WZrF7n1YFxeCZsbxHG4tN
+Y1N1cmVTZXJ2ZXJTVi5jcmwwHQYDVR0OBBYEFIxc+a8hiFsVTqFGQ6tCXewLhbQs
 MAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
 BggrBgEFBQcDAjARBglghkgBhvhCAQEEBAMCBsAwDQYJKoZIhvcNAQEFBQADggEB
-AAhI3MHq/YSC6aMXZR6aVBE2tOpkG8VqhNJbPjXO9sXdJqW/86OeqoOjvmNbvTmC
-I/Phacrk5YYgP2HqU2CYV7imlcq5/KL00IIO1yG+sOA51sp+MxPJT6Rp5/N9xxn6
-LBbV+LHnukdpw4Q7ZVwkwrTVw+iHGpHTzwwrJkyd88Ez9ydUM+mzTmx+tyDzX7x8
-M55+m5zbEBwECyBFVwFJjiUmzhTzJ6gZhm1azLw+9ZikCJx2PAUKkzgcZThP6q+X
-3/P5HnE0Kli/KaaLgu4TANPGIL81PoLX3fKGG8OopEJVbdhn96zfJOA5Cq5P/Fff
-uz4tR1ZyASXcO8NEyEICKBs=
+ABFk0k0P1UY71hv4s7WRs+k9B/fYYvtMmUJGGPqTswb9YM2xcX7ImiOElhjOrPuB
+t0Jf0Mb3TGU04pO0ga7LfVAnGctPCdYftUORYxwqcn/KPxPiAh+k1sqQWVdDTe/q
+0JKEyMDSBy/uMcoryzqVjuV6E0YDFnGN+JglEnOf4slGKpquxfwJIUXGRYeCbYHR
+CVcMkJM/2gOZkZUblTVPsjt5w1Yb4UYXiDnrvjrpEBAyZpx4Poy66u3uUERIDL93
+m7m75XwRId/HZk+j6aFCq1HQGRl0KGDKMFC8RJvPSgJ6KEo6CZ8y0DT98YJJ3ew5
+RErQgv+9W9k+KaFKzX5TpTM=
 -----END CERTIFICATE-----
diff --git res/raw/cert_americanexpress2.pem res/raw/cert_americanexpress2.pem
deleted file mode 100644
index 3df759a..0000000
--- res/raw/cert_americanexpress2.pem
+++ /dev/null
@@ -1,38 +0,0 @@
------BEGIN CERTIFICATE-----

-LQfnNyKUeTuq343tlqPfYy9NGKwD
------END CERTIFICATE-----
-
diff --git res/raw/cert_americanexpress3.pem res/raw/cert_americanexpress3.pem
deleted file mode 100644
index 04e020f..0000000
--- res/raw/cert_americanexpress3.pem
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----

-tC3C6Lbk+7TZl82Ktn48njQpcfhbB26b1ro=
------END CERTIFICATE-----
diff --git res/raw/cert_americanexpress4.pem res/raw/cert_americanexpress4.pem
deleted file mode 100644
index 74d1921..0000000
--- res/raw/cert_americanexpress4.pem
+++ /dev/null
@@ -1,25 +0,0 @@
------BEGIN CERTIFICATE-----

-RErQgv+9W9k+KaFKzX5TpTM=
------END CERTIFICATE-----
diff --git res/raw/cert_americanexpress_global.pem res/raw/cert_americanexpress_global.pem
new file mode 100644
index 0000000..773b769
--- /dev/null
+++ res/raw/cert_americanexpress_global.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+ZZZmPHKzZcQMXHKr/HckqlRrzxUHdgdryY0=
+-----END CERTIFICATE-----
diff --git res/raw/cert_paypal2.pem res/raw/cert_paypal2.pem
new file mode 100644
index 0000000..5407ef2
--- /dev/null
+++ res/raw/cert_paypal2.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----

+pA5cRcJCTj+6x7nfpV3x84/iyfX5
+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 568579f..a2268b4 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -49,35 +49,35 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AmericanExpress extends Bank {
-	private static final String TAG = "AmericanExpress";
-	private static final String NAME = "American Express";
-	private static final String NAME_SHORT = "americanexpress";
-	private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
-	private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
-	
-	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	private String response = null;
-
-	public AmericanExpress(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+    private static final String TAG = "AmericanExpress";
+    private static final String NAME = "American Express";
+    private static final String NAME_SHORT = "americanexpress";
+    private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
+    private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
+
+    private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+    private String response = null;
+
+    public AmericanExpress(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress3, R.raw.cert_americanexpress4));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress_global));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
@@ -101,34 +101,34 @@ public class AmericanExpress extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			if (!response.contains("Your Personal Cards")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen = login();
-		Matcher matcher = reAccounts.matcher(response);
-		
-		while (matcher.find()) {
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+            if (!response.contains("Your Personal Cards")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher = reAccounts.matcher(response);
+
+        while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                    EXAMPLE DATA
@@ -138,32 +138,32 @@ public class AmericanExpress extends Bank {
              * 4: Amount                1.111,11 kr
              * 
              */   			    
-			accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
-			        Helpers.parseBalance(matcher.group(4)).negate(),
-			        matcher.group(2).trim()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
-		}
-		
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	    super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-
-		try {
-			response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
-			Matcher matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			
-			SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
+            accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
+                    Helpers.parseBalance(matcher.group(4)).negate(),
+                    matcher.group(2).trim()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        try {
+            response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
+            Matcher matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+            SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
             SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
             Date transactionDate;
-			
-			while (matcher.find()) {
+
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
@@ -182,14 +182,14 @@ public class AmericanExpress extends Bank {
                 catch (ParseException e) {
                     Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}	
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 7773aaa..75f489b 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -80,7 +80,7 @@ public class PayPal extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal, R.raw.cert_paypal2));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
@@ -89,7 +89,7 @@ public class PayPal extends Bank {
         
         String strPostUrl;
         if (e != null && !TextUtils.isEmpty(e.attr("action"))) {
-            strPostUrl = e.attr("action");
+            strPostUrl = e.attr("action").trim();
         }
         else {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
diff --git src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index 89fa2c9..fd3081f 100644
--- src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -44,6 +44,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
     private SSLContext sslcontext = null;
     private Certificate[] certificates;
     private String lastHost;
+    private CertPinningTrustManager mTrustManager;
 
     public CertPinningSSLSocketFactory(Certificate[] certificates) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
         super(null);
@@ -55,7 +56,8 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
         //Log.v(TAG, "createSSLContext()");
         try {
             SSLContext context = SSLContext.getInstance("TLS");
-            context.init(null, new TrustManager[] { new CertPinningTrustManager(certificates, lastHost) }, null);
+            mTrustManager = new CertPinningTrustManager(certificates, lastHost);
+            context.init(null, new TrustManager[] { mTrustManager }, null);
             return context;
         } catch (Exception e) {
             throw new IOException(e.getMessage());
@@ -132,4 +134,11 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
         lastHost = host;
         return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
     }
+
+    public void setHost(String host) {
+        lastHost = host;
+        if (mTrustManager != null) {
+            mTrustManager.setHost(host);
+        }
+    }
 }
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
index 5128e8f..7f3b29c 100644
--- src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
+++ src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -39,4 +39,8 @@ public class CertPinningTrustManager implements X509TrustManager {
         }
         throw new CertificateException(host == null ? "Server certificate not trusted." : String.format("Server certificate not trusted for host: %s.", host));
 	}
+
+    public void setHost(String host) {
+        this.host = host;
+    }
 }
diff --git src/eu/nullbyte/android/urllib/CertificateReader.java src/eu/nullbyte/android/urllib/CertificateReader.java
index 05ca183..5df64d7 100644
--- src/eu/nullbyte/android/urllib/CertificateReader.java
+++ src/eu/nullbyte/android/urllib/CertificateReader.java
@@ -16,30 +16,30 @@ import java.util.List;
 
 public class CertificateReader {
 
-	public static Certificate[] getCertificates(Context context,
-			int... rawResCerts) {
-		List<Certificate> certificates = new ArrayList<Certificate>();
-		try {
-			CertificateFactory cf = CertificateFactory.getInstance("X.509");
-			for (int resId : rawResCerts) {
-				InputStream is = new BufferedInputStream(context.getResources()
-						.openRawResource(resId));
-				try {
-					X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
-					certificates.add(cert);
-				} finally {
-					try {
-						is.close();
-					} catch (IOException e) {
-						e.printStackTrace();
-					}
-				}
-			}
-		} catch (CertificateException e1) {
-			e1.printStackTrace();
-		}
-		return certificates.toArray(new Certificate[certificates.size()]);
-	}
+    public static Certificate[] getCertificates(Context context,
+            int... rawResCerts) {
+        List<Certificate> certificates = new ArrayList<Certificate>();
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            for (int resId : rawResCerts) {
+                InputStream is = new BufferedInputStream(context.getResources()
+                        .openRawResource(resId));
+                try {
+                    X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
+                    certificates.add(cert);
+                } finally {
+                    try {
+                        is.close();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } catch (CertificateException e1) {
+            e1.printStackTrace();
+        }
+        return certificates.toArray(new Certificate[certificates.size()]);
+    }
 
     public static String[] getPins(Context context, int... rawResCerts) {
         Certificate[] certs = getCertificates(context, rawResCerts);
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index cbaa877..d3c4565 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -27,18 +27,28 @@ import android.preference.PreferenceManager;
 import com.liato.bankdroid.BuildConfig;
 import com.liato.bankdroid.R;
 
+import org.apache.http.ConnectionReuseStrategy;
 import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.NameValuePair;
+import org.apache.http.client.AuthenticationHandler;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.RedirectHandler;
+import org.apache.http.client.RequestDirector;
 import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.UserTokenHandler;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.conn.ClientConnectionManager;
 import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.routing.HttpRoutePlanner;
 import org.apache.http.conn.scheme.PlainSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
@@ -47,6 +57,7 @@ import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.DefaultRequestDirector;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpParams;
@@ -54,6 +65,8 @@ import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestExecutor;
 import org.apache.http.util.EntityUtils;
 
 import java.io.IOException;
@@ -72,23 +85,24 @@ public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
     private String userAgent = null;
     private DefaultHttpClient httpclient;
-	private HttpContext mHttpContext;
-	private String currentURI;
-	private String charset = HTTP.UTF_8;
-	private HashMap<String, String> headers;
+    private HttpContext mHttpContext;
+    private String currentURI;
+    private String charset = HTTP.UTF_8;
+    private HashMap<String, String> headers;
     private Context mContext;
+    private CertPinningSSLSocketFactory mSSLSocketFactory;
 
 
     public Urllib(Context context) {
         this(context, null);
     }
 
-	public Urllib(Context context, Certificate[] pins) {
+    public Urllib(Context context, Certificate[] pins) {
         mContext = context;
-		this.headers = new HashMap<String, String>();
+        this.headers = new HashMap<String, String>();
         userAgent = createUserAgentString();
-    	HttpParams params = new BasicHttpParams(); 
-    	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+        HttpParams params = new BasicHttpParams();
+        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, this.charset);
         params.setBooleanParameter("http.protocol.expect-continue", false);
         SchemeRegistry registry = new SchemeRegistry();
@@ -96,7 +110,8 @@ public class Urllib {
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         boolean trustSystemKeystore = prefs.getBoolean("debug_mode", false) && prefs.getBoolean("no_cert_pinning", false);
         try {
-            registry.register(new Scheme("https", pins != null && !trustSystemKeystore ? new CertPinningSSLSocketFactory(pins) : SSLSocketFactory.getSocketFactory(), 443));
+            mSSLSocketFactory = new CertPinningSSLSocketFactory(pins);
+            registry.register(new Scheme("https", pins != null && !trustSystemKeystore ? mSSLSocketFactory : SSLSocketFactory.getSocketFactory(), 443));
         } catch (UnrecoverableKeyException e) {
             e.printStackTrace();
         } catch (KeyManagementException e) {
@@ -107,20 +122,21 @@ public class Urllib {
             e.printStackTrace();
         }
         ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
-        httpclient = new DefaultHttpClient(manager, params);
-    	mHttpContext = new BasicHttpContext();
+        httpclient = new BankdroidHttpClient(manager, params);
+        mHttpContext = new BasicHttpContext();
+
     }
     
     public String open(String url) throws ClientProtocolException, IOException {
-    	return this.open(url, new ArrayList <NameValuePair>());
+        return this.open(url, new ArrayList <NameValuePair>());
     }
     
     public String post(String url) throws ClientProtocolException, IOException {
-    	return this.open(url, new ArrayList <NameValuePair>(), true);
+        return this.open(url, new ArrayList <NameValuePair>(), true);
     }
     
     public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
-    	return open(url, postData, false);
+        return open(url, postData, false);
     }
     public String open(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
         return EntityUtils.toString(openAsHttpResponse(url, postData, forcePost).getEntity());
@@ -163,22 +179,22 @@ public class Urllib {
     }
     
     public HttpEntity toEntity(List<NameValuePair> postData) {
-    	if (postData != null && !postData.isEmpty()) {
-    		try {
-				return new UrlEncodedFormEntity(postData, this.charset);
-			} catch (UnsupportedEncodingException e) {
-				e.printStackTrace();
-			} 
-    	}
-    	return null;
+        if (postData != null && !postData.isEmpty()) {
+            try {
+                return new UrlEncodedFormEntity(postData, this.charset);
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
     }
     
     public InputStream openStream(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
-    	return openStream(url, toEntity(postData), forcePost);
+        return openStream(url, toEntity(postData), forcePost);
     }
     
     public InputStream openStream(String url, String postData, boolean forcePost) throws ClientProtocolException, IOException {
-    	return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, forcePost);
+        return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, forcePost);
     }
     
     public InputStream openStream(String url, HttpEntity postData, boolean forcePost) throws ClientProtocolException, IOException {
@@ -211,11 +227,11 @@ public class Urllib {
     }
     
     public HttpContext getmHttpContext() {
-    	return mHttpContext;
+        return mHttpContext;
     }
     
     public String getCurrentURI() {
-    	return currentURI;
+        return currentURI;
     }
     
     public DefaultHttpClient getHttpclient() {
@@ -259,7 +275,7 @@ public class Urllib {
 
     
     public void setUserAgent(String userAgent) {
-    	this.userAgent = userAgent; 
+        this.userAgent = userAgent;
     }
 
     private String createUserAgentString() {
@@ -287,5 +303,49 @@ public class Urllib {
                 , Build.MANUFACTURER
                 , Build.MODEL);
     }
-    
+
+    class BankdroidHttpClient extends DefaultHttpClient {
+
+        BankdroidHttpClient(ClientConnectionManager conman, HttpParams params) {
+            super(conman, params);
+        }
+
+        @Override
+        public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
+            updateSocketFactoryHost(target);
+            return super.execute(target, request, responseHandler);
+        }
+
+        @Override
+        public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
+            updateSocketFactoryHost(target);
+            return super.execute(target, request, responseHandler, context);
+        }
+
+        @Override
+        protected RequestDirector createClientRequestDirector(HttpRequestExecutor requestExec, ClientConnectionManager conman, ConnectionReuseStrategy reustrat, ConnectionKeepAliveStrategy kastrat, HttpRoutePlanner rouplan, HttpProcessor httpProcessor, HttpRequestRetryHandler retryHandler, RedirectHandler redirectHandler, AuthenticationHandler targetAuthHandler, AuthenticationHandler proxyAuthHandler, UserTokenHandler stateHandler, HttpParams params) {
+            return new DefaultishRequestDirector(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, stateHandler, params);
+        }
+    }
+
+    class DefaultishRequestDirector extends DefaultRequestDirector {
+
+        public DefaultishRequestDirector(HttpRequestExecutor requestExec, ClientConnectionManager conman, ConnectionReuseStrategy reustrat, ConnectionKeepAliveStrategy kastrat, HttpRoutePlanner rouplan, HttpProcessor httpProcessor, HttpRequestRetryHandler retryHandler, RedirectHandler redirectHandler, AuthenticationHandler targetAuthHandler, AuthenticationHandler proxyAuthHandler, UserTokenHandler userTokenHandler, HttpParams params) {
+            super(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params);
+        }
+
+        @Override
+        public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws HttpException, IOException {
+            updateSocketFactoryHost(target);
+            return super.execute(target, request, context);
+        }
+    }
+
+
+    private void updateSocketFactoryHost(HttpHost host) {
+        if (mSSLSocketFactory != null && host != null) {
+            mSSLSocketFactory.setHost(host.getHostName());
+        }
+    }
+
 }
\ No newline at end of file

commit 57e88a6d7afb74bdc9193334890ff1d97a604718
Author: liato <x@x00.us>
Date:   Wed Mar 19 23:47:32 2014 +0100

    Fix indentation in ICABAnken.

diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 9bcb310..d863898 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -46,121 +46,121 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
-	private static final String TAG = "ICABanken";
-	private static final String NAME = "ICA Banken";
-	private static final String NAME_SHORT = "icabanken";
-	private static final String URL = "https://mobil.icabanken.se/";
-	private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-	private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
-	private static final boolean STATIC_BALANCE = false;
-
-	private static final String API_KEY = "E063BAEF-F87B-40A6-A309-3A6CC0F1174E";
-	private static final String API_URL = "https://appserver.icabanken.se";
-	private static final String API_VERSION = "1.0";
-
-	public ICABanken(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-	}
-
-	public ICABanken(String username, String password, Context context)
-			throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken, R.raw.cert_icabanken2));
-		urlopen.addHeader("ApiVersion", API_VERSION);
-		urlopen.addHeader("Accept", "application/json");
-		urlopen.addHeader("ApiKey", API_KEY);
-		urlopen.addHeader("ClientHardware", Build.MODEL);
-		urlopen.addHeader("ClientOS", "Android");
-		urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
-
-		try {
-			String response = urlopen.open(API_URL + "/login?customerId="
-					+ username + "&password=" + password);
-			if(response == null || "".equals(response)) {
-				throw new LoginException(res.getText(
-						R.string.invalid_username_password).toString());
-			}
-			ObjectMapper vObjectMapper = new ObjectMapper();
-			vObjectMapper.setDateFormat(new SimpleDateFormat(
-					"yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
-			LoginResponse loginResponse = vObjectMapper.readValue(response,
-					LoginResponse.class);
-
-			addAccounts(loginResponse.getAccountList());
-
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException,
-			BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0
-				|| password.length() == 0) {
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
-		}
-		login();
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found)
-					.toString());
-		}
+    private static final String TAG = "ICABanken";
+    private static final String NAME = "ICA Banken";
+    private static final String NAME_SHORT = "icabanken";
+    private static final String URL = "https://mobil.icabanken.se/";
+    private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
+    private static final boolean STATIC_BALANCE = false;
+
+    private static final String API_KEY = "E063BAEF-F87B-40A6-A309-3A6CC0F1174E";
+    private static final String API_URL = "https://appserver.icabanken.se";
+    private static final String API_VERSION = "1.0";
+
+    public ICABanken(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public ICABanken(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken, R.raw.cert_icabanken2));
+        urlopen.addHeader("ApiVersion", API_VERSION);
+        urlopen.addHeader("Accept", "application/json");
+        urlopen.addHeader("ApiKey", API_KEY);
+        urlopen.addHeader("ClientHardware", Build.MODEL);
+        urlopen.addHeader("ClientOS", "Android");
+        urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
+
+        try {
+            String response = urlopen.open(API_URL + "/login?customerId="
+                    + username + "&password=" + password);
+            if(response == null || "".equals(response)) {
+                throw new LoginException(res.getText(
+                        R.string.invalid_username_password).toString());
+            }
+            ObjectMapper vObjectMapper = new ObjectMapper();
+            vObjectMapper.setDateFormat(new SimpleDateFormat(
+                    "yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
+            LoginResponse loginResponse = vObjectMapper.readValue(response,
+                    LoginResponse.class);
+
+            addAccounts(loginResponse.getAccountList());
+
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException,
+            BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0
+                || password.length() == 0) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_username_password).toString());
+        }
+        login();
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found)
+                    .toString());
+        }
         super.updateComplete();
 
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen)
-			throws LoginException, BankException {
-	}
-
-	private void addAccounts(IcaBankenAccountList pAccountList) {
-		for (IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
-			Account account = new Account(icaAccount.getName()
-					+ " (Disponibelt)", icaAccount.getAvailableAmount(),
-					icaAccount.getAccountId());
-			account.setTransactions(mapTransactions(icaAccount));
-			Account alias = new Account(icaAccount.getName() + " (Saldo)",
-					icaAccount.getCurrentAmount(), "a:"
-							+ icaAccount.getAccountId());
-			alias.setAliasfor(icaAccount.getAccountId());
-			accounts.add(account);
-			accounts.add(alias);
-			balance.add(account.getBalance());
-		}
-	}
-
-	private ArrayList<Transaction> mapTransactions(IcaBankenAccount pAccount) {
-		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-		DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd",
-				Locale.getDefault());
-		for (IcaBankenTransaction icaTransaction : pAccount.getTransactions()) {
-			String date = dateFormatter.format(icaTransaction.getPostedDate());
-			Transaction transaction = new Transaction(date,
-					icaTransaction.getMemoText(), icaTransaction.getAmount());
-			transactions.add(transaction);
-		}
-		return transactions;
-	}
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen)
+            throws LoginException, BankException {
+    }
+
+    private void addAccounts(IcaBankenAccountList pAccountList) {
+        for (IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
+            Account account = new Account(icaAccount.getName()
+                    + " (Disponibelt)", icaAccount.getAvailableAmount(),
+                    icaAccount.getAccountId());
+            account.setTransactions(mapTransactions(icaAccount));
+            Account alias = new Account(icaAccount.getName() + " (Saldo)",
+                    icaAccount.getCurrentAmount(), "a:"
+                            + icaAccount.getAccountId());
+            alias.setAliasfor(icaAccount.getAccountId());
+            accounts.add(account);
+            accounts.add(alias);
+            balance.add(account.getBalance());
+        }
+    }
+
+    private ArrayList<Transaction> mapTransactions(IcaBankenAccount pAccount) {
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd",
+                Locale.getDefault());
+        for (IcaBankenTransaction icaTransaction : pAccount.getTransactions()) {
+            String date = dateFormatter.format(icaTransaction.getPostedDate());
+            Transaction transaction = new Transaction(date,
+                    icaTransaction.getMemoText(), icaTransaction.getAmount());
+            transactions.add(transaction);
+        }
+        return transactions;
+    }
 }

commit 1f376faf5d1d38b416a950e5e8a7d3ab93be00de
Author: liato <x@x00.us>
Date:   Wed Mar 19 23:46:26 2014 +0100

    Update API key for ICA Banken.

diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index ee492bb..9bcb310 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -56,7 +56,7 @@ public class ICABanken extends Bank {
 	private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
 	private static final boolean STATIC_BALANCE = false;
 
-	private static final String API_KEY = "9A75DD46-82EE-449B-9F78-F11F636BB7BE";
+	private static final String API_KEY = "E063BAEF-F87B-40A6-A309-3A6CC0F1174E";
 	private static final String API_URL = "https://appserver.icabanken.se";
 	private static final String API_VERSION = "1.0";
 

commit 6da0d959245f6804060e46ccbc56f29982271989 (tag: v1.9.6.7)
Author: liato <x@x00.us>
Date:   Fri Feb 21 01:57:48 2014 +0100

    Bump version. v1.9.6.7.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0531ad0..f7f07ae 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.6" android:versionCode="176">
+	android:versionName="1.9.6.7" android:versionCode="177">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index eff255a..c757fff 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,10 @@
+v1.9.6.7: (2014-02-21)
+* Fix login fields parsing for Nordnet
+* Fix for regular Jojo cards
+* Use FLAG_SECURE for ICS and newer to prevent thumbnail in recent tasks list
+* Updated SSL certificates for American Express and Swedbank
+
+
 v1.9.6.6: (2014-01-24)
 * Fix for Lunchkortet
 * Fix for Jojo
diff --git build.gradle build.gradle
index cf4ffc7..8879c9a 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 176
-        versionName '1.9.6.6'
+        versionCode 177
+        versionName '1.9.6.7'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit b9502be136cee222541b9f5a618e04a6faeb60ba
Author: liato <x@x00.us>
Date:   Fri Feb 21 01:38:31 2014 +0100

    Fix login fields parsing for Nordnet.

diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index 9bc326d..7dacb9c 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -26,6 +26,9 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
 
 import android.content.Context;
 import android.text.Html;
@@ -43,30 +46,29 @@ import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnet extends Bank {
-	private static final String TAG = "Nordnet";
-	private static final String NAME = "Nordnet";
-	private static final String NAME_SHORT = "nordnet";
-	private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
-	private static final int BANKTYPE_ID = IBankTypes.NORDNET;
-	
+    private static final String TAG = "Nordnet";
+    private static final String NAME = "Nordnet";
+    private static final String NAME_SHORT = "nordnet";
+    private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
+    private static final int BANKTYPE_ID = IBankTypes.NORDNET;
+
     
-	private Pattern reLoginFields = Pattern.compile("class=\"formular\">\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"[^>]*>\\s*</fieldset>\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*\\s*<input.*name=\"([^\"]+)");
     private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)([0-9 ]{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
-	private String response = null;
-	
-	public Nordnet(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public Nordnet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+    private String response = null;
+
+    public Nordnet(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Nordnet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
     
     @Override
@@ -75,13 +77,18 @@ public class Nordnet extends Bank {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnet));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
-        
-        Matcher matcher = reLoginFields.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login fields.");
+
+        Document d = Jsoup.parse(response);
+        Element e = d.getElementById("input1");
+        if (e == null || "".equals(e.attr("name"))) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" username field.");
         }
-        String loginFieldName = matcher.group(1);
-        String loginFieldPassword = matcher.group(2);
+        String loginFieldName = e.attr("name");
+        e = d.getElementById("pContHidden");
+        if (e == null || "".equals(e.attr("name"))) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" password field.");
+        }
+        String loginFieldPassword = e.attr("name");
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("checksum", ""));
@@ -94,34 +101,34 @@ public class Nordnet extends Bank {
     }
 
     @Override
-	public Urllib login() throws LoginException, BankException {
-		try {
+    public Urllib login() throws LoginException, BankException {
+        try {
             LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("fel vid inloggningen")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		try {
-			Matcher matcher;
-			matcher = reBalance.matcher(response);
-			while (matcher.find()) {
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("fel vid inloggningen")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            Matcher matcher;
+            matcher = reBalance.matcher(response);
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
@@ -131,25 +138,25 @@ public class Nordnet extends Bank {
                  * 4: Amount            31 337                | 123
                  *  
                  */
-			    Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
+                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
                         + Html.fromHtml(matcher.group(3)).toString().trim(),
                         Helpers.parseBalance(matcher.group(4)),
                         Html.fromHtml(matcher.group(3)).toString().trim().replaceAll(" ", ""));
 
-			    // Saving accounts contain white space characters in the account number
-			    if (!matcher.group(3).trim().contains(" ")) {
-			        account.setType(Account.FUNDS);
-			    }
-				accounts.add(account);
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}		
+                // Saving accounts contain white space characters in the account number
+                if (!matcher.group(3).trim().contains(" ")) {
+                    account.setType(Account.FUNDS);
+                }
+                accounts.add(account);
+                balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+            }
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
         finally {
             super.updateComplete();
         }
-	}
+    }
 }

commit c19e9093c6002eaba15d60efc37337e498546c8c
Author: liato <x@x00.us>
Date:   Fri Feb 21 01:15:04 2014 +0100

    Include the host in the server sertificate exception.

diff --git src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index 5598489..89fa2c9 100644
--- src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -19,8 +19,6 @@ package eu.nullbyte.android.urllib;
  * under the License.
  */
 
-import android.util.Log;
-
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.params.HttpConnectionParams;
@@ -43,8 +41,9 @@ import javax.net.ssl.TrustManager;
 
 public class CertPinningSSLSocketFactory extends SSLSocketFactory {
     private final static String TAG = CertPinningSSLSocketFactory.class.getSimpleName();
-	private SSLContext sslcontext = null;
+    private SSLContext sslcontext = null;
     private Certificate[] certificates;
+    private String lastHost;
 
     public CertPinningSSLSocketFactory(Certificate[] certificates) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
         super(null);
@@ -52,51 +51,53 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
         setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
     }
 
-	private SSLContext createSSLContext() throws IOException {
+    private SSLContext createSSLContext() throws IOException {
+        //Log.v(TAG, "createSSLContext()");
         try {
             SSLContext context = SSLContext.getInstance("TLS");
-            context.init(null, new TrustManager[] { new CertPinningTrustManager(certificates) }, null);
+            context.init(null, new TrustManager[] { new CertPinningTrustManager(certificates, lastHost) }, null);
             return context;
         } catch (Exception e) {
             throw new IOException(e.getMessage());
         }
-	}
+    }
 
-	private SSLContext getSSLContext() throws IOException {
-		if (this.sslcontext == null) {
-			this.sslcontext = createSSLContext();
-		}
-		return this.sslcontext;
-	}
+    private SSLContext getSSLContext() throws IOException {
+        //Log.v(TAG, "getSSLContext()");
+        if (this.sslcontext == null) {
+            this.sslcontext = createSSLContext();
+        }
+        return this.sslcontext;
+    }
 
-	/**
-	 * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
-	 *      String, int, java.net.InetAddress, int,
-	 *      org.apache.http.params.HttpParams)
-	 */
-	@Override
+    /**
+     * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
+     *      String, int, java.net.InetAddress, int,
+     *      org.apache.http.params.HttpParams)
+     */
+    @Override
     public Socket connectSocket(Socket sock, String host, int port,
-			InetAddress localAddress, int localPort, HttpParams params)
-			throws IOException, UnknownHostException, ConnectTimeoutException {
-        Log.v(TAG, "SSL socket connecting to: " + host);
-		int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
-		int soTimeout = HttpConnectionParams.getSoTimeout(params);
-
-		InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
-		SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
-
-		if ((localAddress != null) || (localPort > 0)) {
-			// we need to bind explicitly
-			if (localPort < 0) {
-				localPort = 0; // indicates "any"
-			}
-			InetSocketAddress isa = new InetSocketAddress(localAddress,
-					localPort);
-			sslsock.bind(isa);
-		}
+            InetAddress localAddress, int localPort, HttpParams params)
+            throws IOException, UnknownHostException, ConnectTimeoutException {
+        //Log.v(TAG, "connectSocket(socket: " + sock + ", host: " + host + ", port: " + port + ", localAddress: " + localAddress + ", localPort: " + localPort + ", params: " + params);
+        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
+        int soTimeout = HttpConnectionParams.getSoTimeout(params);
+
+        InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
+        SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
+
+        if ((localAddress != null) || (localPort > 0)) {
+            // we need to bind explicitly
+            if (localPort < 0) {
+                localPort = 0; // indicates "any"
+            }
+            InetSocketAddress isa = new InetSocketAddress(localAddress,
+                    localPort);
+            sslsock.bind(isa);
+        }
 
-		sslsock.connect(remoteAddress, connTimeout);
-		sslsock.setSoTimeout(soTimeout);
+        sslsock.connect(remoteAddress, connTimeout);
+        sslsock.setSoTimeout(soTimeout);
         try {
             getHostnameVerifier().verify(host, sslsock);
             // verifyHostName() didn't blowup - good!
@@ -108,24 +109,27 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
             throw iox;
         }
         return sslsock;
-	}
+    }
 
-	/**
-	 * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
-	 */
+    /**
+     * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
+     */
     @Override
-	public Socket createSocket() throws IOException {
-		return getSSLContext().getSocketFactory().createSocket();
-	}
+    public Socket createSocket() throws IOException {
+        //Log.v(TAG, "createSocket()");
+        return getSSLContext().getSocketFactory().createSocket();
+    }
 
 
-	/**
-	 * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
-	 *      String, int, boolean)
-	 */
+    /**
+     * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
+     *      String, int, boolean)
+     */
     @Override
     public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
-                    throws IOException, UnknownHostException {
-            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
-    }		
+            throws IOException, UnknownHostException {
+        //Log.v(TAG, "createSocket(socket: " + socket + ", host: " + host + ", port: " + port + ", autoClose: " + autoClose);
+        lastHost = host;
+        return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
+    }
 }
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
index 4ef336a..5128e8f 100644
--- src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
+++ src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -9,9 +9,11 @@ import javax.net.ssl.X509TrustManager;
 
 public class CertPinningTrustManager implements X509TrustManager {
     private Certificate[] certificates;
+    private String host;
 
-    public CertPinningTrustManager(Certificate[] certificates) {
+    public CertPinningTrustManager(Certificate[] certificates, String host) {
         this.certificates = certificates;
+        this.host = host;
     }
 
     public X509Certificate[] getAcceptedIssuers() {
@@ -35,6 +37,6 @@ public class CertPinningTrustManager implements X509TrustManager {
                 }
             }
         }
-        throw new CertificateException("Server certificate not trusted.");
+        throw new CertificateException(host == null ? "Server certificate not trusted." : String.format("Server certificate not trusted for host: %s.", host));
 	}
 }

commit 69fbefc7813b3e487fa10ac584eb4c5598946f43
Author: liato <x@x00.us>
Date:   Fri Feb 21 01:13:38 2014 +0100

    New SSL certificate for American Express.

diff --git res/raw/cert_americanexpress4.pem res/raw/cert_americanexpress4.pem
new file mode 100644
index 0000000..74d1921
--- /dev/null
+++ res/raw/cert_americanexpress4.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----

+RErQgv+9W9k+KaFKzX5TpTM=
+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 374df74..568579f 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -77,7 +77,7 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress3));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress3, R.raw.cert_americanexpress4));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");

commit f2d577fdf3fadd46564eeffd39b7f5790818e090
Author: liato <x@x00.us>
Date:   Fri Feb 21 00:38:09 2014 +0100

    Update Swedbank certificate.

diff --git res/raw/cert_swedbank.pem res/raw/cert_swedbank.pem
index 5ec7c8d..321b0d0 100644
--- res/raw/cert_swedbank.pem
+++ res/raw/cert_swedbank.pem
@@ -1,31 +1,31 @@
 -----BEGIN CERTIFICATE-----
-MIIFSTCCBDGgAwIBAgIQAeiwUTxfBbuWSmREo7+8OzANBgkqhkiG9w0BAQUFADCB
+MIIFSTCCBDGgAwIBAgIQMDmESSXZfdIWMfXp3SGzTjANBgkqhkiG9w0BAQUFADCB
 vDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMt
 VmVyaVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMB4X
-DTEzMDIxMzAwMDAwMFoXDTE0MDMwMzIzNTk1OVoweDELMAkGA1UEBhMCU0UxEjAQ
+DTE0MDIxMzAwMDAwMFoXDTE1MDMwNDIzNTk1OVoweDELMAkGA1UEBhMCU0UxEjAQ
 BgNVBAgTCVN0b2NraG9sbTESMBAGA1UEBxQJU3RvY2tob2xtMRQwEgYDVQQKFAtT
 V0VEQkFOSyBBQjELMAkGA1UECxQCSVQxHjAcBgNVBAMUFW1vYmlsYmFuay5zd2Vk

 ZXJpc2lnbi5jb20wPAYIKwYBBQUHMAKGMGh0dHA6Ly9TVlJJbnRsLUczLWFpYS52
-ZXJpc2lnbi5jb20vU1ZSSW50bEczLmNlcjANBgkqhkiG9w0BAQUFAAOCAQEALWOL
-Uax+C7QtHf7wl1M3CvHpyxJIlZFe0o6zv+cZI0GvkZQ7Lcf6OGCB7wD2O4YL7DEE
-wWfTj0rJP8U6p2UI0QPec/4hC3V6Jlv56A1VtSVRax4SISwr/iYiJHywDQZG6MNQ
-tWZnF4spqDWi4nQ7yFqJ0piIeFdo3JLDS05OeGMLtWJlULy5q76qDX/twy+ssU+/
-tor1HeKSEB6h8R6CnH4UesnHnbxnoEj8J7EWJwjbjOGQivt5kaDuEjla43C4FpUm
-6762y1GFRrEnCc/G2nBOoDl55mmQBpGk4yA6o+O/D61BA5oxy27DCH/6ljPSolne
-o/wBKYKk1cLnWLP7mg==
+ZXJpc2lnbi5jb20vU1ZSSW50bEczLmNlcjANBgkqhkiG9w0BAQUFAAOCAQEAgRUy
+n4szWXjgqATAN06eLZszNEkmDrZD5Y0VOu8mQlcZCU9vtxVCWcwqFDXOIFXas7Ny
+bZI9RLaBku/yCwg0aJ+UEyyI3f7EuQmTf9xxPPXl0koiBzz6QkjqzUjO0vc2lNf0
+UbRlD69H6ckBl8UosAC3jV5jD8sVhBlmT75MMkAxpOnKSxNVoghUZZHZGXG24aIi
+J5GBFHj2XM1trwUmIE/dSnhAz7gt0zNKvk9IBp82Fwdr64NOBXeFUwLXGRaxcvzA
+Co0n7zW6bCb8N7nS6Y8+a0M9qw+WZk4Oe0LXBsCc5sJP6C38UYLa/lw1kZIKELpI
+F26ZS8MiRZ8WWW1yGg==
 -----END CERTIFICATE-----

commit 56b2dc00169786f7e6b32565080ae078becd7880
Author: liato <x@x00.us>
Date:   Wed Feb 5 23:51:29 2014 +0100

    Fix for regular Jojo cards.

diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index ba8001f..e77556d 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -34,6 +34,7 @@ import org.apache.http.message.BasicNameValuePair;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -104,17 +105,23 @@ public class Jojo extends Bank {
         }
         urlopen = login();
         Document d = Jsoup.parse(response);
-        Element e = d.select(".saldo_ok_wrapper > table > tbody tr:eq(0) > td:eq(1)").first();
-        if (e != null) {
-            accounts.add(new Account("Tillgängligt nu", Helpers.parseBalance(e.text()), "1"));
-            balance = balance.add(Helpers.parseBalance(e.text()));
-        }
-        e = d.select(".saldo_ok_wrapper > table > tbody tr:eq(1) > td:eq(1)").first();
-        if (e != null) {
-            accounts.add(new Account("Att hämta", Helpers.parseBalance(e.text()), "1"));
-            balance = balance.add(Helpers.parseBalance(e.text()));
-        }
 
+        Elements es = d.select(".saldo_ok_wrapper > table > tbody tr");
+        if (es != null) {
+            for (int i = 0; i < 2; i++) {
+                int index = es.size()-4+i;
+                if (index >= 0) {
+                    Element e = es.get(index);
+                    Element name = e.select(".first").first();
+                    Element amount = e.select(".right").first();
+                    if (name != null && amount != null) {
+                        Account a = new Account(name.text().replaceAll(":", "").trim(), Helpers.parseBalance(amount.text()), Integer.toString(i));
+                        accounts.add(a);
+                        balance = balance.add(a.getBalance());
+                    }
+                }
+            }
+        }
 
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit de9af33f71a6bf1b3624cf01ee6e874783a27f7f
Author: liato <x@x00.us>
Date:   Wed Feb 5 23:13:05 2014 +0100

    Use FLAG_SECURE for ICS and newer.

diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 17f4654..b42f633 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -28,6 +28,7 @@ import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
 import android.graphics.RectF;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
@@ -35,6 +36,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
+import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
@@ -69,6 +71,9 @@ public class LockableActivity extends Activity {
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+        }
     }
 	
 	@Override

commit 09df08015ed145d58777ac825c1d99c405ecaff1
Author: liato <x@x00.us>
Date:   Wed Feb 5 23:08:47 2014 +0100

    Get all transactions for bioklubben.

diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
index c1c55be..bb1e91a 100644
--- src/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -138,7 +138,7 @@ public class Bioklubben extends Bank {
             accounts.add(a);
             balance = balance.add(a.getBalance());
 
-            Elements es = d.select(".GridViewStd_Item");
+            Elements es = d.select(".GridViewStd_Item,.GridViewStd_ItemAlt");
             List<Transaction> transactions = new ArrayList<Transaction>();
             if (es != null) {
                 for (Element el : es) {

commit 9670aceb43c46302cde7c5471a1d5fc21a12798d (tag: v1.9.6.6)
Author: liato <x@x00.us>
Date:   Fri Jan 24 02:58:04 2014 +0100

    Bump version. v1.9.6.6.

diff --git AndroidManifest.xml AndroidManifest.xml
index c62ca11..0531ad0 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.5" android:versionCode="174">
+	android:versionName="1.9.6.6" android:versionCode="176">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index 23c5dca..eff255a 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,9 @@
+v1.9.6.6: (2014-01-24)
+* Fix for Lunchkortet
+* Fix for Jojo
+* Updated SSL certificates for Ticket Rikskortet, Paypal, Avanza, Avanza Mini and Payson
+
+
 v1.9.6.5: (2013-12-19)
 * Correct currency for SAS Eurobonus Mastercard Norway and Denmark
 * Fix for ICA Banken (new api-key)
diff --git build.gradle build.gradle
index 90e7197..cf4ffc7 100644
--- build.gradle
+++ build.gradle
@@ -35,8 +35,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 174
-        versionName '1.9.6.5'
+        versionCode 176
+        versionName '1.9.6.6'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 24e0d9a7ddec6ee238f64dfe5572483bfef5bdc0
Author: liato <x@x00.us>
Date:   Fri Jan 24 02:43:14 2014 +0100

    Update ssl certs for avanza, paypal, payson and ticket rikskortet.

diff --git res/raw/cert_avanza_mini.pem res/raw/cert_avanza_mini.pem
new file mode 100644
index 0000000..ff45953
--- /dev/null
+++ res/raw/cert_avanza_mini.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+ckqfiJM8yNuuHA==
+-----END CERTIFICATE-----
diff --git res/raw/cert_paypal.pem res/raw/cert_paypal.pem
index b23f422..8729515 100644
--- res/raw/cert_paypal.pem
+++ res/raw/cert_paypal.pem
@@ -1,35 +1,34 @@
 -----BEGIN CERTIFICATE-----
-MIIGFTCCBP2gAwIBAgIQNlFL9KRy51iD/qafxhevQDANBgkqhkiG9w0BAQUFADCB
+MIIF+TCCBOGgAwIBAgIQJ5YBtzGVFcWhgQF5HesilzANBgkqhkiG9w0BAQUFADCB
 ujELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE0MDIGA1UEAxMr
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQTAeFw0x
-MzA2MjAwMDAwMDBaFw0xNTA0MDIyMzU5NTlaMIIBCTETMBEGCysGAQQBgjc8AgED
+MzAxMTAwMDAwMDBaFw0xNTA0MDIyMzU5NTlaMIIBDzETMBEGCysGAQQBgjc8AgED
 EwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0
 ZSBPcmdhbml6YXRpb24xEDAOBgNVBAUTBzMwMTQyNjcxCzAJBgNVBAYTAlVTMRMw
 EQYDVQQRFAo5NTEzMS0yMDIxMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQH
 FAhTYW4gSm9zZTEWMBQGA1UECRQNMjIxMSBOIDFzdCBTdDEVMBMGA1UEChQMUGF5

-O7ugV9tPvj01jhp3LXSQH9KDSo0QXD0a6g==

 -----END CERTIFICATE-----
diff --git res/raw/cert_payson.pem res/raw/cert_payson.pem
index 3c33a54..2accfb6 100644
--- res/raw/cert_payson.pem
+++ res/raw/cert_payson.pem
@@ -1,32 +1,33 @@
 -----BEGIN CERTIFICATE-----
-MIIFezCCBGOgAwIBAgIQb1oeIrK0rtSJFIthYC8KxDANBgkqhkiG9w0BAQUFADCB
+MIIFsDCCBJigAwIBAgIQSVsMq9Q8O26a4JGuv+2mODANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew

-MQyrnOskB283xLgbTob9

+1bmZ1AQg4SGDu8X5MQa+BwRg5/Y=
 -----END CERTIFICATE-----
diff --git res/raw/cert_ticketrikskortet.pem res/raw/cert_ticketrikskortet.pem
index 42d26d1..0d40b84 100644
--- res/raw/cert_ticketrikskortet.pem
+++ res/raw/cert_ticketrikskortet.pem
@@ -1,30 +1,30 @@
 -----BEGIN CERTIFICATE-----
-MIIFJTCCBA2gAwIBAgISESGytd44G6lMoaM6b1kAe21DMA0GCSqGSIb3DQEBBQUA
+MIIFIjCCBAqgAwIBAgISESF95N9H2DLTEX3RJGtJj9l8MA0GCSqGSIb3DQEBBQUA
 MF0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTMwMQYD
 VQQDEypHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBWYWxpZGF0aW9uIENBIC0gRzIw
-HhcNMTIxMDEwMDc0MDAyWhcNMTQwMTI2MTMwMDAwWjBnMQswCQYDVQQGEwJGUjEX
+HhcNMTQwMTE3MTEwMTAyWhcNMTUwMjI2MTMwMDAwWjBnMQswCQYDVQQGEwJGUjEX
 MBUGA1UECBMOSGF1dHMtZGUtU2VpbmUxETAPBgNVBAcTCE1hbGFrb2ZmMRMwEQYD
 VQQKEwpFREVOUkVEIFNBMRcwFQYDVQQDEw53d3cuZWRlbnJlZC5zZTCCASIwDQYJ

-k6xRfB3oW/H25YzF/b8MBZXr4TcAfLW1Hw==

+1psJlnRKDzQWFAj6CZ0oyGA1qHsxHA==
 -----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index c5543be..cf1d245 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -70,7 +70,7 @@ public class AvanzaMini extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza_mini));
         urlopen.setAllowCircularRedirects(true);
         String response = urlopen.open("https://www.avanza.se/mini/logga_in/");
         Document d = Jsoup.parse(response);
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 3a557d9..17ec257 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -84,69 +84,11 @@ public class Rikslunchen extends Bank {
     public Rikslunchen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
-    }
-
-    @Override
-    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
-        urlopen.setAllowCircularRedirects(true);
-
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
-        postData.add(new BasicNameValuePair("c0-param0", "string:" + username));
-        postData.add(new BasicNameValuePair("callCount", "1"));
-        postData.add(new BasicNameValuePair("windowName", ""));
-        postData.add(new BasicNameValuePair("c0-scriptName", "cardUtil"));
-        postData.add(new BasicNameValuePair("c0-methodName", "getCardData"));
-        postData.add(new BasicNameValuePair("c0-id", "0"));
-        postData.add(new BasicNameValuePair("batchId", "1"));
-        postData.add(new BasicNameValuePair("page", "%2Friks-cp%2Fcheck_balance.html"));
-        postData.add(new BasicNameValuePair("scriptSessionId", ""));
-
-        HttpClient httpclient = new DefaultHttpClient();
-        CookieStore cookieStore = new BasicCookieStore();
-        HttpContext httpContext = new BasicHttpContext();
-        httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
-
-        // Connect to check_balance to get a session cookie
-        HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/check_balance.html");
-        HttpResponse response = httpclient.execute(httppost, httpContext);
-
-        List<Cookie> cookies = cookieStore.getCookies();
-        if (cookies.size() == 0) {
-            throw new BankException("No session cookie found, login will fail.");
-        }
-
-        Cookie c = cookies.get(0);
-        postData.add(new BasicNameValuePair("c0-param1", "string:" + c.getValue()));
-        postData.add(new BasicNameValuePair("httpSessionId", c.getValue()));
-
-        response.getEntity().consumeContent();
-
-        httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
-        httppost.setEntity(new UrlEncodedFormEntity(postData));
-
-        response = httpclient.execute(httppost, httpContext);
-        InputStream streamResponse = response.getEntity().getContent();
-        StringWriter writer = new StringWriter();
-        IOUtils.copy(streamResponse, writer);
 
-        return new LoginPackage(urlopen, postData, writer.toString(), "http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
     }
 
     @Override
     public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-
-            if (lp.getResponse().contains("Ange giltigt kortnummer.")) {
-                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-            }
-
-            myResponse = lp.getResponse();
-
-        } catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
         return urlopen;
     }
 

commit 93b397797ce9f289cb675b3fed11e60cc2f53f73
Author: liato <x@x00.us>
Date:   Mon Jan 13 00:19:43 2014 +0100

    Use cert pinning with Rikslunchen.

diff --git build.gradle build.gradle
index a6ad2c7..90e7197 100644
--- build.gradle
+++ build.gradle
@@ -18,7 +18,7 @@ dependencies {
     compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
     compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
     compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
-    compile 'org.jsoup:jsoup:1.7.2'
+    compile 'org.jsoup:jsoup:1.7.3'
     compile('org.simpleframework:simple-xml:2.7.+') {
         exclude module: 'stax'
         exclude module: 'stax-api'
diff --git res/values/strings.xml res/values/strings.xml
index cd1af41..1f9591d 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -296,7 +296,8 @@
 	<string name="card_id">Card ID</string>
 	<string name="card_number">Card number</string>
 	<string name="bitcoin_address">Bitcoin address</string>
-		
+    <string name="cvc">CVC</string>
+
 	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 100bd5a..5c24bcb 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -375,7 +375,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return new SessionPackage(html, null);
     }
 
-    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+    protected LoginPackage preLogin() throws BankException, IOException {
         return null;
     }
 
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 49af2bb..3a557d9 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -144,7 +144,7 @@ public class Rikslunchen extends Bank {
 
             myResponse = lp.getResponse();
 
-        } catch (ClientProtocolException e) {
+        } catch (IOException e) {
             throw new BankException(e.getMessage());
         }
         return urlopen;
@@ -157,7 +157,7 @@ public class Rikslunchen extends Bank {
             throw new LoginException(res.getText(R.string.invalid_card_number).toString());
         }
         try {
-            urlopen = new Urllib(context);
+            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
             urlopen.addHeader("Authorization", "basic Q0g6ODlAUHFqJGw4NyMjTVM=");
             urlopen.addHeader("SOAPAction", "");
             urlopen.addHeader("Content-Type", "text/xml;charset=UTF-8");

commit b3b6a258a02409da37a099b8d09775b11539925c
Author: liato <x@x00.us>
Date:   Mon Jan 13 00:18:43 2014 +0100

    Jojo cert.

diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index 6014d7f..ba8001f 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -16,18 +16,8 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
 import android.content.Context;
-import android.text.Html;
+import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -38,6 +28,18 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -48,9 +50,6 @@ public class Jojo extends Bank {
     private static final String URL = "https://www.skanetrafiken.se/templates/MSRootPage.aspx?id=2935&epslanguage=SV";
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
 
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reAccounts = Pattern.compile("\"></a>\\s*</td>\\s*<td\\s*class=\"cardinfoaligntop\">\\s*<a\\s*id=\"ctl\\d*_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl(\\d{2,3})_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>\\s*</td>\\s*<td[^>]+>\\s*<a\\s*id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl\\d{2,3}_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>", Pattern.CASE_INSENSITIVE);
-    private Pattern reBalance = Pattern.compile("labelsaldoinfo\">([^<]+)<", Pattern.CASE_INSENSITIVE);
     private String response = null;
 
     public Jojo(Context context) {
@@ -60,6 +59,9 @@ public class Jojo extends Bank {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+        super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
+        super.INPUT_TITLETEXT_PASSWORD = R.string.cvc;
     }
 
     public Jojo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -70,37 +72,25 @@ public class Jojo extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException,
-    ClientProtocolException, IOException {
+            IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_jojo));
-        response = urlopen.open("http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-        }
-        String strViewState = matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ctl00$ctl00$UsernameTextBox", username));
-        postData.add(new BasicNameValuePair("ctl00$ctl00$PasswordTextBox", password));
-        postData.add(new BasicNameValuePair("ctl00$ctl00$LoginButton", "Logga in"));
-
-        return new LoginPackage(urlopen, postData, response, "https://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("cardno", username));
+        postData.add(new BasicNameValuePair("backno", password));
+        postData.add(new BasicNameValuePair("ST_CHECK_SALDO", "Se saldo"));
+        return new LoginPackage(urlopen, postData, response, "https://www.shop.skanetrafiken.se/kollasaldo.html");
     }
 
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Inloggningen misslyckades")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            if (response.contains("Kortnumret finns inte.")) {
+                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
             }
-        }
-        catch (ClientProtocolException e) {
+        } catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
+        } catch (IOException e) {
             throw new BankException(e.getMessage());
         }
         return urlopen;
@@ -113,62 +103,22 @@ public class Jojo extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        try {
-            response = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV");
-            Matcher matcher;
-            Matcher matcher_b;
-            matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }			
-            String strViewState = matcher.group(1);
-
-            matcher = reAccounts.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: ID                01
-                 * 2: Name              Nytt
-                 * 3: Card number       1111111111
-                 * 
-                 */
-
-                List <NameValuePair> postData = new ArrayList <NameValuePair>();
-                postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-                postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-                postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-                postData.add(new BasicNameValuePair("ctl00$fullRegion$mainRegion$CardInformation1$mRepeaterMyCards$ctl" + matcher.group(1) + "$Button", "Kortinfo"));
-                String accinfo = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV", postData);
-
-                matcher_b = reBalance.matcher(accinfo);
-                if (matcher_b.find()) {
-                    /*
-                     * Capture groups:
-                     * GROUP                EXAMPLE DATA
-                     * 1: Amount            592,80 kr
-                     * 
-                     */
-
-                    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() , Helpers.parseBalance(matcher_b.group(1)), matcher.group(1)));
-                    balance = balance.add(Helpers.parseBalance(matcher_b.group(1)));
-                }
-            }
-
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
+        Document d = Jsoup.parse(response);
+        Element e = d.select(".saldo_ok_wrapper > table > tbody tr:eq(0) > td:eq(1)").first();
+        if (e != null) {
+            accounts.add(new Account("Tillgängligt nu", Helpers.parseBalance(e.text()), "1"));
+            balance = balance.add(Helpers.parseBalance(e.text()));
         }
-        catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+        e = d.select(".saldo_ok_wrapper > table > tbody tr:eq(1) > td:eq(1)").first();
+        if (e != null) {
+            accounts.add(new Account("Att hämta", Helpers.parseBalance(e.text()), "1"));
+            balance = balance.add(Helpers.parseBalance(e.text()));
         }
-        catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }		
-        finally {
-            super.updateComplete();
+
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        super.updateComplete();
     }
 }

commit e890fc42ca7240d87dd86c30a77b6fa6f4eda9df
Author: liato <x@x00.us>
Date:   Mon Jan 13 00:18:04 2014 +0100

    Jojo cert.

diff --git res/raw/cert_jojo.pem res/raw/cert_jojo.pem
index 4651046..b000c8d 100644
--- res/raw/cert_jojo.pem
+++ res/raw/cert_jojo.pem
@@ -1,34 +1,34 @@
 -----BEGIN CERTIFICATE-----
-MIIF+TCCBOGgAwIBAgIQDiusz2ZP0CUM0em8bVXCszANBgkqhkiG9w0BAQUFADCB
+MIIF9zCCBN+gAwIBAgIQOtcZrJagCxtjZKtEHlaGzjANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTIwNTIzMDAwMDAwWhcNMTQwNTI0MjM1OTU5WjCB+TETMBEGCysGAQQBgjc8
+HhcNMTMxMTIyMDAwMDAwWhcNMTQxMTIzMjM1OTU5WjCB/jETMBEGCysGAQQBgjc8
 AgEDEwJTRTEaMBgGA1UEDxMRR292ZXJubWVudCBFbnRpdHkxEzARBgNVBAUTCjIz
 MjEwMDAyNTUxCzAJBgNVBAYTAlNFMQ8wDQYDVQQRFAYyODEgODMxDjAMBgNVBAgT
 BVNLQU5FMRMwEQYDVQQHFApIYXNzbGVob2xtMRgwFgYDVQQJFA9BbmRyYSBBdmVu
 eWVuIDcxHTAbBgNVBAoUFFNrYW5lIExhbnMgTGFuZHN0aW5nMRYwFAYDVQQLFA1T

 -----END CERTIFICATE-----

commit 867b0d0d8bb34c4d82b499b31eb1e0d9f680d28f
Author: liato <x@x00.us>
Date:   Sun Jan 12 23:35:21 2014 +0100

    Whitespace fixes for Rikslunchen.

diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index b9ae041..49af2bb 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2014 Nullbyte <http://nullbyte.eu>
  * Contributors: PMC
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -61,103 +61,101 @@ import eu.nullbyte.android.urllib.Urllib;
 
 public class Rikslunchen extends Bank {
 
-	private static final String TAG = "Rikslunchen";
-	private static final String NAME = "Rikslunchen";
-	private static final String NAME_SHORT = "rikslunchen";
-	private static final String URL = "http://www.rikslunchen.se/index.html";
-	private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
-
-	private String myResponse = "";
-
-	public Rikslunchen(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-		super.INPUT_TITLETEXT_USERNAME = R.string.card_id;
+    private static final String TAG = "Rikslunchen";
+    private static final String NAME = "Rikslunchen";
+    private static final String NAME_SHORT = "rikslunchen";
+    private static final String URL = "http://www.rikslunchen.se/index.html";
+    private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
+
+    private String myResponse = "";
+
+    public Rikslunchen(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+        super.INPUT_TITLETEXT_USERNAME = R.string.card_id;
         super.INPUT_HIDDEN_PASSWORD = true;
-	}
+    }
 
-	public Rikslunchen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+    public Rikslunchen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
-	@Override
-	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+    @Override
+    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
         urlopen.setAllowCircularRedirects(true);
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("c0-param0", "string:" + username));
-		postData.add(new BasicNameValuePair("callCount", "1"));
-		postData.add(new BasicNameValuePair("windowName", ""));
-		postData.add(new BasicNameValuePair("c0-scriptName", "cardUtil"));
-		postData.add(new BasicNameValuePair("c0-methodName", "getCardData"));
-		postData.add(new BasicNameValuePair("c0-id", "0"));
-		postData.add(new BasicNameValuePair("batchId", "1"));
-		postData.add(new BasicNameValuePair("page", "%2Friks-cp%2Fcheck_balance.html"));
-		postData.add(new BasicNameValuePair("scriptSessionId", ""));
-
-		HttpClient httpclient = new DefaultHttpClient();
-		CookieStore cookieStore = new BasicCookieStore();
-		HttpContext httpContext = new BasicHttpContext();
-		httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
-
-		// Connect to check_balance to get a session cookie
-		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/check_balance.html");
-		HttpResponse response = httpclient.execute(httppost, httpContext);
-
-		List<Cookie> cookies = cookieStore.getCookies();
-		if (cookies.size() == 0) {
-			throw new BankException("No session cookie found, login will fail.");
-		}
-
-		Cookie c = cookies.get(0);
-		postData.add(new BasicNameValuePair("c0-param1", "string:" + c.getValue()));
-		postData.add(new BasicNameValuePair("httpSessionId", c.getValue()));
-
-		response.getEntity().consumeContent();
-
-		httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
-		httppost.setEntity(new UrlEncodedFormEntity(postData));
-
-		response = httpclient.execute(httppost, httpContext);
-		InputStream streamResponse = response.getEntity().getContent();
-		StringWriter writer = new StringWriter();
-		IOUtils.copy(streamResponse, writer);
-
-		return new LoginPackage(urlopen, postData, writer.toString(), "http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
-	}
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-
-			if (lp.getResponse().contains("Ange giltigt kortnummer.")) {
-				throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-			}
-
-			myResponse = lp.getResponse();
-
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (TextUtils.isEmpty(username)) {
-			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
-		}
+        postData.add(new BasicNameValuePair("c0-param0", "string:" + username));
+        postData.add(new BasicNameValuePair("callCount", "1"));
+        postData.add(new BasicNameValuePair("windowName", ""));
+        postData.add(new BasicNameValuePair("c0-scriptName", "cardUtil"));
+        postData.add(new BasicNameValuePair("c0-methodName", "getCardData"));
+        postData.add(new BasicNameValuePair("c0-id", "0"));
+        postData.add(new BasicNameValuePair("batchId", "1"));
+        postData.add(new BasicNameValuePair("page", "%2Friks-cp%2Fcheck_balance.html"));
+        postData.add(new BasicNameValuePair("scriptSessionId", ""));
+
+        HttpClient httpclient = new DefaultHttpClient();
+        CookieStore cookieStore = new BasicCookieStore();
+        HttpContext httpContext = new BasicHttpContext();
+        httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
+
+        // Connect to check_balance to get a session cookie
+        HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/check_balance.html");
+        HttpResponse response = httpclient.execute(httppost, httpContext);
+
+        List<Cookie> cookies = cookieStore.getCookies();
+        if (cookies.size() == 0) {
+            throw new BankException("No session cookie found, login will fail.");
+        }
+
+        Cookie c = cookies.get(0);
+        postData.add(new BasicNameValuePair("c0-param1", "string:" + c.getValue()));
+        postData.add(new BasicNameValuePair("httpSessionId", c.getValue()));
+
+        response.getEntity().consumeContent();
+
+        httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
+        httppost.setEntity(new UrlEncodedFormEntity(postData));
+
+        response = httpclient.execute(httppost, httpContext);
+        InputStream streamResponse = response.getEntity().getContent();
+        StringWriter writer = new StringWriter();
+        IOUtils.copy(streamResponse, writer);
+
+        return new LoginPackage(urlopen, postData, writer.toString(), "http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+
+            if (lp.getResponse().contains("Ange giltigt kortnummer.")) {
+                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+            }
+
+            myResponse = lp.getResponse();
+
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (TextUtils.isEmpty(username)) {
+            throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+        }
         try {
             urlopen = new Urllib(context);
             urlopen.addHeader("Authorization", "basic Q0g6ODlAUHFqJGw4NyMjTVM=");
@@ -194,7 +192,7 @@ public class Rikslunchen extends Bank {
             throw new BankException(res.getText(R.string.no_accounts_found)
                     .toString());
         }
-		super.updateComplete();
-	}
+        super.updateComplete();
+    }
 
 }
\ No newline at end of file

commit 48c01d8691cc293c77ddd8bb22de63ff66091079
Author: liato <x@x00.us>
Date:   Sun Jan 12 23:33:19 2014 +0100

    Fix for Rikslunchen.

diff --git CHANGES.txt CHANGES.txt
index 87955b3..23c5dca 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,8 @@
+v1.9.6.5: (2013-12-19)
+* Correct currency for SAS Eurobonus Mastercard Norway and Denmark
+* Fix for ICA Banken (new api-key)
+
+
 v1.9.6.4: (2013-12-13)
 * Fix for SAS Eurobonus Mastercard Norway﻿
 * Fix for SEB Cards (Eurocard, SAS Eurobonus, Statoil, SJ Prio...) with multiple accounts﻿
diff --git build.gradle build.gradle
index 24981c6..a6ad2c7 100644
--- build.gradle
+++ build.gradle
@@ -3,7 +3,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.6.+'
+        classpath 'com.android.tools.build:gradle:0.7.+'
     }
 }
 apply plugin: 'android'
@@ -13,12 +13,17 @@ repositories {
 }
 
 dependencies {
-	compile 'commons-io:commons-io:2.1'
-	compile 'com.google.collections:google-collections:1.0'
-	compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
-	compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
-	compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0' 
-	compile 'org.jsoup:jsoup:1.7.2'
+    compile 'org.apache.commons:commons-io:1.3.2'
+    compile 'com.google.collections:google-collections:1.0'
+    compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
+    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
+    compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0'
+    compile 'org.jsoup:jsoup:1.7.2'
+    compile('org.simpleframework:simple-xml:2.7.+') {
+        exclude module: 'stax'
+        exclude module: 'stax-api'
+        exclude module: 'xpp3'
+    }
 }
 
 tasks.withType(Compile) {
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 861eddc..f3c40e0 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Sun Jan 12 21:49:53 CET 2014
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-all.zip
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index f836d0a..b9ae041 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -16,12 +16,18 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
+import android.content.Context;
+import android.text.InputType;
+import android.text.TextUtils;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.rikslunchen.model.Envelope;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpResponse;
@@ -33,23 +39,22 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.protocol.ClientContext;
 import org.apache.http.cookie.Cookie;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HttpContext;
+import org.simpleframework.xml.Serializer;
+import org.simpleframework.xml.core.Persister;
 
-import android.content.Context;
-import android.text.InputType;
-import android.util.Log;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -61,9 +66,6 @@ public class Rikslunchen extends Bank {
 	private static final String NAME_SHORT = "rikslunchen";
 	private static final String URL = "http://www.rikslunchen.se/index.html";
 	private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
-	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    protected boolean INPUT_HIDDEN_USERNAME = true;
-    protected int INPUT_TITLETEXT_PASSWORD = R.string.card_id;	
 
 	private String myResponse = "";
 
@@ -74,10 +76,9 @@ public class Rikslunchen extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_HINT_USERNAME = "Rikslunchen";
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HIDDEN_USERNAME = INPUT_HIDDEN_USERNAME;
-		super.INPUT_TITLETEXT_PASSWORD = INPUT_TITLETEXT_PASSWORD;
+		super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+		super.INPUT_TITLETEXT_USERNAME = R.string.card_id;
+        super.INPUT_HIDDEN_PASSWORD = true;
 	}
 
 	public Rikslunchen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -91,7 +92,7 @@ public class Rikslunchen extends Bank {
         urlopen.setAllowCircularRedirects(true);
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
-		postData.add(new BasicNameValuePair("c0-param0", "string:" + password));
+		postData.add(new BasicNameValuePair("c0-param0", "string:" + username));
 		postData.add(new BasicNameValuePair("callCount", "1"));
 		postData.add(new BasicNameValuePair("windowName", ""));
 		postData.add(new BasicNameValuePair("c0-scriptName", "cardUtil"));
@@ -138,7 +139,7 @@ public class Rikslunchen extends Bank {
 			LoginPackage lp = preLogin();
 
 			if (lp.getResponse().contains("Ange giltigt kortnummer.")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+				throw new LoginException(res.getText(R.string.invalid_card_number).toString());
 			}
 
 			myResponse = lp.getResponse();
@@ -154,22 +155,46 @@ public class Rikslunchen extends Bank {
 	@Override
 	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
-		if (password == null || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		urlopen = login();
-		try {
-
-			int begin = myResponse.indexOf("balance");
-			int end = myResponse.indexOf("cardNo");
-			BigDecimal balance = Helpers.parseBalance(myResponse.substring(begin + 9, end - 2));
-
-			accounts.add(new Account("Rikslunchen", balance, "1"));
-		} catch (StringIndexOutOfBoundsException e) {
-			Log.e(TAG, "StringIndexOutOfBoundsException", e);
-		} finally {
-			super.updateComplete();
+		if (TextUtils.isEmpty(username)) {
+			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
 		}
+        try {
+            urlopen = new Urllib(context);
+            urlopen.addHeader("Authorization", "basic Q0g6ODlAUHFqJGw4NyMjTVM=");
+            urlopen.addHeader("SOAPAction", "");
+            urlopen.addHeader("Content-Type", "text/xml;charset=UTF-8");
+            StringEntity body = new StringEntity(String.format("<v:Envelope xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:v=\"http://schemas.xmlsoap.org/soap/envelope/\"><v:Header /><v:Body><n0:getBalance id=\"o0\" c:root=\"1\" xmlns:n0=\"urn:PhoneService\"><cardNo i:type=\"d:string\">%s</cardNo></n0:getBalance></v:Body></v:Envelope>", username), "UTF-8");
+            InputStream is = urlopen.openStream("https://www.rikslunchen.se/rkchws/PhoneService", body, true);
+
+            Serializer serializer = new Persister();
+            Envelope resp = null;
+            try {
+                resp = serializer.read(Envelope.class, is, false);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            if (resp != null && resp.body != null && resp.body.fault != null && !TextUtils.isEmpty(resp.body.fault.faultstring)) {
+                throw new BankException(context.getString(R.string.invalid_card_number));
+                //faultString isn't always very descriptive
+                //throw new BankException(resp.body.fault.faultstring);
+            } else if (resp == null || resp.body == null || resp.body.getBalanceResponse == null || resp.body.getBalanceResponse.responseReturn == null || resp.body.getBalanceResponse.responseReturn.amount == null) {
+                throw new BankException(context.getString(R.string.invalid_card_number));
+            }
+            BigDecimal balance = Helpers.parseBalance(resp.body.getBalanceResponse.responseReturn.amount);
+            accounts.add(new Account("Rikslunchen", balance, "1"));
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found)
+                    .toString());
+        }
+		super.updateComplete();
 	}
+
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java src/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
new file mode 100644
index 0000000..205bb92
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/rikslunchen/model/Envelope.java
@@ -0,0 +1,56 @@
+package com.liato.bankdroid.banking.banks.rikslunchen.model;
+
+import org.simpleframework.xml.Element;
+import org.simpleframework.xml.Root;
+
+/*
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+	<soap:Body>
+		<ns2:getBalanceResponse xmlns:ns2="urn:PhoneService">
+			<return>
+				<amount>1101.14</amount>
+				<lastTopUpDate>2014-01-01</lastTopUpDate>
+			</return>
+		</ns2:getBalanceResponse>
+		<soap:Fault>
+			<faultcode>soap:Server</faultcode>
+			<faultstring>card for 48565643 cannot be found!</faultstring>
+		</soap:Fault>
+	</soap:Body>
+</soap:Envelope>
+ */
+
+@Root
+public class Envelope {
+    public static class Body {
+        public static class GetBalanceResponse {
+            public static class Return {
+                @Element
+                public String amount;
+
+                @Element
+                public String lastTopUpDate;
+            }
+
+            @Element(name="return")
+            public Return responseReturn;
+        }
+
+        public static class Fault {
+            @Element
+            public String faultcode;
+
+            @Element
+            public String faultstring;
+        }
+
+        @Element(required=false)
+        public GetBalanceResponse getBalanceResponse;
+
+        @Element(name="Fault", required=false)
+        public Fault fault;
+    }
+
+    @Element(name="Body")
+    public Body body;
+}
\ No newline at end of file

commit b76c70f39f57edf45447c1aa77ba547779b08ad0 (tag: v1.9.6.5)
Author: liato <x@x00.us>
Date:   Thu Dec 19 23:26:42 2013 +0100

    Bump version. v1.9.6.5.

diff --git AndroidManifest.xml AndroidManifest.xml
index 258ad44..c62ca11 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.4" android:versionCode="173">
+	android:versionName="1.9.6.5" android:versionCode="174">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index d52d8e9..24981c6 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 173
-        versionName '1.9.6.4'
+        versionCode 174
+        versionName '1.9.6.5'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit f0e9942f8d0c88357e9100d13ec5dda2f8ccf141
Author: liato <x@x00.us>
Date:   Thu Dec 19 23:21:20 2013 +0100

    Update api key for ICA Banken.

diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index bcc679c..ee492bb 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -56,7 +56,7 @@ public class ICABanken extends Bank {
 	private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
 	private static final boolean STATIC_BALANCE = false;
 
-	private static final String API_KEY = "A026CF97-5F6A-438D-A921-AA3406A6CE09";
+	private static final String API_KEY = "9A75DD46-82EE-449B-9F78-F11F636BB7BE";
 	private static final String API_URL = "https://appserver.icabanken.se";
 	private static final String API_VERSION = "1.0";
 

commit cf057f48b80eb0fa83de4429e2f7ebe60db09a25
Author: liato <x@x00.us>
Date:   Tue Dec 17 00:09:37 2013 +0100

    Correct currency for Eurobonus Mastercard DK and NO. Fix bug where Eurobonus Mastercard DK were loaded as NO from database. Closes #263.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index d6cb584..f184327 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -158,7 +158,7 @@ public class BankFactory {
         case IBankTypes.SASEUROBONUSMASTERCARD_NO:
         	return new EurobonusMastercardNo(context);
         case IBankTypes.SASEUROBONUSMASTERCARD_DK:
-            return new EurobonusMastercardNo(context);
+            return new EurobonusMastercardDk(context);
         case IBankTypes.RIKSLUNCHEN:
             return new Rikslunchen(context);            
         case IBankTypes.HEMKOP:
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 515d1e1..6b94bcf 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -26,21 +26,21 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
 public class EurobonusMastercard extends SEBKortBase {
-	private static final String TAG = "EurobonusMastercard";
-	private static final String NAME = "SAS EuroBonus MasterCard (Sweden)";
-	private static final String NAME_SHORT = "ebmaster";
-	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
+    private static final String TAG = "EurobonusMastercard";
+    private static final String NAME = "SAS EuroBonus MasterCard (Sweden)";
+    private static final String NAME_SHORT = "ebmaster";
+    private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
 
-	public EurobonusMastercard(Context context) {
-		super(context, "sase", "0102");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
-	
-	public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		super(username, password, context, "sase", "0102");
-	}
+    public EurobonusMastercard(Context context) {
+        super(context, "sase", "0102");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+    }
+
+    public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        super(username, password, context, "sase", "0102");
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index 6dacbc3..20161c3 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -26,21 +26,22 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
 public class EurobonusMastercardDk extends SEBKortBase {
-	private static final String TAG = "EurobonusMastercardDk";
-	private static final String NAME = "SAS EuroBonus MasterCard (Denmark)";
-	private static final String NAME_SHORT = "ebmaster_dk";
-	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_DK;
+    private static final String TAG = "EurobonusMastercardDk";
+    private static final String NAME = "SAS EuroBonus MasterCard (Denmark)";
+    private static final String NAME_SHORT = "ebmaster_dk";
+    private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_DK;
 
-	public EurobonusMastercardDk(Context context) {
-		super(context, "sadk", "0101");
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
+    public EurobonusMastercardDk(Context context) {
+        super(context, "sadk", "0101");
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.currency = "DKK";
+    }
 
-	public EurobonusMastercardDk(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		super(username, password, context, "sadk", "0101");
-	}
+    public EurobonusMastercardDk(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        super(username, password, context, "sadk", "0101");
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index b953b19..a4f295c 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -37,7 +37,8 @@ public class EurobonusMastercardNo extends SEBKortBase {
 		super.NAME = NAME;
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
-	}
+        super.currency = "NOK";
+    }
 	
 	public EurobonusMastercardNo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "sano", "0117");
diff --git src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 81334af..8a2ec23 100644
--- src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -70,7 +70,7 @@ public abstract class SEBKortBase extends Bank {
 
 
     public SEBKortBase(Context context, String providerPart, String prodgroup) {
-        this(context, providerPart, prodgroup, "secure.sebkort.com", new int[] {R.raw.cert_sebkort});
+        this(context, providerPart, prodgroup, "secure.sebkort.com", new int[]{R.raw.cert_sebkort});
     }
 
     public SEBKortBase(Context context, String providerPart, String prodgroup, String apiBase, int[] certificates) {
@@ -161,16 +161,19 @@ public abstract class SEBKortBase extends Bank {
             for (BillingUnit bu : br.getBody()) {
                 Account account = new Account(formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp", multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
                 account.setType(Account.CCARD);
+                account.setCurrency(currency);
                 mBillingUnitIds.put(account, bu.getBillingUnitId());
                 accounts.add(account);
                 balance = balance.add(account.getBalance());
                 account = new Account(formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts), Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
                 account.setType(Account.OTHER);
                 account.setAliasfor(bu.getArrangementNumber());
+                account.setCurrency(currency);
                 accounts.add(account);
                 account = new Account(formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts), Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
                 account.setType(Account.OTHER);
                 account.setAliasfor(bu.getArrangementNumber());
+                account.setCurrency(currency);
                 accounts.add(account);
             }
 
@@ -200,7 +203,7 @@ public abstract class SEBKortBase extends Bank {
             for (CardGroup cg : r.getBody().getCardGroups()) {
                 for (TransactionGroup tg : cg.getTransactionGroups()) {
                     for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg.getTransactions()) {
-                        transactions.add(new Transaction(Helpers.formatDate(new Date(t.getOriginalAmountDateDate())), t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate()));
+                        transactions.add(new Transaction(Helpers.formatDate(new Date(t.getOriginalAmountDateDate())), t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate(), account.getCurrency()));
                     }
                 }
             }

commit e5f010463043eece2e07623362028489d00975ab
Author: liato <x@x00.us>
Date:   Fri Dec 13 00:48:16 2013 +0100

    Changelog fixes.

diff --git CHANGES.txt CHANGES.txt
index 5048106..87955b3 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -72,7 +72,7 @@ v1.9.5: (2013-02-21)
 + Support for Appeak Poker
 
 
-1.9.4: (2013-01-04)
+v1.9.4: (2013-01-04)
 * Fix for ICA Banken transactions (thanks to fruktsallad)
 * Fix for Länsförsäkringar
 * Fix for Skandiabanken accounts without transactions
@@ -80,18 +80,18 @@ v1.9.5: (2013-02-21)
 * Fixes for Marginalen Bank (thanks to jsiverskog)
 
 
-1.9.3: (2012-11-29)
+v1.9.3: (2012-11-29)
 + Support for Marginalen Bank (thanks to jsiverskog)
 * Fix for password saving in Android 4.2+ (thanks to gfu)
 * Fix for ICA (thanks to oskla129)
 * Fix reappearing accounts on ICA Banken
 
 
-1.9.2: (2012-10-21)
+v1.9.2: (2012-10-21)
 * Fix for Länsförsäkringar - Now uses the same API as their official app
 
 
-1.9.1: (2012-10-11)
+v1.9.1: (2012-10-11)
 + Support for Chalmrest (thanks to emilan)
 * Fix for Västtrafik (thanks to erifre)
 * Fix for Nordea captcha - login as many times as you want with the built in captcha breaker
@@ -103,7 +103,7 @@ v1.9.5: (2013-02-21)
 - Removed support for Steam Wallet
 
 
-1.9.0: (2012-06-25)
+v1.9.0: (2012-06-25)
 + Support for Ticket Rikskortet
 + Support for Bioklubben
 * Fix for Meniga (thanks to bjooork)
@@ -114,12 +114,12 @@ v1.9.5: (2013-02-21)
 * Fix for Eurocard
 
 
-1.8.9: (2012-04-16)
+v1.8.9: (2012-04-16)
 + New setting: Number of simultaneous notifications
 * Fix for graphical bug on devices running older versions of Android (sorry for the poor testing before release)
 
 
-1.8.8: (2012-04-13)
+v1.8.8: (2012-04-13)
 + Support for Meniga (thanks to bjooork)
 + New notification setting: Display change only
 + Disable thumbnail in recent apps list (Honeycomb, ICS)
@@ -129,17 +129,17 @@ v1.9.5: (2013-02-21)
 * Fix for IKEA
 
 
-1.8.7: (2012-01-29)
+v1.8.7: (2012-01-29)
 * Fix for SEB
 * Fix for double lock pattern when opening transactions view from widget
 
 
-1.8.6: (2012-01-29)
+v1.8.6: (2012-01-29)
 * Fix for SEB 
 * Fix for LED color picker on pre ICS devices
 
 
-1.8.5: (2012-01-27)
+v1.8.5: (2012-01-27)
 + Support for LED notifications
 + Support for Akelius Invest
 * Fix for Coop
@@ -149,7 +149,7 @@ v1.9.5: (2013-02-21)
 * Fix for ICA
 
 
-1.8.4: (2011-12-04)
+v1.8.4: (2011-12-04)
 * Fix for Coop
 * Fix for Länsförsäkringar (thanks to MatsKarlsson!)
 + Support for Everydaycard (thanks to d95andek!)
@@ -157,19 +157,19 @@ v1.9.5: (2013-02-21)
 * Smarter automatic updates
 
 
-1.8.3: (2011-11-13)
+v1.8.3: (2011-11-13)
 + Support for American Express
 + Support for Västtrafik
 * Fix for SEB
 
 
-1.8.1: (2011-09-26)
+v1.8.1: (2011-09-26)
 + Support for Danske Bank
 + Support for Nordea (Danmark) (thanks to goober!)
 * Fix for Skandiabanken (thanks to woody!)
 
 
-1.8.0: (2011-08-24)
+v1.8.0: (2011-08-24)
 + Support for AudiKortet
 + Support for Chevrolet Big Plus Card
 + Support for Djurgårdskortet
@@ -193,7 +193,7 @@ v1.9.5: (2013-02-21)
 + Donate button added
 
 
-1.7.3 (2011-05-04)
+v1.7.3 (2011-05-04)
 * Fix for Jojo
 + Support for OpelKortet
 + Support for SJ Prio MasterCard
@@ -205,13 +205,13 @@ v1.9.5: (2013-02-21)
 + New setting: Smallest change to trigger notification
 
 
-1.7.2: (2011-04-14)
+v1.7.2: (2011-04-14)
 * Fix for Swedbank transactions (update account from app to see transactions)
 * Fix for Länsförsäkringar
 + New setting: Update transaction history from widget
 
 
-1.7.1: (2011-04-12)
+v1.7.1: (2011-04-12)
 * Fix for Swedbank
 * For for Payson when using multiple currencies
 * Support for multiple currencies in DinersClub
@@ -221,7 +221,7 @@ v1.9.5: (2013-02-21)
 + Setting: Disable visible pattern on pattern lock
 
 
-1.7.0: (2011-03-25)
+v1.7.0: (2011-03-25)
 + Support for SevenDay
 + Support for Nordnet
 + Support for Osuuspankki/Andelsbanken
@@ -242,11 +242,11 @@ v1.9.5: (2013-02-21)
 * "Home" button clears history stack
 
 
-1.6.3: (2011-02-06)
+v1.6.3: (2011-02-06)
 * FC fix when opening settings
 
 
-1.6.2: (2011-02-05)
+v1.6.2: (2011-02-05)
 + Support for SEB (automatic website login doesn't work yet)
 + Support for SAS EuroBonus Mastercard
 + Support for Rikslunchen
@@ -256,37 +256,37 @@ v1.9.5: (2013-02-21)
 + Content Provider - Lets other apps use data from Bankdroid after user confirmation
 
 
-1.6.1: (2010-12-29)
+v1.6.1: (2010-12-29)
 * Fix for FC when using pattern lock in landscape mode
 * Larger hit box on "Home" button
 
 
-1.6.0: (2010-12-29)
+v1.6.0: (2010-12-29)
 + Login to any of your banks website automatically by clicking the WWW-button.
 * Design changes
 * Eurocard widgetbug fixed
 * Fix for Ikano Bank
 
 
-1.5.3: (2010-12-21)
+v1.5.3: (2010-12-21)
 + Support for Ikano Bank
 + MedMera Faktura for Coop 
 * Multiple accounts for Eurocard
 
 
-1.5.2: (2010-12-18)
+v1.5.2: (2010-12-18)
 + Support for Diners Club
 + Transactions for Länsförsäkringar 
 
 
-1.5.1: (2010-12-15)
+v1.5.1: (2010-12-15)
 + Funds and loans for Länsförsäkringar
 * MedMera Visa for Coop fixed
 * Fix for Handelsbanken
 * Password field show numeric keyboard if appropriate
 
 
-1.5.0: (2010-12-12)
+v1.5.0: (2010-12-12)
 + Support for Jojo Reskassa
 + Support for Steam Wallet
 + Support for Avanza (again...)
@@ -297,14 +297,14 @@ v1.9.5: (2013-02-21)
 * Fix for Coop
 
 
-1.4.4: (2010-11-26)
+v1.4.4: (2010-11-26)
 + Support for Payson
-* Länsförsäkringar fixad
+* Länsförsäkringar fixed
 * Coop login problems fixed/improved
 + New settings: Blur account balance on widgets
 
 
-1.4.3: (2010-11-19)
+v1.4.3: (2010-11-19)
 - Support for Avanza removed
 * PayPal is working again
 * Show all transactions for Statoil
@@ -318,15 +318,15 @@ v1.9.5: (2013-02-21)
 + New setting: Don't update transactions on automatic updates
 
 
-1.4.2: (2010-11-03)
+v1.4.2: (2010-11-03)
 * Fixed username field for Avanza
 
 
-1.4.1: (2010-11-03)
+v1.4.1: (2010-11-03)
 * Fix for Nordea
 
 
-1.4.0: (2010-11-02)
+v1.4.0: (2010-11-02)
 + Support for OKQ8 (thanks to cola)
 + Support for PayPal
 + Support for Eurocard with transactions
@@ -346,14 +346,14 @@ v1.9.5: (2013-02-21)
 * Loans are not counted towards the total bank sum
 
 
-1.3.1: (2010-09-20)
+v1.3.1: (2010-09-20)
 * Fix for Swedbank
 * Fix for Avanza
 + Support for Avanza mini
 + Support for Villabanken
 
 
-1.3.0: (2010-09-19)
+v1.3.0: (2010-09-19)
 * Widgets with Handelsbanken accounts are working again
 * Transactions for ICA Banken
 * Coop now also works with "MedMera-kortet"
@@ -368,12 +368,12 @@ v1.9.5: (2013-02-21)
 + Support for Avanza
 
 
-1.2.1: (2010-07-13)
+v1.2.1: (2010-07-13)
 * Added missing ICA Banken logo
 * Fix amount formatting
 
 
-1.2.0: (2010-07-12)
+v1.2.0: (2010-07-12)
 * Fixed Nordea bug (login failed when user had an "e-faktura" waiting)
 * New design
 * Confirm password field
@@ -386,25 +386,25 @@ v1.9.5: (2013-02-21)
 + Support for QVGA devices
 
 
-1.1.4: (2010-06-03)
+v1.1.4: (2010-06-03)
 * Fix for Nordea
 
 
-1.1.3: (2010-06-02)
+v1.1.3: (2010-06-02)
 + New widget size, 2x1
 * Widgets are updated on boot
 
 
-1.1.2: (2010-05-31)
+v1.1.2: (2010-05-31)
 * Working fix for ICA Banken
 
 
-1.1.1: (2010-05-31)
+v1.1.1: (2010-05-31)
 * Fix for FC bug with widgets
 * Fix for ICA Banken
 
 
-1.1.0: (2010-05-31)
+v1.1.0: (2010-05-31)
 + Widgets
 + Automatic updates
 + Notifications on account changes
@@ -412,19 +412,19 @@ v1.9.5: (2013-02-21)
 + Improved application lock
 
 
-1.0.3: (2010-05-16)
+v1.0.3: (2010-05-16)
 + Option to password protect the application
 
 
-1.0.2: (2010-05-12)
+v1.0.2: (2010-05-12)
 * Fix for Swedbank
 
 
-1.0.1: (2010-05-10)
+v1.0.1: (2010-05-10)
 + Support for ICA Banken
 
 
-1.0.0: (2010-05-05)
+v1.0.0: (2010-05-05)
 + First public release
 + Support for Nordea
 + Support for Swedbank

commit ace4ff051881a5d8352d7ef8161a528a4e2bc56b
Author: liato <x@x00.us>
Date:   Fri Dec 13 00:35:26 2013 +0100

    Update changelog.

diff --git CHANGES.txt CHANGES.txt
index 61a09e7..5048106 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,10 @@
+v1.9.6.4: (2013-12-13)
+* Fix for SAS Eurobonus Mastercard Norway﻿
+* Fix for SEB Cards (Eurocard, SAS Eurobonus, Statoil, SJ Prio...) with multiple accounts﻿
+* Fix for Bitcoin where transfers had notes
+* Fix for ICA Banken
+
+
 v1.9.6.3: (2013-12-05)
 * Fix for American Express
 * Fix for Eurocard
@@ -7,6 +14,7 @@ v1.9.6.3: (2013-12-05)
 * Fix for SJPrio
 * Various bugfixes
 
+
 v1.9.6.2: (2013-11-03)
 * Fix for Avanza (thanks to NanoRage)
 * Fix for Ikano Bank

commit 7b613fb7f4127bb7fea0c062d395c84db755b826 (tag: v1.9.6.4)
Author: liato <x@x00.us>
Date:   Fri Dec 13 00:27:35 2013 +0100

    Bump version. v1.9.6.4

diff --git AndroidManifest.xml AndroidManifest.xml
index cf90a5f..258ad44 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.4-RC3" android:versionCode="172">
+	android:versionName="1.9.6.4" android:versionCode="173">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index ca804c3..d52d8e9 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 172
-        versionName '1.9.6.4-RC3'
+        versionCode 173
+        versionName '1.9.6.4'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit a8e243e875c36e6d497d1559853a4a8f676f7d3e (tag: v1.9.6.4-RC3)
Author: liato <x@x00.us>
Date:   Mon Dec 9 23:22:42 2013 +0100

    Bump version. v1.9.6.4-RC3.

diff --git AndroidManifest.xml AndroidManifest.xml
index c693062..cf90a5f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.4-RC2" android:versionCode="171">
+	android:versionName="1.9.6.4-RC3" android:versionCode="172">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 1c1fe10..ca804c3 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 171
-        versionName '1.9.6.4-RC2'
+        versionCode 172
+        versionName '1.9.6.4-RC3'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 7aa886b2bdec7fb7202023e4dd68861269b0595d
Author: liato <x@x00.us>
Date:   Mon Dec 9 23:17:30 2013 +0100

    Update SSL cert for ICABanken.

diff --git res/raw/cert_icabanken2.pem res/raw/cert_icabanken2.pem
new file mode 100644
index 0000000..2bb925b
--- /dev/null
+++ res/raw/cert_icabanken2.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+w8z6/jIFgTDUeoqdfZrN++iWQjq4DAB6pS4/6nRJeX0wj2iJJw==
+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 324077f..bcc679c 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -80,7 +80,7 @@ public class ICABanken extends Bank {
 	}
 
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken));
+		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken, R.raw.cert_icabanken2));
 		urlopen.addHeader("ApiVersion", API_VERSION);
 		urlopen.addHeader("Accept", "application/json");
 		urlopen.addHeader("ApiKey", API_KEY);

commit 53248d43a11a777bd8ff2ac53e163560a0441c9a (tag: v1.9.6.4-RC2)
Author: liato <x@x00.us>
Date:   Sun Dec 8 22:36:10 2013 +0100

    Bump version. v1.9.6.4-RC2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 09de62f..c693062 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.4-RC1" android:versionCode="170">
+	android:versionName="1.9.6.4-RC2" android:versionCode="171">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index e516e76..1c1fe10 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 170
-        versionName '1.9.6.4-RC1'
+        versionCode 171
+        versionName '1.9.6.4-RC2'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit ba48e5d12834d7dbf49ba38057504f9d22eb64f3
Author: liato <x@x00.us>
Date:   Sun Dec 8 22:34:54 2013 +0100

    Handle multiple accounts for SEBKort.

diff --git src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 3bb9578..81334af 100644
--- src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -157,22 +157,22 @@ public abstract class SEBKortBase extends Bank {
             UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)), UserResponse.class);
             BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)), BillingUnitsResponse.class);
 
-            //TODO: Handle multiple cards?
-            BillingUnit bu = br.getBody().get(0);
-
-            Account account = new Account("Disponibelt belopp", Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
-            account.setType(Account.CCARD);
-            mBillingUnitIds.put(account, bu.getBillingUnitId());
-            accounts.add(account);
-            balance = balance.add(account.getBalance());
-            account = new Account("Saldo", Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
-            account.setType(Account.OTHER);
-            account.setAliasfor(bu.getArrangementNumber());
-            accounts.add(account);
-            account = new Account("Köpgräns", Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
-            account.setType(Account.OTHER);
-            account.setAliasfor(bu.getArrangementNumber());
-            accounts.add(account);
+            boolean multipleAccounts = br.getBody().size() > 1;
+            for (BillingUnit bu : br.getBody()) {
+                Account account = new Account(formatAccountName(bu.getArrangementNumber(), "Disponibelt belopp", multipleAccounts), Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
+                account.setType(Account.CCARD);
+                mBillingUnitIds.put(account, bu.getBillingUnitId());
+                accounts.add(account);
+                balance = balance.add(account.getBalance());
+                account = new Account(formatAccountName(bu.getArrangementNumber(), "Saldo", multipleAccounts), Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
+                account.setType(Account.OTHER);
+                account.setAliasfor(bu.getArrangementNumber());
+                accounts.add(account);
+                account = new Account(formatAccountName(bu.getArrangementNumber(), "Köpgräns", multipleAccounts), Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
+                account.setType(Account.OTHER);
+                account.setAliasfor(bu.getArrangementNumber());
+                accounts.add(account);
+            }
 
             if (accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -186,6 +186,10 @@ public abstract class SEBKortBase extends Bank {
         }
     }
 
+    private String formatAccountName(String accountNumber, String name, boolean includeAccountNnumber) {
+        return includeAccountNnumber ? String.format("%s (%s)", accountNumber, name) : name;
+    }
+
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);

commit a9f71afaeb425197e20117d722c86c7261b940d7
Author: liato <x@x00.us>
Date:   Sun Dec 8 21:27:52 2013 +0100

    Fix for Bitcoint transfers with notes.

diff --git src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index bb29a3d..0feb7bd 100644
--- src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -26,6 +26,7 @@ import android.content.Context;
 import android.text.TextUtils;
 
 import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
@@ -80,6 +81,8 @@ public class Bitcoin extends Bank {
 						R.string.invalid_username_password).toString());
 			}
 			ObjectMapper vObjectMapper = new ObjectMapper();
+            vObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            vObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
 			BlockchainResponse r = vObjectMapper.readValue(urlopen.open(API_URL + username), BlockchainResponse.class);
 			Account a = new Account("Bitcoin", new BigDecimal(r.getFinalBalance()).divide(BigDecimal.valueOf(100000000)), "1");
 			a.setCurrency("BTC");
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
index 50c3031..19bdc54 100644
--- src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
+++ src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
@@ -32,6 +32,9 @@ public class Transfer implements Serializable {
 	private List<Out> mOut = Collections.emptyList();
 	@JsonProperty("result")
 	private long mResult;
+    @JsonProperty("note")
+    private String mNote;
+
 
 	@JsonProperty("size")
 	public long getSize() {
@@ -93,4 +96,9 @@ public class Transfer implements Serializable {
 		return mResult;
 	}
 
+    @JsonProperty("note")
+    public String getNote() {
+        return mNote;
+    }
+
 }
\ No newline at end of file

commit 5d670b27c750d2904cf5c0a16f3306ace9e302ac (tag: v1.9.6.4-RC1)
Author: liato <x@x00.us>
Date:   Fri Dec 6 00:40:00 2013 +0100

    Fix for SAS Eurobonus Mastercard Norway.

diff --git AndroidManifest.xml AndroidManifest.xml
index 1f71f46..09de62f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.3" android:versionCode="169">
+	android:versionName="1.9.6.4-RC1" android:versionCode="170">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 9346ff8..e516e76 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 169
-        versionName '1.9.6.3'
+        versionCode 170
+        versionName '1.9.6.4-RC1'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index 7c518ef..b953b19 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -32,7 +32,7 @@ public class EurobonusMastercardNo extends SEBKortBase {
 	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_NO;
 
 	public EurobonusMastercardNo(Context context) {
-		super(context, "sano", "0102");
+		super(context, "sano", "0117");
 		super.TAG = TAG;
 		super.NAME = NAME;
 		super.NAME_SHORT = NAME_SHORT;
@@ -40,7 +40,7 @@ public class EurobonusMastercardNo extends SEBKortBase {
 	}
 	
 	public EurobonusMastercardNo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		super(username, password, context, "sano", "0102");
+		super(username, password, context, "sano", "0117");
 	}
 
 }

commit 863649e4094b9d7fcee07405f37b223dfb9a3f74 (tag: v1.9.6.3)
Author: liato <x@x00.us>
Date:   Thu Dec 5 00:11:01 2013 +0100

    Bump version. 1.9.6.3.

diff --git AndroidManifest.xml AndroidManifest.xml
index 49cdf49..1f71f46 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.3-RC2" android:versionCode="168">
+	android:versionName="1.9.6.3" android:versionCode="169">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git CHANGES.txt CHANGES.txt
index b0f97d0..61a09e7 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,12 @@
+v1.9.6.3: (2013-12-05)
+* Fix for American Express
+* Fix for Eurocard
+* Fix for SAS Eurobonus Mastercard
+* Fix for Statoil Mastercard
+* Fix for Bioklubben
+* Fix for SJPrio
+* Various bugfixes
+
 v1.9.6.2: (2013-11-03)
 * Fix for Avanza (thanks to NanoRage)
 * Fix for Ikano Bank
diff --git build.gradle build.gradle
index 6306e39..9346ff8 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 168
-        versionName '1.9.6.3-RC2'
+        versionCode 169
+        versionName '1.9.6.3'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 159c0688ec6043d8cb6319ecab6c547612486a12
Author: liato <x@x00.us>
Date:   Tue Dec 3 04:49:33 2013 +0100

    Bump version. 1.9.6.3-RC2.

diff --git AndroidManifest.xml AndroidManifest.xml
index c834144..49cdf49 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.3" android:versionCode="167">
+	android:versionName="1.9.6.3-RC2" android:versionCode="168">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 5804fc9..6306e39 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 167
-        versionName '1.9.6.3-RC1'
+        versionCode 168
+        versionName '1.9.6.3-RC2'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 155b1c2aeb2d2e3468857c9d6bb346d15622a5b0
Author: liato <x@x00.us>
Date:   Tue Dec 3 04:48:40 2013 +0100

    Fix for Bioklubben. Closes #253.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 4e93661..7446023 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -28,6 +28,7 @@
     <string name="bank">Bank</string>
     <string name="custom_name">Eget Namn (frivilligt)</string>
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
+    <string name="email">E-post</string>
 
     <string name="cancel">AVBRYT</string>
     <string name="save">SPARA</string>
diff --git res/values/strings.xml res/values/strings.xml
index 8c9dd7d..cd1af41 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -28,7 +28,7 @@
     <string name="extras_field">Extras</string>
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
-
+    <string name="email">E-mail</string>
 
     <string name="cancel">CANCEL</string>
     <string name="save">SAVE</string>
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index 77ef2fb..17a0591 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -16,17 +16,8 @@
 
 package com.liato.bankdroid;
 
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.Transaction;
-
 import android.content.Context;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.InflateException;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -37,6 +28,15 @@ import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.Transaction;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
 public class TransactionsActivity extends LockableActivity {
 	final static String TAG = "TransactionActivity";
 	
@@ -63,7 +63,7 @@ public class TransactionsActivity extends LockableActivity {
 		viewAccountName.setText(account.getName());
 		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
 		icon.setImageResource(bank.getImageResource());
-		ArrayList<Transaction> transactions = account.getTransactions();
+		List<Transaction> transactions = account.getTransactions();
 
 		if (transactions.size() > 0) {
 			findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
@@ -90,7 +90,7 @@ public class TransactionsActivity extends LockableActivity {
 		private LayoutInflater inflater;
 		private ArrayList<Object> items = new ArrayList<Object>();
 
-		public TransactionsAdapter(ArrayList<Transaction> transactions) {
+		public TransactionsAdapter(List<Transaction> transactions) {
 			inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 			if (!transactions.isEmpty()) {
 				String date = transactions.get(0).getDate();
diff --git src/com/liato/bankdroid/banking/Account.java src/com/liato/bankdroid/banking/Account.java
index 998d309..46097e6 100644
--- src/com/liato/bankdroid/banking/Account.java
+++ src/com/liato/bankdroid/banking/Account.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.List;
 
 import com.liato.bankdroid.provider.IAccountTypes;
 
@@ -31,14 +32,14 @@ public class Account implements IAccountTypes {
 	private boolean hidden = false;
 	private boolean notify = true;
 	private String currency;
-	private ArrayList<Transaction> transactions;
+	private List<Transaction> transactions;
 	private String aliasfor;
 
-	public ArrayList<Transaction> getTransactions() {
+	public List<Transaction> getTransactions() {
 		return transactions;
 	}
 
-	public void setTransactions(final ArrayList<Transaction> transactions) {
+	public void setTransactions(final List<Transaction> transactions) {
 		this.transactions = transactions;
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
index 3b06c3e..c1c55be 100644
--- src/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -15,42 +15,43 @@
  */
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
 import android.content.Context;
+import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bioklubben extends Bank {
-	private static final String TAG = "Bioklubben";
-	private static final String NAME = "Bioklubben";
-	private static final String NAME_SHORT = "bioklubben";
-	private static final String URL = "https://bioklubben.sfbio.se/user/login";
-	private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
-	private static final boolean DISPLAY_DECIMALS = false;
-
-    private Pattern reBalance = Pattern.compile("pointsblock-bignumber-bn\">([^<]+)</div>");
-
+    private static final String TAG = "Bioklubben";
+    private static final String NAME = "Bioklubben";
+    private static final String NAME_SHORT = "bioklubben";
+    private static final String URL = "http://bioklubben.sf.se/Start.aspx";
+    private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
+    private static final boolean DISPLAY_DECIMALS = false;
     private String response = null;
-    
+
     public Bioklubben(Context context) {
         super(context);
         super.TAG = TAG;
@@ -59,7 +60,8 @@ public class Bioklubben extends Bank {
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
         super.DISPLAY_DECIMALS = DISPLAY_DECIMALS;
-        
+        super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+        super.INPUT_HINT_USERNAME = context.getString(R.string.email);
         currency = context.getString(R.string.points);
     }
 
@@ -68,34 +70,49 @@ public class Bioklubben extends Bank {
         this.update(username, password);
     }
 
-    
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bioklubben));
+        urlopen.setAllowCircularRedirects(true);
+        response = urlopen.open("http://bioklubben.sf.se/Start.aspx");
+
+        Document d = Jsoup.parse(response);
+        Element e = d.getElementById("__VIEWSTATE");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String viewState = e.attr("value");
+
+        e = d.getElementById("__EVENTVALIDATION");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+        }
+        String eventValidation = e.attr("value");
+
 
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("name", username));
-        postData.add(new BasicNameValuePair("pass", password));
-        postData.add(new BasicNameValuePair("form_build_id", "form-5fab45c2b5bcacfe564ef96cf8329a82"));
-        postData.add(new BasicNameValuePair("form_id", "user_login"));
-        postData.add(new BasicNameValuePair("op", "Logga in"));
-        postData.add(new BasicNameValuePair("persistent_login", "1"));
-        return new LoginPackage(urlopen, postData, response, "https://bioklubben.sfbio.se/user/login");
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair("ctl00_toolkitscriptmanager_HiddenField", ""));
+        postData.add(new BasicNameValuePair("ctl00$toolkitscriptmanager", "ctl00$UpdatePanel|ctl00$ContentPlaceHolder1$LoginUserControl$LogonButton"));
+        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$LoginNameTextBox", username));
+        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolder1$LoginUserControl$PasswordTextBox", password));
+        return new LoginPackage(urlopen, postData, response, "http://bioklubben.sf.se/Start.aspx");
     }
 
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());         
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("Felaktigt anv")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
-        }
-        catch (ClientProtocolException e) {
+        } catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
+        } catch (IOException e) {
             e.printStackTrace();
             throw new BankException(e.getMessage());
         }
@@ -109,19 +126,31 @@ public class Bioklubben extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
         urlopen = login();
-        Matcher matcher = reBalance.matcher(response);
-        if (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Balance           218
-             * 
-             */
-            BigDecimal b = Helpers.parseBalance(matcher.group(1));
+        try {
+            Document d = Jsoup.parse(urlopen.open("http://bioklubben.sf.se/MyPurchases.aspx?ParentTreeID=1&TreeID=1"));
+            Element e = d.getElementById("ctl00_ContentPlaceHolder1_BonusPointsLabel");
+            if (e == null) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString() + " points element.");
+            }
+            BigDecimal b = Helpers.parseBalance(e.text());
             Account a = new Account("Poäng", b, "1");
             a.setCurrency(context.getString(R.string.points));
             accounts.add(a);
-            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+            balance = balance.add(a.getBalance());
+
+            Elements es = d.select(".GridViewStd_Item");
+            List<Transaction> transactions = new ArrayList<Transaction>();
+            if (es != null) {
+                for (Element el : es) {
+                    transactions.add(new Transaction(el.child(0).text().trim(), el.child(1).text().trim(), Helpers.parseBalance(el.child(2).text())));
+                }
+            }
+            a.setTransactions(transactions);
+
+        } catch (IOException e) {
+            if (e == null) {
+                throw new BankException(e.getMessage());
+            }
         }
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git src/com/liato/bankdroid/db/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
index bdcb0a1..9269a49 100644
--- src/com/liato/bankdroid/db/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.db;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.List;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.ContentValues;
@@ -174,7 +175,7 @@ public class DBAdapter {
                 vals.put("aliasfor", acc.getAliasfor());
 	            mDb.insert("accounts", null, vals);
 	            if (acc.getAliasfor() == null || acc.getAliasfor().length() == 0) {
-    	            ArrayList<Transaction> transactions = acc.getTransactions();
+    	            List<Transaction> transactions = acc.getTransactions();
     	            if (transactions != null && !transactions.isEmpty()) {
     	                deleteTransactions(new Long(bankId).toString()+"_"+acc.getId());
     		            for(Transaction transaction : transactions) {
diff --git src/com/liato/bankdroid/liveview/LiveViewService.java src/com/liato/bankdroid/liveview/LiveViewService.java
index f2b9ab7..7a1d0d1 100644
--- src/com/liato/bankdroid/liveview/LiveViewService.java
+++ src/com/liato/bankdroid/liveview/LiveViewService.java
@@ -148,7 +148,7 @@ public class LiveViewService extends Service {
 	public void onStart(Intent intent, int startId) {
         super.onStart(intent, startId);
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
-        
+        if (intent == null) return;
 		if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
 			Bundle extras = intent.getExtras();
 			if (extras != null) {
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index dc85ee8..cbaa877 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -159,7 +159,7 @@ public class Urllib {
     }
 
     public InputStream openStream(String url) throws ClientProtocolException, IOException {
-        return openStream(url, new BasicHttpEntity(), false);
+        return openStream(url, (HttpEntity)null, false);
     }
     
     public HttpEntity toEntity(List<NameValuePair> postData) {
@@ -186,7 +186,7 @@ public class Urllib {
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         HttpUriRequest request;
-        if (!forcePost) {
+        if (!forcePost && postData == null) {
             request = new HttpGet(url);
         }
         else {

commit 558ceb7ade4bf115ee214687220b46500494bff0
Author: liato <x@x00.us>
Date:   Tue Dec 3 04:47:51 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 6cca12e..c834144 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.2" android:versionCode="166">
+	android:versionName="1.9.6.3" android:versionCode="167">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 021ea9f..5804fc9 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 166
-        versionName '1.9.6.2'
+        versionCode 167
+        versionName '1.9.6.3-RC1'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 34c0faff0a797ff8d36edc5dbc85a112204cd2cb
Author: liato <x@x00.us>
Date:   Sat Nov 30 12:46:11 2013 +0100

    Prevent fc from AutoRefreshService. Log errors instead.

diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 4425669..22fbf96 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -320,8 +320,10 @@ public class AutoRefreshService extends Service {
 					db.disableBank(bank.getDbId());
 				}
                 catch (BankChoiceException e) {
+                }
+                catch (Exception e) {
                     Log.e(TAG, "Error while updating bank '" + bank.getDbId()
-                            + "'; LoginException: " + e.getMessage());
+                            + "'; Exception: " + e.getMessage());
                 }
 			}
 
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index 2467669..df01cdd 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -176,11 +176,13 @@ public class IkanoBank extends Bank {
         matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             Log.e(TAG, "Unable to find ViewState. L156.");
+            return;
         }
         String strViewState = matcher.group(1);
         matcher = reEventValidation.matcher(response);
         if (!matcher.find()) {
             Log.e(TAG, "Unable to find EventValidation. L161.");
+            return;
         }
         String strEventValidation = matcher.group(1);       
 

commit 9c427c9915e9e7c900e5842f8acc2f0b1b236a92
Author: liato <x@x00.us>
Date:   Sat Nov 30 01:04:08 2013 +0100

    More certs for Amex.

diff --git res/raw/cert_americanexpress2.pem res/raw/cert_americanexpress2.pem
new file mode 100644
index 0000000..3df759a
--- /dev/null
+++ res/raw/cert_americanexpress2.pem
@@ -0,0 +1,38 @@
+-----BEGIN CERTIFICATE-----

+LQfnNyKUeTuq343tlqPfYy9NGKwD
+-----END CERTIFICATE-----
+
diff --git res/raw/cert_americanexpress3.pem res/raw/cert_americanexpress3.pem
new file mode 100644
index 0000000..04e020f
--- /dev/null
+++ res/raw/cert_americanexpress3.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+tC3C6Lbk+7TZl82Ktn48njQpcfhbB26b1ro=
+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 071d28f..374df74 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -52,7 +52,7 @@ public class AmericanExpress extends Bank {
 	private static final String TAG = "AmericanExpress";
 	private static final String NAME = "American Express";
 	private static final String NAME_SHORT = "americanexpress";
-	private static final String URL = "https://home.americanexpress.com/home/se/home_c.shtml";
+	private static final String URL = "https://www.americanexpress.com/home/se/home_c.shtml";
 	private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
 	
 	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -77,10 +77,10 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress, R.raw.cert_americanexpress2, R.raw.cert_americanexpress3));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
-        response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
+        response = urlopen.open("https://www.americanexpress.com/home/se/home_c.shtml");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
 
         postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));

commit 45087e3b89a79a44506a8fa96b445ec22e3d6821
Author: liato <x@x00.us>
Date:   Sat Nov 30 01:03:48 2013 +0100

    Possible fix for Eurocard.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 25d2814..623c056 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -281,7 +281,8 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	                });
 				}
 				else {
-    				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
+                    exc.printStackTrace();
+                    builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
     				.setIcon(android.R.drawable.ic_dialog_alert)
     				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
     					public void onClick(DialogInterface dialog, int id) {
diff --git src/com/liato/bankdroid/banking/banks/Chevrolet.java src/com/liato/bankdroid/banking/banks/Chevrolet.java
index 1e8e165..8cfe6f8 100644
--- src/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ src/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -39,7 +39,7 @@ public class Chevrolet extends SEBKortBase {
 	}
 	
 	public Chevrolet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		super(username, password, context, "wase", "0086");
+		super(username, password, context, "chse", "0086");
 	}
 
 }
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 07925bf..ce648e7 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,202 +16,31 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
 import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
 
-import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Eurocard extends Bank {
+public class Eurocard extends SEBKortBase {
 	private static final String TAG = "Eurocard";
 	private static final String NAME = "Eurocard";
 	private static final String NAME_SHORT = "eurocard";
-	private static final String URL = "https://secure.eurocard.se/nis/external/ecse/login.do";
 	private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-	
-	private Pattern reAccounts = Pattern.compile("Welcomepagecardimagecontainer\">\\s*[^<]+<br>[^>]+<br>([^>]+)</div>\\s*</div>\\s*</div>.*?indentationwrapper\">\\s*<a\\s*href=\"getPendingTransactions\\.do\\?id=([^\"]+)\">.*?billedamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reSaldo = Pattern.compile("Billingunitbalanceamount\">\\s*([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*(?:<div[^>]+>\\s*)?<span>([^<]*)</span>\\s*(?:</div>\\s*)?</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
-    private ArrayList<String> accountIds = new ArrayList<String>();
-	private String response = null;
-	public Eurocard(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public Eurocard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
 
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_eurocard));
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        response = urlopen.open("https://secure.eurocard.se/nis/external/ecse/login.do");
-        urlopen.addHeader("Referer", String.format("https://secure.eurocard.se/nis/external/ecse/login.do"));
-        response = urlopen.open(String.format("https://secure.eurocard.se/nis/external/hidden.jsp?USERNAME=%s&CURRENT_METHOD=&referer=login.jsp", "0005"+username.toUpperCase()));
-        urlopen.removeHeader("Referer");
-        
-        postData.clear();
-        postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
-        postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
-        postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));
-        postData.add(new BasicNameValuePair("prodgroup", "0005"));
-        postData.add(new BasicNameValuePair("UID", "0005"+username.toUpperCase()));
-        postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
-        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
-        postData.add(new BasicNameValuePair("PASSWORD", password));
-        
-        return new LoginPackage(urlopen, postData, response, "https://secure.eurocard.se/auth4/Authentication/select.jsp");        
+    public Eurocard(Context context) {
+        super(context, "ecse", "0005", "secure.eurocard.se", new int[] {R.raw.cert_eurocard});
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktig kombination") || response.contains("ett felaktigt") || response.contains("invalid login")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		Matcher matcher = reAccounts.matcher(response);
-        Integer accountId = 0;
-		while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                     EXAMPLE DATA           NOTES
-             * 1: account number         **** **** **** 1234
-             * 2: id                     a1c2d3d4e5f6s7b8c9d0   Changes when session expires
-             * 3: ofakturerat amount     &nbsp;2 988,96
-             * 
-             */
-
-		    // Create a separate account for "Ofakturerat".
-		    // Set the balance for the main account to 0 and update it later
-			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), new BigDecimal(0), accountId.toString()));
-			accounts.add(new Account("└ " + "Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak:"+accountId.toString(), Account.OTHER));
-            accountIds.add(matcher.group(2).trim());
-            accountId += 1;			
-		}
-
-		try {
-            response = urlopen.open("https://secure.eurocard.se/nis/ecse/getBillingUnits.do");
-            matcher = reSaldo.matcher(response);
-            int i = 0;
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                     EXAMPLE DATA
-                 * 1: balance                &nbsp;40 988,96
-                 * 
-                 */ 
-                
-                // Update the main account balance
-                if (accounts.size() >= i*2+1) {
-                    accounts.get(i*2).setBalance(Helpers.parseBalance(matcher.group(1)));
-                }
-            }
-		}
-        catch (ClientProtocolException e) {
-            e.printStackTrace();
-        }
-        catch (IOException e) {
-            e.printStackTrace();
-        }
-
-
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-        super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		Matcher matcher;
-		// If the account is of type "other" it's the fake "Ofakturerat" account.
-		if (account.getType() == Account.OTHER) return;
-		try {
-		    String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			response = urlopen.open("https://secure.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: trans. date       10-18
-                 * 2: reg. date         10-19
-                 * 3: specification     ICA Kvantum
-                 * 4: location          Stockholm
-                 * 5: currency          SEK
-                 * 6: amount/tax        147,64
-                 * 7: amount in sek     5791,18
-                 * 
-                 */
-			    String[] monthday = matcher.group(1).trim().split("-");
-				transactions.add(new Transaction(Helpers.getTransactionDate(monthday[0], monthday[1]),
-				        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""),
-				        Helpers.parseBalance(matcher.group(7)).negate()));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
+    public Eurocard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        super(username, password, context, "ecse", "0005", "secure.eurocard.se", new int[] {R.raw.cert_eurocard});
+    }
 	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
index 837ff3f..3bb9578 100644
--- src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -58,22 +58,31 @@ public abstract class SEBKortBase extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
     private static final boolean STATIC_BALANCE = true;
-    ObjectMapper mObjectMapper = new ObjectMapper();
+    private ObjectMapper mObjectMapper = new ObjectMapper();
     private String response = null;
-    private String provider_part;
-    private String prodgroup;
+    private String mProviderPart;
+    private String mProdgroup;
+    private String mApiBase;
+    private int[] mCertificates;
     private BasicNameValuePair mParamsTarget;
     private BasicNameValuePair mParamsErrorTarget;
     private Map<Account, String> mBillingUnitIds = new HashMap<Account, String>();
 
-    public SEBKortBase(Context context, String provider_part, String prodgroup) {
+
+    public SEBKortBase(Context context, String providerPart, String prodgroup) {
+        this(context, providerPart, prodgroup, "secure.sebkort.com", new int[] {R.raw.cert_sebkort});
+    }
+
+    public SEBKortBase(Context context, String providerPart, String prodgroup, String apiBase, int[] certificates) {
         super(context);
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
-        this.provider_part = provider_part;
-        this.prodgroup = prodgroup;
-        super.URL = String.format("https://secure.sebkort.com/nis/m/%s/external/t/login/index", provider_part);
+        super.URL = String.format("https://%s/nis/m/%s/external/t/login/index", apiBase, providerPart);
+        mProviderPart = providerPart;
+        mProdgroup = prodgroup;
+        mApiBase = apiBase;
+        mCertificates = certificates;
         mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
         mParamsTarget = new BasicNameValuePair("target", URL);
@@ -85,38 +94,43 @@ public abstract class SEBKortBase extends Bank {
         this.update(username, password);
     }
 
+    public SEBKortBase(String username, String password, Context context, String url, String prodgroup, String apiBase, int[] certificates) throws BankException, LoginException, BankChoiceException {
+        this(context, url, prodgroup, apiBase, certificates);
+        this.update(username, password);
+    }
+
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sebkort));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, mCertificates));
         //Get required cookies
-        response = urlopen.open(String.format("https://secure.sebkort.com/nis/m/%s/external/t/login/index", provider_part));
+        response = urlopen.open(String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
         postData.clear();
         postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
         postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
         postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
         postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        postData.add(new BasicNameValuePair("UID", prodgroup + username.toUpperCase()));
+        postData.add(new BasicNameValuePair("UID", mProdgroup + username.toUpperCase()));
         postData.add(new BasicNameValuePair("PASSWORD", password));
-        postData.add(new BasicNameValuePair("prodgroup", prodgroup));
+        postData.add(new BasicNameValuePair("mProdgroup", mProdgroup));
         postData.add(mParamsTarget);
         postData.add(mParamsErrorTarget);
-        return new LoginPackage(urlopen, postData, response, "https://secure.sebkort.com/auth4/Authentication/select.jsp");
+        return new LoginPackage(urlopen, postData, response, String.format("https://%s/auth4/Authentication/select.jsp", mApiBase));
     }
 
     @Override
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
-            urlopen.addHeader("Origin", "https://secure.sebkort.com");
-            urlopen.addHeader("Referer", String.format("https://secure.sebkort.com/nis/m/%s/external/t/login/index", provider_part));
+            urlopen.addHeader("Origin", String.format("https://%s", mApiBase));
+            urlopen.addHeader("Referer", String.format("https://%s/nis/m/%s/external/t/login/index", mApiBase, mProviderPart));
             urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
             List<NameValuePair> postData = lp.getPostData();
             postData.remove(mParamsTarget);
             postData.remove(mParamsErrorTarget);
-            postData.add(new BasicNameValuePair("target", String.format("/nis/m/%s/login/loginSuccess", provider_part)));
-            postData.add(new BasicNameValuePair("errorTarget", String.format("/nis/m/%s/external/login/loginError", provider_part)));
+            postData.add(new BasicNameValuePair("target", String.format("/nis/m/%s/login/loginSuccess", mProviderPart)));
+            postData.add(new BasicNameValuePair("errorTarget", String.format("/nis/m/%s/external/login/loginError", mProviderPart)));
 
             LoginResponse r = mObjectMapper.readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
                     LoginResponse.class);
@@ -140,8 +154,8 @@ public abstract class SEBKortBase extends Bank {
         }
         urlopen = login();
         try {
-            UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://secure.sebkort.com/nis/m/%s/a/user", provider_part)), UserResponse.class);
-            BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://secure.sebkort.com/nis/m/%s/a/billingUnits", provider_part)), BillingUnitsResponse.class);
+            UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/user", mApiBase, mProviderPart)), UserResponse.class);
+            BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/billingUnits", mApiBase, mProviderPart)), BillingUnitsResponse.class);
 
             //TODO: Handle multiple cards?
             BillingUnit bu = br.getBody().get(0);
@@ -177,7 +191,7 @@ public abstract class SEBKortBase extends Bank {
         super.updateTransactions(account, urlopen);
         if (account.getType() != Account.CCARD) return;
         try {
-            PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(String.format("https://secure.sebkort.com/nis/m/%s/a/pendingTransactions/%s", provider_part, mBillingUnitIds.get(account))), PendingTransactionsResponse.class);
+            PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(String.format("https://%s/nis/m/%s/a/pendingTransactions/%s", mApiBase, mProviderPart, mBillingUnitIds.get(account))), PendingTransactionsResponse.class);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
             for (CardGroup cg : r.getBody().getCardGroups()) {
                 for (TransactionGroup tg : cg.getTransactionGroups()) {
diff --git src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index f1638a6..5598489 100644
--- src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -19,6 +19,8 @@ package eu.nullbyte.android.urllib;
  * under the License.
  */
 
+import android.util.Log;
+
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.params.HttpConnectionParams;
@@ -40,7 +42,7 @@ import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
 
 public class CertPinningSSLSocketFactory extends SSLSocketFactory {
-
+    private final static String TAG = CertPinningSSLSocketFactory.class.getSimpleName();
 	private SSLContext sslcontext = null;
     private Certificate[] certificates;
 
@@ -76,6 +78,7 @@ public class CertPinningSSLSocketFactory extends SSLSocketFactory {
     public Socket connectSocket(Socket sock, String host, int port,
 			InetAddress localAddress, int localPort, HttpParams params)
 			throws IOException, UnknownHostException, ConnectTimeoutException {
+        Log.v(TAG, "SSL socket connecting to: " + host);
 		int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
 		int soTimeout = HttpConnectionParams.getSoTimeout(params);
 
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
index 5fc2f9f..4ef336a 100644
--- src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
+++ src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -1,7 +1,5 @@
 package eu.nullbyte.android.urllib;
 
-import android.util.Log;
-
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;

commit e5d2c1827050b6b0e45f8e78f39dd2c11cdf5d17
Author: liato <x@x00.us>
Date:   Sat Nov 30 00:02:28 2013 +0100

    Fix for SEBKort.

diff --git res/drawable-hdpi-v4/button_bg_2.9.2010-07-02_1033.png res/drawable-hdpi-v4/button_bg_2.9.2010-07-02_1033.png
deleted file mode 100644
index 99aae62..0000000
Binary files res/drawable-hdpi-v4/button_bg_2.9.2010-07-02_1033.png and /dev/null differ
diff --git res/drawable-hdpi-v4/button_bg_pressed__2.9.2010-07-02_1022.png res/drawable-hdpi-v4/button_bg_pressed__2.9.2010-07-02_1022.png
deleted file mode 100644
index 54ac66d..0000000
Binary files res/drawable-hdpi-v4/button_bg_pressed__2.9.2010-07-02_1022.png and /dev/null differ
diff --git res/raw/cert_sebkort.pem res/raw/cert_sebkort.pem
index e8bf87e..3c36878 100644
--- res/raw/cert_sebkort.pem
+++ res/raw/cert_sebkort.pem
@@ -1,33 +1,35 @@
 -----BEGIN CERTIFICATE-----
-MIIFwjCCBKqgAwIBAgIQNaq8AmApNGbtQIKJLQkFyjANBgkqhkiG9w0BAQUFADCB
+MIIGATCCBOmgAwIBAgIQepNmMtz4xl/eNW5BjwmTQTANBgkqhkiG9w0BAQUFADCB
 vjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
 ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
 YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMv
 VmVyaVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0Ew
-HhcNMTIxMjA1MDAwMDAwWhcNMTQwMjAzMjM1OTU5WjCB8TETMBEGCysGAQQBgjc8
+HhcNMTIwNTMwMDAwMDAwWhcNMTQwNTMwMjM1OTU5WjCB5zETMBEGCysGAQQBgjc8
 AgEDEwJTRTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xFDASBgNVBAUT
 CzU1NjU3NC02NjI0MQswCQYDVQQGEwJTRTESMBAGA1UECBQJU3RvY2tob2xtMRIw

-gOwWPG5B14jvhuMMjC2XC4BpnVbeU5Ahui1lgkszFMg17ttTnUg=

+wka6NGg=
 -----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 6b0e43b..100bd5a 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -324,7 +324,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
                     a.setHidden(oa.isHidden());
                     a.setNotify(oa.isNotify());
                     a.setCurrency(oa.getCurrency());
-                    a.setAliasfor(oa.getAliasfor());
                 }
             }
             a.setBank(this);
@@ -350,6 +349,8 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             if (lp == null) {
                 throw new BankException("No automatic login for this bank. preLogin() is not implemented or has failed.");
             }
+            //TODO: Skip the form submission. Login using Bank.login(...) and transfer cookies to webview. The user is now logged in
+            //      and can me directed to any page.
             String html = String.format(preloader,
                     "function go(){document.getElementById('submitform').submit(); }", // Javascript function
                     Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
diff --git src/com/liato/bankdroid/banking/banks/Chevrolet.java src/com/liato/bankdroid/banking/banks/Chevrolet.java
index 007cefe..1e8e165 100644
--- src/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ src/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/Djurgarden.java src/com/liato/bankdroid/banking/banks/Djurgarden.java
index 29df4b0..7a5c706 100644
--- src/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ src/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index cc5ab7f..515d1e1 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index d5ce051..6dacbc3 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
index 1c2ba64..7c518ef 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/Opel.java src/com/liato/bankdroid/banking/banks/Opel.java
index 26c163b..18365aa 100644
--- src/com/liato/bankdroid/banking/banks/Opel.java
+++ src/com/liato/bankdroid/banking/banks/Opel.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/Quintessentially.java src/com/liato/bankdroid/banking/banks/Quintessentially.java
index 5dfe6b9..4f0e6b6 100644
--- src/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ src/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
deleted file mode 100644
index 227b3bf..0000000
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public abstract class SEBKortBase extends Bank {
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-    private static final boolean STATIC_BALANCE = true;
-
-	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunit(?:last(?:disposable|credit)amount|2rowcol2)\">([^<]+)</(?:div|td)>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*(?:<div[^>]+>\\s*)?<span>([^<]*)</span>\\s*(?:</div>\\s*)?</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	private String provider_part;
-	private String prodgroup;
-	public SEBKortBase(Context context, String provider_part, String prodgroup) {
-		super(context);
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-		super.STATIC_BALANCE = STATIC_BALANCE;
-		this.provider_part = provider_part;
-		this.prodgroup = prodgroup;
-		super.URL = String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part);
-	}
-
-	public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException, BankChoiceException {
-		this(context, url, prodgroup);
-		this.update(username, password);
-	}
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sebkort));
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        response = urlopen.open(String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
-        urlopen.addHeader("Referer", String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
-        response = urlopen.open(String.format("https://application.sebkort.com/nis/external/hidden.jsp?USERNAME=%s&CURRENT_METHOD=&referer=login.jsp", prodgroup+username.toUpperCase()));
-        urlopen.removeHeader("Referer");
-        
-        postData.clear();
-        postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
-        postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
-        postData.add(new BasicNameValuePair("target", String.format("/nis/%s/main.do", provider_part)));
-        postData.add(new BasicNameValuePair("prodgroup", prodgroup));
-        postData.add(new BasicNameValuePair("UID", prodgroup+username.toUpperCase()));
-        postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
-        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
-        postData.add(new BasicNameValuePair("PASSWORD", password));
-        
-        return new LoginPackage(urlopen, postData, response, "https://application.sebkort.com/auth4/Authentication/select.jsp");
-    }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("elaktig kombination") || response.contains("ett felaktigt") || response.contains("invalid login")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-            e.printStackTrace();
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		Matcher matcher;
-		try {
-			if (!String.format("https://application.sebkort.com/nis/%s/main.do", provider_part).equals(urlopen.getCurrentURI())) {
-				response = urlopen.open(String.format("https://application.sebkort.com/nis/%s/main.do", provider_part));
-			}
-			matcher = reAccounts.matcher(response);
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: amount            10 579,43
-             * 
-             */
-			if (matcher.find()) {
-			    Account account = new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3");
-			    account.setType(Account.OTHER);
-                account.setAliasfor("1");
-			    accounts.add(account);
-			}
-            if (matcher.find()) {
-                Account account = new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2");
-                account.setType(Account.OTHER);
-                account.setAliasfor("1");
-                accounts.add(account);
-            }
-            if (matcher.find()) {
-                Account account = new Account("Disponibelt belopp" , Helpers.parseBalance(matcher.group(1)), "1");
-                account.setType(Account.CCARD);
-                accounts.add(account);
-                balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-            }
-            Collections.reverse(accounts);
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-        finally {
-            super.updateComplete();
-        }
-	}
-	
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		if (account.getType() != Account.CCARD) return;
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open(String.format("https://application.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				/*
-				 * Capture groups:
-				 * GROUP				EXAMPLE DATA
-				 * 1: Trans. date		10-18
-				 * 2: Book. date		10-19
-				 * 3: Specification		ICA Kvantum
-				 * 4: Location			Stockholm
-				 * 5: Currency			currency code (e.g. EUR) for transactions in non-SEK
-				 * 6: Amount			local currency amount (in $currency) for transactions in non-SEK
-				 * 7: Amount in sek		5791,18
-				 * 
-				 */
-			    String[] monthday = matcher.group(1).trim().split("-");
-				transactions.add(new Transaction(Helpers.getTransactionDate(monthday[0], monthday[1]),
-				        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""),
-				        Helpers.parseBalance(matcher.group(7)).negate()));
-	            Collections.sort(transactions, Collections.reverseOrder());
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}	
-}
diff --git src/com/liato/bankdroid/banking/banks/SJPrio.java src/com/liato/bankdroid/banking/banks/SJPrio.java
index 6d0409a..fadfbf9 100644
--- src/com/liato/bankdroid/banking/banks/SJPrio.java
+++ src/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/Saab.java src/com/liato/bankdroid/banking/banks/Saab.java
index de3a07b..8de2dda 100644
--- src/com/liato/bankdroid/banking/banks/Saab.java
+++ src/com/liato/bankdroid/banking/banks/Saab.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
index 5cc55fc..c2c1064 100644
--- src/com/liato/bankdroid/banking/banks/Statoil.java
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -17,6 +17,7 @@ package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
 
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/Wallet.java src/com/liato/bankdroid/banking/banks/Wallet.java
index 22d9293..e73684f 100644
--- src/com/liato/bankdroid/banking/banks/Wallet.java
+++ src/com/liato/bankdroid/banking/banks/Wallet.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.sebkort.SEBKortBase;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index c9eceac..bb29a3d 100644
--- src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -58,9 +58,6 @@ public class Bitcoin extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 		super.STATIC_BALANCE = STATIC_BALANCE;
 		super.currency = "BTC";
 		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
@@ -89,7 +86,7 @@ public class Bitcoin extends Bank {
 			accounts.add(a);
 			setCurrency("BTC");
 		} catch (JsonParseException e) {
-			throw new LoginException(res.getText(
+			throw new BankException(res.getText(
 					R.string.invalid_bitcoin_address).toString());
 		}catch (ClientProtocolException e) {
 			e.printStackTrace();
diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index a5de3ea..324077f 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -126,14 +126,13 @@ public class ICABanken extends Bank {
 			throw new BankException(res.getText(R.string.no_accounts_found)
 					.toString());
 		}
+        super.updateComplete();
 
 	}
 
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen)
 			throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		super.updateComplete();
 	}
 
 	private void addAccounts(IcaBankenAccountList pAccountList) {
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 1e10ea3..45f0579 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -136,7 +136,7 @@ public class Lansforsakringar extends Bank {
         urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
         urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
         //TODO: Change user-agent to "lf-android-app" if they block Bankdroid
-        urlopen.setUserAgent(Helpers.getAppUserAgentString(getContext()));
+        //urlopen.setUserAgent("lf-android-app");
 
         NumberResponse nr = readJsonValue(API_BASEURL + "security/client", null, NumberResponse.class);
         ChallengeResponse cr = readJsonValue(API_BASEURL + "security/client", objectAsJson(new ChallengeRequest(nr.getNumber(), nr.getNumberPair(), generateChallenge(nr.getNumber()))), ChallengeResponse.class);
diff --git src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
new file mode 100644
index 0000000..837ff3f
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/SEBKortBase.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.sebkort;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.text.TextUtils;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.sebkort.model.BillingUnit;
+import com.liato.bankdroid.banking.banks.sebkort.model.CardGroup;
+import com.liato.bankdroid.banking.banks.sebkort.model.TransactionGroup;
+import com.liato.bankdroid.banking.banks.sebkort.model.response.BillingUnitsResponse;
+import com.liato.bankdroid.banking.banks.sebkort.model.response.LoginResponse;
+import com.liato.bankdroid.banking.banks.sebkort.model.response.PendingTransactionsResponse;
+import com.liato.bankdroid.banking.banks.sebkort.model.response.UserResponse;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public abstract class SEBKortBase extends Bank {
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final boolean STATIC_BALANCE = true;
+    ObjectMapper mObjectMapper = new ObjectMapper();
+    private String response = null;
+    private String provider_part;
+    private String prodgroup;
+    private BasicNameValuePair mParamsTarget;
+    private BasicNameValuePair mParamsErrorTarget;
+    private Map<Account, String> mBillingUnitIds = new HashMap<Account, String>();
+
+    public SEBKortBase(Context context, String provider_part, String prodgroup) {
+        super(context);
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+        this.provider_part = provider_part;
+        this.prodgroup = prodgroup;
+        super.URL = String.format("https://secure.sebkort.com/nis/m/%s/external/t/login/index", provider_part);
+        mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
+        mParamsTarget = new BasicNameValuePair("target", URL);
+        mParamsErrorTarget = new BasicNameValuePair("errorTarget", URL);
+    }
+
+    public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException, BankChoiceException {
+        this(context, url, prodgroup);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sebkort));
+        //Get required cookies
+        response = urlopen.open(String.format("https://secure.sebkort.com/nis/m/%s/external/t/login/index", provider_part));
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.clear();
+        postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
+        postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
+        postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
+        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
+        postData.add(new BasicNameValuePair("UID", prodgroup + username.toUpperCase()));
+        postData.add(new BasicNameValuePair("PASSWORD", password));
+        postData.add(new BasicNameValuePair("prodgroup", prodgroup));
+        postData.add(mParamsTarget);
+        postData.add(mParamsErrorTarget);
+        return new LoginPackage(urlopen, postData, response, "https://secure.sebkort.com/auth4/Authentication/select.jsp");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            urlopen.addHeader("Origin", "https://secure.sebkort.com");
+            urlopen.addHeader("Referer", String.format("https://secure.sebkort.com/nis/m/%s/external/t/login/index", provider_part));
+            urlopen.addHeader("X-Requested-With", "XMLHttpRequest");
+            List<NameValuePair> postData = lp.getPostData();
+            postData.remove(mParamsTarget);
+            postData.remove(mParamsErrorTarget);
+            postData.add(new BasicNameValuePair("target", String.format("/nis/m/%s/login/loginSuccess", provider_part)));
+            postData.add(new BasicNameValuePair("errorTarget", String.format("/nis/m/%s/external/login/loginError", provider_part)));
+
+            LoginResponse r = mObjectMapper.readValue(urlopen.openStream(lp.getLoginTarget(), postData, true),
+                    LoginResponse.class);
+            if ("Failure".equalsIgnoreCase(r.getReturnCode())) {
+                throw new LoginException(!TextUtils.isEmpty(r.getMessage()) ? Html.fromHtml(r.getMessage()).toString() : res.getText(R.string.invalid_username_password).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            UserResponse ur = mObjectMapper.readValue(urlopen.openStream(String.format("https://secure.sebkort.com/nis/m/%s/a/user", provider_part)), UserResponse.class);
+            BillingUnitsResponse br = mObjectMapper.readValue(urlopen.openStream(String.format("https://secure.sebkort.com/nis/m/%s/a/billingUnits", provider_part)), BillingUnitsResponse.class);
+
+            //TODO: Handle multiple cards?
+            BillingUnit bu = br.getBody().get(0);
+
+            Account account = new Account("Disponibelt belopp", Helpers.parseBalance(bu.getDisposableAmount()), bu.getArrangementNumber());
+            account.setType(Account.CCARD);
+            mBillingUnitIds.put(account, bu.getBillingUnitId());
+            accounts.add(account);
+            balance = balance.add(account.getBalance());
+            account = new Account("Saldo", Helpers.parseBalance(bu.getBalance()), bu.getArrangementNumber() + "_2");
+            account.setType(Account.OTHER);
+            account.setAliasfor(bu.getArrangementNumber());
+            accounts.add(account);
+            account = new Account("Köpgräns", Helpers.parseBalance(bu.getCreditAmountNumber()), bu.getArrangementNumber() + "_3");
+            account.setType(Account.OTHER);
+            account.setAliasfor(bu.getArrangementNumber());
+            accounts.add(account);
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        } finally {
+            super.updateComplete();
+        }
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        if (account.getType() != Account.CCARD) return;
+        try {
+            PendingTransactionsResponse r = mObjectMapper.readValue(urlopen.openStream(String.format("https://secure.sebkort.com/nis/m/%s/a/pendingTransactions/%s", provider_part, mBillingUnitIds.get(account))), PendingTransactionsResponse.class);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            for (CardGroup cg : r.getBody().getCardGroups()) {
+                for (TransactionGroup tg : cg.getTransactionGroups()) {
+                    for (com.liato.bankdroid.banking.banks.sebkort.model.Transaction t : tg.getTransactions()) {
+                        transactions.add(new Transaction(Helpers.formatDate(new Date(t.getOriginalAmountDateDate())), t.getDescription(), BigDecimal.valueOf(t.getAmountNumber()).negate()));
+                    }
+                }
+            }
+            //TODO: Sort?
+            //Collections.sort(transactions, Collections.reverseOrder());
+            account.setTransactions(transactions);
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java src/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
new file mode 100644
index 0000000..9ad2aa5
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/BillingUnit.java
@@ -0,0 +1,210 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+public class BillingUnit implements Serializable {
+    private static final long serialVersionUID = 335801680600207389L;
+    private String mUnInvoicedAmount;
+    private boolean mShowCreditAmount;
+    private String mArrangementId;
+    private ArrayList<Contract> mContracts = new ArrayList<Contract>();
+    private String mCutOffDate;
+    private String mInterestPercentage;
+    private String mCreditAmount;
+    private String mLatestPaymentDate;
+    private boolean mShowInvoices;
+    private String mCreditAmountNumber;
+    private String mBillingUnitName;
+    private String mBillingUnitId;
+    private String mDisposableAmount;
+    private String mBalance;
+    private boolean mFinanceServiceAllowed;
+    private String mLatestPaymentAmount;
+    private String mArrangementNumber;
+    private String mNextInvoiceDate;
+
+    @JsonProperty("unInvoicedAmount")
+    public String getUnInvoicedAmount() {
+        return mUnInvoicedAmount;
+    }
+
+    @JsonSetter("unInvoicedAmount")
+    public void setUnInvoicedAmount(String u) {
+        mUnInvoicedAmount = u;
+    }
+
+    @JsonProperty("showCreditAmount")
+    public boolean getShowCreditAmount() {
+        return mShowCreditAmount;
+    }
+
+    @JsonSetter("showCreditAmount")
+    public void setShowCreditAmount(boolean s) {
+        mShowCreditAmount = s;
+    }
+
+    @JsonProperty("arrangementId")
+    public String getArrangementId() {
+        return mArrangementId;
+    }
+
+    @JsonSetter("arrangementId")
+    public void setArrangementId(String a) {
+        mArrangementId = a;
+    }
+
+    @JsonProperty("contracts")
+    public ArrayList<Contract> getContracts() {
+        return mContracts;
+    }
+
+    @JsonSetter("contracts")
+    public void setContracts(ArrayList<Contract> c) {
+        mContracts = c;
+    }
+
+    @JsonProperty("cutOffDate")
+    public String getCutOffDate() {
+        return mCutOffDate;
+    }
+
+    @JsonSetter("cutOffDate")
+    public void setCutOffDate(String c) {
+        mCutOffDate = c;
+    }
+
+    @JsonProperty("interestPercentage")
+    public String getInterestPercentage() {
+        return mInterestPercentage;
+    }
+
+    @JsonSetter("interestPercentage")
+    public void setInterestPercentage(String i) {
+        mInterestPercentage = i;
+    }
+
+    @JsonProperty("creditAmount")
+    public String getCreditAmount() {
+        return mCreditAmount;
+    }
+
+    @JsonSetter("creditAmount")
+    public void setCreditAmount(String c) {
+        mCreditAmount = c;
+    }
+
+    @JsonProperty("latestPaymentDate")
+    public String getLatestPaymentDate() {
+        return mLatestPaymentDate;
+    }
+
+    @JsonSetter("latestPaymentDate")
+    public void setLatestPaymentDate(String l) {
+        mLatestPaymentDate = l;
+    }
+
+    @JsonProperty("showInvoices")
+    public boolean getShowInvoices() {
+        return mShowInvoices;
+    }
+
+    @JsonSetter("showInvoices")
+    public void setShowInvoices(boolean s) {
+        mShowInvoices = s;
+    }
+
+    @JsonProperty("creditAmountNumber")
+    public String getCreditAmountNumber() {
+        return mCreditAmountNumber;
+    }
+
+    @JsonSetter("creditAmountNumber")
+    public void setCreditAmountNumber(String c) {
+        mCreditAmountNumber = c;
+    }
+
+    @JsonProperty("billingUnitName")
+    public String getBillingUnitName() {
+        return mBillingUnitName;
+    }
+
+    @JsonSetter("billingUnitName")
+    public void setBillingUnitName(String b) {
+        mBillingUnitName = b;
+    }
+
+    @JsonProperty("billingUnitId")
+    public String getBillingUnitId() {
+        return mBillingUnitId;
+    }
+
+    @JsonSetter("billingUnitId")
+    public void setBillingUnitId(String b) {
+        mBillingUnitId = b;
+    }
+
+    @JsonProperty("disposableAmount")
+    public String getDisposableAmount() {
+        return mDisposableAmount;
+    }
+
+    @JsonSetter("disposableAmount")
+    public void setDisposableAmount(String d) {
+        mDisposableAmount = d;
+    }
+
+    @JsonProperty("balance")
+    public String getBalance() {
+        return mBalance;
+    }
+
+    @JsonSetter("balance")
+    public void setBalance(String b) {
+        mBalance = b;
+    }
+
+    @JsonProperty("financeServiceAllowed")
+    public boolean getFinanceServiceAllowed() {
+        return mFinanceServiceAllowed;
+    }
+
+    @JsonSetter("financeServiceAllowed")
+    public void setFinanceServiceAllowed(boolean f) {
+        mFinanceServiceAllowed = f;
+    }
+
+    @JsonProperty("latestPaymentAmount")
+    public String getLatestPaymentAmount() {
+        return mLatestPaymentAmount;
+    }
+
+    @JsonSetter("latestPaymentAmount")
+    public void setLatestPaymentAmount(String l) {
+        mLatestPaymentAmount = l;
+    }
+
+    @JsonProperty("arrangementNumber")
+    public String getArrangementNumber() {
+        return mArrangementNumber;
+    }
+
+    @JsonSetter("arrangementNumber")
+    public void setArrangementNumber(String a) {
+        mArrangementNumber = a;
+    }
+
+    @JsonProperty("nextInvoiceDate")
+    public String getNextInvoiceDate() {
+        return mNextInvoiceDate;
+    }
+
+    @JsonSetter("nextInvoiceDate")
+    public void setNextInvoiceDate(String n) {
+        mNextInvoiceDate = n;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java src/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
new file mode 100644
index 0000000..bdb0a1d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/CardGroup.java
@@ -0,0 +1,69 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CardGroup implements Serializable {
+    private static final long serialVersionUID = 4603347903479018508L;
+
+    private List<TransactionGroup> mTransactionGroups = new ArrayList<TransactionGroup>();
+    private double mTotalNumber;
+    private String mTotal;
+    private String mMaskedCardNumber;
+    private String mNameOnCard;
+
+    @JsonProperty("transactionGroups")
+    public List<TransactionGroup> getTransactionGroups() {
+        return mTransactionGroups;
+    }
+
+    @JsonSetter("transactionGroups")
+    public void setTransactionGroups(List<TransactionGroup> t) {
+        mTransactionGroups = t;
+    }
+
+    @JsonProperty("totalNumber")
+    public double getTotalNumber() {
+        return mTotalNumber;
+    }
+
+    @JsonSetter("totalNumber")
+    public void setTotalNumber(double t) {
+        mTotalNumber = t;
+    }
+
+    @JsonProperty("total")
+    public String getTotal() {
+        return mTotal;
+    }
+
+    @JsonSetter("total")
+    public void setTotal(String t) {
+        mTotal = t;
+    }
+
+    @JsonProperty("maskedCardNumber")
+    public String getMaskedCardNumber() {
+        return mMaskedCardNumber;
+    }
+
+    @JsonSetter("maskedCardNumber")
+    public void setMaskedCardNumber(String m) {
+        mMaskedCardNumber = m;
+    }
+
+    @JsonProperty("nameOnCard")
+    public String getNameOnCard() {
+        return mNameOnCard;
+    }
+
+    @JsonSetter("nameOnCard")
+    public void setNameOnCard(String n) {
+        mNameOnCard = n;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java src/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
new file mode 100644
index 0000000..31658ce
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/Contract.java
@@ -0,0 +1,55 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+
+public class Contract implements Serializable {
+    private static final long serialVersionUID = 9210413430068677151L;
+    private String mUnInvoicedAmount;
+    private String mContractName;
+    private String mCreditAmount;
+    private String mContractId;
+
+    @JsonProperty("unInvoicedAmount")
+    public String getUnInvoicedAmount() {
+        return mUnInvoicedAmount;
+    }
+
+    @JsonSetter("unInvoicedAmount")
+    public void setUnInvoicedAmount(String u) {
+        mUnInvoicedAmount = u;
+    }
+
+    @JsonProperty("contractName")
+    public String getContractName() {
+        return mContractName;
+    }
+
+    @JsonSetter("contractName")
+    public void setContractName(String c) {
+        mContractName = c;
+    }
+
+    @JsonProperty("creditAmount")
+    public String getCreditAmount() {
+        return mCreditAmount;
+    }
+
+    @JsonSetter("creditAmount")
+    public void setCreditAmount(String c) {
+        mCreditAmount = c;
+    }
+
+    @JsonProperty("contractId")
+    public String getContractId() {
+        return mContractId;
+    }
+
+    @JsonSetter("contractId")
+    public void setContractId(String c) {
+        mContractId = c;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java src/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
new file mode 100644
index 0000000..04c031c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/PendingTransactions.java
@@ -0,0 +1,101 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PendingTransactions implements Serializable {
+    private static final long serialVersionUID = 8675073239578979403L;
+    private double mTotalNumber;
+    private boolean mMoreDataExists;
+    private List<CardGroup> mCobrandCardGroups = new ArrayList<CardGroup>();
+    private String mReservedAmount;
+    private String mReservedAmountNumber;
+    private List<CardGroup> mCardGroups = new ArrayList<CardGroup>();
+    private List<TransactionGroup> mTransactionGroups = new ArrayList<TransactionGroup>();
+    private String mTotal;
+
+    @JsonProperty("totalNumber")
+    public double getTotalNumber() {
+        return mTotalNumber;
+    }
+
+    @JsonSetter("totalNumber")
+    public void setTotalNumber(double t) {
+        mTotalNumber = t;
+    }
+
+    @JsonProperty("moreDataExists")
+    public boolean getMoreDataExists() {
+        return mMoreDataExists;
+    }
+
+    @JsonSetter("moreDataExists")
+    public void setMoreDataExists(boolean m) {
+        mMoreDataExists = m;
+    }
+
+    @JsonProperty("cobrandCardGroups")
+    public List<CardGroup> getCobrandCardGroups() {
+        return mCobrandCardGroups;
+    }
+
+    @JsonSetter("cobrandCardGroups")
+    public void setCobrandCardGroups(List<CardGroup> c) {
+        mCobrandCardGroups = c;
+    }
+
+    @JsonProperty("reservedAmount")
+    public String getReservedAmount() {
+        return mReservedAmount;
+    }
+
+    @JsonSetter("reservedAmount")
+    public void setReservedAmount(String r) {
+        mReservedAmount = r;
+    }
+
+    @JsonProperty("reservedAmountNumber")
+    public String getReservedAmountNumber() {
+        return mReservedAmountNumber;
+    }
+
+    @JsonSetter("reservedAmountNumber")
+    public void setReservedAmountNumber(String r) {
+        mReservedAmountNumber = r;
+    }
+
+    @JsonProperty("cardGroups")
+    public List<CardGroup> getCardGroups() {
+        return mCardGroups;
+    }
+
+    @JsonSetter("cardGroups")
+    public void setCardGroups(List<CardGroup> c) {
+        mCardGroups = c;
+    }
+
+    @JsonProperty("transactionGroups")
+    public List<TransactionGroup> getTransactionGroups() {
+        return mTransactionGroups;
+    }
+
+    @JsonSetter("transactionGroups")
+    public void setTransactionGroups(List<TransactionGroup> t) {
+        mTransactionGroups = t;
+    }
+
+    @JsonProperty("total")
+    public String getTotal() {
+        return mTotal;
+    }
+
+    @JsonSetter("total")
+    public void setTotal(String t) {
+        mTotal = t;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java src/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
new file mode 100644
index 0000000..7e89bf5
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/Transaction.java
@@ -0,0 +1,166 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+
+public class Transaction implements Serializable {
+    private static final long serialVersionUID = 2810644466680342679L;
+
+    private String mCity;
+    private String mRefTransactionId;
+    private String mDescription;
+    private String mExchangeRateDescription;
+    private String mOriginalAmountDate;
+    private String mOriginalAmountOrVat;
+    private String mPostingDate;
+    private long mPostingDateDate;
+    private String mCurrency;
+    private String mAmount;
+    private double mAmountNumber;
+    private long mTransactionId;
+    private String mOriginalAmountOrVatNumber;
+    private long mOriginalAmountDateDate;
+
+    @JsonProperty("city")
+    public String getCity() {
+        return mCity;
+    }
+
+    @JsonSetter("city")
+    public void setCity(String c) {
+        mCity = c;
+    }
+
+    @JsonProperty("refTransactionId")
+    public String getRefTransactionId() {
+        return mRefTransactionId;
+    }
+
+    @JsonSetter("refTransactionId")
+    public void setRefTransactionId(String r) {
+        mRefTransactionId = r;
+    }
+
+    @JsonProperty("description")
+    public String getDescription() {
+        return mDescription;
+    }
+
+    @JsonSetter("description")
+    public void setDescription(String d) {
+        mDescription = d;
+    }
+
+    @JsonProperty("exchangeRateDescription")
+    public String getExchangeRateDescription() {
+        return mExchangeRateDescription;
+    }
+
+    @JsonSetter("exchangeRateDescription")
+    public void setExchangeRateDescription(String e) {
+        mExchangeRateDescription = e;
+    }
+
+    @JsonProperty("originalAmountDate")
+    public String getOriginalAmountDate() {
+        return mOriginalAmountDate;
+    }
+
+    @JsonSetter("originalAmountDate")
+    public void setOriginalAmountDate(String o) {
+        mOriginalAmountDate = o;
+    }
+
+    @JsonProperty("originalAmountOrVat")
+    public String getOriginalAmountOrVat() {
+        return mOriginalAmountOrVat;
+    }
+
+    @JsonSetter("originalAmountOrVat")
+    public void setOriginalAmountOrVat(String o) {
+        mOriginalAmountOrVat = o;
+    }
+
+    @JsonProperty("postingDate")
+    public String getPostingDate() {
+        return mPostingDate;
+    }
+
+    @JsonSetter("postingDate")
+    public void setPostingDate(String p) {
+        mPostingDate = p;
+    }
+
+    @JsonProperty("postingDateDate")
+    public long getPostingDateDate() {
+        return mPostingDateDate;
+    }
+
+    @JsonSetter("postingDateDate")
+    public void setPostingDateDate(long p) {
+        mPostingDateDate = p;
+    }
+
+    @JsonProperty("currency")
+    public String getCurrency() {
+        return mCurrency;
+    }
+
+    @JsonSetter("currency")
+    public void setCurrency(String c) {
+        mCurrency = c;
+    }
+
+    @JsonProperty("amount")
+    public String getAmount() {
+        return mAmount;
+    }
+
+    @JsonSetter("amount")
+    public void setAmount(String a) {
+        mAmount = a;
+    }
+
+    @JsonProperty("amountNumber")
+    public double getAmountNumber() {
+        return mAmountNumber;
+    }
+
+    @JsonSetter("amountNumber")
+    public void setAmountNumber(double a) {
+        mAmountNumber = a;
+    }
+
+    @JsonProperty("transactionId")
+    public long getTransactionId() {
+        return mTransactionId;
+    }
+
+    @JsonSetter("transactionId")
+    public void setTransactionId(long t) {
+        mTransactionId = t;
+    }
+
+    @JsonProperty("originalAmountOrVatNumber")
+    public String getOriginalAmountOrVatNumber() {
+        return mOriginalAmountOrVatNumber;
+    }
+
+    @JsonSetter("originalAmountOrVatNumber")
+    public void setOriginalAmountOrVatNumber(String o) {
+        mOriginalAmountOrVatNumber = o;
+    }
+
+    @JsonProperty("originalAmountDateDate")
+    public long getOriginalAmountDateDate() {
+        return mOriginalAmountDateDate;
+    }
+
+    @JsonSetter("originalAmountDateDate")
+    public void setOriginalAmountDateDate(long o) {
+        mOriginalAmountDateDate = o;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java src/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
new file mode 100644
index 0000000..a22f47e
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/TransactionGroup.java
@@ -0,0 +1,68 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TransactionGroup implements Serializable {
+    private static final long serialVersionUID = 5011424262690542196L;
+    private String mTotal;
+    private String mType;
+    private double mTotalNumber;
+    private List<Transaction> mTransactions = new ArrayList<Transaction>();
+    private String mTitle;
+
+    @JsonProperty("total")
+    public String getTotal() {
+        return mTotal;
+    }
+
+    @JsonSetter("total")
+    public void setTotal(String t) {
+        mTotal = t;
+    }
+
+    @JsonProperty("type")
+    public String getType() {
+        return mType;
+    }
+
+    @JsonSetter("type")
+    public void setType(String t) {
+        mType = t;
+    }
+
+    @JsonProperty("totalNumber")
+    public double getTotalNumber() {
+        return mTotalNumber;
+    }
+
+    @JsonSetter("totalNumber")
+    public void setTotalNumber(double t) {
+        mTotalNumber = t;
+    }
+
+    @JsonProperty("transactions")
+    public List<Transaction> getTransactions() {
+        return mTransactions;
+    }
+
+    @JsonSetter("transactions")
+    public void setTransactions(List<Transaction> t) {
+        mTransactions = t;
+    }
+
+    @JsonProperty("title")
+    public String getTitle() {
+        return mTitle;
+    }
+
+    @JsonSetter("title")
+    public void setTitle(String t) {
+        mTitle = t;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/User.java src/com/liato/bankdroid/banking/banks/sebkort/model/User.java
new file mode 100644
index 0000000..969fe4c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/User.java
@@ -0,0 +1,112 @@
+package com.liato.bankdroid.banking.banks.sebkort.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+
+public class User implements Serializable {
+    private static final long serialVersionUID = -6588506336066035322L;
+
+    private String mSurName;
+    private String mFirstName;
+    private boolean mPasswordAuthentication;
+    private boolean mCoBrowse;
+    private int mAuthenticationTypeId;
+    private String mPhone;
+    private boolean mHsu;
+    private String mEmail;
+    private boolean mOtpAuthentication;
+
+
+    @JsonSetter("surName")
+    public void setSurName(String s) {
+        mSurName = s;
+    }
+
+    @JsonProperty("surName")
+    public String getSurName() {
+        return mSurName;
+    }
+
+    @JsonSetter("firstName")
+    public void setFirstName(String f) {
+        mFirstName = f;
+    }
+
+    @JsonProperty("firstName")
+    public String getFirstName() {
+        return mFirstName;
+    }
+
+    @JsonSetter("passwordAuthentication")
+    public void setPasswordAuthentication(boolean p) {
+        mPasswordAuthentication = p;
+    }
+
+    @JsonProperty("passwordAuthentication")
+    public boolean getPasswordAuthentication() {
+        return mPasswordAuthentication;
+    }
+
+    @JsonSetter("coBrowse")
+    public void setCoBrowse(boolean c) {
+        mCoBrowse = c;
+    }
+
+    @JsonProperty("coBrowse")
+    public boolean getCoBrowse() {
+        return mCoBrowse;
+    }
+
+    @JsonSetter("authenticationTypeId")
+    public void setAuthenticationTypeId(int a) {
+        mAuthenticationTypeId = a;
+    }
+
+    @JsonProperty("authenticationTypeId")
+    public int getAuthenticationTypeId() {
+        return mAuthenticationTypeId;
+    }
+
+    @JsonSetter("phone")
+    public void setPhone(String p) {
+        mPhone = p;
+    }
+
+    @JsonProperty("phone")
+    public String getPhone() {
+        return mPhone;
+    }
+
+    @JsonSetter("hsu")
+    public void setHsu(boolean h) {
+        mHsu = h;
+    }
+
+    @JsonProperty("hsu")
+    public boolean getHsu() {
+        return mHsu;
+    }
+
+    @JsonSetter("email")
+    public void setEmail(String e) {
+        mEmail = e;
+    }
+
+    @JsonProperty("email")
+    public String getEmail() {
+        return mEmail;
+    }
+
+    @JsonSetter("otpAuthentication")
+    public void setOtpAuthentication(boolean o) {
+        mOtpAuthentication = o;
+    }
+
+    @JsonProperty("otpAuthentication")
+    public boolean getOtpAuthentication() {
+        return mOtpAuthentication;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java src/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
new file mode 100644
index 0000000..e6eb465
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/response/BaseResponse.java
@@ -0,0 +1,37 @@
+package com.liato.bankdroid.banking.banks.sebkort.model.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+import java.io.Serializable;
+
+public abstract class BaseResponse<T> implements Serializable {
+    private static final long serialVersionUID = 2771913870986291964L;
+
+    private String mErrorCode;
+    private String mMessage;
+    private String mReturnCode;
+    private T mBody;
+
+
+    @JsonSetter("errorCode")
+    public void setErrorCode(String e) { mErrorCode = e; }
+    @JsonProperty("errorCode")
+    public String getErrorCode() { return mErrorCode; }
+
+    @JsonSetter("body")
+    public void setBody(T b) { mBody = b; }
+    @JsonProperty("body")
+    public T getBody() { return mBody; }
+
+    @JsonSetter("message")
+    public void setMessage(String m) { mMessage = m; }
+    @JsonProperty("message")
+    public String getMessage() { return mMessage; }
+
+    @JsonSetter("returnCode")
+    public void setReturnCode(String r) { mReturnCode = r; }
+    @JsonProperty("returnCode")
+    public String getReturnCode() { return mReturnCode; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java src/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
new file mode 100644
index 0000000..a09b7a3
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/response/BillingUnitsResponse.java
@@ -0,0 +1,9 @@
+package com.liato.bankdroid.banking.banks.sebkort.model.response;
+
+import com.liato.bankdroid.banking.banks.sebkort.model.BillingUnit;
+
+import java.util.ArrayList;
+
+public class BillingUnitsResponse extends BaseResponse<ArrayList<BillingUnit>> {
+    private static final long serialVersionUID = 2004033024178420458L;
+}
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java src/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
new file mode 100644
index 0000000..2759db9
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/response/LoginResponse.java
@@ -0,0 +1,5 @@
+package com.liato.bankdroid.banking.banks.sebkort.model.response;
+
+public class LoginResponse extends BaseResponse<Object> {
+    private static final long serialVersionUID = -5831397352860729105L;
+}
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java src/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
new file mode 100644
index 0000000..93df752
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/response/PendingTransactionsResponse.java
@@ -0,0 +1,7 @@
+package com.liato.bankdroid.banking.banks.sebkort.model.response;
+
+import com.liato.bankdroid.banking.banks.sebkort.model.PendingTransactions;
+
+public class PendingTransactionsResponse extends BaseResponse<PendingTransactions> {
+    private static final long serialVersionUID = 3753708966368822328L;
+}
diff --git src/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java src/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
new file mode 100644
index 0000000..6308f42
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/sebkort/model/response/UserResponse.java
@@ -0,0 +1,8 @@
+package com.liato.bankdroid.banking.banks.sebkort.model.response;
+
+import com.liato.bankdroid.banking.banks.sebkort.model.User;
+
+
+public class UserResponse extends BaseResponse<User> {
+    private static final long serialVersionUID = -7005608413740529742L;
+}
\ No newline at end of file
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index c98b484..dc85ee8 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -186,7 +186,7 @@ public class Urllib {
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         HttpUriRequest request;
-        if (postData == null && !forcePost) {
+        if (!forcePost) {
             request = new HttpGet(url);
         }
         else {

commit a91e78741500d60924c931998fb2375bf990af40
Author: liato <x@x00.us>
Date:   Wed Nov 27 23:31:53 2013 +0100

    Use bankdroid user agent.

diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 3c9a522..236c4af 100644
--- src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -73,7 +73,6 @@ public class Avanza extends Bank {
     public Urllib login() throws LoginException, BankException {
         urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
-        urlopen.setUserAgent("Avanza Bank 131 (iPhone; iPhone OS 6.1.4; sv_SE)");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
 
         try {
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 05244a2..c98b484 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -18,9 +18,14 @@ package eu.nullbyte.android.urllib;
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.os.Build;
 import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.BuildConfig;
+import com.liato.bankdroid.R;
 
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -65,7 +70,7 @@ import java.util.List;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
-    private String userAgent = DEFAULT_USER_AGENT;
+    private String userAgent = null;
     private DefaultHttpClient httpclient;
 	private HttpContext mHttpContext;
 	private String currentURI;
@@ -81,6 +86,7 @@ public class Urllib {
 	public Urllib(Context context, Certificate[] pins) {
         mContext = context;
 		this.headers = new HashMap<String, String>();
+        userAgent = createUserAgentString();
     	HttpParams params = new BasicHttpParams(); 
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, this.charset);
@@ -255,5 +261,31 @@ public class Urllib {
     public void setUserAgent(String userAgent) {
     	this.userAgent = userAgent; 
     }
+
+    private String createUserAgentString() {
+        String appName = mContext.getString(R.string.app_name);
+        String packageName = "";
+        String appVersion = "";
+
+        try {
+            PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS);
+            packageName = packageInfo.packageName;
+            appVersion = packageInfo.versionName;
+        } catch (PackageManager.NameNotFoundException ignore) {
+        }
+
+        Configuration config = mContext.getResources().getConfiguration();
+        return String.format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %10$s Build/%7$s; %8$s) %9$s %10$s"
+                , appName
+                , appVersion
+                , System.getProperty("os.name", "Linux")
+                , Build.VERSION.RELEASE
+                , config.locale.getLanguage().toLowerCase()
+                , config.locale.getCountry().toLowerCase()
+                , Build.ID
+                , Build.BRAND
+                , Build.MANUFACTURER
+                , Build.MODEL);
+    }
     
 }
\ No newline at end of file

commit ae6846348b98cfe029129de380f675a110cde6df
Author: liato <x@x00.us>
Date:   Wed Nov 27 22:59:30 2013 +0100

    Enable back key on lock screen.

diff --git build.gradle build.gradle
index 588a65e..021ea9f 100644
--- build.gradle
+++ build.gradle
@@ -3,7 +3,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.5.+'
+        classpath 'com.android.tools.build:gradle:0.6.+'
     }
 }
 apply plugin: 'android'
diff --git project.properties project.properties
index b98aa9c..fd44ee5 100644
--- project.properties
+++ project.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-18
+target=android-17
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 17517df..17f4654 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -216,7 +216,6 @@ public class LockableActivity extends Activity {
 
 	private void launchPatternLock() {
         Intent intent = new Intent(this, ConfirmLockPattern.class);
-        intent.putExtra(ConfirmLockPattern.DISABLE_BACK_KEY, true);
         intent.putExtra(ConfirmLockPattern.HEADER_TEXT, getText(R.string.patternlock_header));
         startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
 	}
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index ca9e34f..ee1e53c 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -92,7 +92,6 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 
 	private void launchPatternLock() {
         Intent intent = new Intent(this, ConfirmLockPattern.class);
-        intent.putExtra(ConfirmLockPattern.DISABLE_BACK_KEY, true);
         intent.putExtra(ConfirmLockPattern.HEADER_TEXT, getText(R.string.patternlock_header));
         startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
 	}
diff --git src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
index 1e9f3d5..a1f49ff 100644
--- src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
+++ src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
@@ -55,8 +55,7 @@ public class ConfirmLockPattern extends Activity {
     public static final String FOOTER_TEXT = "com.liato.bankdroid.footer";
     public static final String HEADER_WRONG_TEXT = "com.liato.bankdroid.header_wrong";
     public static final String FOOTER_WRONG_TEXT = "com.liato.bankdroid.footer_wrong";
-    public static final String DISABLE_BACK_KEY = "com.liato.bankdroid.ConfirmLockPattern.disable_back_key";
-    
+
     // how long we wait to clear a wrong pattern
     private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
 
@@ -75,7 +74,6 @@ public class ConfirmLockPattern extends Activity {
     private CharSequence mFooterText;
     private CharSequence mHeaderWrongText;
     private CharSequence mFooterWrongText;
-    private boolean mDisableBackButton = false;
 
 
     private enum Stage {
@@ -110,7 +108,6 @@ public class ConfirmLockPattern extends Activity {
             mFooterText = intent.getCharSequenceExtra(FOOTER_TEXT);
             mHeaderWrongText = intent.getCharSequenceExtra(HEADER_WRONG_TEXT);
             mFooterWrongText = intent.getCharSequenceExtra(FOOTER_WRONG_TEXT);
-            mDisableBackButton = intent.getBooleanExtra(DISABLE_BACK_KEY, false);
         }
 
         mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
@@ -147,12 +144,16 @@ public class ConfirmLockPattern extends Activity {
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-      if (keyCode == KeyEvent.KEYCODE_BACK && this.mDisableBackButton) {
-          return true;
-      }
-      return super.onKeyDown(keyCode, event);
-    }    
-    
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+            homeIntent.addCategory(Intent.CATEGORY_HOME);
+            homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            startActivity(homeIntent);
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
     @Override
     protected void onResume() {
         super.onResume();

commit 22ebecd2072fab609e43f5dcb190e89f74444007
Author: liato <x@x00.us>
Date:   Wed Nov 27 22:38:34 2013 +0100

    Copy fix.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 765f089..4e93661 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -59,7 +59,7 @@
 	<string name="update_transaction_history_title">Uppdatera kontoutdrag</string>
 	<string name="update_transaction_history_summary">Uppdatera kontoutdrag vid automatiska uppdateringar</string>
 	<string name="number_of_notifications_title">Antal notifieringar</string>
-	<string name="number_of_notifications_summary">Antal notifieringa som visas samtidigt</string>
+	<string name="number_of_notifications_summary">Antal notifieringar som visas samtidigt</string>
 	<string name="appearance_title">Utseende</string>
 	<string name="widgets_title">Widgets</string>
 	<string name="round_widget_balance_title">Avrunda saldo på widgets</string>

commit c2db1b22af3fb7766e2a436334d8e8446d9cbf1e
Author: liato <x@x00.us>
Date:   Wed Nov 27 22:33:16 2013 +0100

    Copy fixes.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 1c6d2a9..765f089 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -69,16 +69,16 @@
 	<string name="notify_min_delta_title">Minsta förändring</string>
 	<string name="notify_min_delta_summary">Visa endast notifiering om saldoförändringar är minst så här stor</string>
 	<string name="widget_opens_transactions_title">Widget-klick öppnar kontoutdrag</string>
-	<string name="widget_opens_transactions_summary">Öppna kontoutdraget för kontot när du klickar på en widget.</string>
+	<string name="widget_opens_transactions_summary">Öppna kontoutdraget för kontot när du klickar på en widget</string>
 	<string name="widget_updates_transactions_title">Uppdatera kontoutdrag från widget</string>
-	<string name="widget_updates_transactions_summary">Uppdatering från widget uppdaterar både saldo och kontoutdrag.</string>
+	<string name="widget_updates_transactions_summary">Uppdatering från widget uppdaterar både saldo och kontoutdrag</string>
 	<string name="notifications_title">Notifieringar</string>
 	<string name="enable_notifications_title">Aktivera notifieringar</string>
 	<string name="enable_notifications_summary">Notifiera vid kontoförändringar</string>
 	<string name="vibrate_title">Vibrera</string>
 	<string name="vibrate_summary">Vibrera vid kontoförändringar</string>
 	<string name="led_title">Blinka LED:en</string>
-	<string name="led_summary">Blinka LED:en vid kontoförändringar. (Fungerar ej på alla enheter.)</string>
+	<string name="led_summary">Blinka LED:en vid kontoförändringar (fungerar ej på alla enheter)</string>
 	<string name="led_color_title">LED-färg</string>
    	<string name="notification_sound_title">Notifieringsljud</string>
 	<string name="notification_sound_summary">Välj ett notifieringsljud</string>
diff --git res/values/strings.xml res/values/strings.xml
index 363f0ab..8c9dd7d 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -71,16 +71,16 @@
 	<string name="notify_min_delta_title">Minimum change</string>
 	<string name="notify_min_delta_summary">Only display a notification if the change is at least this big</string>
 	<string name="widget_opens_transactions_title">Widget click opens transactions</string>
-	<string name="widget_opens_transactions_summary">Open the transactions screen when a widget is clicked. If unchecked the main screen is shown.</string>
-	<string name="widget_updates_transactions_title">Update transactions from widget.</string>
-	<string name="widget_updates_transactions_summary">Updates from widgets will update both the balance and the transaction history.</string>
+	<string name="widget_opens_transactions_summary">If unchecked the main screen is shown</string>
+	<string name="widget_updates_transactions_title">Update transactions from widget</string>
+	<string name="widget_updates_transactions_summary">Updates from widgets will update both the balance and the transaction history</string>
 	<string name="notifications_title">Notifications</string>
 	<string name="enable_notifications_title">Enable notifications</string>
 	<string name="enable_notifications_summary">Notify on account changes</string>
 	<string name="vibrate_title">Vibrate</string>
 	<string name="vibrate_summary">Vibrate on account changes</string>
 	<string name="led_title">Flash LED</string>
-	<string name="led_summary">Flash the LED on account changes. (Not supported by all devices.)</string>
+	<string name="led_summary">Flash the LED on account changes (not supported by all devices)</string>
 	<string name="led_color_title">LED color</string>
    	<string name="notification_sound_title">Notification sound</string>
 	<string name="notification_sound_summary">Select notification sound</string>

commit 56e4a308f2c38def0632e29a51ccf1d645738b10
Author: liato <x@x00.us>
Date:   Wed Nov 27 22:33:06 2013 +0100

    Update gradle wrapper.

diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
index 5c22dec..861eddc 100644
--- gradle/wrapper/gradle-wrapper.properties
+++ gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip

commit c48e60a24c15916b8c124956d68ed24afc462832
Author: liato <x@x00.us>
Date:   Mon Nov 4 00:01:56 2013 +0100

    Updated contributors and changelog.

diff --git CHANGES.txt CHANGES.txt
index 467f957..b0f97d0 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,11 @@
+v1.9.6.2: (2013-11-03)
+* Fix for Avanza (thanks to NanoRage)
+* Fix for Ikano Bank
+* Improved security of secure connection with certificate pinning
++ Support for Eurobonus Mastercard Denmark
++ Support for Bitcoin
+
+
 v1.9.6.1: (2013-09-30)
 * Fix for PayPal
 * Fix for Diners Club (thanks to ScuttleSE)
diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index f6d6e6a..0c910ab 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -31,6 +31,7 @@ Development
   Richard Ginzburg                  https://github.com/rickythefox
   ScuttleSE                         https://github.com/ScuttleSE
   Andreas Knifh                     https://github.com/knifhen
+  NanoRage                          https://github.com/NanoRage
 
 
   Stats at:

commit 53344629db0da8e2ada729c4ac492d8e4afe3cb5
Author: liato <x@x00.us>
Date:   Sun Nov 3 23:44:51 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 4ce5cbe..6cca12e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.2-RC4" android:versionCode="165">
+	android:versionName="1.9.6.2" android:versionCode="166">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 0811e8a..588a65e 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 165
-        versionName '1.9.6.2-RC4'
+        versionCode 166
+        versionName '1.9.6.2'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit e67b4ee1dc5e7cf8a72ecf47df83e6dda1a4eb19
Author: liato <x@x00.us>
Date:   Sun Nov 3 23:44:15 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 70d677d..4ce5cbe 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.2-RC1" android:versionCode="162">
+	android:versionName="1.9.6.2-RC4" android:versionCode="165">
     <uses-sdk
         android:targetSdkVersion="10"
         android:minSdkVersion="7" />
diff --git build.gradle build.gradle
index 7be06f1..0811e8a 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 164
-        versionName '1.9.6.2-RC3'
+        versionCode 165
+        versionName '1.9.6.2-RC4'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'

commit 12646e72419a8c537856a798291b02cc11a9013e
Author: liato <x@x00.us>
Date:   Sun Nov 3 17:05:16 2013 +0100

    Avanza fixes.

diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index 40971bc..3c9a522 100644
--- src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -22,10 +22,13 @@ import android.util.Base64;
 
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.banks.avanza.model.AccountOverview;
+import com.liato.bankdroid.banking.banks.avanza.model.Position;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -36,6 +39,9 @@ import org.apache.http.client.ClientProtocolException;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
 
 import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
@@ -79,10 +85,20 @@ public class Avanza extends Bank {
             ObjectMapper vObjectMapper = new ObjectMapper();
             AccountOverview r = vObjectMapper.readValue(httpResponse.getEntity().getContent(), AccountOverview.class);
             for (com.liato.bankdroid.banking.banks.avanza.model.Account account : r.getAccounts()) {
-                Account a = new Account(account.getAccountName(), new BigDecimal(account.getBalance()), account.getAccountId());
+                Account a = new Account(account.getAccountName(), new BigDecimal(account.getOwnCapital()), account.getAccountId());
                 if (!account.getCurrencyAccounts().isEmpty()) {
                     a.setCurrency(account.getCurrencyAccounts().get(0).getCurrency());
                 }
+                if (!account.getPositionAggregations().isEmpty() && !account.getPositionAggregations().get(0).getPositions().isEmpty()) {
+                    List<Position> positions = account.getPositionAggregations().get(0).getPositions();
+                    Date now = new Date();
+                    ArrayList<Transaction> transactions = new ArrayList<Transaction>(positions.size());
+                    for (Position p : positions) {
+                        Transaction t = new Transaction(Helpers.formatDate(now), p.getInstrumentName(), BigDecimal.valueOf(p.getProfit()), a.getCurrency());
+                        transactions.add(t);
+                    }
+                    a.setTransactions(transactions);
+                }
                 accounts.add(a);
             }
         } catch (JsonParseException e) {
@@ -102,9 +118,9 @@ public class Avanza extends Bank {
     public void update() throws BankException, LoginException,
             BankChoiceException {
         super.update();
-        if (TextUtils.isEmpty(username)) {
+        if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
             throw new LoginException(res.getText(
-                    R.string.invalid_bitcoin_address).toString());
+                    R.string.invalid_username_password).toString());
         }
         login();
         if (accounts.isEmpty()) {

commit b6954a56e965d07a0a524b44b6b8eb71eb0fe78d
Author: liato <x@x00.us>
Date:   Wed Oct 23 23:56:08 2013 +0200

    Debug setting to disable certificate pinning.

diff --git res/xml/settings.xml res/xml/settings.xml
index b85e57f..3be47d9 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -252,12 +252,18 @@
 					android:title="Update freq. in sec."
 					android:summary="Update frequenzy is given in seconds instead of minutes"
 					android:dependency="debug_mode" />
-				<CheckBoxPreference
-					android:key="debug_only_testbank"
-					android:defaultValue="false"
-					android:title="Testbank only"
-					android:summary="Only auto update 'Testbank' banks"
-					android:dependency="debug_mode" />
+                <CheckBoxPreference
+                    android:key="debug_only_testbank"
+                    android:defaultValue="false"
+                    android:title="Testbank only"
+                    android:summary="Only auto update 'Testbank' banks"
+                    android:dependency="debug_mode" />
+                <CheckBoxPreference
+                    android:key="no_cert_pinning"
+                    android:defaultValue="false"
+                    android:title="Don't use certificate pinning"
+                    android:summary="Use the system trust store"
+                    android:dependency="debug_mode" />
 				<!-- <CheckBoxPreference
 					android:key="debug_coop_sendmail"
 					android:defaultValue="false"
diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 7317118..d48956f 100644
--- src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -66,7 +66,7 @@ public abstract class AbsIkanoPartner extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("__VIEWSTATE");
diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 383cb1c..2326e01 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -86,7 +86,7 @@ public class AkeliusInvest extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_akeliusinvest));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_akeliusinvest));
         String response = urlopen.open("https://online.akeliusinvest.com/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 902d942..f51b6cf 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -87,7 +87,7 @@ public class AkeliusSpar extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_akeliusspar));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_akeliusspar));
         String response = urlopen.open("https://www.online.akeliusspar.se/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 15e30e5..071d28f 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -77,7 +77,7 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_americanexpress));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_americanexpress));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
diff --git src/com/liato/bankdroid/banking/banks/AppeakPoker.java src/com/liato/bankdroid/banking/banks/AppeakPoker.java
index 9618350..71a62b6 100644
--- src/com/liato/bankdroid/banking/banks/AppeakPoker.java
+++ src/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -70,7 +70,7 @@ public class AppeakPoker extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-		urlopen = new Urllib();
+		urlopen = new Urllib(context);
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
 		return new LoginPackage(urlopen, postData, "", String.format("http://poker.appeak.se/playerInfo/?username=%s", username));
 	}
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 4ae94ae..c5543be 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -70,7 +70,7 @@ public class AvanzaMini extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.setAllowCircularRedirects(true);
         String response = urlopen.open("https://www.avanza.se/mini/logga_in/");
         Document d = Jsoup.parse(response);
diff --git src/com/liato/bankdroid/banking/banks/BetterGlobe.java src/com/liato/bankdroid/banking/banks/BetterGlobe.java
index b411853..b053557 100644
--- src/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ src/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -83,7 +83,7 @@ public class BetterGlobe extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(context);
         urlopen.setAllowCircularRedirects(true);
 		HashMap<String, String> headers = urlopen.getHeaders();
 		headers.put("Referer","http://betterglobe.com/login.aspx?lang=sv-SE");
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
index 74a1fee..3b06c3e 100644
--- src/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -72,7 +72,7 @@ public class Bioklubben extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_bioklubben));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_bioklubben));
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("name", username));
diff --git src/com/liato/bankdroid/banking/banks/BrummerKF.java src/com/liato/bankdroid/banking/banks/BrummerKF.java
index bccdf23..87862aa 100644
--- src/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ src/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -84,7 +84,7 @@ public class BrummerKF extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_brummer));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_brummer));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.brummer.se/sv/online/privat/Login/");
         
diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index be9e0a2..4f74059 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -85,7 +85,7 @@ public class CSN extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_csn));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_csn));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://www.csn.se/bas/");
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index f2ec282..26c05a0 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -72,7 +72,7 @@ public class Coop extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_coop));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_coop));
         urlopen.addHeader("Origin", "https://www.coop.se");
         urlopen.addHeader("Referer", "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
         response = urlopen.open("https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index c9b337e..8f8eed8 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -85,7 +85,7 @@ public class DanskeBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_danskebank));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_danskebank));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://mobil.danskebank.se/");
 
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index ed8d7d5..e0d7c1c 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -77,7 +77,7 @@ public class DinersClub extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
         try {
             response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
         } catch (IOException e) {
diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index ac65ae2..2c85e57 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -66,7 +66,7 @@ public class EasyCard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
 
-        urlopen                         = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_easycard));
+        urlopen                         = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_easycard));
         response                        = urlopen.open(EasyCard.URL);
         List<NameValuePair> postData    = new ArrayList<NameValuePair>();
 
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 1b1b0f2..07925bf 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -78,7 +78,7 @@ public class Eurocard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_eurocard));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_eurocard));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open("https://secure.eurocard.se/nis/external/ecse/login.do");
         urlopen.addHeader("Referer", String.format("https://secure.eurocard.se/nis/external/ecse/login.do"));
diff --git src/com/liato/bankdroid/banking/banks/Everydaycard.java src/com/liato/bankdroid/banking/banks/Everydaycard.java
index 1d1e75d..4770b07 100644
--- src/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ src/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -87,7 +87,7 @@ public class Everydaycard extends Bank {
 
     private LoginPackage preLoginInternal(String url) throws BankException,
     		ClientProtocolException, IOException {
-    	urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
+    	urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
     	List <NameValuePair> postData = new ArrayList <NameValuePair>();
     	postData.add(new BasicNameValuePair("nextPage", "firstPage"));                
     	postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index 3553ddb..7239948 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -75,7 +75,7 @@ public class FirstCard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_firstcard));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_firstcard));
         response = urlopen.open("https://www.firstcard.se/login.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("op", "login"));                
diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index ae9a3c0..a8a1266 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -79,7 +79,7 @@ public class ForexBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_forexbank));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_forexbank));
         String baseUrl = "https://nettbank.edb.com";
         String res = urlopen.open(baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
         String formAction = "";
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 7625683..761bf2d 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -85,7 +85,7 @@ public class Handelsbanken extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
         response = urlopen.open("https://m.handelsbanken.se/primary/");
         Matcher matcher = reLoginUrl.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index cffa87f..edbaf34 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -80,7 +80,7 @@ public class Hemkop extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_hemkop));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_hemkop));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.hemkop.se/Mina-sidor/Logga-in/");
         
diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index c83958d..96b5be9 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -79,7 +79,7 @@ public class ICA extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ica));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ica));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         String response = urlopen.open("https://www.ica.se/logga-in/");
         Matcher matcher = reViewState.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index e14d122..2467669 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -83,7 +83,7 @@ public class IkanoBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ikanobank));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanobank));
         response = urlopen.open("https://secure.ikanobank.se/login");
         Matcher matcher;
         if (response.contains("Banken är stängd")) {
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 6f8c8d1..b6147a7 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -74,7 +74,7 @@ public abstract class IkanoPartnerBase extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index f53bedc..6014d7f 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -71,7 +71,7 @@ public class Jojo extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
     ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_jojo));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_jojo));
         response = urlopen.open("http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java src/com/liato/bankdroid/banking/banks/Marginalen.java
index 6ec092d..b678b91 100644
--- src/com/liato/bankdroid/banking/banks/Marginalen.java
+++ src/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -65,7 +65,7 @@ public class Marginalen extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_marginalen));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_marginalen));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open(BASE_URL + "engine");
diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java src/com/liato/bankdroid/banking/banks/McDonalds.java
index fcf6deb..75df832 100644
--- src/com/liato/bankdroid/banking/banks/McDonalds.java
+++ src/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -75,7 +75,7 @@ public class McDonalds extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-		urlopen = new Urllib();
+		urlopen = new Urllib(context);
 
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
 		postData.add(new BasicNameValuePair("__Click", "0"));
diff --git src/com/liato/bankdroid/banking/banks/Meniga.java src/com/liato/bankdroid/banking/banks/Meniga.java
index 85c0b99..c14f3b8 100644
--- src/com/liato/bankdroid/banking/banks/Meniga.java
+++ src/com/liato/bankdroid/banking/banks/Meniga.java
@@ -60,7 +60,7 @@ public class Meniga extends Bank{
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_meniga));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_meniga));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.meniga.is/Mobile");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
diff --git src/com/liato/bankdroid/banking/banks/MobilbankenBase.java src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 9738d09..9961bb3 100644
--- src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -72,7 +72,7 @@ public abstract class MobilbankenBase extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
         urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         String postUrl = String.format("https://mobil-banken.se/%s/login.html", targetId);
diff --git src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
index a473836..08eec39 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
@@ -85,7 +85,7 @@ public class Nordea extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordea));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordea));
         Matcher matcher;
         String response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
         matcher = reCSRF.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java src/com/liato/bankdroid/banking/banks/NordeaDK.java
index d45987b..93d8af5 100644
--- src/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ src/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -91,7 +91,7 @@ public class NordeaDK extends Bank {
 	protected LoginPackage preLogin() throws BankException,
 			ClientProtocolException, IOException {
 		if (urlopen == null) {
-            urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
+            urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
 		}
 		response = urlopen
 				.open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index 857c07a..9bc326d 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -72,7 +72,7 @@ public class Nordnet extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordnet));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnet));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
         
diff --git src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 420aa28..d170c48 100644
--- src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -77,7 +77,7 @@ public class Nordnetdirekt extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html");
 
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index aaa0ad1..51e53dc 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -81,7 +81,7 @@ public class OKQ8 extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_okq8));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_okq8));
         Date d = new Date();
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
diff --git src/com/liato/bankdroid/banking/banks/Osuuspankki.java src/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 96c1695..705fa5b 100644
--- src/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ src/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -71,7 +71,7 @@ public class Osuuspankki extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_osuuspankki, R.raw.cert_osuuspankki_mobile));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_osuuspankki, R.raw.cert_osuuspankki_mobile));
         response = urlopen.open("https://www.op.fi/op?kielikoodi=sv");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("REQUEST_LOGIN_ATTEMPTED", "true"));
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index be1ee12..7773aaa 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -80,7 +80,7 @@ public class PayPal extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_paypal));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_paypal));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
index 043f182..fb087cd 100644
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -76,7 +76,7 @@ public class Payson extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_payson));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_payson));
         response = urlopen.open("https://www.payson.se/signin/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java src/com/liato/bankdroid/banking/banks/PlusGirot.java
index 9624775..2b6b026 100644
--- src/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ src/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -74,7 +74,7 @@ public class PlusGirot extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_plusgirot));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_plusgirot));
         // Request first page to get cookies
         response = urlopen.open("https://kontoutdrag.plusgirot.se/ku/html/epostllg.htm");
 
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 64e55d7..04c88a5 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -72,7 +72,7 @@ public class ResursBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_resursbank));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_resursbank));
         response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("kontonummer", username));
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 5ae1c5b..f836d0a 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -87,7 +87,7 @@ public class Rikslunchen extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
         urlopen.setAllowCircularRedirects(true);
 
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 91c94cd..64d7e61 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -78,7 +78,7 @@ public class SEB extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_seb));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_seb));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://m.seb.se/");
         urlopen.setKeepAliveTimeout(5);
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index bda5427..227b3bf 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -71,7 +71,7 @@ public abstract class SEBKortBase extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_sebkort));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sebkort));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open(String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
         urlopen.addHeader("Referer", String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
diff --git src/com/liato/bankdroid/banking/banks/SevenDay.java src/com/liato/bankdroid/banking/banks/SevenDay.java
index 041d812..69d85ef 100644
--- src/com/liato/bankdroid/banking/banks/SevenDay.java
+++ src/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -76,7 +76,7 @@ public class SevenDay extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_sevenday));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_sevenday));
         response = urlopen.open("https://www.sevenday.se/mina-sidor/mina-sidor.htm");
         
         Matcher matcher = reViewState.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index caa035a..3b76c0d 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -76,7 +76,7 @@ public class Skandiabanken extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
 
 		HashMap<String, String> headers = urlopen.getHeaders();
 		headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID,
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index c465528..6c9a97e 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -79,7 +79,7 @@ public class Steam extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_steam));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_steam));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("redir", "account"));
         postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/SvenskaSpel.java src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 277515e..e1731ed 100644
--- src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -71,7 +71,7 @@ public class SvenskaSpel extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
 
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
 		postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index fc63857..5199a61 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -83,7 +83,7 @@ public class Swedbank extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_swedbank));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_swedbank));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
diff --git src/com/liato/bankdroid/banking/banks/TestBank.java src/com/liato/bankdroid/banking/banks/TestBank.java
index defe192..c30dd55 100644
--- src/com/liato/bankdroid/banking/banks/TestBank.java
+++ src/com/liato/bankdroid/banking/banks/TestBank.java
@@ -71,7 +71,7 @@ public class TestBank extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
+		urlopen = new Urllib(context);
 		return urlopen;
 	}
 	
diff --git src/com/liato/bankdroid/banking/banks/TicketRikskortet.java src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 00e7caa..8b5b449 100644
--- src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -74,7 +74,7 @@ public class TicketRikskortet extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
         response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/TrustBuddy.java src/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 48512ba..b2614e0 100644
--- src/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ src/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -79,7 +79,7 @@ public class TrustBuddy extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
         urlopen.setAllowCircularRedirects(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 83bb8c9..f712602 100644
--- src/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -70,7 +70,7 @@ public class Vasttrafik extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
     ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_vasttrafik));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_vasttrafik));
         response = urlopen.open("https://www.vasttrafik.se/mina-sidor/logga-in/");
 
 		Matcher matcher = reViewState.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index fee07f7..a178c00 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -70,7 +70,7 @@ public class Villabanken extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_villabanken));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_villabanken));
 		String response = urlopen.open(URL);
 		Matcher matcher = reRequestDigest.matcher(response);
 		if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 23c0dbe..7d223c6 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -84,7 +84,7 @@ public class Volvofinans extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/Zidisha.java src/com/liato/bankdroid/banking/banks/Zidisha.java
index f8ba08c..e08b654 100644
--- src/com/liato/bankdroid/banking/banks/Zidisha.java
+++ src/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -81,7 +81,7 @@ public class Zidisha extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_zidisha));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_zidisha));
         urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.zidisha.org/");
         Matcher mUserGuess = reUserGuess.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
index c842c78..40971bc 100644
--- src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -65,7 +65,7 @@ public class Avanza extends Bank {
     }
 
     public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_avanza));
         urlopen.addHeader("ctag", "1122334455");
         urlopen.setUserAgent("Avanza Bank 131 (iPhone; iPhone OS 6.1.4; sv_SE)");
         urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
index 7fb8f9c..c9eceac 100644
--- src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
+++ src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -74,7 +74,7 @@ public class Bitcoin extends Bank {
 	}
 
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
+		urlopen = new Urllib(context);
 
 		try {
 			String response = urlopen.open(API_URL + username);
diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index cd85015..a5de3ea 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -80,7 +80,7 @@ public class ICABanken extends Bank {
 	}
 
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_icabanken));
+		urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_icabanken));
 		urlopen.addHeader("ApiVersion", API_VERSION);
 		urlopen.addHeader("Accept", "application/json");
 		urlopen.addHeader("ApiKey", API_KEY);
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index f32fd7f..1e10ea3 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -104,7 +104,7 @@ public class Lansforsakringar extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        Urllib weblogin = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
+        Urllib weblogin = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         weblogin.setAllowCircularRedirects(true);
 
         String response = weblogin.open("https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces");
@@ -131,7 +131,7 @@ public class Lansforsakringar extends Bank {
     }
 
     public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
+        urlopen = new Urllib(context, CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
         urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
         urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 37911ff..05244a2 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -16,7 +16,9 @@
 
 package eu.nullbyte.android.urllib;
 
-import android.util.Log;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.BuildConfig;
 
@@ -63,20 +65,21 @@ import java.util.List;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
-    private static boolean TRUST_SYSTEM_KEYSTORE = false;
     private String userAgent = DEFAULT_USER_AGENT;
     private DefaultHttpClient httpclient;
-	private HttpContext mContext;
+	private HttpContext mHttpContext;
 	private String currentURI;
 	private String charset = HTTP.UTF_8;
 	private HashMap<String, String> headers;
+    private Context mContext;
 
 
-    public Urllib() {
-        this(null);
+    public Urllib(Context context) {
+        this(context, null);
     }
 
-	public Urllib(Certificate[] pins) {
+	public Urllib(Context context, Certificate[] pins) {
+        mContext = context;
 		this.headers = new HashMap<String, String>();
     	HttpParams params = new BasicHttpParams(); 
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
@@ -84,8 +87,10 @@ public class Urllib {
         params.setBooleanParameter("http.protocol.expect-continue", false);
         SchemeRegistry registry = new SchemeRegistry();
         registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        boolean trustSystemKeystore = prefs.getBoolean("debug_mode", false) && prefs.getBoolean("no_cert_pinning", false);
         try {
-            registry.register(new Scheme("https", pins != null && !TRUST_SYSTEM_KEYSTORE && BuildConfig.DEBUG ? new CertPinningSSLSocketFactory(pins) : SSLSocketFactory.getSocketFactory(), 443));
+            registry.register(new Scheme("https", pins != null && !trustSystemKeystore ? new CertPinningSSLSocketFactory(pins) : SSLSocketFactory.getSocketFactory(), 443));
         } catch (UnrecoverableKeyException e) {
             e.printStackTrace();
         } catch (KeyManagementException e) {
@@ -97,7 +102,7 @@ public class Urllib {
         }
         ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
         httpclient = new DefaultHttpClient(manager, params);
-    	mContext = new BasicHttpContext();
+    	mHttpContext = new BasicHttpContext();
     }
     
     public String open(String url) throws ClientProtocolException, IOException {
@@ -137,10 +142,10 @@ public class Urllib {
             request.addHeader(headerKeys[i], headerVals[i]);
         }
 
-        response = httpclient.execute(request, mContext);
+        response = httpclient.execute(request, mHttpContext);
 
-        //HttpUriRequest currentReq = (HttpUriRequest)mContext.getAttribute(ExecutionContext.HTTP_REQUEST);
-        //HttpHost currentHost = (HttpHost)mContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+        //HttpUriRequest currentReq = (HttpUriRequest)mHttpContext.getAttribute(ExecutionContext.HTTP_REQUEST);
+        //HttpHost currentHost = (HttpHost)mHttpContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
         //this.currentURI = currentHost.toURI() + currentReq.getURI();
         this.currentURI = request.getURI().toString();
 
@@ -199,8 +204,8 @@ public class Urllib {
         httpclient.getConnectionManager().shutdown();
     }
     
-    public HttpContext getmContext() {
-    	return mContext;
+    public HttpContext getmHttpContext() {
+    	return mHttpContext;
     }
     
     public String getCurrentURI() {

commit 50905310f51b83998b0b267768347a3a610fb419
Author: liato <x@x00.us>
Date:   Wed Oct 23 08:41:09 2013 +0200

    Bump version.

diff --git build.gradle build.gradle
index 6f94fb7..7be06f1 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 163
-        versionName '1.9.6.2-RC2 (Certpinning)'
+        versionCode 164
+        versionName '1.9.6.2-RC3'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'
diff --git test.txt test.txt
deleted file mode 100644
index 76afcce..0000000
--- test.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-test
-test
\ No newline at end of file

commit b8678adb894289b11ee606799eefab6fe9488317
Merge: fd7dc5b 785cfa0
Author: liato <x@x00.us>
Date:   Tue Oct 22 14:15:25 2013 -0700

    Merge pull request #250 from NanoRage/master
    
    Fix for Avanza. Use the iPhone api.

commit 785cfa05d3362f5b43a52e6c817bd5196d18462a
Author: NanoRage <nano@Nanorages-Mac-mini.local>
Date:   Tue Oct 22 18:49:22 2013 +0200

    Use Avanza api.

diff --git res/raw/cert_avanza.pem res/raw/cert_avanza.pem
index ff45953..f6c862c 100644
--- res/raw/cert_avanza.pem
+++ res/raw/cert_avanza.pem
@@ -1,35 +1,27 @@
 -----BEGIN CERTIFICATE-----

-ckqfiJM8yNuuHA==

+UJM2koY+ZtcwVM4YjfAIi2YzYdzYccsODhamwBVtpe38WcF1pQw=
 -----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index dcdd64d..d6cb584 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -30,7 +30,6 @@ import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.AppeakPoker;
 import com.liato.bankdroid.banking.banks.Audi;
-import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
@@ -95,6 +94,7 @@ import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
+import com.liato.bankdroid.banking.banks.avanza.Avanza;
 import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
 import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
deleted file mode 100644
index 2e89456..0000000
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.CertificateReader;
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Avanza extends Bank {
-	private static final String TAG = "Avanza";
-	private static final String NAME = "Avanza";
-	private static final String NAME_SHORT = "avanza";
-	private static final String URL = "https://www.avanza.se/";
-    private static final int BANKTYPE_ID = IBankTypes.AVANZA;
-	
-	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>(.+?)\\s(Private|Pro|Premium|Bas).*?>.*?( - (.*?))?</span>.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reConnect = Pattern.compile("Kopplat till (\\d+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	public Avanza(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public Avanza(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-	
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_avanza));
-        urlopen.setAllowCircularRedirects(true);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("username", username));
-        postData.add(new BasicNameValuePair("password", password));
-        return new LoginPackage(urlopen, postData, null, "https://www.avanza.se/aza/login/login.jsp");
-    }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		String response = null;
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		Urllib urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
-						
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: ID                3505060
-                 * 2: Type              Aktie- och fondkonto
-                 * 5: Custom name       ISK
-                 * 6: % since purchase  1,90
-                 * 7: Amount in SEK     820
-                 */
-				String account_name = matcher.group(5);
-				if (account_name == null) {
-					account_name = matcher.group(2);
-				}
-				else if (account_name.matches("Kopplat till \\d+")) {
-					Matcher mConnect = reConnect.matcher(account_name);
-					mConnect.matches();
-					String idConnect = mConnect.group(1);
-					account_name = matcher.group(2);
-					for(Account a : accounts) {
-						if (a.getId().equals(idConnect)) {
-							accounts.add(new Account(
-									a.getName() + " (netto)",
-									a.getBalance().add(Helpers.parseBalance(matcher.group(7))),
-									idConnect+"_netto"
-							));
-							break;
-						}
-					}
-				}
-				
-			    accounts.add(new Account(account_name.trim(), Helpers.parseBalance(matcher.group(7)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(7)));
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-        finally {
-            super.updateComplete();
-        }
-	}
-
-	
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		
-		String response = null;
-		Matcher matcher;
-		try {						
-			response = urlopen.open("https://www.avanza.se/aza/depa/depa.jsp?depotnr="+account.getId());
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			String strDate = null;
-			Calendar cal = Calendar.getInstance();
-			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-			strDate = sdf.format(cal.getTime());
-
-			while (matcher.find()) {
-				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2))));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/Avanza.java src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
new file mode 100644
index 0000000..c842c78
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/avanza/Avanza.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.avanza;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Base64;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.avanza.model.AccountOverview;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+import eu.nullbyte.android.urllib.CertificateReader;
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Avanza extends Bank {
+    private static final String TAG = "Avanza";
+    private static final String NAME = "Avanza";
+    private static final String NAME_SHORT = "avanza";
+    private static final String URL = "https://www.avanza.se/";
+    private static final int BANKTYPE_ID = IBankTypes.AVANZA;
+
+    private static final String API_URL = "https://iphone.avanza.se/iphone-ws/";
+
+    public Avanza(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Avanza(String username, String password, Context context)
+            throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen.addHeader("ctag", "1122334455");
+        urlopen.setUserAgent("Avanza Bank 131 (iPhone; iPhone OS 6.1.4; sv_SE)");
+        urlopen.addHeader("Authorization", "Basic " + Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.NO_WRAP));
+
+        try {
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(API_URL + "account/overview/all", null, false);
+            if (httpResponse.getStatusLine().getStatusCode() == 401) {
+                throw new LoginException(context.getText(
+                        R.string.invalid_username_password).toString());
+            }
+            ObjectMapper vObjectMapper = new ObjectMapper();
+            AccountOverview r = vObjectMapper.readValue(httpResponse.getEntity().getContent(), AccountOverview.class);
+            for (com.liato.bankdroid.banking.banks.avanza.model.Account account : r.getAccounts()) {
+                Account a = new Account(account.getAccountName(), new BigDecimal(account.getBalance()), account.getAccountId());
+                if (!account.getCurrencyAccounts().isEmpty()) {
+                    a.setCurrency(account.getCurrencyAccounts().get(0).getCurrency());
+                }
+                accounts.add(a);
+            }
+        } catch (JsonParseException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException,
+            BankChoiceException {
+        super.update();
+        if (TextUtils.isEmpty(username)) {
+            throw new LoginException(res.getText(
+                    R.string.invalid_bitcoin_address).toString());
+        }
+        login();
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found)
+                    .toString());
+        }
+        super.updateComplete();
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/Account.java src/com/liato/bankdroid/banking/banks/avanza/model/Account.java
new file mode 100644
index 0000000..65116c4
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/avanza/model/Account.java
@@ -0,0 +1,153 @@
+package com.liato.bankdroid.banking.banks.avanza.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+public class Account implements Serializable {
+    private static final long serialVersionUID = -5718585872348469144L;
+    @JsonProperty("balance")
+    private double mBalance;
+    @JsonProperty("totalProfit")
+    private double mTotalProfit;
+    @JsonProperty("accountName")
+    private String mAccountName;
+    @JsonProperty("totalAccruedInterest")
+    private double mTotalAccruedInterest;
+    @JsonProperty("adjustedForwardAmount")
+    private double mAdjustedForwardAmount;
+    @JsonProperty("unUsedCredit")
+    private double mUnUsedCredit;
+    @JsonProperty("superInterest")
+    private double mSuperInterest;
+    @JsonProperty("totalMarginRequirement")
+    private double mTotalMarginRequirement;
+    @JsonProperty("tradingPower")
+    private double mTradingPower;
+    @JsonProperty("resAmount")
+    private double mResAmount;
+    @JsonProperty("loanAmount")
+    private double mLoanAmount;
+    @JsonProperty("accountId")
+    private String mAccountId;
+    @JsonProperty("currencyAccounts")
+    private List<CurrencyAccount> mCurrencyAccounts = Collections.emptyList();
+    @JsonProperty("creditLimit")
+    private double mCreditLimit;
+    @JsonProperty("totalProfitPercent")
+    private double mTotalProfitPercent;
+    @JsonProperty("ownCapital")
+    private double mOwnCapital;
+    @JsonProperty("totalValue")
+    private double mTotalValue;
+    @JsonProperty("interestAmount")
+    private double mInterestAmount;
+    @JsonProperty("secAmount")
+    private double mSecAmount;
+    @JsonProperty("positionAggregations")
+    private List<PositionAggregation> mPositionAggregations = Collections.emptyList();
+
+
+    @JsonProperty("balance")
+    public double getBalance() {
+        return mBalance;
+    }
+
+    @JsonProperty("totalProfit")
+    public double getTotalProfit() {
+        return mTotalProfit;
+    }
+
+    @JsonProperty("accountName")
+    public String getAccountName() {
+        return mAccountName;
+    }
+
+    @JsonProperty("totalAccruedInterest")
+    public double getTotalAccruedInterest() {
+        return mTotalAccruedInterest;
+    }
+
+    @JsonProperty("adjustedForwardAmount")
+    public double getAdjustedForwardAmount() {
+        return mAdjustedForwardAmount;
+    }
+
+    @JsonProperty("unUsedCredit")
+    public double getUnUsedCredit() {
+        return mUnUsedCredit;
+    }
+
+    @JsonProperty("superInterest")
+    public double getSuperInterest() {
+        return mSuperInterest;
+    }
+
+    @JsonProperty("totalMarginRequirement")
+    public double getTotalMarginRequirement() {
+        return mTotalMarginRequirement;
+    }
+
+    @JsonProperty("tradingPower")
+    public double getTradingPower() {
+        return mTradingPower;
+    }
+
+    @JsonProperty("resAmount")
+    public double getResAmount() {
+        return mResAmount;
+    }
+
+    @JsonProperty("loanAmount")
+    public double getLoanAmount() {
+        return mLoanAmount;
+    }
+
+    @JsonProperty("accountId")
+    public String getAccountId() {
+        return mAccountId;
+    }
+
+    @JsonProperty("currencyAccounts")
+    public List<CurrencyAccount> getCurrencyAccounts() {
+        return mCurrencyAccounts;
+    }
+
+    @JsonProperty("creditLimit")
+    public double getCreditLimit() {
+        return mCreditLimit;
+    }
+
+    @JsonProperty("totalProfitPercent")
+    public double getTotalProfitPercent() {
+        return mTotalProfitPercent;
+    }
+
+    @JsonProperty("ownCapital")
+    public double getOwnCapital() {
+        return mOwnCapital;
+    }
+
+    @JsonProperty("totalValue")
+    public double getTotalValue() {
+        return mTotalValue;
+    }
+
+    @JsonProperty("interestAmount")
+    public double getInterestAmount() {
+        return mInterestAmount;
+    }
+
+    @JsonProperty("secAmount")
+    public double getSecAmount() {
+        return mSecAmount;
+    }
+
+    @JsonProperty("positionAggregations")
+    public List<PositionAggregation> getPositionAggregations() {
+        return mPositionAggregations;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java src/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
new file mode 100644
index 0000000..939ef2b
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/avanza/model/AccountOverview.java
@@ -0,0 +1,27 @@
+package com.liato.bankdroid.banking.banks.avanza.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+public class AccountOverview implements Serializable {
+    private static final long serialVersionUID = -5511775495529857976L;
+    @JsonProperty("totalOwnCapital")
+    private float mTotalOwnCapital;
+    @JsonProperty("accounts")
+    private List<Account> mAccounts = Collections.emptyList();
+
+
+    @JsonProperty("totalOwnCapital")
+    public float getTotalOwnCapital() {
+        return mTotalOwnCapital;
+    }
+
+    @JsonProperty("accounts")
+    public List<Account> getAccounts() {
+        return mAccounts;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java src/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
new file mode 100644
index 0000000..61f831f
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/avanza/model/CurrencyAccount.java
@@ -0,0 +1,32 @@
+package com.liato.bankdroid.banking.banks.avanza.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+public class CurrencyAccount implements Serializable {
+    private static final long serialVersionUID = 6004713686055778196L;
+    @JsonProperty("currency")
+    private String mCurrency;
+    @JsonProperty("balance")
+    private double mBalance;
+    @JsonProperty("accountId")
+    private String mAccountId;
+
+
+    @JsonProperty("currency")
+    public String getCurrency() {
+        return mCurrency;
+    }
+
+    @JsonProperty("balance")
+    public double getBalance() {
+        return mBalance;
+    }
+
+    @JsonProperty("accountId")
+    public String getAccountId() {
+        return mAccountId;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/Position.java src/com/liato/bankdroid/banking/banks/avanza/model/Position.java
new file mode 100644
index 0000000..86a9b1c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/avanza/model/Position.java
@@ -0,0 +1,109 @@
+package com.liato.bankdroid.banking.banks.avanza.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+public class Position implements Serializable {
+    private static final long serialVersionUID = 4138023852221811457L;
+    @JsonProperty("instrumentName")
+    private String mInstrumentName;
+    @JsonProperty("averageAcquiredPrice")
+    private double mAverageAcquiredPrice;
+    @JsonProperty("marketValue")
+    private double mMarketValue;
+    @JsonProperty("price")
+    private double mPrice;
+    @JsonProperty("profit")
+    private double mProfit;
+    @JsonProperty("modified")
+    private long mModified;
+    @JsonProperty("expiryDate")
+    private long mExpiryDate;
+    @JsonProperty("volume")
+    private int mVolume;
+    @JsonProperty("tradable")
+    private boolean mTradable;
+    @JsonProperty("orderbookId")
+    private long mOrderbookId;
+    @JsonProperty("profitPercent")
+    private double mProfitPercent;
+    @JsonProperty("type")
+    private int mType;
+    @JsonProperty("instrumentType")
+    private String mInstrumentType;
+    @JsonProperty("change")
+    private double mChange;
+
+
+    @JsonProperty("instrumentName")
+    public String getInstrumentName() {
+        return mInstrumentName;
+    }
+
+    @JsonProperty("averageAcquiredPrice")
+    public double getAverageAcquiredPrice() {
+        return mAverageAcquiredPrice;
+    }
+
+    @JsonProperty("marketValue")
+    public double getMarketValue() {
+        return mMarketValue;
+    }
+
+    @JsonProperty("price")
+    public double getPrice() {
+        return mPrice;
+    }
+
+    @JsonProperty("profit")
+    public double getProfit() {
+        return mProfit;
+    }
+
+    @JsonProperty("modified")
+    public long getModified() {
+        return mModified;
+    }
+
+    @JsonProperty("expiryDate")
+    public long getExpiryDate() {
+        return mExpiryDate;
+    }
+
+    @JsonProperty("volume")
+    public int getVolume() {
+        return mVolume;
+    }
+
+    @JsonProperty("tradable")
+    public boolean getTradable() {
+        return mTradable;
+    }
+
+    @JsonProperty("orderbookId")
+    public long getOrderbookId() {
+        return mOrderbookId;
+    }
+
+    @JsonProperty("profitPercent")
+    public double getProfitPercent() {
+        return mProfitPercent;
+    }
+
+    @JsonProperty("type")
+    public int getType() {
+        return mType;
+    }
+
+    @JsonProperty("instrumentType")
+    public String getInstrumentType() {
+        return mInstrumentType;
+    }
+
+    @JsonProperty("change")
+    public double getChange() {
+        return mChange;
+    }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java src/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
new file mode 100644
index 0000000..508a339
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/avanza/model/PositionAggregation.java
@@ -0,0 +1,70 @@
+package com.liato.bankdroid.banking.banks.avanza.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class PositionAggregation implements Serializable {
+    private static final long serialVersionUID = 5531947007427482418L;
+    @JsonProperty("totalChange")
+    private double mTotalChange;
+    @JsonProperty("positions")
+    private List<Position> mPositions = Collections.emptyList();
+    @JsonProperty("totalProfit")
+    private double mTotalProfit;
+    @JsonProperty("instrumentTypeName")
+    private String mInstrumentTypeName;
+    @JsonProperty("totalProfitPercent")
+    private double mTotalProfitPercent;
+    @JsonProperty("totalValue")
+    private double mTotalValue;
+    @JsonProperty("instrumentType")
+    private int mInstrumentType;
+    @JsonProperty("totalAverage")
+    private double mTotalAverage;
+
+
+    @JsonProperty("totalChange")
+    public double getTotalChange() {
+        return mTotalChange;
+    }
+
+    @JsonProperty("positions")
+    public List<Position> getPositions() {
+        return mPositions;
+    }
+
+    @JsonProperty("totalProfit")
+    public double getTotalProfit() {
+        return mTotalProfit;
+    }
+
+    @JsonProperty("instrumentTypeName")
+    public String getInstrumentTypeName() {
+        return mInstrumentTypeName;
+    }
+
+    @JsonProperty("totalProfitPercent")
+    public double getTotalProfitPercent() {
+        return mTotalProfitPercent;
+    }
+
+    @JsonProperty("totalValue")
+    public double getTotalValue() {
+        return mTotalValue;
+    }
+
+    @JsonProperty("instrumentType")
+    public int getInstrumentType() {
+        return mInstrumentType;
+    }
+
+    @JsonProperty("totalAverage")
+    public double getTotalAverage() {
+        return mTotalAverage;
+    }
+
+}
\ No newline at end of file

commit 23c384a9522ba19f6c1e9c96936c8989d671ce1a
Author: NanoRage <nano@Nanorages-Mac-mini.local>
Date:   Tue Oct 22 17:26:50 2013 +0200

    Test

diff --git test.txt test.txt
new file mode 100644
index 0000000..76afcce
--- /dev/null
+++ test.txt
@@ -0,0 +1,2 @@
+test
+test
\ No newline at end of file

commit fd7dc5bc45e7f54407797879dd2da591ffbd32bf
Author: liato <x@x00.us>
Date:   Wed Oct 16 23:18:17 2013 +0200

    Add support for Eurobonus Mastercard Denmark.

diff --git res/drawable/logo_ebmaster_dk.png res/drawable/logo_ebmaster_dk.png
new file mode 100644
index 0000000..0354e55
Binary files /dev/null and res/drawable/logo_ebmaster_dk.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 5cf8909..dcdd64d 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
+import com.liato.bankdroid.banking.banks.EurobonusMastercardDk;
 import com.liato.bankdroid.banking.banks.EurobonusMastercardNo;
 import com.liato.bankdroid.banking.banks.Eurocard;
 import com.liato.bankdroid.banking.banks.Everydaycard;
@@ -156,6 +157,8 @@ public class BankFactory {
         	return new EurobonusMastercard(context);
         case IBankTypes.SASEUROBONUSMASTERCARD_NO:
         	return new EurobonusMastercardNo(context);
+        case IBankTypes.SASEUROBONUSMASTERCARD_DK:
+            return new EurobonusMastercardNo(context);
         case IBankTypes.RIKSLUNCHEN:
             return new Rikslunchen(context);            
         case IBankTypes.HEMKOP:
@@ -332,7 +335,8 @@ public class BankFactory {
         banks.add(new ForexBank(context));
         banks.add(new EurobonusMastercardNo(context));
         banks.add(new Bitcoin(context));
-        
+        banks.add(new EurobonusMastercardDk(context));
+
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 2cb141a..cc5ab7f 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -26,7 +26,7 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 public class EurobonusMastercard extends SEBKortBase {
 	private static final String TAG = "EurobonusMastercard";
-	private static final String NAME = "SAS EuroBonus MasterCard";
+	private static final String NAME = "SAS EuroBonus MasterCard (Sweden)";
 	private static final String NAME_SHORT = "ebmaster";
 	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
 
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
similarity index 64%
copy from src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
copy to src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
index 2cb141a..d5ce051 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardDk.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
  * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,22 +24,22 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class EurobonusMastercard extends SEBKortBase {
-	private static final String TAG = "EurobonusMastercard";
-	private static final String NAME = "SAS EuroBonus MasterCard";
-	private static final String NAME_SHORT = "ebmaster";
-	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
+public class EurobonusMastercardDk extends SEBKortBase {
+	private static final String TAG = "EurobonusMastercardDk";
+	private static final String NAME = "SAS EuroBonus MasterCard (Denmark)";
+	private static final String NAME_SHORT = "ebmaster_dk";
+	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_DK;
 
-	public EurobonusMastercard(Context context) {
-		super(context, "sase", "0102");
+	public EurobonusMastercardDk(Context context) {
+		super(context, "sadk", "0101");
 		super.TAG = TAG;
 		super.NAME = NAME;
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
-	
-	public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		super(username, password, context, "sase", "0102");
+
+	public EurobonusMastercardDk(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		super(username, password, context, "sadk", "0101");
 	}
 
 }
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 969b8ae..b39922c 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -94,4 +94,5 @@ public interface IBankTypes {
     public static final int FOREX = 70;
     public final static int SASEUROBONUSMASTERCARD_NO = 71;
     public final static int BITCOIN = 72;
+    public final static int SASEUROBONUSMASTERCARD_DK = 73;
 }

commit 68e4f18b6eafa1f5b6af623b7d8eec04b96e828d
Author: liato <x@x00.us>
Date:   Wed Oct 9 21:40:47 2013 +0200

    Update gitignore and gradle file.

diff --git .gitignore .gitignore
index b6b22d5..8b22f74 100644
--- .gitignore
+++ .gitignore
@@ -24,3 +24,4 @@ target/
 .gradle
 *.iml
 build/
+release.keystore
\ No newline at end of file
diff --git build.gradle build.gradle
index 1a137ec..6f94fb7 100644
--- build.gradle
+++ build.gradle
@@ -30,8 +30,8 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 162
-        versionName '1.9.6.2-RC1'
+        versionCode 163
+        versionName '1.9.6.2-RC2 (Certpinning)'
         minSdkVersion 7
         targetSdkVersion 10
         packageName 'com.liato.bankdroid'
@@ -50,4 +50,35 @@ android {
 
         instrumentTest.setRoot('tests')
     }
+
+    final Console console = System.console();
+    if (console != null) {
+
+        // Building from console
+        signingConfigs {
+            release {
+                storeFile file("release.keystore")
+                storePassword console.readLine("\nEnter keystore password: ")
+                keyAlias "andmrkt"
+                keyPassword console.readLine("Enter key password: ")
+            }
+        }
+
+    } else {
+
+        // Building from IDE
+        signingConfigs {
+            release {
+
+            }
+        }
+
+    }
+
+
+    buildTypes {
+        release {
+            signingConfig signingConfigs.release
+        }
+    }
 }

commit dd900df5dba35d3093243084a7fe35f1378eb33b
Author: liato <x@x00.us>
Date:   Wed Oct 9 01:50:34 2013 +0200

    Force cert pinning.

diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 4f37f59..37911ff 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -63,7 +63,7 @@ import java.util.List;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
-    private static boolean TRUST_SYSTEM_KEYSTORE = true;
+    private static boolean TRUST_SYSTEM_KEYSTORE = false;
     private String userAgent = DEFAULT_USER_AGENT;
     private DefaultHttpClient httpclient;
 	private HttpContext mContext;

commit bd6cbbbc26cfa60f6920450042d995e38ae27230
Author: liato <x@x00.us>
Date:   Wed Oct 9 01:14:53 2013 +0200

    Remove unnecessary logging.

diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 69ff11a..8f5d355 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -128,22 +128,6 @@ public class Helpers {
         return formatBalance(new BigDecimal(balance), curr);
     }
 
-    public static void slowDebug(String TAG, String text) {
-        slowDebug(TAG, text, 100);
-    }
-    public static void slowDebug(String TAG, String text, int sleep) {
-        for (String s : text.split("\n")) {
-            Log.d(TAG, s);
-            try {
-                Thread.sleep(sleep);
-            }
-            catch (InterruptedException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }
-        }
-    }
-
     static public void setActivityAnimation(Activity activity, int in, int out) {
         try {
             Method method = Activity.class.getMethod("overridePendingTransition", new Class[]{int.class, int.class});
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 82cf92a..4425669 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -139,7 +139,6 @@ public class AutoRefreshService extends Service {
 
 		// http://www.freesound.org/samplesViewSingle.php?id=75235
 		// http://www.freesound.org/samplesViewSingle.php?id=91924
-		//Log.d(TAG, "Notification sound: " + prefs.getString("notification_sound", "none"));
 		if (prefs.getString("notification_sound", null) != null) {
 			notification.sound = Uri.parse(prefs.getString(
 					"notification_sound", null));
@@ -150,7 +149,6 @@ public class AutoRefreshService extends Service {
 			// notification.defaults |= Notification.DEFAULT_VIBRATE;
 		}
 
-		Log.d("LED", "true? " + prefs.getBoolean("notify_with_led", true));
         if (prefs.getBoolean("notify_with_led", true)) {
             notification.ledARGB = prefs.getInt("notify_with_led_color", context.getResources().getColor(R.color.default_led_color));
             notification.flags |= Notification.FLAG_SHOW_LIGHTS;
@@ -241,10 +239,8 @@ public class AutoRefreshService extends Service {
 					continue;
 				}
 				if (bank.isDisabled()) {
-					//Log.d(TAG, bank.getName() + " (" + bank.getDisplayName() + ") is disabled. Skipping refresh.");
 					continue;
 				}
-				//Log.d(TAG, "Refreshing " + bank.getName() + " (" + bank.getDisplayName() + ").");
 				try {
 					currentBalance = bank.getBalance();
 					accounts.clear();
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 88eeaea..15e30e5 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -125,10 +125,7 @@ public class AmericanExpress extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		
-		Log.d(TAG, "Logging in...");
 		urlopen = login();
-        Log.d(TAG, "Url after login: " + urlopen.getCurrentURI());
-		
 		Matcher matcher = reAccounts.matcher(response);
 		
 		while (matcher.find()) {
@@ -183,7 +180,7 @@ public class AmericanExpress extends Bank {
                                                      Helpers.parseBalance(matcher.group(3).trim()).negate()));
                 }
                 catch (ParseException e) {
-                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                    Log.w(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
 			}
 			account.setTransactions(transactions);
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index e6fa73d..be1ee12 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -109,7 +109,6 @@ public class PayPal extends Bank {
         postData.add(new BasicNameValuePair("bp_ks3", ""));
         postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
         postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
-        Log.d("HEJ", "Posturl: " + strPostUrl);
         return new LoginPackage(urlopen, postData, response, strPostUrl);
     }
 

commit 3a54ace82132a8a325b8ddf591d5bd9610c5d3ff
Author: liato <x@x00.us>
Date:   Wed Oct 9 01:07:38 2013 +0200

    Certpinning work.

diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index e1ca05e..1b1b0f2 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -104,7 +104,7 @@ public class Eurocard extends Bank {
 		try {
 			LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktig kombination")) {
+			if (response.contains("Felaktig kombination") || response.contains("ett felaktigt") || response.contains("invalid login")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			
diff --git src/com/liato/bankdroid/banking/banks/Osuuspankki.java src/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 44eb8a4..96c1695 100644
--- src/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ src/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -71,7 +71,7 @@ public class Osuuspankki extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_osuuspankki));
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_osuuspankki, R.raw.cert_osuuspankki_mobile));
         response = urlopen.open("https://www.op.fi/op?kielikoodi=sv");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("REQUEST_LOGIN_ATTEMPTED", "true"));
@@ -96,6 +96,7 @@ public class Osuuspankki extends Bank {
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
+            e.printStackTrace();
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 629974d..bda5427 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -97,7 +97,7 @@ public abstract class SEBKortBase extends Bank {
 		try {
 			LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("elaktig kombination")) {
+			if (response.contains("elaktig kombination") || response.contains("ett felaktigt") || response.contains("invalid login")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		}
@@ -105,6 +105,7 @@ public abstract class SEBKortBase extends Bank {
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
+            e.printStackTrace();
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 26993fb..23c0dbe 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -84,7 +84,7 @@ public class Volvofinans extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_volvofinans));
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_volvofinans, R.raw.cert_volvofinans_logged_in));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
index 4ef336a..5fc2f9f 100644
--- src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
+++ src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -1,5 +1,7 @@
 package eu.nullbyte.android.urllib;
 
+import android.util.Log;
+
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
diff --git src/eu/nullbyte/android/urllib/CertificateReader.java src/eu/nullbyte/android/urllib/CertificateReader.java
index 25aac89..05ca183 100644
--- src/eu/nullbyte/android/urllib/CertificateReader.java
+++ src/eu/nullbyte/android/urllib/CertificateReader.java
@@ -47,13 +47,13 @@ public class CertificateReader {
             String[] pins = new String[certs.length];
             for (int i = 0; i < certs.length; i++) {
                 Certificate cert = certs[i];
+                String hash = getCertificateHash(cert);
+                pins[i] = hash;
                 try {
                     MessageDigest digest = MessageDigest.getInstance("SHA1");
                     byte[] publicKey = cert.getPublicKey().getEncoded();
                     byte[] pin = digest.digest(publicKey);
                     pins[i] = CertificateReader.byteArrayToHexString(pin);
-//                    System.out.println("pin=" + CertificateReader.byteArrayToHexString(pin) + ", version=" + ((X509Certificate)cert).getVersion() + ", ca="
-//                            + ((X509Certificate) cert).getSubjectDN());
                 } catch (NoSuchAlgorithmException e) {
                     e.printStackTrace();
                 }
@@ -73,4 +73,16 @@ public class CertificateReader {
         }
         return data;
     }
+
+    public static String getCertificateHash(Certificate cert) {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA1");
+            byte[] publicKey = cert.getPublicKey().getEncoded();
+            byte[] pin = digest.digest(publicKey);
+            return CertificateReader.byteArrayToHexString(pin);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 66cabdc..4f37f59 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -16,6 +16,10 @@
 
 package eu.nullbyte.android.urllib;
 
+import android.util.Log;
+
+import com.liato.bankdroid.BuildConfig;
+
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
@@ -59,6 +63,7 @@ import java.util.List;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+    private static boolean TRUST_SYSTEM_KEYSTORE = true;
     private String userAgent = DEFAULT_USER_AGENT;
     private DefaultHttpClient httpclient;
 	private HttpContext mContext;
@@ -77,11 +82,10 @@ public class Urllib {
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, this.charset);
         params.setBooleanParameter("http.protocol.expect-continue", false);
-        boolean noCertValidation = false;
         SchemeRegistry registry = new SchemeRegistry();
         registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
         try {
-            registry.register(new Scheme("https", noCertValidation ? new EasySSLSocketFactory() : pins != null ? new CertPinningSSLSocketFactory(pins) : SSLSocketFactory.getSocketFactory(), 443));
+            registry.register(new Scheme("https", pins != null && !TRUST_SYSTEM_KEYSTORE && BuildConfig.DEBUG ? new CertPinningSSLSocketFactory(pins) : SSLSocketFactory.getSocketFactory(), 443));
         } catch (UnrecoverableKeyException e) {
             e.printStackTrace();
         } catch (KeyManagementException e) {

commit 0fa15dd807828052196c7e936668dfa2875ffbce
Author: liato <x@x00.us>
Date:   Wed Oct 9 01:05:25 2013 +0200

    Add missing certs.

diff --git res/raw/cert_osuuspankki_mobile.pem res/raw/cert_osuuspankki_mobile.pem
new file mode 100644
index 0000000..7e28598
--- /dev/null
+++ res/raw/cert_osuuspankki_mobile.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+Cub+YU2Z3sMnI2U=
+-----END CERTIFICATE-----
diff --git res/raw/cert_volvofinans_logged_in.pem res/raw/cert_volvofinans_logged_in.pem
new file mode 100644
index 0000000..15fde8e
--- /dev/null
+++ res/raw/cert_volvofinans_logged_in.pem
@@ -0,0 +1,41 @@
+-----BEGIN CERTIFICATE-----

+GxUHutMVEtqW9aCSv5wMdnDd/BKF1qHk
+-----END CERTIFICATE-----
diff --git src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
deleted file mode 100644
index 0ccd322..0000000
--- src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package eu.nullbyte.android.urllib;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyStore;
-import java.security.cert.Certificate;
-import java.util.List;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.conn.scheme.LayeredSocketFactory;
-import org.apache.http.conn.scheme.SocketFactory;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-
-/**
- * This socket factory will create ssl socket that accepts self signed
- * certificate
- * 
- * @author olamy
- * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
- *          $
- * @since 1.2.3
- */
-public class EasySSLSocketFactory implements SocketFactory,
-		LayeredSocketFactory {
-
-	private SSLContext sslcontext = null;
-
-	private SSLContext createEasySSLContext() throws IOException {
-        try {
-            SSLContext context = SSLContext.getInstance("TLS");
-            context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
-            return context;
-        } catch (Exception e) {
-            throw new IOException(e.getMessage());
-        }
-	}
-
-	private SSLContext getSSLContext() throws IOException {
-		if (this.sslcontext == null) {
-			this.sslcontext = createEasySSLContext();
-		}
-		return this.sslcontext;
-	}
-	
-	/**
-	 * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
-	 *      java.lang.String, int, java.net.InetAddress, int,
-	 *      org.apache.http.params.HttpParams)
-	 */
-	public Socket connectSocket(Socket sock, String host, int port,
-			InetAddress localAddress, int localPort, HttpParams params)
-			throws IOException, UnknownHostException, ConnectTimeoutException {
-		int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
-		int soTimeout = HttpConnectionParams.getSoTimeout(params);
-
-		InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
-		SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
-
-		if ((localAddress != null) || (localPort > 0)) {
-			// we need to bind explicitly
-			if (localPort < 0) {
-				localPort = 0; // indicates "any"
-			}
-			InetSocketAddress isa = new InetSocketAddress(localAddress,
-					localPort);
-			sslsock.bind(isa);
-		}
-
-		sslsock.connect(remoteAddress, connTimeout);
-		sslsock.setSoTimeout(soTimeout);
-		return sslsock;
-
-	}
-
-	/**
-	 * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
-	 */
-	public Socket createSocket() throws IOException {
-		return getSSLContext().getSocketFactory().createSocket();
-		
-	}
-	
-
-
-	/**
-	 * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
-	 */
-	public boolean isSecure(Socket socket) throws IllegalArgumentException {
-		return true;
-	}
-
-	/**
-	 * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
-	 *      java.lang.String, int, boolean)
-	 */
-	/*public Socket createSocket(Socket socket, String host, int port,
-			boolean autoClose) throws IOException, UnknownHostException {
-		return getSSLContext().getSocketFactory().createSocket();
-	}*/
-    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
-                    throws IOException, UnknownHostException {
-            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
-    }		
-
-	// -------------------------------------------------------------------
-	// javadoc in org.apache.http.conn.scheme.SocketFactory says :
-	// Both Object.equals() and Object.hashCode() must be overridden
-	// for the correct operation of some connection managers
-	// -------------------------------------------------------------------
-
-	public boolean equals(Object obj) {
-		return ((obj != null) && obj.getClass().equals(
-				EasySSLSocketFactory.class));
-	}
-
-	public int hashCode() {
-		return EasySSLSocketFactory.class.hashCode();
-	}
-
-
-}
diff --git src/eu/nullbyte/android/urllib/TrivialTrustManager.java src/eu/nullbyte/android/urllib/TrivialTrustManager.java
deleted file mode 100644
index 54e4d8f..0000000
--- src/eu/nullbyte/android/urllib/TrivialTrustManager.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package eu.nullbyte.android.urllib;
-
-import javax.net.ssl.X509TrustManager;
-
-public class TrivialTrustManager implements X509TrustManager {
-    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
-        return new java.security.cert.X509Certificate[0];
-    }
-	@Override
-	public void checkClientTrusted(
-			java.security.cert.X509Certificate[] chain, String authType)
-			throws java.security.cert.CertificateException {
-	}
-
-	@Override
-	public void checkServerTrusted(
-			java.security.cert.X509Certificate[] chain, String authType)
-			throws java.security.cert.CertificateException {
-	}
-}

commit b751ddfeef83f6713e64170f17d42113ca5f296a
Author: liato <x@x00.us>
Date:   Tue Oct 8 01:47:11 2013 +0200

    gradle changes.

diff --git AndroidManifest.xml AndroidManifest.xml
index 19fb39d..70d677d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -3,6 +3,9 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
 	android:versionName="1.9.6.2-RC1" android:versionCode="162">
+    <uses-sdk
+        android:targetSdkVersion="10"
+        android:minSdkVersion="7" />
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
@@ -162,11 +165,8 @@
 			</intent-filter>
 		</activity>
 	</application>
-	<uses-sdk
-		android:targetSdkVersion="4"
-		android:minSdkVersion="4" />
 	<uses-permission
-		android:name="android.permission.INTERNET"></uses-permission>
+		android:name="android.permission.INTERNET" />
 	<uses-permission
 		android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 	<uses-permission
diff --git build.gradle build.gradle
index 6a3b9d5..1a137ec 100644
--- build.gradle
+++ build.gradle
@@ -3,7 +3,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:0.5.1'
+        classpath 'com.android.tools.build:gradle:0.5.+'
     }
 }
 apply plugin: 'android'
@@ -18,9 +18,7 @@ dependencies {
 	compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
 	compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
 	compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0' 
-	compile  'org.jsoup:jsoup:1.7.2'
-                      
-    // compile fileTree(dir: 'libs', include: '*.jar')
+	compile 'org.jsoup:jsoup:1.7.2'
 }
 
 tasks.withType(Compile) {
@@ -32,10 +30,10 @@ android {
     buildToolsVersion "17.0.0"
 
     defaultConfig {
-        versionCode 160
-        versionName '1.9.6.0'
-        minSdkVersion 4
-        targetSdkVersion 4
+        versionCode 162
+        versionName '1.9.6.2-RC1'
+        minSdkVersion 7
+        targetSdkVersion 10
         packageName 'com.liato.bankdroid'
     }
 

commit 36014d9492bdaddbc4c08a07e15e6052baa17761
Author: liato <x@x00.us>
Date:   Tue Oct 8 01:46:20 2013 +0200

    Certificate pinning for all banks.

diff --git res/raw/cert_akeliusinvest.pem res/raw/cert_akeliusinvest.pem
new file mode 100644
index 0000000..6e4f345
--- /dev/null
+++ res/raw/cert_akeliusinvest.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+5RCwjnQllRzWF+dCwDvLi1mbFOW7
+-----END CERTIFICATE-----
diff --git res/raw/cert_akeliusspar.pem res/raw/cert_akeliusspar.pem
new file mode 100644
index 0000000..3bc318c
--- /dev/null
+++ res/raw/cert_akeliusspar.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+8irFtCk8VpC+XNWWVdm0ib5peSsXcqaHOTKz00E=
+-----END CERTIFICATE-----
diff --git res/raw/cert_americanexpress.pem res/raw/cert_americanexpress.pem
new file mode 100644
index 0000000..7787e79
--- /dev/null
+++ res/raw/cert_americanexpress.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----

+uz4tR1ZyASXcO8NEyEICKBs=
+-----END CERTIFICATE-----
diff --git res/raw/cert_avanza.pem res/raw/cert_avanza.pem
new file mode 100644
index 0000000..ff45953
--- /dev/null
+++ res/raw/cert_avanza.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+ckqfiJM8yNuuHA==
+-----END CERTIFICATE-----
diff --git res/raw/cert_bioklubben.pem res/raw/cert_bioklubben.pem
new file mode 100644
index 0000000..59685ac
--- /dev/null
+++ res/raw/cert_bioklubben.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+CymqjlSx+5sQ6fzET22+ENOvOyglP8vJ/7/IxIBCfRPfRWEAZAk=
+-----END CERTIFICATE-----
diff --git res/raw/cert_brummer.pem res/raw/cert_brummer.pem
new file mode 100644
index 0000000..356a688
--- /dev/null
+++ res/raw/cert_brummer.pem
@@ -0,0 +1,41 @@
+-----BEGIN CERTIFICATE-----

+JO863R2r7jc5
+-----END CERTIFICATE-----
diff --git res/raw/cert_coop.pem res/raw/cert_coop.pem
new file mode 100644
index 0000000..851aba5
--- /dev/null
+++ res/raw/cert_coop.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----

+g9inbt1p3SfEqes=
+-----END CERTIFICATE-----
diff --git res/raw/cert_csn.pem res/raw/cert_csn.pem
new file mode 100644
index 0000000..61ad639
--- /dev/null
+++ res/raw/cert_csn.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----

+8VE5wSZttMXr17Me
+-----END CERTIFICATE-----
diff --git res/raw/cert_danskebank.pem res/raw/cert_danskebank.pem
new file mode 100644
index 0000000..c598978
--- /dev/null
+++ res/raw/cert_danskebank.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+f7/fEt942nMenqvNpWMF9jNb3rYNS9phdg==
+-----END CERTIFICATE-----
diff --git res/raw/cert_dinersclub.pem res/raw/cert_dinersclub.pem
new file mode 100644
index 0000000..d504022
--- /dev/null
+++ res/raw/cert_dinersclub.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+TLZpQwLZfSpf
+-----END CERTIFICATE-----
diff --git res/raw/cert_easycard.pem res/raw/cert_easycard.pem
new file mode 100644
index 0000000..14b3d1c
--- /dev/null
+++ res/raw/cert_easycard.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+YMvo8caizM268OdHzj3WQt4biECp/9TWO3wAfGm1PjaY1A==
+-----END CERTIFICATE-----
diff --git res/raw/cert_eurocard.pem res/raw/cert_eurocard.pem
new file mode 100644
index 0000000..88a2b81
--- /dev/null
+++ res/raw/cert_eurocard.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+SQCaPQ==
+-----END CERTIFICATE-----
diff --git res/raw/cert_everydaycard.pem res/raw/cert_everydaycard.pem
new file mode 100644
index 0000000..b4dd7e2
--- /dev/null
+++ res/raw/cert_everydaycard.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git res/raw/cert_firstcard.pem res/raw/cert_firstcard.pem
new file mode 100644
index 0000000..7c25deb
--- /dev/null
+++ res/raw/cert_firstcard.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+oUmjrWbulK5DddWqewYyfC0PKc9TPiDYhC/3V4/yQ/wL3g==
+-----END CERTIFICATE-----
diff --git res/raw/cert_forexbank.pem res/raw/cert_forexbank.pem
new file mode 100644
index 0000000..07511e9
--- /dev/null
+++ res/raw/cert_forexbank.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git res/raw/cert_handelsbanken.pem res/raw/cert_handelsbanken.pem
new file mode 100644
index 0000000..d21d1cf
--- /dev/null
+++ res/raw/cert_handelsbanken.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+ItVlHNP6y6DtxuQ+m6iUovm7eJNG5Y8bhcTh5+sEOQ==
+-----END CERTIFICATE-----
diff --git res/raw/cert_hemkop.pem res/raw/cert_hemkop.pem
new file mode 100644
index 0000000..6b760d8
--- /dev/null
+++ res/raw/cert_hemkop.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+volhqsuGij2QcsZR2V5tF9iSsmo=
+-----END CERTIFICATE-----
diff --git res/raw/cert_ica.pem res/raw/cert_ica.pem
new file mode 100644
index 0000000..c789350
--- /dev/null
+++ res/raw/cert_ica.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+wgsukWiO3rus98dCxpFI
+-----END CERTIFICATE-----
diff --git res/raw/cert_icabanken.pem res/raw/cert_icabanken.pem
new file mode 100644
index 0000000..e3d0aad
--- /dev/null
+++ res/raw/cert_icabanken.pem
@@ -0,0 +1,36 @@
+-----BEGIN CERTIFICATE-----

+u2PDuCEHH9/zksq1dfLTwiDRinMCzw==
+-----END CERTIFICATE-----
diff --git res/raw/cert_ikanobank.pem res/raw/cert_ikanobank.pem
new file mode 100644
index 0000000..e22c19a
--- /dev/null
+++ res/raw/cert_ikanobank.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----

+fJ+H45cviS+GsER81pQ=
+-----END CERTIFICATE-----
diff --git res/raw/cert_ikanopartner.pem res/raw/cert_ikanopartner.pem
new file mode 100644
index 0000000..de03a0d
--- /dev/null
+++ res/raw/cert_ikanopartner.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----

+npgXOrhX
+-----END CERTIFICATE-----
diff --git res/raw/cert_jojo.pem res/raw/cert_jojo.pem
new file mode 100644
index 0000000..4651046
--- /dev/null
+++ res/raw/cert_jojo.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git res/raw/cert_lansforsakringar.pem res/raw/cert_lansforsakringar.pem
new file mode 100644
index 0000000..cc8b79b
--- /dev/null
+++ res/raw/cert_lansforsakringar.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+TA==
+-----END CERTIFICATE-----
diff --git res/raw/cert_marginalen.pem res/raw/cert_marginalen.pem
new file mode 100644
index 0000000..c56eadf
--- /dev/null
+++ res/raw/cert_marginalen.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+zN0LZmKqGQ==
+-----END CERTIFICATE-----
diff --git res/raw/cert_meniga.pem res/raw/cert_meniga.pem
new file mode 100644
index 0000000..9818831
--- /dev/null
+++ res/raw/cert_meniga.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+BXFYr71BrBjmug==
+-----END CERTIFICATE-----
diff --git res/raw/cert_mobilbanken.pem res/raw/cert_mobilbanken.pem
new file mode 100644
index 0000000..f437418
--- /dev/null
+++ res/raw/cert_mobilbanken.pem
@@ -0,0 +1,37 @@
+-----BEGIN CERTIFICATE-----

+I9g29oOgu4jg3vE=
+-----END CERTIFICATE-----
diff --git res/raw/cert_nordea_dk.pem res/raw/cert_nordea_dk.pem
new file mode 100644
index 0000000..99a9bb4
--- /dev/null
+++ res/raw/cert_nordea_dk.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+wnHAZGWM1O3xF54uWoBxuhg4dTFcK0P/wCwqG72cNyitx2Yd
+-----END CERTIFICATE-----
diff --git res/raw/cert_nordnet.pem res/raw/cert_nordnet.pem
new file mode 100644
index 0000000..1457151
--- /dev/null
+++ res/raw/cert_nordnet.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+zOljAA==
+-----END CERTIFICATE-----
diff --git res/raw/cert_nordnetdirekt.pem res/raw/cert_nordnetdirekt.pem
new file mode 100644
index 0000000..fc08c3b
--- /dev/null
+++ res/raw/cert_nordnetdirekt.pem
@@ -0,0 +1,41 @@
+-----BEGIN CERTIFICATE-----

+xBCLPXX17IGWWLHb+rZ0YU68b85++9CodblvjKqqCEXG
+-----END CERTIFICATE-----
diff --git res/raw/cert_okq8.pem res/raw/cert_okq8.pem
new file mode 100644
index 0000000..07511e9
--- /dev/null
+++ res/raw/cert_okq8.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+-----END CERTIFICATE-----
diff --git res/raw/cert_osuuspankki.pem res/raw/cert_osuuspankki.pem
new file mode 100644
index 0000000..4660fce
--- /dev/null
+++ res/raw/cert_osuuspankki.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----

+/Cad9TAS2uv1yg4nZDwIeQzWXXfxRrK0scbZpVU=
+-----END CERTIFICATE-----
diff --git res/raw/cert_plusgirot.pem res/raw/cert_plusgirot.pem
new file mode 100644
index 0000000..4849466
--- /dev/null
+++ res/raw/cert_plusgirot.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+dTSCRHZJTC7cHBdc8T6SFBy9uGrIEuOYRfvSvY1emj9lgwKZ
+-----END CERTIFICATE-----
diff --git res/raw/cert_resursbank.pem res/raw/cert_resursbank.pem
new file mode 100644
index 0000000..4f2f9bd
--- /dev/null
+++ res/raw/cert_resursbank.pem
@@ -0,0 +1,38 @@
+-----BEGIN CERTIFICATE-----

+PFLkY3zo7wY1C4ZwgXLQsb0QPc6eSdeg6C7rEa8XgS4=
+-----END CERTIFICATE-----
diff --git res/raw/cert_rikslunchen.pem res/raw/cert_rikslunchen.pem
new file mode 100644
index 0000000..0b0ef83
--- /dev/null
+++ res/raw/cert_rikslunchen.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----

+94VaODj3eZ9v1Tguxg==
+-----END CERTIFICATE-----
diff --git res/raw/cert_seb.pem res/raw/cert_seb.pem
new file mode 100644
index 0000000..15c1a40
--- /dev/null
+++ res/raw/cert_seb.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+cgz4UMS+A3qV9vPIs0HH5WQ8wkpYjv85ju7492w=
+-----END CERTIFICATE-----
diff --git res/raw/cert_sebkort.pem res/raw/cert_sebkort.pem
new file mode 100644
index 0000000..e8bf87e
--- /dev/null
+++ res/raw/cert_sebkort.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----

+gOwWPG5B14jvhuMMjC2XC4BpnVbeU5Ahui1lgkszFMg17ttTnUg=
+-----END CERTIFICATE-----
diff --git res/raw/cert_sevenday.pem res/raw/cert_sevenday.pem
new file mode 100644
index 0000000..0a233b5
--- /dev/null
+++ res/raw/cert_sevenday.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----

+PV2hZ7XKpVDd+Q41irJ0O6JluWFl8A==
+-----END CERTIFICATE-----
diff --git res/raw/cert_skandiabanken.pem res/raw/cert_skandiabanken.pem
new file mode 100644
index 0000000..67a03c4
--- /dev/null
+++ res/raw/cert_skandiabanken.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+aN+n7CUSNcYXnjgT6Yk3
+-----END CERTIFICATE-----
diff --git res/raw/cert_steam.pem res/raw/cert_steam.pem
new file mode 100644
index 0000000..17112e7
--- /dev/null
+++ res/raw/cert_steam.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+R/VAuYULZeKj+BWoYS4TCTWFmQQwkVtak1li4vIdIXC8
+-----END CERTIFICATE-----
diff --git res/raw/cert_svenskaspel.pem res/raw/cert_svenskaspel.pem
new file mode 100644
index 0000000..f7307c5
--- /dev/null
+++ res/raw/cert_svenskaspel.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+GjFd
+-----END CERTIFICATE-----
diff --git res/raw/cert_swedbank.pem res/raw/cert_swedbank.pem
new file mode 100644
index 0000000..5ec7c8d
--- /dev/null
+++ res/raw/cert_swedbank.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----

+o/wBKYKk1cLnWLP7mg==
+-----END CERTIFICATE-----
diff --git res/raw/cert_ticketrikskortet.pem res/raw/cert_ticketrikskortet.pem
new file mode 100644
index 0000000..42d26d1
--- /dev/null
+++ res/raw/cert_ticketrikskortet.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+k6xRfB3oW/H25YzF/b8MBZXr4TcAfLW1Hw==
+-----END CERTIFICATE-----
diff --git res/raw/cert_trustbuddy.pem res/raw/cert_trustbuddy.pem
new file mode 100644
index 0000000..7d05516
--- /dev/null
+++ res/raw/cert_trustbuddy.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----

+a3CPSRzu+D48dh22vCKG7AV7EE47QzaZaYSSgqRHeSmR3ws=
+-----END CERTIFICATE-----
diff --git res/raw/cert_vasttrafik.pem res/raw/cert_vasttrafik.pem
new file mode 100644
index 0000000..7f471f0
--- /dev/null
+++ res/raw/cert_vasttrafik.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+n4sqTE3G
+-----END CERTIFICATE-----
diff --git res/raw/cert_villabanken.pem res/raw/cert_villabanken.pem
new file mode 100644
index 0000000..14b3d1c
--- /dev/null
+++ res/raw/cert_villabanken.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+YMvo8caizM268OdHzj3WQt4biECp/9TWO3wAfGm1PjaY1A==
+-----END CERTIFICATE-----
diff --git res/raw/cert_volvofinans.pem res/raw/cert_volvofinans.pem
new file mode 100644
index 0000000..83bc563
--- /dev/null
+++ res/raw/cert_volvofinans.pem
@@ -0,0 +1,38 @@
+-----BEGIN CERTIFICATE-----

+sN/gfwvxMEN+/vG1PlRjDjlF2BkvnZhkt2Lc6GD552FhtLeYarLsgEiL
+-----END CERTIFICATE-----
diff --git res/raw/cert_zidisha.pem res/raw/cert_zidisha.pem
new file mode 100644
index 0000000..d6ff6a3
--- /dev/null
+++ res/raw/cert_zidisha.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----

+XpV9MUJd99mF
+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 7ea103a..7317118 100644
--- src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class AbsIkanoPartner extends Bank {
@@ -65,7 +66,7 @@ public abstract class AbsIkanoPartner extends Bank {
 
     @Override
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("__VIEWSTATE");
diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 8cce888..383cb1c 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AkeliusInvest extends Bank {
@@ -85,7 +86,7 @@ public class AkeliusInvest extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_akeliusinvest));
         String response = urlopen.open("https://online.akeliusinvest.com/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 010a3dc..902d942 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AkeliusSpar extends Bank {
@@ -86,7 +87,7 @@ public class AkeliusSpar extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_akeliusspar));
         String response = urlopen.open("https://www.online.akeliusspar.se/login.mws");
         Matcher matcher = reLogintoken.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index c906006..88eeaea 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -45,6 +45,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AmericanExpress extends Bank {
@@ -76,7 +77,8 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_americanexpress));
+        urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
index eb52b03..2e89456 100644
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -30,7 +30,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -42,6 +41,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Avanza extends Bank {
@@ -73,7 +73,8 @@ public class Avanza extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen.setAllowCircularRedirects(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index efe2fd6..4ae94ae 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class AvanzaMini extends Bank {
@@ -69,7 +70,8 @@ public class AvanzaMini extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_avanza));
+        urlopen.setAllowCircularRedirects(true);
         String response = urlopen.open("https://www.avanza.se/mini/logga_in/");
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("javax.faces.ViewState");
diff --git src/com/liato/bankdroid/banking/banks/BetterGlobe.java src/com/liato/bankdroid/banking/banks/BetterGlobe.java
index 34ad61f..b411853 100644
--- src/com/liato/bankdroid/banking/banks/BetterGlobe.java
+++ src/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class BetterGlobe extends Bank {
@@ -82,7 +83,8 @@ public class BetterGlobe extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true,true);
+        urlopen = new Urllib();
+        urlopen.setAllowCircularRedirects(true);
 		HashMap<String, String> headers = urlopen.getHeaders();
 		headers.put("Referer","http://betterglobe.com/login.aspx?lang=sv-SE");
     	List <NameValuePair> postData = new ArrayList <NameValuePair>();
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
index 42128cd..74a1fee 100644
--- src/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -36,13 +36,14 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Bioklubben extends Bank {
 	private static final String TAG = "Bioklubben";
 	private static final String NAME = "Bioklubben";
 	private static final String NAME_SHORT = "bioklubben";
-	private static final String URL = "http://bioklubben.sfbio.se/user/login";
+	private static final String URL = "https://bioklubben.sfbio.se/user/login";
 	private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
 	private static final boolean DISPLAY_DECIMALS = false;
 
@@ -71,22 +72,8 @@ public class Bioklubben extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
-        /*
-        response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-        }
-        String viewState = matcher.group(1);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_bioklubben));
 
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-        }
-        String eventValidation = matcher.group(1);            
-        */
-        
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("name", username));
         postData.add(new BasicNameValuePair("pass", password));
@@ -109,6 +96,7 @@ public class Bioklubben extends Bank {
             throw new BankException(e.getMessage());
         }
         catch (IOException e) {
+            e.printStackTrace();
             throw new BankException(e.getMessage());
         }
         return urlopen;
diff --git src/com/liato/bankdroid/banking/banks/BrummerKF.java src/com/liato/bankdroid/banking/banks/BrummerKF.java
index 3cecbe3..bccdf23 100644
--- src/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ src/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -36,12 +36,12 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class BrummerKF extends Bank {
@@ -84,7 +84,8 @@ public class BrummerKF extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true,true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_brummer));
+        urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.brummer.se/sv/online/privat/Login/");
         
         Matcher mViewstate = reViewstate.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 6124c43..be9e0a2 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -43,6 +43,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class CSN extends Bank {
@@ -84,7 +85,8 @@ public class CSN extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(false, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_csn));
+        urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://www.csn.se/bas/");
         response = urlopen.open("https://www.csn.se/bas/inloggning/pinkod.do");
@@ -124,6 +126,7 @@ public class CSN extends Bank {
 			throw new BankException("login:CPE:"+e.getCause().getMessage());
 		}
 		catch (IOException e) {
+            e.printStackTrace();
 			throw new BankException("login:IOE:"+e.getMessage());
 		}
 		return urlopen;
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index 376c7fa..f2ec282 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -27,9 +27,6 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
 import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
@@ -42,6 +39,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Coop extends Bank {
@@ -74,7 +72,7 @@ public class Coop extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_coop));
         urlopen.addHeader("Origin", "https://www.coop.se");
         urlopen.addHeader("Referer", "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
         response = urlopen.open("https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index 93ec7a4..c9b337e 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -43,6 +43,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class DanskeBank extends Bank {
@@ -84,7 +85,7 @@ public class DanskeBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_danskebank));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://mobil.danskebank.se/");
 
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index 3d0a392..ed8d7d5 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -29,7 +29,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -41,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class DinersClub extends Bank {
@@ -77,8 +77,13 @@ public class DinersClub extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
-        response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_dinersclub));
+        try {
+            response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        }
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
@@ -171,10 +176,6 @@ public class DinersClub extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (!urlopen.acceptsInvalidCertificates()) { //Should never happen, but we'll check it anyway.
-			urlopen = login();
-		}
-
 		String response = null;
 		Matcher matcher;
 		try {
diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 34de1b2..ac65ae2 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -24,6 +24,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class EasyCard extends Bank {
@@ -65,7 +66,7 @@ public class EasyCard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
 
-        urlopen                         = new Urllib(true);
+        urlopen                         = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_easycard));
         response                        = urlopen.open(EasyCard.URL);
         List<NameValuePair> postData    = new ArrayList<NameValuePair>();
 
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 4222c01..e1ca05e 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Eurocard extends Bank {
@@ -77,7 +78,7 @@ public class Eurocard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_eurocard));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open("https://secure.eurocard.se/nis/external/ecse/login.do");
         urlopen.addHeader("Referer", String.format("https://secure.eurocard.se/nis/external/ecse/login.do"));
diff --git src/com/liato/bankdroid/banking/banks/Everydaycard.java src/com/liato/bankdroid/banking/banks/Everydaycard.java
index c20efda..1d1e75d 100644
--- src/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ src/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Everydaycard extends Bank {
@@ -86,7 +87,7 @@ public class Everydaycard extends Bank {
 
     private LoginPackage preLoginInternal(String url) throws BankException,
     		ClientProtocolException, IOException {
-    	urlopen = new Urllib(true);
+    	urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_everydaycard));
     	List <NameValuePair> postData = new ArrayList <NameValuePair>();
     	postData.add(new BasicNameValuePair("nextPage", "firstPage"));                
     	postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index e09ef59..3553ddb 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -29,7 +29,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -41,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class FirstCard extends Bank {
@@ -75,7 +75,7 @@ public class FirstCard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_firstcard));
         response = urlopen.open("https://www.firstcard.se/login.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("op", "login"));                
diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index ecaf754..ae9a3c0 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -28,6 +28,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ForexBank extends Bank {
@@ -78,7 +79,7 @@ public class ForexBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_forexbank));
         String baseUrl = "https://nettbank.edb.com";
         String res = urlopen.open(baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
         String formAction = "";
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 5111ade..7625683 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Handelsbanken extends Bank {
@@ -84,7 +85,7 @@ public class Handelsbanken extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_handelsbanken));
         response = urlopen.open("https://m.handelsbanken.se/primary/");
         Matcher matcher = reLoginUrl.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 0b04c2a..cffa87f 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -45,6 +45,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Hemkop extends Bank {
@@ -79,7 +80,8 @@ public class Hemkop extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_hemkop));
+        urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.hemkop.se/Mina-sidor/Logga-in/");
         
         Document d = Jsoup.parse(response);
diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index 6522dd8..c83958d 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICA extends Bank {
@@ -78,7 +79,7 @@ public class ICA extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ica));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         String response = urlopen.open("https://www.ica.se/logga-in/");
         Matcher matcher = reViewState.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index cbf6f90..e14d122 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class IkanoBank extends Bank {
@@ -82,7 +83,7 @@ public class IkanoBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ikanobank));
         response = urlopen.open("https://secure.ikanobank.se/login");
         Matcher matcher;
         if (response.contains("Banken är stängd")) {
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 3e2b458..6f8c8d1 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -16,16 +16,6 @@
 
 package com.liato.bankdroid.banking.banks;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
@@ -39,6 +29,17 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class IkanoPartnerBase extends Bank {
@@ -73,7 +74,7 @@ public abstract class IkanoPartnerBase extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ikanopartner));
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index 14ee765..f53bedc 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Jojo extends Bank {
@@ -70,7 +71,7 @@ public class Jojo extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
     ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_jojo));
         response = urlopen.open("http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java src/com/liato/bankdroid/banking/banks/Marginalen.java
index 906eec3..6ec092d 100644
--- src/com/liato/bankdroid/banking/banks/Marginalen.java
+++ src/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -25,6 +25,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Marginalen extends Bank {
@@ -64,7 +65,7 @@ public class Marginalen extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_marginalen));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open(BASE_URL + "engine");
diff --git src/com/liato/bankdroid/banking/banks/Meniga.java src/com/liato/bankdroid/banking/banks/Meniga.java
index dc28255..85c0b99 100644
--- src/com/liato/bankdroid/banking/banks/Meniga.java
+++ src/com/liato/bankdroid/banking/banks/Meniga.java
@@ -12,6 +12,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
@@ -58,7 +60,7 @@ public class Meniga extends Bank{
 
     @Override
     protected LoginPackage preLogin() throws BankException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_meniga));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.meniga.is/Mobile");
         List<NameValuePair> postData = new ArrayList<NameValuePair>();
diff --git src/com/liato/bankdroid/banking/banks/MobilbankenBase.java src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 48c813c..9738d09 100644
--- src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class MobilbankenBase extends Bank {
@@ -71,7 +72,8 @@ public abstract class MobilbankenBase extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_mobilbanken));
+        urlopen.setAllowCircularRedirects(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         String postUrl = String.format("https://mobil-banken.se/%s/login.html", targetId);
         response = urlopen.open(postUrl);
diff --git src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
index ad7371e..a473836 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
@@ -85,7 +85,7 @@ public class Nordea extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, false, CertificateReader.getCertificates(context, R.raw.cert_nordea));
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordea));
         Matcher matcher;
         String response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
         matcher = reCSRF.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java src/com/liato/bankdroid/banking/banks/NordeaDK.java
index 1a8e89d..d45987b 100644
--- src/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ src/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -26,6 +26,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class NordeaDK extends Bank {
@@ -90,7 +91,7 @@ public class NordeaDK extends Bank {
 	protected LoginPackage preLogin() throws BankException,
 			ClientProtocolException, IOException {
 		if (urlopen == null) {
-			urlopen = new Urllib();
+            urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordea_dk));
 		}
 		response = urlopen
 				.open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index d935eee..857c07a 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnet extends Bank {
@@ -71,7 +72,7 @@ public class Nordnet extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordnet));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
         
diff --git src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index a153668..420aa28 100644
--- src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordnetdirekt extends Bank {
@@ -76,7 +77,7 @@ public class Nordnetdirekt extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_nordnetdirekt));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html");
 
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index 9110fae..aaa0ad1 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -31,7 +31,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -43,6 +42,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class OKQ8 extends Bank {
@@ -81,7 +81,7 @@ public class OKQ8 extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_okq8));
         Date d = new Date();
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
diff --git src/com/liato/bankdroid/banking/banks/Osuuspankki.java src/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 98d9071..44eb8a4 100644
--- src/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ src/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Osuuspankki extends Bank {
@@ -70,7 +71,7 @@ public class Osuuspankki extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_osuuspankki));
         response = urlopen.open("https://www.op.fi/op?kielikoodi=sv");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("REQUEST_LOGIN_ATTEMPTED", "true"));
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index bddd64f..e6fa73d 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -80,7 +80,7 @@ public class PayPal extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, false, CertificateReader.getCertificates(context, R.raw.cert_paypal));
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_paypal));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
index a47564d..043f182 100644
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -76,7 +76,7 @@ public class Payson extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true, false, CertificateReader.getCertificates(context, R.raw.cert_payson));
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_payson));
         response = urlopen.open("https://www.payson.se/signin/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java src/com/liato/bankdroid/banking/banks/PlusGirot.java
index 6ebe1bf..9624775 100644
--- src/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ src/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PlusGirot extends Bank {
@@ -73,7 +74,7 @@ public class PlusGirot extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_plusgirot));
         // Request first page to get cookies
         response = urlopen.open("https://kontoutdrag.plusgirot.se/ku/html/epostllg.htm");
 
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 4267852..64e55d7 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ResursBank extends Bank {
@@ -71,7 +72,7 @@ public class ResursBank extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_resursbank));
         response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("kontonummer", username));
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index a81e90f..5ae1c5b 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -51,6 +51,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Rikslunchen extends Bank {
@@ -86,9 +87,10 @@ public class Rikslunchen extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-		urlopen = new Urllib(true, true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_rikslunchen));
+        urlopen.setAllowCircularRedirects(true);
 
-		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
 		postData.add(new BasicNameValuePair("c0-param0", "string:" + password));
 		postData.add(new BasicNameValuePair("callCount", "1"));
 		postData.add(new BasicNameValuePair("windowName", ""));
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index e234427..91c94cd 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SEB extends Bank {
@@ -77,7 +78,7 @@ public class SEB extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_seb));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://m.seb.se/");
         urlopen.setKeepAliveTimeout(5);
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 267d406..629974d 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class SEBKortBase extends Bank {
@@ -70,7 +71,7 @@ public abstract class SEBKortBase extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_sebkort));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open(String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
         urlopen.addHeader("Referer", String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
@@ -165,9 +166,6 @@ public abstract class SEBKortBase extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (!urlopen.acceptsInvalidCertificates()) { //Should never happen, but we'll check it anyway.
-			urlopen = login();
-		}
 		if (account.getType() != Account.CCARD) return;
 		String response = null;
 		Matcher matcher;
diff --git src/com/liato/bankdroid/banking/banks/SevenDay.java src/com/liato/bankdroid/banking/banks/SevenDay.java
index 17215a3..041d812 100644
--- src/com/liato/bankdroid/banking/banks/SevenDay.java
+++ src/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SevenDay extends Bank {
@@ -75,7 +76,7 @@ public class SevenDay extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_sevenday));
         response = urlopen.open("https://www.sevenday.se/mina-sidor/mina-sidor.htm");
         
         Matcher matcher = reViewState.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index db12ee4..caa035a 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -29,6 +29,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Skandiabanken extends Bank {
@@ -75,7 +76,7 @@ public class Skandiabanken extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_skandiabanken));
 
 		HashMap<String, String> headers = urlopen.getHeaders();
 		headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID,
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index cf68296..c465528 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -45,6 +45,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Steam extends Bank {
@@ -78,7 +79,7 @@ public class Steam extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_steam));
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("redir", "account"));
         postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/SvenskaSpel.java src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index 53074a5..277515e 100644
--- src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class SvenskaSpel extends Bank {
@@ -70,7 +71,7 @@ public class SvenskaSpel extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-		urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_svenskaspel));
 
 		List<NameValuePair> postData = new ArrayList<NameValuePair>();
 		postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index a0ed9c5..fc63857 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Swedbank extends Bank {
@@ -82,7 +83,7 @@ public class Swedbank extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_swedbank));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
diff --git src/com/liato/bankdroid/banking/banks/TicketRikskortet.java src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 0dbe98d..00e7caa 100644
--- src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class TicketRikskortet extends Bank {
@@ -73,7 +74,7 @@ public class TicketRikskortet extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_ticketrikskortet));
         response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/TrustBuddy.java src/com/liato/bankdroid/banking/banks/TrustBuddy.java
index 82330e6..48512ba 100644
--- src/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ src/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -35,12 +35,12 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class TrustBuddy extends Bank {
@@ -79,7 +79,8 @@ public class TrustBuddy extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true,true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_trustbuddy));
+        urlopen.setAllowCircularRedirects(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 63d5819..83bb8c9 100644
--- src/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Vasttrafik extends Bank {
@@ -69,8 +70,8 @@ public class Vasttrafik extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
     ClientProtocolException, IOException {
-		urlopen = new Urllib(true);
-		response = urlopen.open("https://www.vasttrafik.se/mina-sidor/logga-in/");
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_vasttrafik));
+        response = urlopen.open("https://www.vasttrafik.se/mina-sidor/logga-in/");
 
 		Matcher matcher = reViewState.matcher(response);
 		if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index 0fe7a33..fee07f7 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Villabanken extends Bank {
@@ -69,7 +70,7 @@ public class Villabanken extends Bank {
 
 	@Override
 	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-		urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_villabanken));
 		String response = urlopen.open(URL);
 		Matcher matcher = reRequestDigest.matcher(response);
 		if (!matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 0f1c7c4..26993fb 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -50,6 +50,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Volvofinans extends Bank {
@@ -83,7 +84,7 @@ public class Volvofinans extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_volvofinans));
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
diff --git src/com/liato/bankdroid/banking/banks/Zidisha.java src/com/liato/bankdroid/banking/banks/Zidisha.java
index de3a5b2..f8ba08c 100644
--- src/com/liato/bankdroid/banking/banks/Zidisha.java
+++ src/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -27,7 +27,6 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
@@ -35,12 +34,12 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Zidisha extends Bank {
@@ -82,7 +81,8 @@ public class Zidisha extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true,true);
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_zidisha));
+        urlopen.setAllowCircularRedirects(true);
         response = urlopen.open("https://www.zidisha.org/");
         Matcher mUserGuess = reUserGuess.matcher(response);
         if (!mUserGuess.find()) {
diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 4cc483e..cd85015 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
@@ -79,7 +80,7 @@ public class ICABanken extends Bank {
 	}
 
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
+		urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_icabanken));
 		urlopen.addHeader("ApiVersion", API_VERSION);
 		urlopen.addHeader("Accept", "application/json");
 		urlopen.addHeader("ApiKey", API_KEY);
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index e21f934..f32fd7f 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -32,7 +32,6 @@ import java.util.regex.Pattern;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
-import org.apache.http.conn.EofSensorInputStream;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
@@ -60,6 +59,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Lansforsakringar extends Bank {
@@ -104,7 +104,9 @@ public class Lansforsakringar extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        Urllib weblogin = new Urllib(false, true);
+        Urllib weblogin = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
+        weblogin.setAllowCircularRedirects(true);
+
         String response = weblogin.open("https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
@@ -129,7 +131,7 @@ public class Lansforsakringar extends Bank {
     }
 
     public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(CertificateReader.getCertificates(context, R.raw.cert_lansforsakringar));
         urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
         urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
         urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
diff --git src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
similarity index 52%
copy from src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
copy to src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
index c2868f8..f1638a6 100644
--- src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/CertPinningSSLSocketFactory.java
@@ -19,83 +19,61 @@ package eu.nullbyte.android.urllib;
  * under the License.
  */
 
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
-import java.security.KeyStore;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
 import java.security.cert.Certificate;
-import java.util.List;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
 
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.conn.scheme.LayeredSocketFactory;
-import org.apache.http.conn.scheme.SocketFactory;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-
-/**
- * This socket factory will create ssl socket that accepts self signed
- * certificate
- * 
- * @author olamy
- * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
- *          $
- * @since 1.2.3
- */
-public class EasySSLSocketFactory implements SocketFactory,
-		LayeredSocketFactory {
+public class CertPinningSSLSocketFactory extends SSLSocketFactory {
 
 	private SSLContext sslcontext = null;
-	private List<Certificate> certificates;
-
-	private SSLContext createEasySSLContext() throws IOException {
-		try {
-			SSLContext context = SSLContext.getInstance("TLS");
-			if (certificates != null) {
-			String keyStoreType = KeyStore.getDefaultType();
-			KeyStore keyStore = KeyStore.getInstance(keyStoreType);
-			keyStore.load(null, null);
-			for (int i = 0; i < certificates.size(); i++) {
-		       keyStore.setCertificateEntry("ca_" + i, certificates.get(i));
-		    }
-			
-			String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
-			TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
-			tmf.init(keyStore);
-			
-			context.init(null, tmf.getTrustManagers(), null);
-			} else {
-				context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
-			}
-			return context;
-		} catch (Exception e) {
-			throw new IOException(e.getMessage());
-		}
+    private Certificate[] certificates;
+
+    public CertPinningSSLSocketFactory(Certificate[] certificates) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
+        super(null);
+        this.certificates = certificates;
+        setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
+    }
+
+	private SSLContext createSSLContext() throws IOException {
+        try {
+            SSLContext context = SSLContext.getInstance("TLS");
+            context.init(null, new TrustManager[] { new CertPinningTrustManager(certificates) }, null);
+            return context;
+        } catch (Exception e) {
+            throw new IOException(e.getMessage());
+        }
 	}
 
 	private SSLContext getSSLContext() throws IOException {
 		if (this.sslcontext == null) {
-			this.sslcontext = createEasySSLContext();
+			this.sslcontext = createSSLContext();
 		}
 		return this.sslcontext;
 	}
-	
-	public EasySSLSocketFactory(List<Certificate> certificates) {
-		this.certificates = certificates;
-	}
 
 	/**
 	 * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
-	 *      java.lang.String, int, java.net.InetAddress, int,
+	 *      String, int, java.net.InetAddress, int,
 	 *      org.apache.http.params.HttpParams)
 	 */
-	public Socket connectSocket(Socket sock, String host, int port,
+	@Override
+    public Socket connectSocket(Socket sock, String host, int port,
 			InetAddress localAddress, int localPort, HttpParams params)
 			throws IOException, UnknownHostException, ConnectTimeoutException {
 		int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
@@ -116,56 +94,35 @@ public class EasySSLSocketFactory implements SocketFactory,
 
 		sslsock.connect(remoteAddress, connTimeout);
 		sslsock.setSoTimeout(soTimeout);
-		return sslsock;
-
+        try {
+            getHostnameVerifier().verify(host, sslsock);
+            // verifyHostName() didn't blowup - good!
+        } catch (IOException iox) {
+            // close the socket before re-throwing the exception
+            try {
+                sslsock.close();
+            } catch (Exception x) { /*ignore*/ }
+            throw iox;
+        }
+        return sslsock;
 	}
 
 	/**
 	 * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
 	 */
+    @Override
 	public Socket createSocket() throws IOException {
 		return getSSLContext().getSocketFactory().createSocket();
-		
 	}
-	
 
 
-	/**
-	 * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
-	 */
-	public boolean isSecure(Socket socket) throws IllegalArgumentException {
-		return true;
-	}
-
 	/**
 	 * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
-	 *      java.lang.String, int, boolean)
+	 *      String, int, boolean)
 	 */
-	/*public Socket createSocket(Socket socket, String host, int port,
-			boolean autoClose) throws IOException, UnknownHostException {
-		return getSSLContext().getSocketFactory().createSocket();
-	}*/
+    @Override
     public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                     throws IOException, UnknownHostException {
             return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
     }		
-
-	// -------------------------------------------------------------------
-	// javadoc in org.apache.http.conn.scheme.SocketFactory says :
-	// Both Object.equals() and Object.hashCode() must be overridden
-	// for the correct operation of some connection managers
-	// -------------------------------------------------------------------
-
-	public boolean equals(Object obj) {
-		return ((obj != null) && obj.getClass().equals(
-				EasySSLSocketFactory.class));
-	}
-
-	public int hashCode() {
-		return EasySSLSocketFactory.class.hashCode();
-	}
-
-
-	
-	
 }
diff --git src/eu/nullbyte/android/urllib/CertPinningTrustManager.java src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
new file mode 100644
index 0000000..4ef336a
--- /dev/null
+++ src/eu/nullbyte/android/urllib/CertPinningTrustManager.java
@@ -0,0 +1,40 @@
+package eu.nullbyte.android.urllib;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+
+import javax.net.ssl.X509TrustManager;
+
+public class CertPinningTrustManager implements X509TrustManager {
+    private Certificate[] certificates;
+
+    public CertPinningTrustManager(Certificate[] certificates) {
+        this.certificates = certificates;
+    }
+
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+
+	@Override
+	public void checkClientTrusted(X509Certificate[] chain, String authType)
+			throws CertificateException {
+        throw new CertificateException("Client authentication not implemented.");
+	}
+
+	@Override
+	public void checkServerTrusted(X509Certificate[] chain, String authType)
+			throws java.security.cert.CertificateException {
+        for (X509Certificate certificate : chain) {
+            byte[] publicKey = certificate.getPublicKey().getEncoded();
+            for (Certificate pinnedCert : certificates) {
+                if (Arrays.equals(publicKey, pinnedCert.getPublicKey().getEncoded())) {
+                    return;
+                }
+            }
+        }
+        throw new CertificateException("Server certificate not trusted.");
+	}
+}
diff --git src/eu/nullbyte/android/urllib/CertificateReader.java src/eu/nullbyte/android/urllib/CertificateReader.java
index 3b39698..25aac89 100644
--- src/eu/nullbyte/android/urllib/CertificateReader.java
+++ src/eu/nullbyte/android/urllib/CertificateReader.java
@@ -1,8 +1,12 @@
 package eu.nullbyte.android.urllib;
 
+import android.content.Context;
+
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -10,11 +14,9 @@ import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.List;
 
-import android.content.Context;
-
 public class CertificateReader {
 
-	public static List<Certificate> getCertificates(Context context,
+	public static Certificate[] getCertificates(Context context,
 			int... rawResCerts) {
 		List<Certificate> certificates = new ArrayList<Certificate>();
 		try {
@@ -25,8 +27,6 @@ public class CertificateReader {
 				try {
 					X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
 					certificates.add(cert);
-					System.out.println("ca="
-							+ ((X509Certificate) cert).getSubjectDN());
 				} finally {
 					try {
 						is.close();
@@ -38,7 +38,39 @@ public class CertificateReader {
 		} catch (CertificateException e1) {
 			e1.printStackTrace();
 		}
-
-		return certificates;
+		return certificates.toArray(new Certificate[certificates.size()]);
 	}
+
+    public static String[] getPins(Context context, int... rawResCerts) {
+        Certificate[] certs = getCertificates(context, rawResCerts);
+        if (certs != null && certs.length > 0) {
+            String[] pins = new String[certs.length];
+            for (int i = 0; i < certs.length; i++) {
+                Certificate cert = certs[i];
+                try {
+                    MessageDigest digest = MessageDigest.getInstance("SHA1");
+                    byte[] publicKey = cert.getPublicKey().getEncoded();
+                    byte[] pin = digest.digest(publicKey);
+                    pins[i] = CertificateReader.byteArrayToHexString(pin);
+//                    System.out.println("pin=" + CertificateReader.byteArrayToHexString(pin) + ", version=" + ((X509Certificate)cert).getVersion() + ", ca="
+//                            + ((X509Certificate) cert).getSubjectDN());
+                } catch (NoSuchAlgorithmException e) {
+                    e.printStackTrace();
+                }
+            }
+            return pins;
+        }
+        return null;
+    }
+
+    private static String byteArrayToHexString(byte[] b) {
+        int len = b.length;
+        String data = new String();
+
+        for (int i = 0; i < len; i++){
+            data += Integer.toHexString((b[i] >> 4) & 0xf);
+            data += Integer.toHexString(b[i] & 0xf);
+        }
+        return data;
+    }
 }
diff --git src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
index c2868f8..0ccd322 100644
--- src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
@@ -36,6 +36,7 @@ import javax.net.ssl.TrustManagerFactory;
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.scheme.LayeredSocketFactory;
 import org.apache.http.conn.scheme.SocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 
@@ -52,31 +53,15 @@ public class EasySSLSocketFactory implements SocketFactory,
 		LayeredSocketFactory {
 
 	private SSLContext sslcontext = null;
-	private List<Certificate> certificates;
 
 	private SSLContext createEasySSLContext() throws IOException {
-		try {
-			SSLContext context = SSLContext.getInstance("TLS");
-			if (certificates != null) {
-			String keyStoreType = KeyStore.getDefaultType();
-			KeyStore keyStore = KeyStore.getInstance(keyStoreType);
-			keyStore.load(null, null);
-			for (int i = 0; i < certificates.size(); i++) {
-		       keyStore.setCertificateEntry("ca_" + i, certificates.get(i));
-		    }
-			
-			String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
-			TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
-			tmf.init(keyStore);
-			
-			context.init(null, tmf.getTrustManagers(), null);
-			} else {
-				context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
-			}
-			return context;
-		} catch (Exception e) {
-			throw new IOException(e.getMessage());
-		}
+        try {
+            SSLContext context = SSLContext.getInstance("TLS");
+            context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
+            return context;
+        } catch (Exception e) {
+            throw new IOException(e.getMessage());
+        }
 	}
 
 	private SSLContext getSSLContext() throws IOException {
@@ -86,10 +71,6 @@ public class EasySSLSocketFactory implements SocketFactory,
 		return this.sslcontext;
 	}
 	
-	public EasySSLSocketFactory(List<Certificate> certificates) {
-		this.certificates = certificates;
-	}
-
 	/**
 	 * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
 	 *      java.lang.String, int, java.net.InetAddress, int,
@@ -166,6 +147,4 @@ public class EasySSLSocketFactory implements SocketFactory,
 	}
 
 
-	
-	
 }
diff --git src/eu/nullbyte/android/urllib/TrivialTrustManager.java src/eu/nullbyte/android/urllib/TrivialTrustManager.java
index e2c2e74..54e4d8f 100644
--- src/eu/nullbyte/android/urllib/TrivialTrustManager.java
+++ src/eu/nullbyte/android/urllib/TrivialTrustManager.java
@@ -1,6 +1,8 @@
 package eu.nullbyte.android.urllib;
 
-public class TrivialTrustManager implements javax.net.ssl.X509TrustManager {
+import javax.net.ssl.X509TrustManager;
+
+public class TrivialTrustManager implements X509TrustManager {
     public java.security.cert.X509Certificate[] getAcceptedIssuers() {
         return new java.security.cert.X509Certificate[0];
     }
@@ -8,14 +10,11 @@ public class TrivialTrustManager implements javax.net.ssl.X509TrustManager {
 	public void checkClientTrusted(
 			java.security.cert.X509Certificate[] chain, String authType)
 			throws java.security.cert.CertificateException {
-		// TODO Auto-generated method stub
-		
 	}
+
 	@Override
 	public void checkServerTrusted(
 			java.security.cert.X509Certificate[] chain, String authType)
 			throws java.security.cert.CertificateException {
-		// TODO Auto-generated method stub
-		
 	}
 }
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 80b4c79..66cabdc 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -16,14 +16,6 @@
 
 package eu.nullbyte.android.urllib;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.cert.Certificate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
@@ -53,51 +45,55 @@ import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.EntityUtils;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
-    
     private String userAgent = DEFAULT_USER_AGENT;
     private DefaultHttpClient httpclient;
-	private HttpContext context;
+	private HttpContext mContext;
 	private String currentURI;
-	private boolean acceptInvalidCertificates = false;
 	private String charset = HTTP.UTF_8;
 	private HashMap<String, String> headers;
-	
-	public Urllib() {
-		this(false);
-	}
-	public Urllib(boolean acceptInvalidCertificates) {
-		this(acceptInvalidCertificates, false);
-	}	
-
-	public Urllib(boolean acceptInvalidCertificates, boolean allowCircularRedirects) {
-		this(acceptInvalidCertificates, allowCircularRedirects, null);
-	}
-	
-	public Urllib(boolean acceptInvalidCertificates, boolean allowCircularRedirects, List<Certificate> certificates) {
-		this.acceptInvalidCertificates = acceptInvalidCertificates;
+
+
+    public Urllib() {
+        this(null);
+    }
+
+	public Urllib(Certificate[] pins) {
 		this.headers = new HashMap<String, String>();
     	HttpParams params = new BasicHttpParams(); 
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, this.charset);
         params.setBooleanParameter("http.protocol.expect-continue", false);
-        if (allowCircularRedirects) params.setBooleanParameter("http.protocol.allow-circular-redirects", true);
-		if (acceptInvalidCertificates) {
-	        SchemeRegistry registry = new SchemeRegistry();
-	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
-	        registry.register(new Scheme("https", new EasySSLSocketFactory(certificates), 443));
-	        ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
-	        httpclient = new DefaultHttpClient(manager, params);
-		}
-		else {
-            SchemeRegistry registry = new SchemeRegistry();
-            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
-            registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
-            ClientConnectionManager  manager = new ThreadSafeClientConnManager(params, registry);
-			httpclient = new DefaultHttpClient(manager, params);
-		}
-    	context = new BasicHttpContext();
+        boolean noCertValidation = false;
+        SchemeRegistry registry = new SchemeRegistry();
+        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+        try {
+            registry.register(new Scheme("https", noCertValidation ? new EasySSLSocketFactory() : pins != null ? new CertPinningSSLSocketFactory(pins) : SSLSocketFactory.getSocketFactory(), 443));
+        } catch (UnrecoverableKeyException e) {
+            e.printStackTrace();
+        } catch (KeyManagementException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (KeyStoreException e) {
+            e.printStackTrace();
+        }
+        ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
+        httpclient = new DefaultHttpClient(manager, params);
+    	mContext = new BasicHttpContext();
     }
     
     public String open(String url) throws ClientProtocolException, IOException {
@@ -137,10 +133,10 @@ public class Urllib {
             request.addHeader(headerKeys[i], headerVals[i]);
         }
 
-        response = httpclient.execute(request, context);
+        response = httpclient.execute(request, mContext);
 
-        //HttpUriRequest currentReq = (HttpUriRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
-        //HttpHost currentHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+        //HttpUriRequest currentReq = (HttpUriRequest)mContext.getAttribute(ExecutionContext.HTTP_REQUEST);
+        //HttpHost currentHost = (HttpHost)mContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
         //this.currentURI = currentHost.toURI() + currentReq.getURI();
         this.currentURI = request.getURI().toString();
 
@@ -199,8 +195,8 @@ public class Urllib {
         httpclient.getConnectionManager().shutdown();
     }
     
-    public HttpContext getContext() {
-    	return context;
+    public HttpContext getmContext() {
+    	return mContext;
     }
     
     public String getCurrentURI() {
@@ -214,7 +210,13 @@ public class Urllib {
     public void setContentCharset(String charset) {
         this.charset = charset;
         HttpProtocolParams.setContentCharset(httpclient.getParams(), this.charset);
-    }    
+    }
+
+
+    public void setAllowCircularRedirects(boolean allow) {
+        httpclient.getParams().setBooleanParameter("http.protocol.allow-circular-redirects", allow);
+    }
+
     public void addHeader(String key, String value) {
         this.headers.put(key, value);
     }
@@ -241,10 +243,6 @@ public class Urllib {
     }
 
     
-    public boolean acceptsInvalidCertificates() {
-    	return acceptInvalidCertificates;
-    }
-    
     public void setUserAgent(String userAgent) {
     	this.userAgent = userAgent; 
     }

commit 394a21ad9f396bc47cb96fe0624bdbb20f5e9a44
Merge: 7acf375 56fe67b
Author: liato <x@x00.us>
Date:   Sun Oct 6 06:00:35 2013 +0200

    Merge branch 'master' into certpinning
    
    * master:
      Adds manifest configuration to build file
      Remove libraries, use gradle for dependency resolution instead
      Adds Gradle support

commit 56fe67b163aa15635becb971dd01580a9aba4e1f
Merge: 17d1a8e ac7b265
Author: liato <x@x00.us>
Date:   Sat Oct 5 20:59:18 2013 -0700

    Merge pull request #243 from goober/feature/gradle
    
    Initial gradle support

commit 7acf3751362bf3e98deb91dd2f1902e92a337816
Author: liato <x@x00.us>
Date:   Sun Oct 6 05:56:58 2013 +0200

    Update gitignore.

diff --git .gitignore .gitignore
index c2f1d57..fbfcec9 100644
--- .gitignore
+++ .gitignore
@@ -1,4 +1,5 @@
 .metadata
+.settings
 tmp/**
 .DS_Store
 *.tmp

commit 7d53eb1701c8a9118ddb6a8e8a78f04aece4bb0a
Author: liato <x@x00.us>
Date:   Sun Oct 6 05:55:31 2013 +0200

    Cert pinning stuff.

diff --git res/raw/cert_nordea.pem res/raw/cert_nordea.pem
new file mode 100644
index 0000000..1378da3
--- /dev/null
+++ res/raw/cert_nordea.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----

+H52hgaaXFsWiJlfFdynJgqvbwA==
+-----END CERTIFICATE-----
diff --git res/raw/cert_paypal.pem res/raw/cert_paypal.pem
new file mode 100644
index 0000000..b23f422
--- /dev/null
+++ res/raw/cert_paypal.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----

+O7ugV9tPvj01jhp3LXSQH9KDSo0QXD0a6g==
+-----END CERTIFICATE-----
diff --git res/raw/cert_payson.pem res/raw/cert_payson.pem
new file mode 100644
index 0000000..3c33a54
--- /dev/null
+++ res/raw/cert_payson.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----

+MQyrnOskB283xLgbTob9
+-----END CERTIFICATE-----
diff --git src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
index 6e0f52e..ad7371e 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordea extends Bank {
@@ -84,7 +85,7 @@ public class Nordea extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(true, false, CertificateReader.getCertificates(context, R.raw.cert_nordea));
         Matcher matcher;
         String response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
         matcher = reCSRF.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index cbc39d6..bddd64f 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class PayPal extends Bank {
@@ -79,7 +80,7 @@ public class PayPal extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(true, false, CertificateReader.getCertificates(context, R.raw.cert_paypal));
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
index f59ef3d..a47564d 100644
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
+import eu.nullbyte.android.urllib.CertificateReader;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Payson extends Bank {
@@ -75,7 +76,7 @@ public class Payson extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(true, false, CertificateReader.getCertificates(context, R.raw.cert_payson));
         response = urlopen.open("https://www.payson.se/signin/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
@@ -114,6 +115,7 @@ public class Payson extends Bank {
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
+			e.printStackTrace();
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
diff --git src/eu/nullbyte/android/urllib/CertificateReader.java src/eu/nullbyte/android/urllib/CertificateReader.java
new file mode 100644
index 0000000..3b39698
--- /dev/null
+++ src/eu/nullbyte/android/urllib/CertificateReader.java
@@ -0,0 +1,44 @@
+package eu.nullbyte.android.urllib;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.Context;
+
+public class CertificateReader {
+
+	public static List<Certificate> getCertificates(Context context,
+			int... rawResCerts) {
+		List<Certificate> certificates = new ArrayList<Certificate>();
+		try {
+			CertificateFactory cf = CertificateFactory.getInstance("X.509");
+			for (int resId : rawResCerts) {
+				InputStream is = new BufferedInputStream(context.getResources()
+						.openRawResource(resId));
+				try {
+					X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
+					certificates.add(cert);
+					System.out.println("ca="
+							+ ((X509Certificate) cert).getSubjectDN());
+				} finally {
+					try {
+						is.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+				}
+			}
+		} catch (CertificateException e1) {
+			e1.printStackTrace();
+		}
+
+		return certificates;
+	}
+}
diff --git src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
index 936876d..c2868f8 100644
--- src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
@@ -24,10 +24,14 @@ import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.UnknownHostException;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.util.List;
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
 
 import org.apache.http.conn.ConnectTimeoutException;
 import org.apache.http.conn.scheme.LayeredSocketFactory;
@@ -48,11 +52,27 @@ public class EasySSLSocketFactory implements SocketFactory,
 		LayeredSocketFactory {
 
 	private SSLContext sslcontext = null;
+	private List<Certificate> certificates;
 
-	private static SSLContext createEasySSLContext() throws IOException {
+	private SSLContext createEasySSLContext() throws IOException {
 		try {
 			SSLContext context = SSLContext.getInstance("TLS");
-			context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
+			if (certificates != null) {
+			String keyStoreType = KeyStore.getDefaultType();
+			KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+			keyStore.load(null, null);
+			for (int i = 0; i < certificates.size(); i++) {
+		       keyStore.setCertificateEntry("ca_" + i, certificates.get(i));
+		    }
+			
+			String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+			TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+			tmf.init(keyStore);
+			
+			context.init(null, tmf.getTrustManagers(), null);
+			} else {
+				context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
+			}
 			return context;
 		} catch (Exception e) {
 			throw new IOException(e.getMessage());
@@ -65,6 +85,10 @@ public class EasySSLSocketFactory implements SocketFactory,
 		}
 		return this.sslcontext;
 	}
+	
+	public EasySSLSocketFactory(List<Certificate> certificates) {
+		this.certificates = certificates;
+	}
 
 	/**
 	 * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index a340e12..80b4c79 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -19,6 +19,7 @@ package eu.nullbyte.android.urllib;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -71,6 +72,10 @@ public class Urllib {
 	}	
 
 	public Urllib(boolean acceptInvalidCertificates, boolean allowCircularRedirects) {
+		this(acceptInvalidCertificates, allowCircularRedirects, null);
+	}
+	
+	public Urllib(boolean acceptInvalidCertificates, boolean allowCircularRedirects, List<Certificate> certificates) {
 		this.acceptInvalidCertificates = acceptInvalidCertificates;
 		this.headers = new HashMap<String, String>();
     	HttpParams params = new BasicHttpParams(); 
@@ -81,7 +86,7 @@ public class Urllib {
 		if (acceptInvalidCertificates) {
 	        SchemeRegistry registry = new SchemeRegistry();
 	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
-	        registry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+	        registry.register(new Scheme("https", new EasySSLSocketFactory(certificates), 443));
 	        ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
 	        httpclient = new DefaultHttpClient(manager, params);
 		}

commit 17d1a8e9c7e862a67e03cebfc434fd5cd080d6bb
Author: liato <x@x00.us>
Date:   Thu Oct 3 00:38:10 2013 +0200

    Add support for Bitcoin.

diff --git AndroidManifest.xml AndroidManifest.xml
index 5159121..19fb39d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.1" android:versionCode="161">
+	android:versionName="1.9.6.2-RC1" android:versionCode="162">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/drawable-xxhdpi/logo_bitcoin.png res/drawable-xxhdpi/logo_bitcoin.png
new file mode 100644
index 0000000..9faa62b
Binary files /dev/null and res/drawable-xxhdpi/logo_bitcoin.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index b75a98d..1c6d2a9 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -16,6 +16,7 @@
     <string name="invalid_username_password">Användarnamn och lösenord stämmer ej.</string>
     <string name="invalid_username">Ogiltigt användarnamn.</string>
     <string name="invalid_card_number">Ogiltigt kortnummer.</string>
+    <string name="invalid_bitcoin_address">Ogiltig bitcoin-adress.</string>
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="no_accounts_found">Inga konton funna</string>
     <string name="transparent_background">Transparent bakgrund</string>
@@ -242,7 +243,8 @@
     
 	<string name="card_id">Kort ID</string>
 	<string name="card_number">Kortnummer</string>
-	
+	<string name="bitcoin_address">Bitcoin-adress</string>
+		
 	<string name="nordnetdirekt_extras_title">Nyckel</string>
 	<string name="select_a_bank">Välj en bank</string>
 	<string name="invalid_integer">%1$s är inte ett giltigt positivt heltal, var god försök igen.</string>
diff --git res/values/strings.xml res/values/strings.xml
index 448e910..363f0ab 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -15,6 +15,7 @@
     <string name="invalid_username_password">Invalid username or password.</string>
     <string name="invalid_username">Invalid username.</string>
     <string name="invalid_card_number">Invalid card number.</string>
+    <string name="invalid_bitcoin_address">Invalid bitcoin address.</string>
     <string name="unable_to_find">Unable to find</string>
     <string name="no_accounts_found">No accounts found</string>
     <string name="transparent_background">Transparent background</string>
@@ -294,7 +295,8 @@
          
 	<string name="card_id">Card ID</string>
 	<string name="card_number">Card number</string>
-	
+	<string name="bitcoin_address">Bitcoin address</string>
+		
 	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 82ae807..69ff11a 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -105,22 +105,24 @@ public class Helpers {
         }
         return ret;
     }
-    public static String formatBalance(BigDecimal balance, String curr, boolean round) {
+    public static String formatBalance(BigDecimal balance, String curr, boolean round, DecimalFormat format) {
         DecimalFormatSymbols dfs = new DecimalFormatSymbols();
         dfs.setDecimalSeparator(',');
         dfs.setGroupingSeparator(' ');
-        DecimalFormat currency;
-        if (!round) {
-            currency = new DecimalFormat("#,##0.00 ");
-        }
-        else {
-            currency = new DecimalFormat("#,##0 ");  
+        DecimalFormat currency = format;
+        if (currency == null) {
+	        if (!round) {
+	            currency = new DecimalFormat("#,##0.00 ");
+	        }
+	        else {
+	            currency = new DecimalFormat("#,##0 ");  
+	        }
         }
         currency.setDecimalFormatSymbols(dfs);
         return currency.format(balance.doubleValue())+curr;
     }
     public static String formatBalance(BigDecimal balance, String curr) {
-        return formatBalance(balance, curr, false);
+        return formatBalance(balance, curr, false, null);
     }
     public static String formatBalance(Double balance, String curr) {
         return formatBalance(new BigDecimal(balance), curr);
diff --git src/com/liato/bankdroid/adapters/AccountsAdapter.java src/com/liato/bankdroid/adapters/AccountsAdapter.java
index 4470598..2b86197 100644
--- src/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ src/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -89,7 +89,7 @@ public class AccountsAdapter extends BaseAdapter {
                 .findViewById(R.id.txtListitemAccountsGroupTotal))
                 .setText(Helpers.formatBalance(bank.getBalance(),
                         bank.getCurrency(),
-                        prefs.getBoolean("round_balance", false) || !bank.getDisplayDecimals()));
+                        prefs.getBoolean("round_balance", false) || !bank.getDisplayDecimals(), bank.getDecimalFormatter()));
 		icon.setImageResource(bank.getImageResource());
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
 		if (bank.isDisabled()) {
@@ -116,7 +116,8 @@ public class AccountsAdapter extends BaseAdapter {
         txtBalance
                 .setText(Helpers.formatBalance(account.getBalance(),
                         account.getCurrency(),
-                        prefs.getBoolean("round_balance", false) || !account.getBank().getDisplayDecimals()));
+                        prefs.getBoolean("round_balance", false) || !account.getBank().getDisplayDecimals(),
+                        account.getBank().getDecimalFormatter()));
 		if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
             txtBalance.setTextColor(Color.argb(255, 191, 191, 191));		    
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index f4884fe..7ee4295 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -144,7 +144,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
         views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
-        views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false)));
+        views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false), bank.getDecimalFormatter()));
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
 		if (bank.isDisabled()) {
 			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index cdddcae..6b0e43b 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking;
 
 import java.io.IOException;
 import java.math.BigDecimal;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -27,6 +28,12 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.CookieStore;
 
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.text.InputType;
+import android.util.Log;
+
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
@@ -35,12 +42,6 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.provider.IBankTypes;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.text.InputType;
-import android.util.Log;
-
 import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class Bank implements Comparable<Bank>, IBankTypes {
@@ -424,5 +425,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     protected Context getContext() {
     	return context;
     }
+    
+    public DecimalFormat getDecimalFormatter() {
+    	return null;
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index a8afce2..5cf8909 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -94,6 +94,7 @@ import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
+import com.liato.bankdroid.banking.banks.bitcoin.Bitcoin;
 import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.exceptions.BankException;
@@ -249,6 +250,8 @@ public class BankFactory {
         	return new BetterGlobe(context);
         case IBankTypes.FOREX:
             return new ForexBank(context);
+        case IBankTypes.BITCOIN:
+            return new Bitcoin(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -328,6 +331,7 @@ public class BankFactory {
         banks.add(new BetterGlobe(context));
         banks.add(new ForexBank(context));
         banks.add(new EurobonusMastercardNo(context));
+        banks.add(new Bitcoin(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java src/com/liato/bankdroid/banking/banks/McDonalds.java
index 1f461ca..fcf6deb 100644
--- src/com/liato/bankdroid/banking/banks/McDonalds.java
+++ src/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -50,7 +50,7 @@ public class McDonalds extends Bank {
 	private static final int BANKTYPE_ID = Bank.MCDONALDS;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	private static final boolean INPUT_HIDDEN_PASSWORD = true;
-	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;	
+	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;
 
     private Pattern reBalance = Pattern.compile("saldo:\\s*([0-9,. -]+)\\s*kronor");
     private Pattern reTransactions = Pattern.compile("<tr><td>(\\d{2}-\\d{2}-\\d{2})\\s*\\d{2}:\\d{2}</td><td>([^<]+)</td><td>[^<]+</td><td>([^<]+)</td></tr>");
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
new file mode 100644
index 0000000..7fb8f9c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/bitcoin/Bitcoin.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.bitcoin;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.bitcoin.model.BlockchainResponse;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Bitcoin extends Bank {
+	private static final String TAG = "Bitcoin";
+	private static final String NAME = "Bitcoin";
+	private static final String NAME_SHORT = "bitcoin";
+	private static final String URL = "http://blockchain.info";
+	private static final int BANKTYPE_ID = IBankTypes.BITCOIN;
+	private static final boolean STATIC_BALANCE = false;
+	private static final boolean INPUT_HIDDEN_PASSWORD = true;
+	private static final int INPUT_TITLETEXT_USERNAME = R.string.bitcoin_address;	
+	
+	private static final String API_URL = "http://blockchain.info/rawaddr/";
+	private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0.00000000 ");
+
+	public Bitcoin(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
+		super.currency = "BTC";
+		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
+		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+	}
+
+	public Bitcoin(String username, String password, Context context)
+			throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib();
+
+		try {
+			String response = urlopen.open(API_URL + username);
+			if(response == null || "".equals(response)) {
+				throw new LoginException(res.getText(
+						R.string.invalid_username_password).toString());
+			}
+			ObjectMapper vObjectMapper = new ObjectMapper();
+			BlockchainResponse r = vObjectMapper.readValue(urlopen.open(API_URL + username), BlockchainResponse.class);
+			Account a = new Account("Bitcoin", new BigDecimal(r.getFinalBalance()).divide(BigDecimal.valueOf(100000000)), "1");
+			a.setCurrency("BTC");
+			accounts.add(a);
+			setCurrency("BTC");
+		} catch (JsonParseException e) {
+			throw new LoginException(res.getText(
+					R.string.invalid_bitcoin_address).toString());
+		}catch (ClientProtocolException e) {
+			e.printStackTrace();
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException,
+			BankChoiceException {
+		super.update();
+		if (TextUtils.isEmpty(username)) {
+			throw new LoginException(res.getText(
+					R.string.invalid_bitcoin_address).toString());
+		}
+		login();
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found)
+					.toString());
+		}
+		super.updateComplete();
+	}
+
+	@Override
+	public DecimalFormat getDecimalFormatter() {
+		return DECIMAL_FORMAT;
+	}
+}
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java src/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
new file mode 100644
index 0000000..6f51161
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/bitcoin/model/BlockchainResponse.java
@@ -0,0 +1,61 @@
+package com.liato.bankdroid.banking.banks.bitcoin.model;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class BlockchainResponse implements Serializable {
+	private static final long serialVersionUID = -5144109898538621019L;
+	@JsonProperty("total_sent")
+	private long mTotalSent;
+	@JsonProperty("total_received")
+	private long mTotalReceived;
+	@JsonProperty("final_balance")
+	private long mFinalBalance;
+	@JsonProperty("address")
+	private String mAddress;
+	@JsonProperty("hash160")
+	private String mHash160;
+	@JsonProperty("txs")
+	private List<Transfer> mTxs = Collections.emptyList();
+	@JsonProperty("n_tx")
+	private long mNTx;
+
+	@JsonProperty("total_sent")
+	public long getTotalSent() {
+		return mTotalSent;
+	}
+
+	@JsonProperty("total_received")
+	public long getTotalReceived() {
+		return mTotalReceived;
+	}
+
+	@JsonProperty("final_balance")
+	public long getFinalBalance() {
+		return mFinalBalance;
+	}
+
+	@JsonProperty("address")
+	public String getAddress() {
+		return mAddress;
+	}
+
+	@JsonProperty("hash160")
+	public String getHash160() {
+		return mHash160;
+	}
+
+	@JsonProperty("txs")
+	public List<Transfer> getTxs() {
+		return mTxs;
+	}
+
+	@JsonProperty("n_tx")
+	public long getNTx() {
+		return mNTx;
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java src/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
new file mode 100644
index 0000000..f202150
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/bitcoin/model/Input.java
@@ -0,0 +1,17 @@
+package com.liato.bankdroid.banking.banks.bitcoin.model;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Input implements Serializable {
+	private static final long serialVersionUID = 7507419745749485877L;
+	@JsonProperty("prev_out")
+	private PrevOut mPrevOut;
+
+	@JsonProperty("prev_out")
+	public PrevOut getPrevOut() {
+		return mPrevOut;
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java src/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
new file mode 100644
index 0000000..99142bc
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/bitcoin/model/Out.java
@@ -0,0 +1,45 @@
+package com.liato.bankdroid.banking.banks.bitcoin.model;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Out implements Serializable {
+	private static final long serialVersionUID = 3773393008409837454L;
+	@JsonProperty("tx_index")
+	private long mTxIndex;
+	@JsonProperty("type")
+	private int mType;
+	@JsonProperty("addr")
+	private String mAddr;
+	@JsonProperty("value")
+	private long mValue;
+	@JsonProperty("n")
+	private long mN;
+
+	@JsonProperty("tx_index")
+	public long getTxIndex() {
+		return mTxIndex;
+	}
+
+	@JsonProperty("type")
+	public int getType() {
+		return mType;
+	}
+
+	@JsonProperty("addr")
+	public String getAddr() {
+		return mAddr;
+	}
+
+	@JsonProperty("value")
+	public long getValue() {
+		return mValue;
+	}
+
+	@JsonProperty("n")
+	public long getN() {
+		return mN;
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java src/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
new file mode 100644
index 0000000..c065b0c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/bitcoin/model/PrevOut.java
@@ -0,0 +1,45 @@
+package com.liato.bankdroid.banking.banks.bitcoin.model;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class PrevOut implements Serializable {
+	private static final long serialVersionUID = 9102767809232718841L;
+	@JsonProperty("tx_index")
+	private long mTxIndex;
+	@JsonProperty("type")
+	private int mType;
+	@JsonProperty("addr")
+	private String mAddr;
+	@JsonProperty("value")
+	private long mValue;
+	@JsonProperty("n")
+	private long mN;
+
+	@JsonProperty("tx_index")
+	public long getTxIndex() {
+		return mTxIndex;
+	}
+
+	@JsonProperty("type")
+	public int getType() {
+		return mType;
+	}
+
+	@JsonProperty("addr")
+	public String getAddr() {
+		return mAddr;
+	}
+
+	@JsonProperty("value")
+	public long getValue() {
+		return mValue;
+	}
+
+	@JsonProperty("n")
+	public long getN() {
+		return mN;
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
new file mode 100644
index 0000000..50c3031
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/bitcoin/model/Transfer.java
@@ -0,0 +1,96 @@
+package com.liato.bankdroid.banking.banks.bitcoin.model;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Transfer implements Serializable {
+	private static final long serialVersionUID = -2558362412750999606L;
+	@JsonProperty("size")
+	private long mSize;
+	@JsonProperty("inputs")
+	private List<Input> mInputs = Collections.emptyList();
+	@JsonProperty("hash")
+	private String mHash;
+	@JsonProperty("tx_index")
+	private long mTxIndex;
+	@JsonProperty("relayed_by")
+	private String mRelayedBy;
+	@JsonProperty("block_height")
+	private long mBlockHeight;
+	@JsonProperty("vin_sz")
+	private long mVinSz;
+	@JsonProperty("vout_sz")
+	private long mVoutSz;
+	@JsonProperty("time")
+	private long mTime;
+	@JsonProperty("ver")
+	private long mVer;
+	@JsonProperty("out")
+	private List<Out> mOut = Collections.emptyList();
+	@JsonProperty("result")
+	private long mResult;
+
+	@JsonProperty("size")
+	public long getSize() {
+		return mSize;
+	}
+
+	@JsonProperty("inputs")
+	public List<Input> getInputs() {
+		return mInputs;
+	}
+
+	@JsonProperty("hash")
+	public String getHash() {
+		return mHash;
+	}
+
+	@JsonProperty("tx_index")
+	public long getTxIndex() {
+		return mTxIndex;
+	}
+
+	@JsonProperty("relayed_by")
+	public String getRelayedBy() {
+		return mRelayedBy;
+	}
+
+	@JsonProperty("block_height")
+	public long getBlockHeight() {
+		return mBlockHeight;
+	}
+
+	@JsonProperty("vin_sz")
+	public long getVinSz() {
+		return mVinSz;
+	}
+
+	@JsonProperty("vout_sz")
+	public long getVoutSz() {
+		return mVoutSz;
+	}
+
+	@JsonProperty("time")
+	public long getTime() {
+		return mTime;
+	}
+
+	@JsonProperty("ver")
+	public long getVer() {
+		return mVer;
+	}
+
+	@JsonProperty("out")
+	public List<Out> getOut() {
+		return mOut;
+	}
+
+	@JsonProperty("result")
+	public long getResult() {
+		return mResult;
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index fd07ac6..969b8ae 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -93,4 +93,5 @@ public interface IBankTypes {
     public static final int BETTERGLOBE = 69;
     public static final int FOREX = 70;
     public final static int SASEUROBONUSMASTERCARD_NO = 71;
+    public final static int BITCOIN = 72;
 }

commit f4bc8dd408d3475b00905db5c584de4a05d4c77c
Author: liato <x@x00.us>
Date:   Thu Oct 3 00:37:47 2013 +0200

    Fix for IkanoBank.

diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index e31c665..cbf6f90 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -55,7 +55,7 @@ public class IkanoBank extends Bank {
 
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reErrorMessage = Pattern.compile("<div\\s*class=\"(?:error|message)-box-inner\">\\s*<div>\\s*<p>(.+)</p");
     private String response = null;

commit b993d694273326ba0f2758d8180dd5d310ec5f79
Author: liato <x@x00.us>
Date:   Mon Sep 30 01:06:46 2013 +0200

    Add missing logo.

diff --git res/drawable/logo_ebmaster_no.png res/drawable/logo_ebmaster_no.png
new file mode 100644
index 0000000..0354e55
Binary files /dev/null and res/drawable/logo_ebmaster_no.png differ

commit f4aa2016393d8c6eb19819aae04639deeab5fff1 (tag: v1.9.6.1)
Author: liato <x@x00.us>
Date:   Mon Sep 30 01:04:40 2013 +0200

    Update changelog. Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index b34def7..5159121 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.0" android:versionCode="160">
+	android:versionName="1.9.6.1" android:versionCode="161">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git CHANGES.txt CHANGES.txt
index a8c66ef..467f957 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,9 +1,20 @@
+v1.9.6.1: (2013-09-30)
+* Fix for PayPal
+* Fix for Diners Club (thanks to ScuttleSE)
+* ICA Banken uses their API (thanks to goober)
+* Fix for multiple accounts in Forex Bank (thanks to rickythefox)
+* Fix for Villabanken (thanks to knifhen)
++ Support for SAS EuroBonus MasterCard Norway
+- Removed Danske Bank
+- Removed Sparbanken Öresund
+
+
 v1.9.6.0: (2013-06-22)
 * Fix for PayPal
 * Fix for Hemköp
 * Fix for ICA
 * Fix for Volvofinans
-+ Support for Forex Bank (thanks till rickythefox)
++ Support for Forex Bank (thanks to rickythefox)
 + Support for BetterGlobe (thanks to Tuxie)
 + Support for Zidisha (thanks to Tuxie)
 

commit 89b66a28b0b8be256221a45b19db977e61f040da
Author: liato <x@x00.us>
Date:   Mon Sep 30 01:03:34 2013 +0200

    Add SAS EuroBonus MasterCard Norway.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index bb64996..a8afce2 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -24,7 +24,7 @@ import android.content.Context;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
-import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
+
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
+import com.liato.bankdroid.banking.banks.EurobonusMastercardNo;
 import com.liato.bankdroid.banking.banks.Eurocard;
 import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
@@ -93,6 +94,7 @@ import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
+import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
@@ -151,6 +153,8 @@ public class BankFactory {
             return new IkanoBank(context);
         case IBankTypes.SASEUROBONUSMASTERCARD:
         	return new EurobonusMastercard(context);
+        case IBankTypes.SASEUROBONUSMASTERCARD_NO:
+        	return new EurobonusMastercardNo(context);
         case IBankTypes.RIKSLUNCHEN:
             return new Rikslunchen(context);            
         case IBankTypes.HEMKOP:
@@ -323,6 +327,7 @@ public class BankFactory {
         banks.add(new Zidisha(context));
         banks.add(new BetterGlobe(context));
         banks.add(new ForexBank(context));
+        banks.add(new EurobonusMastercardNo(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
new file mode 100644
index 0000000..1c2ba64
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercardNo.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class EurobonusMastercardNo extends SEBKortBase {
+	private static final String TAG = "EurobonusMastercardNo";
+	private static final String NAME = "SAS EuroBonus MasterCard (Norway)";
+	private static final String NAME_SHORT = "ebmaster_no";
+	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD_NO;
+
+	public EurobonusMastercardNo(Context context) {
+		super(context, "sano", "0102");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public EurobonusMastercardNo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		super(username, password, context, "sano", "0102");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index e8a76b0..fd07ac6 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -92,4 +92,5 @@ public interface IBankTypes {
     public static final int ZIDISHA = 68;
     public static final int BETTERGLOBE = 69;
     public static final int FOREX = 70;
+    public final static int SASEUROBONUSMASTERCARD_NO = 71;
 }

commit f974149d92f052456c3fd093e47d0a8fff921244
Author: liato <x@x00.us>
Date:   Mon Sep 30 00:44:38 2013 +0200

    Remove Danske Bank.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index ba42547..bb64996 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -308,7 +308,7 @@ public class BankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
-        banks.add(new DanskeBank(context));
+//        banks.add(new DanskeBank(context));
         banks.add(new NordeaDK(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));

commit 36f8d2c7c9d5b52fbe33d5fab4b21cf3a371a03f
Author: liato <x@x00.us>
Date:   Mon Sep 30 00:28:31 2013 +0200

    Remove Sparbanken Öresund.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index cd2619c..ba42547 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -290,7 +290,7 @@ public class BankFactory {
         banks.add(new McDonalds(context));
         banks.add(new SJPrio(context));
         banks.add(new SparbankenSyd(context));
-        banks.add(new SparbankenOresund(context));
+//        banks.add(new SparbankenOresund(context));
         banks.add(new Opel(context));
         banks.add(new Skandiabanken(context));
         banks.add(new AmericanExpress(context));

commit 4c1f61a65f10f9a04a503a8898d7bc792d1eddb6
Author: liato <x@x00.us>
Date:   Sun Sep 29 22:52:35 2013 +0200

    Fix for Paypal.

diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index cfb7524..cbc39d6 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -25,10 +25,15 @@ import java.util.regex.Pattern;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -50,7 +55,7 @@ public class PayPal extends Bank {
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 	private static final boolean STATIC_BALANCE = true;
 	
-	private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>", Pattern.CASE_INSENSITIVE);
 	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
 	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
@@ -78,10 +83,12 @@ public class PayPal extends Bank {
         urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
-        Matcher matcher = reFormAction.matcher(response);
+        Document d = Jsoup.parse(response);
+        Element e = d.select("form[name=login_form]").first();
+        
         String strPostUrl;
-        if (matcher.find()) {
-            strPostUrl = Html.fromHtml(matcher.group(1)).toString();
+        if (e != null && !TextUtils.isEmpty(e.attr("action"))) {
+            strPostUrl = e.attr("action");
         }
         else {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
@@ -101,6 +108,7 @@ public class PayPal extends Bank {
         postData.add(new BasicNameValuePair("bp_ks3", ""));
         postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
         postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
+        Log.d("HEJ", "Posturl: " + strPostUrl);
         return new LoginPackage(urlopen, postData, response, strPostUrl);
     }
 

commit 6e99a9e33813ebfda081294dd904512fe5162c09
Author: liato <x@x00.us>
Date:   Sun Sep 29 22:17:08 2013 +0200

    ADT changes.

diff --git .classpath .classpath
index f1a81f8..9d6723c 100644
--- .classpath
+++ .classpath
@@ -10,5 +10,6 @@
 	<classpathentry kind="lib" path="libs/jsoup-1.7.2.jar"/>
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git project.properties project.properties
index fd44ee5..b98aa9c 100644
--- project.properties
+++ project.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-17
+target=android-18

commit b22a8a3b4fed82b4876c94269c115786b16593f0
Author: liato <x@x00.us>
Date:   Sun Sep 29 21:32:33 2013 +0200

    Add knifhen to  contributors list.

diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index 477ae02..f6d6e6a 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -30,6 +30,7 @@ Development
   Christer Fletcher                 https://github.com/chrfle
   Richard Ginzburg                  https://github.com/rickythefox
   ScuttleSE                         https://github.com/ScuttleSE
+  Andreas Knifh                     https://github.com/knifhen
 
 
   Stats at:

commit 966248b54d910a1ee15bca23e347cc342c59e75e
Merge: 266787a b846b73
Author: liato <x@x00.us>
Date:   Tue Aug 20 14:04:26 2013 -0700

    Merge pull request #245 from knifhen/master
    
    Fixes Villabanken, issue 226

commit b846b731ea618fddf32db931ce02ac19b9c55771
Author: Andreas Knifh <andreas.knifh@jadestone.se>
Date:   Wed Aug 14 15:29:49 2013 +0200

    Fixed Villabanken
     - Removed obsolete use of MSO_PageHashCode
     - Use correct matcher.group to get balance
     - Parse accountNumber, password and Login button input keys from
       response to handle changes to their names
     - Added new input fields that where missing

diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index 95e78dc..0fe7a33 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -28,7 +28,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -47,12 +46,12 @@ public class Villabanken extends Bank {
 	private static final String NAME_SHORT = "villabanken";
 	private static final String URL = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
 	private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
-	
-	private Pattern reAccounts = Pattern.compile("<td[^>]+>((?:utnyttjad|kvar)[^:]+)[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
-	private Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
-	private Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
-	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
-	private Pattern rePageHashCode = Pattern.compile("MSO_PageHashCode\".*?value=\"([^\"]+)\"");
+
+	private final Pattern reAccounts = Pattern.compile("<td[^>]+>((?:utnyttjad|kvar)[^:]+)[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private final Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
+	private final Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
+	private final Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
+	private final Pattern reCtl00 = Pattern.compile("\"(ctl00.*?ctl00)\"");
 
 	public Villabanken(Context context) {
 		super(context);
@@ -68,66 +67,68 @@ public class Villabanken extends Bank {
 		this.update(username, password);
 	}
 
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib();
-        String response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
-        Matcher matcher = reRequestDigest.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" request digest.");
-        }
-        String requestDigest = matcher.group(1);
-        
-        matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" view state.");
-        }
-        String viewState = matcher.group(1);
-        
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" event validation.");
-        }
-        String eventValidation = matcher.group(1);
-
-        matcher = rePageHashCode.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" page hash code.");
-        }
-        String pageHashCode = matcher.group(1);
-
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("__spDummyText1", ""));
-        postData.add(new BasicNameValuePair("__spDummyText2", ""));
-        postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
-        postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
-        postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
-        postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
-        postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
-        postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
-        postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
-        postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
-        postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
-        postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
-        postData.add(new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
-        postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$ctl00", "Logga in"));
-        
-        postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-        postData.add(new BasicNameValuePair("MSO_PageHashCode", pageHashCode));
-        postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$accountNumber", username));
-        postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$password", password));
-        
-        return new LoginPackage(urlopen, postData, response, "https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
-    }
+	@Override
+	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+		urlopen = new Urllib();
+		String response = urlopen.open(URL);
+		Matcher matcher = reRequestDigest.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString() + " request digest.");
+		}
+		String requestDigest = matcher.group(1);
+
+		matcher = reCtl00.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl00");
+		}
+		String ctl00 = matcher.group(1);
+
+		matcher = reViewState.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString() + " view state.");
+		}
+		String viewState = matcher.group(1);
+
+		matcher = reEventValidation.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString() + " event validation.");
+		}
+		String eventValidation = matcher.group(1);
+
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
+		postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
+		postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
+		postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
+		postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
+		postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
+		postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
+		postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+		postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+		postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
+		postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
+		postData.add(new BasicNameValuePair("MSOSPWebPartManager_ExitingDesignMode", "false"));
+		postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
+		postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
+		postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
+		postData.add(new BasicNameValuePair("_wpSelected", ""));
+		postData.add(new BasicNameValuePair("_wzSelected", ""));
+		postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
+		postData.add(new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
+		postData.add(new BasicNameValuePair("MSOSPWebPartManager_EndWebPartEditing", "false"));
+		postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+		postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+		postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+		postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "accountNumber"), username));
+		postData.add(new BasicNameValuePair(ctl00.replaceAll("ctl00$", "password"), password));
+		postData.add(new BasicNameValuePair(ctl00, "Logga in"));
+		postData.add(new BasicNameValuePair("__spDummyText1", ""));
+		postData.add(new BasicNameValuePair("__spDummyText2", ""));
+		postData.add(new BasicNameValuePair("_wpcmWpid", ""));
+		postData.add(new BasicNameValuePair("wpcmVal", ""));
+
+		return new LoginPackage(urlopen, postData, response, URL);
+	}
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
@@ -137,7 +138,7 @@ public class Villabanken extends Bank {
 			if (response.contains("misslyckades")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
-			
+
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
@@ -145,6 +146,7 @@ public class Villabanken extends Bank {
 		}
 		return urlopen;
 	}
+
 	@Override
 	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
@@ -161,7 +163,7 @@ public class Villabanken extends Bank {
 			Integer accountId = 0;
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), accountId.toString()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
 				accountId += 1;
 			}
 
@@ -169,15 +171,12 @@ public class Villabanken extends Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 
-		}
-		catch (ClientProtocolException e) {
+		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
+		} catch (IOException e) {
 			throw new BankException(e.getMessage());
+		} finally {
+			super.updateComplete();
 		}
-        finally {
-            super.updateComplete();
-        }
 	}
 }
\ No newline at end of file

commit ac7b2657a25bb3038ab2d855d0a76aa8bee52378
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Jul 16 14:25:54 2013 +0200

    Adds manifest configuration to build file

diff --git build.gradle build.gradle
index e34711f..6a3b9d5 100644
--- build.gradle
+++ build.gradle
@@ -31,6 +31,14 @@ android {
     compileSdkVersion 17
     buildToolsVersion "17.0.0"
 
+    defaultConfig {
+        versionCode 160
+        versionName '1.9.6.0'
+        minSdkVersion 4
+        targetSdkVersion 4
+        packageName 'com.liato.bankdroid'
+    }
+
     sourceSets {
         main {
             manifest.srcFile 'AndroidManifest.xml'

commit 23298943ecd18b453483c0a736ce3d06afacfa12
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Jul 16 11:19:37 2013 +0200

    Remove libraries, use gradle for dependency resolution instead

diff --git libs/commons-io-2.0.1.jar libs/commons-io-2.0.1.jar
deleted file mode 100644
index 5b64b7d..0000000
Binary files libs/commons-io-2.0.1.jar and /dev/null differ
diff --git libs/google-collect-1.0.jar libs/google-collect-1.0.jar
deleted file mode 100644
index a7abdbb..0000000
Binary files libs/google-collect-1.0.jar and /dev/null differ
diff --git libs/jackson-annotations-2.1.0.jar libs/jackson-annotations-2.1.0.jar
deleted file mode 100644
index e4ca559..0000000
Binary files libs/jackson-annotations-2.1.0.jar and /dev/null differ
diff --git libs/jackson-core-2.1.0.jar libs/jackson-core-2.1.0.jar
deleted file mode 100644
index 6899eda..0000000
Binary files libs/jackson-core-2.1.0.jar and /dev/null differ
diff --git libs/jackson-databind-2.1.0.jar libs/jackson-databind-2.1.0.jar
deleted file mode 100644
index 5eceb00..0000000
Binary files libs/jackson-databind-2.1.0.jar and /dev/null differ
diff --git libs/jsoup-1.7.2.jar libs/jsoup-1.7.2.jar
deleted file mode 100644
index 8eeb5c7..0000000
Binary files libs/jsoup-1.7.2.jar and /dev/null differ

commit b3709ba3ed567db190e6d2019768f7a5fa2e4f9e
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Tue Jul 16 10:59:27 2013 +0200

    Adds Gradle support

diff --git .gitignore .gitignore
index c2f1d57..2cfb382 100644
--- .gitignore
+++ .gitignore
@@ -17,3 +17,9 @@ local.properties
 dev/
 src/com/liato/bankdroid/db/Crypto.*
 src/com/liato/bankdroid/db/Crypto.java.dev
+
+target/
+.idea
+.gradle
+*.iml
+build/
\ No newline at end of file
diff --git build.gradle build.gradle
new file mode 100644
index 0000000..e34711f
--- /dev/null
+++ build.gradle
@@ -0,0 +1,47 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.5.1'
+    }
+}
+apply plugin: 'android'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+	compile 'commons-io:commons-io:2.1'
+	compile 'com.google.collections:google-collections:1.0'
+	compile 'com.fasterxml.jackson.core:jackson-core:2.1.0'
+	compile 'com.fasterxml.jackson.core:jackson-databind:2.1.0'
+	compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.0' 
+	compile  'org.jsoup:jsoup:1.7.2'
+                      
+    // compile fileTree(dir: 'libs', include: '*.jar')
+}
+
+tasks.withType(Compile) {
+    options.encoding = "UTF-8"
+}
+
+android {
+    compileSdkVersion 17
+    buildToolsVersion "17.0.0"
+
+    sourceSets {
+        main {
+            manifest.srcFile 'AndroidManifest.xml'
+            java.srcDirs = ['src']
+            resources.srcDirs = ['src']
+            aidl.srcDirs = ['src']
+            renderscript.srcDirs = ['src']
+            res.srcDirs = ['res']
+            assets.srcDirs = ['assets']
+        }
+
+        instrumentTest.setRoot('tests')
+    }
+}
diff --git gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
Binary files /dev/null and gradle/wrapper/gradle-wrapper.jar differ
diff --git gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..5c22dec
--- /dev/null
+++ gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
diff --git gradlew gradlew
new file mode 100644
index 0000000..91a7e26
--- /dev/null
+++ gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git gradlew.bat gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

commit 266787a357a66303120c4145428b9753b822e824
Author: liato <x@x00.us>
Date:   Sat Jul 13 15:42:28 2013 +0200

    Add ScuttleSE to contributors list.

diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
index 0d53a68..477ae02 100644
--- CONTRIBUTORS.txt
+++ CONTRIBUTORS.txt
@@ -29,6 +29,11 @@ Development
   Tim Jansson                       https://github.com/timtux
   Christer Fletcher                 https://github.com/chrfle
   Richard Ginzburg                  https://github.com/rickythefox
+  ScuttleSE                         https://github.com/ScuttleSE
+
+
+  Stats at:
+  https://github.com/liato/android-bankdroid/graphs/contributors?type=a
  
 --------------------------------------------------------------------------------
 Beta testing

commit d6a668cbb1ba063361204efb1a11ea244dd52e80
Merge: 537d893 39fe775
Author: liato <x@x00.us>
Date:   Wed Jul 10 20:37:20 2013 -0700

    Merge pull request #240 from rickythefox/master
    
    Forex - support for multiple accounts

commit 39fe775648604e34da00cd85b0ae06dbbf09c60c
Merge: 478084b 537d893
Author: richard <richard@ginzburg.se>
Date:   Tue Jul 9 23:26:38 2013 +0200

    Merge branch 'master' of https://github.com/liato/android-bankdroid

commit 478084bb226aa55e30c6b447c8a70d47f098c5ff
Author: richard <richard@ginzburg.se>
Date:   Tue Jul 9 23:26:34 2013 +0200

    Forex - fix för multipla konton

diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index 719a869..d92a9b8 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -175,21 +175,19 @@ public class ForexBank extends Bank {
             Matcher mAccountBalances = reAccountBalance.matcher(result);
             Matcher mDisposables = reDisposable.matcher(result);
 
-            if(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
-                for (int i = 0; i < mAccountNumbers.groupCount() ; i++) {
-                    mIdMappings.put(Integer.toString(i+1), mAccountIds.group(i+1));
-                    if(mDisposables.find()) {
-                        accounts.add(new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(mDisposables.group(i+1).trim()), Integer.toString(i+1)));
-                        Account account = new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Saldo)", Helpers.parseBalance(mAccountBalances.group(i+1).trim()), "a:" + i+1);
-                        account.setAliasfor(Integer.toString(i+1));
-                        accounts.add(account);
-                    }
-                    else {
-                        accounts.add(new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(i+1).trim()), Integer.toString(i+1)));
-                    }
-
-                    balance = balance.add(Helpers.parseBalance(mAccountBalances.group(i+1)));
+            while(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
+                mIdMappings.put(Integer.toString(1), mAccountIds.group(1));
+                if(!mAccountIds.group(1).startsWith("-") && mDisposables.find()) {
+                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(mDisposables.group(1).trim()), Integer.toString(1)));
+                    Account account = new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(mAccountBalances.group(1).trim()), "a:" + 1);
+                    account.setAliasfor(Integer.toString(1));
+                    accounts.add(account);
                 }
+                else {
+                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(1).trim()), Integer.toString(1)));
+                }
+
+                balance = balance.add(Helpers.parseBalance(mAccountBalances.group(1)));
             }
             if (accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 537d893843343b40122a82924a33f51029ffd2f5
Merge: d1d8a21 144a972
Author: liato <x@x00.us>
Date:   Tue Jul 9 00:25:43 2013 -0700

    Merge pull request #239 from ScuttleSE/master
    
    Diners Club updates with new URL

commit 144a9722da7fc8d3efcbcc9bd95f141e1182db4a
Author: ScuttleSE <gustav@almstrom.org>
Date:   Mon Jul 8 09:17:26 2013 +0200

    Update DinersClub.java

diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index 98d16c0..3d0a392 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -47,7 +47,7 @@ public class DinersClub extends Bank {
 	private static final String TAG = "DinersClub";
 	private static final String NAME = "Diners Club";
 	private static final String NAME_SHORT = "dinersclub";
-	private static final String URL = "https://www.dinersclub.se/dcs/login.aspx";
+	private static final String URL = "https://secure.dinersclub.se/dcs/login.aspx";
 	private static final int BANKTYPE_ID = IBankTypes.DINERSCLUB;
 	
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -78,7 +78,7 @@ public class DinersClub extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
-        response = urlopen.open("https://www.dinersclub.se/dcs/login.aspx");
+        response = urlopen.open("https://secure.dinersclub.se/dcs/login.aspx");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
@@ -100,7 +100,7 @@ public class DinersClub extends Bank {
         postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", password));
         postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
 
-        return new LoginPackage(urlopen, postData, response, "https://www.dinersclub.se/dcs/login.aspx");
+        return new LoginPackage(urlopen, postData, response, "https://secure.dinersclub.se/dcs/login.aspx");
     }
 
 	public Urllib login() throws LoginException, BankException {
@@ -127,9 +127,9 @@ public class DinersClub extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		if (!"https://www.dinersclub.se/dcs/eSaldo/Default.aspx".equalsIgnoreCase(urlopen.getCurrentURI())) {
+		if (!"https://secure.dinersclub.se/dcs/eSaldo/Default.aspx".equalsIgnoreCase(urlopen.getCurrentURI())) {
 		    try {
-                response = urlopen.open("https://www.dinersclub.se/dcs/eSaldo/Default.aspx");
+                response = urlopen.open("https://secure.dinersclub.se/dcs/eSaldo/Default.aspx");
             }
             catch (ClientProtocolException e) {
                 throw new BankException(e.getMessage());
@@ -179,7 +179,7 @@ public class DinersClub extends Bank {
 		Matcher matcher;
 		try {
 			/* We're going to look at all the pages until we find one that has transactions on it */
-			response = urlopen.open(String.format("https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
+			response = urlopen.open(String.format("https://secure.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 

commit d1d8a219b667fd630c52d3626fb6ecc6e1e96423
Merge: 90cd221 7ce051c
Author: liato <x@x00.us>
Date:   Wed Jul 3 03:49:40 2013 -0700

    Merge pull request #235 from goober/master
    
    Use ICABankens API

commit 7ce051c45a180667de181477ab8b43b610b40fbc
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sat Jun 29 01:53:48 2013 +0200

    Additional error handling
    
    * Correct message on login failure.
    * Adds more headers in request for statistical usage.
    * Fix balance.

diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index 4bba111..4cc483e 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -25,6 +25,7 @@ import java.util.Locale;
 import org.apache.http.client.ClientProtocolException;
 
 import android.content.Context;
+import android.os.Build;
 import android.text.InputType;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -56,6 +57,7 @@ public class ICABanken extends Bank {
 
 	private static final String API_KEY = "A026CF97-5F6A-438D-A921-AA3406A6CE09";
 	private static final String API_URL = "https://appserver.icabanken.se";
+	private static final String API_VERSION = "1.0";
 
 	public ICABanken(Context context) {
 		super(context);
@@ -78,14 +80,20 @@ public class ICABanken extends Bank {
 
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib();
-		urlopen.addHeader("ApiVersion", "1.0");
+		urlopen.addHeader("ApiVersion", API_VERSION);
 		urlopen.addHeader("Accept", "application/json");
 		urlopen.addHeader("ApiKey", API_KEY);
-		String response = null;
-		try {
-			response = urlopen.open(API_URL + "/login?customerId=" + username
-					+ "&password=" + password);
+		urlopen.addHeader("ClientHardware", Build.MODEL);
+		urlopen.addHeader("ClientOS", "Android");
+		urlopen.addHeader("ClientOSVersion", Integer.toString(Build.VERSION.SDK_INT));
 
+		try {
+			String response = urlopen.open(API_URL + "/login?customerId="
+					+ username + "&password=" + password);
+			if(response == null || "".equals(response)) {
+				throw new LoginException(res.getText(
+						R.string.invalid_username_password).toString());
+			}
 			ObjectMapper vObjectMapper = new ObjectMapper();
 			vObjectMapper.setDateFormat(new SimpleDateFormat(
 					"yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
@@ -95,11 +103,9 @@ public class ICABanken extends Bank {
 			addAccounts(loginResponse.getAccountList());
 
 		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new BankException(e.getMessage());
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new BankException(e.getMessage());
 		}
 		return urlopen;
 	}
@@ -141,6 +147,7 @@ public class ICABanken extends Bank {
 			alias.setAliasfor(icaAccount.getAccountId());
 			accounts.add(account);
 			accounts.add(alias);
+			balance.add(account.getBalance());
 		}
 	}
 

commit 7f5df9ba69598b39ecffaee2182b6f2bc735a3d5
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jun 28 18:10:56 2013 +0200

    Fixes formatting

diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
index a907ccd..4bba111 100644
--- src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -20,19 +20,14 @@ import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.apache.http.client.ClientProtocolException;
 
 import android.content.Context;
-import android.text.Html;
 import android.text.InputType;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
@@ -49,56 +44,56 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
-    private static final String TAG = "ICABanken";
-    private static final String NAME = "ICA Banken";
-    private static final String NAME_SHORT = "icabanken";
-    private static final String URL = "https://mobil.icabanken.se/";
-    private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
-    private static final boolean STATIC_BALANCE = false;
-
-    private static final String API_KEY = "A026CF97-5F6A-438D-A921-AA3406A6CE09";
-    private static final String API_URL = "https://appserver.icabanken.se";
-    
-    private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
-
-    public ICABanken(Context context) {
-        super(context);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-        this(context);
-        this.update(username, password);
-    }
-
-    
-   public Urllib login() throws LoginException, BankException {
-        urlopen = new Urllib();
-        urlopen.addHeader("ApiVersion", "1.0");
-        urlopen.addHeader("Accept", "application/json");
-        urlopen.addHeader("ApiKey", API_KEY);
-        String response = null;
-        try {
-		response = urlopen.open(API_URL+"/login?customerId="+username+"&password="+password);
-		
-		ObjectMapper vObjectMapper = new ObjectMapper();
-		vObjectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss",new Locale("sv","SE")));
-		LoginResponse loginResponse = vObjectMapper.readValue(response, LoginResponse.class);
-		
-		addAccounts(loginResponse.getAccountList());
-		
+	private static final String TAG = "ICABanken";
+	private static final String NAME = "ICA Banken";
+	private static final String NAME_SHORT = "icabanken";
+	private static final String URL = "https://mobil.icabanken.se/";
+	private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+	private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
+	private static final boolean STATIC_BALANCE = false;
+
+	private static final String API_KEY = "A026CF97-5F6A-438D-A921-AA3406A6CE09";
+	private static final String API_URL = "https://appserver.icabanken.se";
+
+	public ICABanken(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public ICABanken(String username, String password, Context context)
+			throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib();
+		urlopen.addHeader("ApiVersion", "1.0");
+		urlopen.addHeader("Accept", "application/json");
+		urlopen.addHeader("ApiKey", API_KEY);
+		String response = null;
+		try {
+			response = urlopen.open(API_URL + "/login?customerId=" + username
+					+ "&password=" + password);
+
+			ObjectMapper vObjectMapper = new ObjectMapper();
+			vObjectMapper.setDateFormat(new SimpleDateFormat(
+					"yyyy-MM-dd hh:mm:ss", new Locale("sv", "SE")));
+			LoginResponse loginResponse = vObjectMapper.readValue(response,
+					LoginResponse.class);
+
+			addAccounts(loginResponse.getAccountList());
+
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
@@ -106,48 +101,59 @@ public class ICABanken extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-        return urlopen;
-    }    
-    
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
-        super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-             login();
-           
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-        super.updateTransactions(account, urlopen);
-            super.updateComplete();
-    }
-
-private void addAccounts(IcaBankenAccountList pAccountList) {
-	for(IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
-		Account account = new Account(icaAccount.getName()+" (Disponibelt)",icaAccount.getAvailableAmount(),icaAccount.getAccountId());
-		account.setTransactions(mapTransactions(icaAccount));
-		Account alias = new Account(icaAccount.getName() + " (Saldo)",icaAccount.getCurrentAmount(),"a:" +icaAccount.getAccountId());
-		alias.setAliasfor(icaAccount.getAccountId());
-		accounts.add(account);		
-		accounts.add(alias);
+		return urlopen;
 	}
-}
-private ArrayList<Transaction> mapTransactions(IcaBankenAccount pAccount) {
-	ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-	DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd",Locale.getDefault());
-	for(IcaBankenTransaction icaTransaction : pAccount.getTransactions()) {
-		String date = dateFormatter.format(icaTransaction.getPostedDate());
-		Transaction transaction = new Transaction(date,icaTransaction.getMemoText(),icaTransaction.getAmount());
-		transactions.add(transaction);
+
+	@Override
+	public void update() throws BankException, LoginException,
+			BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0
+				|| password.length() == 0) {
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+		}
+		login();
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found)
+					.toString());
+		}
+
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen)
+			throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		super.updateComplete();
 	}
-	return transactions;
-}
-}
 
+	private void addAccounts(IcaBankenAccountList pAccountList) {
+		for (IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
+			Account account = new Account(icaAccount.getName()
+					+ " (Disponibelt)", icaAccount.getAvailableAmount(),
+					icaAccount.getAccountId());
+			account.setTransactions(mapTransactions(icaAccount));
+			Account alias = new Account(icaAccount.getName() + " (Saldo)",
+					icaAccount.getCurrentAmount(), "a:"
+							+ icaAccount.getAccountId());
+			alias.setAliasfor(icaAccount.getAccountId());
+			accounts.add(account);
+			accounts.add(alias);
+		}
+	}
+
+	private ArrayList<Transaction> mapTransactions(IcaBankenAccount pAccount) {
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd",
+				Locale.getDefault());
+		for (IcaBankenTransaction icaTransaction : pAccount.getTransactions()) {
+			String date = dateFormatter.format(icaTransaction.getPostedDate());
+			Transaction transaction = new Transaction(date,
+					icaTransaction.getMemoText(), icaTransaction.getAmount());
+			transactions.add(transaction);
+		}
+		return transactions;
+	}
+}

commit cbaaba3e4dca10fd6d5dfd79df121b4a7a771cbf
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Fri Jun 28 18:04:58 2013 +0200

    Use ICABanken's API instead of mobile site.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 7213f22..cd2619c 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -16,22 +16,88 @@
 
 package com.liato.bankdroid.banking;
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
+
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
-
-import com.liato.bankdroid.banking.banks.*;
-import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.icabanken.ICABanken;
+import com.liato.bankdroid.banking.banks.AkeliusInvest;
+import com.liato.bankdroid.banking.banks.AkeliusSpar;
+import com.liato.bankdroid.banking.banks.AmericanExpress;
+import com.liato.bankdroid.banking.banks.AppeakPoker;
+import com.liato.bankdroid.banking.banks.Audi;
+import com.liato.bankdroid.banking.banks.Avanza;
+import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.BetterGlobe;
+import com.liato.bankdroid.banking.banks.Bioklubben;
+import com.liato.bankdroid.banking.banks.BrummerKF;
+import com.liato.bankdroid.banking.banks.CSN;
+import com.liato.bankdroid.banking.banks.Chalmrest;
+import com.liato.bankdroid.banking.banks.Chevrolet;
+import com.liato.bankdroid.banking.banks.Coop;
+import com.liato.bankdroid.banking.banks.DanskeBank;
+import com.liato.bankdroid.banking.banks.DinersClub;
+import com.liato.bankdroid.banking.banks.Djurgarden;
+import com.liato.bankdroid.banking.banks.EasyCard;
+import com.liato.bankdroid.banking.banks.EurobonusMastercard;
+import com.liato.bankdroid.banking.banks.Eurocard;
+import com.liato.bankdroid.banking.banks.Everydaycard;
+import com.liato.bankdroid.banking.banks.FirstCard;
+import com.liato.bankdroid.banking.banks.ForexBank;
+import com.liato.bankdroid.banking.banks.Handelsbanken;
+import com.liato.bankdroid.banking.banks.Hemkop;
+import com.liato.bankdroid.banking.banks.ICA;
+import com.liato.bankdroid.banking.banks.IKEA;
+import com.liato.bankdroid.banking.banks.IkanoBank;
+import com.liato.bankdroid.banking.banks.Jojo;
+import com.liato.bankdroid.banking.banks.Marginalen;
+import com.liato.bankdroid.banking.banks.McDonalds;
+import com.liato.bankdroid.banking.banks.Meniga;
+import com.liato.bankdroid.banking.banks.NordeaDK;
+import com.liato.bankdroid.banking.banks.Nordnet;
+import com.liato.bankdroid.banking.banks.Nordnetdirekt;
+import com.liato.bankdroid.banking.banks.OKQ8;
+import com.liato.bankdroid.banking.banks.Opel;
+import com.liato.bankdroid.banking.banks.Osuuspankki;
+import com.liato.bankdroid.banking.banks.PayPal;
+import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.PlusGirot;
+import com.liato.bankdroid.banking.banks.Preem;
+import com.liato.bankdroid.banking.banks.Quintessentially;
+import com.liato.bankdroid.banking.banks.ResursBank;
+import com.liato.bankdroid.banking.banks.Rikslunchen;
+import com.liato.bankdroid.banking.banks.SEB;
+import com.liato.bankdroid.banking.banks.SJPrio;
+import com.liato.bankdroid.banking.banks.Saab;
+import com.liato.bankdroid.banking.banks.Seat;
+import com.liato.bankdroid.banking.banks.SevenDay;
+import com.liato.bankdroid.banking.banks.Shell;
+import com.liato.bankdroid.banking.banks.Skandiabanken;
+import com.liato.bankdroid.banking.banks.Skoda;
+import com.liato.bankdroid.banking.banks.SparbankenOresund;
+import com.liato.bankdroid.banking.banks.SparbankenSyd;
+import com.liato.bankdroid.banking.banks.Statoil;
+import com.liato.bankdroid.banking.banks.SvenskaSpel;
+import com.liato.bankdroid.banking.banks.Swedbank;
+import com.liato.bankdroid.banking.banks.TestBank;
+import com.liato.bankdroid.banking.banks.TicketRikskortet;
+import com.liato.bankdroid.banking.banks.TrustBuddy;
+import com.liato.bankdroid.banking.banks.Vasttrafik;
+import com.liato.bankdroid.banking.banks.Villabanken;
+import com.liato.bankdroid.banking.banks.Volkswagen;
+import com.liato.bankdroid.banking.banks.Volvofinans;
+import com.liato.bankdroid.banking.banks.Wallet;
+import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
+import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.provider.IBankTypes;
-import net.sf.andhsli.hotspotlogin.SimpleCrypto;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
 
 public class BankFactory {
 
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
deleted file mode 100644
index 5aa4f47..0000000
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.util.Log;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.Urllib;
-
-public class ICABanken extends Bank {
-    private static final String TAG = "ICABanken";
-    private static final String NAME = "ICA Banken";
-    private static final String NAME_SHORT = "icabanken";
-    private static final String URL = "https://mobil.icabanken.se/";
-    private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
-    private static final boolean STATIC_BALANCE = false;
-
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
-
-    public ICABanken(Context context) {
-        super(context);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
-    }
-
-    public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-        this(context);
-        this.update(username, password);
-    }
-
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib();
-        String response = urlopen.open("https://mobil2.icabanken.se/login/login.aspx");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
-        }
-        String strViewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
-        }
-        String strEventValidation = matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("pnr_phone", username));
-        postData.add(new BasicNameValuePair("pwd_phone", password));
-        postData.add(new BasicNameValuePair("btnLogin", "Logga in"));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        return new LoginPackage(urlopen, postData, response, "https://mobil2.icabanken.se/login/login.aspx");
-    }
-
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            Matcher matcher = reError.matcher(response);
-            if (matcher.find()) {
-                String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-                if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
-                    throw new LoginException(errormsg);    
-                }
-                else {
-                     throw new BankException(errormsg);    
-                }
-            }
-        }
-        catch (ClientProtocolException e) {
-            Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-            throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
-            Log.e(TAG, "IOException: "+e.getMessage());
-            throw new BankException(e.getMessage());
-        }
-        return urlopen;
-    }    
-    
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
-        super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        String response = null;
-        Matcher matcher;
-        try {
-            response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
-            matcher = reBalance.matcher(response);
-            int accid = 0;
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: ID                0000000000 - not static?
-                 * 2: Name              ICA KONTO
-                 * 3: Disponibelt       00.000,00
-                 * 4: Saldo             1.655,71
-                 *  
-                 */                
-                mIdMappings.put(Integer.toString(accid), matcher.group(1).trim());           
-                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), Integer.toString(accid)));
-                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + accid);
-                account.setAliasfor(Integer.toString(accid));
-                accounts.add(account);
-
-                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-                accid++;
-            }
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-        super.updateTransactions(account, urlopen);
-        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
-        String accountId = mIdMappings.get(account.getId());
-        String response = null;
-        Matcher matcher;
-        try {
-            response = urlopen.open("https://mobil2.icabanken.se/account/account.aspx?id="+accountId);
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                transactions.add(new Transaction(matcher.group(2).trim().substring(8), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-            }
-            account.setTransactions(transactions);
-        } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        finally {
-            super.updateComplete();
-        }
-    }
-}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
new file mode 100644
index 0000000..a907ccd
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/icabanken/ICABanken.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.icabanken;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccount;
+import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccountList;
+import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenTransaction;
+import com.liato.bankdroid.banking.banks.icabanken.model.response.LoginResponse;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class ICABanken extends Bank {
+    private static final String TAG = "ICABanken";
+    private static final String NAME = "ICA Banken";
+    private static final String NAME_SHORT = "icabanken";
+    private static final String URL = "https://mobil.icabanken.se/";
+    private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
+    private static final boolean STATIC_BALANCE = false;
+
+    private static final String API_KEY = "A026CF97-5F6A-438D-A921-AA3406A6CE09";
+    private static final String API_URL = "https://appserver.icabanken.se";
+    
+    private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
+
+    public ICABanken(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    
+   public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib();
+        urlopen.addHeader("ApiVersion", "1.0");
+        urlopen.addHeader("Accept", "application/json");
+        urlopen.addHeader("ApiKey", API_KEY);
+        String response = null;
+        try {
+		response = urlopen.open(API_URL+"/login?customerId="+username+"&password="+password);
+		
+		ObjectMapper vObjectMapper = new ObjectMapper();
+		vObjectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss",new Locale("sv","SE")));
+		LoginResponse loginResponse = vObjectMapper.readValue(response, LoginResponse.class);
+		
+		addAccounts(loginResponse.getAccountList());
+		
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        return urlopen;
+    }    
+    
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+             login();
+           
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+            super.updateComplete();
+    }
+
+private void addAccounts(IcaBankenAccountList pAccountList) {
+	for(IcaBankenAccount icaAccount : pAccountList.getAccounts()) {
+		Account account = new Account(icaAccount.getName()+" (Disponibelt)",icaAccount.getAvailableAmount(),icaAccount.getAccountId());
+		account.setTransactions(mapTransactions(icaAccount));
+		Account alias = new Account(icaAccount.getName() + " (Saldo)",icaAccount.getCurrentAmount(),"a:" +icaAccount.getAccountId());
+		alias.setAliasfor(icaAccount.getAccountId());
+		accounts.add(account);		
+		accounts.add(alias);
+	}
+}
+private ArrayList<Transaction> mapTransactions(IcaBankenAccount pAccount) {
+	ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+	DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd",Locale.getDefault());
+	for(IcaBankenTransaction icaTransaction : pAccount.getTransactions()) {
+		String date = dateFormatter.format(icaTransaction.getPostedDate());
+		Transaction transaction = new Transaction(date,icaTransaction.getMemoText(),icaTransaction.getAmount());
+		transactions.add(transaction);
+	}
+	return transactions;
+}
+}
+
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
new file mode 100644
index 0000000..6cdfeb0
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccount.java
@@ -0,0 +1,162 @@
+package com.liato.bankdroid.banking.banks.icabanken.model;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class IcaBankenAccount {
+	private String mAccountId;
+
+	private String mAccountNumber;
+
+	private String mAddress;
+
+	private BigDecimal mAvailableAmount;
+
+	private String mBic;
+
+	private BigDecimal mCurrentAmount;
+
+	private String mGroup;
+
+	private String mHolder;
+
+	private String mIban;
+
+	private String mName;
+
+	private BigDecimal mOutstandingAmount;
+
+	private List<String> mServices;
+
+	private List<IcaBankenTransaction> mTransactions;
+
+	private List<String> mValidFor;
+
+	@JsonProperty("AccountId")
+	public String getAccountId() {
+		return mAccountId;
+	}
+
+	public void setAccountId(String pAccountId) {
+		this.mAccountId = pAccountId;
+	}
+
+	@JsonProperty("AccountNumber")
+	public String getAccountNumber() {
+		return mAccountNumber;
+	}
+
+	public void setAccountNumber(String pAccountNumber) {
+		this.mAccountNumber = pAccountNumber;
+	}
+
+	@JsonProperty("Address")
+	public String getAddress() {
+		return mAddress;
+	}
+
+	public void setAddress(String pAddress) {
+		this.mAddress = pAddress;
+	}
+
+	@JsonProperty("AvailableAmount")
+	public BigDecimal getAvailableAmount() {
+		return mAvailableAmount;
+	}
+
+	public void setAvailableAmount(BigDecimal pAvailableAmount) {
+		this.mAvailableAmount = pAvailableAmount;
+	}
+
+	@JsonProperty("BIC")
+	public String getBic() {
+		return mBic;
+	}
+
+	public void setBic(String pBic) {
+		this.mBic = pBic;
+	}
+
+	@JsonProperty("CurrentAmount")
+	public BigDecimal getCurrentAmount() {
+		return mCurrentAmount;
+	}
+
+	public void setCurrentAmount(BigDecimal pCurrentAmount) {
+		this.mCurrentAmount = pCurrentAmount;
+	}
+
+	@JsonProperty("Group")
+	public String getGroup() {
+		return mGroup;
+	}
+
+	public void setGroup(String pGroup) {
+		this.mGroup = pGroup;
+	}
+
+	@JsonProperty("Holder")
+	public String getHolder() {
+		return mHolder;
+	}
+
+	public void setHolder(String pHolder) {
+		this.mHolder = pHolder;
+	}
+
+	@JsonProperty("IBAN")
+	public String getIban() {
+		return mIban;
+	}
+
+	public void setIban(String pIban) {
+		this.mIban = pIban;
+	}
+
+	@JsonProperty("Name")
+	public String getName() {
+		return mName;
+	}
+
+	public void setName(String pName) {
+		this.mName = pName;
+	}
+
+	@JsonProperty("OutstandingAmount")
+	public BigDecimal getOutstandingAmount() {
+		return mOutstandingAmount;
+	}
+
+	public void setOutstandingAmount(BigDecimal pOutstandingAmount) {
+		this.mOutstandingAmount = pOutstandingAmount;
+	}
+
+	@JsonProperty("Services")
+	public List<String> getServices() {
+		return mServices;
+	}
+
+	public void setServices(List<String> pServices) {
+		this.mServices = pServices;
+	}
+
+	@JsonProperty("Transactions")
+	public List<IcaBankenTransaction> getTransactions() {
+		return mTransactions;
+	}
+
+	public void setTransactions(List<IcaBankenTransaction> pTransactions) {
+		this.mTransactions = pTransactions;
+	}
+
+	@JsonProperty("ValidFor")
+	public List<String> getValidFor() {
+		return mValidFor;
+	}
+
+	public void setValidFor(List<String> pValidFor) {
+		this.mValidFor = pValidFor;
+	}
+}
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
new file mode 100644
index 0000000..c08aca1
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenAccountList.java
@@ -0,0 +1,120 @@
+package com.liato.bankdroid.banking.banks.icabanken.model;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class IcaBankenAccountList {
+
+	private List<IcaBankenAccount> mAccounts;
+
+	private String mDefaultAccountIdForEgiros;
+	private String mDefaultAccountIdForPayments;
+	private String mDefaultAccountIdForTransfers;
+	private BigDecimal mJointAccountsTotalAvailableAmount;
+
+	private BigDecimal mJointAccountsTotalCurrentAmount;
+	private BigDecimal mMinorsAccountsTotalAvailableAmount;
+	private BigDecimal mMinorsAccountsTotalCurrentAmount;
+	private BigDecimal mOwnAccountsTotalAvailableAmount;
+	private BigDecimal mOwnAccountsTotalCurrentAmount;
+
+	@JsonProperty("Accounts")
+	public List<IcaBankenAccount> getAccounts() {
+		return mAccounts;
+	}
+
+	public void setAccounts(List<IcaBankenAccount> pAccounts) {
+		this.mAccounts = pAccounts;
+	}
+
+	@JsonProperty("DefaultAccountIdForEgiros")
+	public String getDefaultAccountIdForEgiros() {
+		return mDefaultAccountIdForEgiros;
+	}
+
+	public void setDefaultAccountIdForEgiros(String pDefaultAccountIdForEgiros) {
+		this.mDefaultAccountIdForEgiros = pDefaultAccountIdForEgiros;
+	}
+
+	@JsonProperty("DefaultAccountIdForPayments")
+	public String getDefaultAccountIdForPayments() {
+		return mDefaultAccountIdForPayments;
+	}
+
+	public void setDefaultAccountIdForPayments(
+			String pDefaultAccountIdForPayments) {
+		this.mDefaultAccountIdForPayments = pDefaultAccountIdForPayments;
+	}
+
+	@JsonProperty("DefaultAccountIdForTransfers")
+	public String getDefaultAccountIdForTransfers() {
+		return mDefaultAccountIdForTransfers;
+	}
+
+	public void setDefaultAccountIdForTransfers(
+			String pDefaultAccountIdForTransfers) {
+		this.mDefaultAccountIdForTransfers = pDefaultAccountIdForTransfers;
+	}
+
+	@JsonProperty("JointAccountsTotalAvailableAmount")
+	public BigDecimal getJointAccountsTotalAvailableAmount() {
+		return mJointAccountsTotalAvailableAmount;
+	}
+
+	public void setJointAccountsTotalAvailableAmount(
+			BigDecimal pJointAccountsTotalAvailableAmount) {
+		this.mJointAccountsTotalAvailableAmount = pJointAccountsTotalAvailableAmount;
+	}
+
+	@JsonProperty("JointAccountsTotalCurrentAmount")
+	public BigDecimal getJointAccountsTotalCurrentAmount() {
+		return mJointAccountsTotalCurrentAmount;
+	}
+
+	public void setJointAccountsTotalCurrentAmount(
+			BigDecimal pJointAccountsTotalCurrentAmount) {
+		this.mJointAccountsTotalCurrentAmount = pJointAccountsTotalCurrentAmount;
+	}
+
+	@JsonProperty("MinorsAccountsTotalAvailableAmount")
+	public BigDecimal getMinorsAccountsTotalAvailableAmount() {
+		return mMinorsAccountsTotalAvailableAmount;
+	}
+
+	public void setMinorsAccountsTotalAvailableAmount(
+			BigDecimal pMinorsAccountsTotalAvailableAmount) {
+		this.mMinorsAccountsTotalAvailableAmount = pMinorsAccountsTotalAvailableAmount;
+	}
+
+	@JsonProperty("MinorsAccountsTotalCurrentAmount")
+	public BigDecimal getMinorsAccountsTotalCurrentAmount() {
+		return mMinorsAccountsTotalCurrentAmount;
+	}
+
+	public void setMinorsAccountsTotalCurrentAmount(
+			BigDecimal pMinorsAccountsTotalCurrentAmount) {
+		this.mMinorsAccountsTotalCurrentAmount = pMinorsAccountsTotalCurrentAmount;
+	}
+
+	@JsonProperty("OwnAccountsTotalAvailableAmount")
+	public BigDecimal getOwnAccountsTotalAvailableAmount() {
+		return mOwnAccountsTotalAvailableAmount;
+	}
+
+	public void setOwnAccountsTotalAvailableAmount(
+			BigDecimal pOwnAccountsTotalAvailableAmount) {
+		this.mOwnAccountsTotalAvailableAmount = pOwnAccountsTotalAvailableAmount;
+	}
+
+	@JsonProperty("OwnAccountsTotalCurrentAmount")
+	public BigDecimal getOwnAccountsTotalCurrentAmount() {
+		return mOwnAccountsTotalCurrentAmount;
+	}
+
+	public void setOwnAccountsTotalCurrentAmount(
+			BigDecimal pOwnAccountsTotalCurrentAmount) {
+		this.mOwnAccountsTotalCurrentAmount = pOwnAccountsTotalCurrentAmount;
+	}
+}
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
new file mode 100644
index 0000000..f126dbd
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/IcaBankenTransaction.java
@@ -0,0 +1,53 @@
+package com.liato.bankdroid.banking.banks.icabanken.model;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class IcaBankenTransaction {
+
+	private BigDecimal mAccountBalance;
+
+	private BigDecimal mAmount;
+
+	private String mMemoText;
+
+	private Date mPostedDate;
+
+	@JsonProperty("AccountBalance")
+	public BigDecimal getAccountBalance() {
+		return mAccountBalance;
+	}
+
+	public void setAccountBalance(BigDecimal pAccountBalance) {
+		this.mAccountBalance = pAccountBalance;
+	}
+
+	@JsonProperty("Amount")
+	public BigDecimal getAmount() {
+		return mAmount;
+	}
+
+	public void setAmount(BigDecimal pAmount) {
+		this.mAmount = pAmount;
+	}
+
+	@JsonProperty("MemoText")
+	public String getMemoText() {
+		return mMemoText;
+	}
+
+	public void setMemoText(String pMemoText) {
+		this.mMemoText = pMemoText;
+	}
+
+	@JsonProperty("PostedDate")
+	public Date getPostedDate() {
+		return mPostedDate;
+	}
+
+	public void setPostedDate(Date pPostedDate) {
+		this.mPostedDate = pPostedDate;
+	}
+}
diff --git src/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java src/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
new file mode 100644
index 0000000..a7e578a
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/icabanken/model/response/LoginResponse.java
@@ -0,0 +1,42 @@
+package com.liato.bankdroid.banking.banks.icabanken.model.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.liato.bankdroid.banking.banks.icabanken.model.IcaBankenAccountList;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LoginResponse {
+
+	private String mABCustomerId;
+
+	private IcaBankenAccountList mAccountList;
+
+	private String mSessionId;
+
+	@JsonProperty("ABCustomerId")
+	public String getABCustomerId() {
+		return mABCustomerId;
+	}
+
+	public void setABCustomerId(String pABCustomerId) {
+		this.mABCustomerId = pABCustomerId;
+	}
+
+	@JsonProperty("AccountList")
+	public IcaBankenAccountList getAccountList() {
+		return mAccountList;
+	}
+
+	public void setAccountList(IcaBankenAccountList pAccountList) {
+		this.mAccountList = pAccountList;
+	}
+
+	@JsonProperty("SessionId")
+	public String getSessionId() {
+		return mSessionId;
+	}
+
+	public void setSessionId(String pSessionId) {
+		this.mSessionId = pSessionId;
+	}
+}

commit 90cd221af5e831486de88b4dc624195b1320be64
Author: liato <x@x00.us>
Date:   Sat Jun 22 19:16:33 2013 +0200

    Add contributors file.

diff --git CONTRIBUTORS.txt CONTRIBUTORS.txt
new file mode 100644
index 0000000..0d53a68
--- /dev/null
+++ CONTRIBUTORS.txt
@@ -0,0 +1,36 @@
+--------------------------------------------------------------------------------
+Development
+--------------------------------------------------------------------------------
+  liato                             https://github.com/liato
+  DEGE1                             https://github.com/DEGE1
+  Magnus Hagander                   https://github.com/mhagander
+  Pierre Chateau                    https://github.com/PMC
+  Magnus Andersson                  https://github.com/magnusart
+  cork                              https://github.com/cork
+  Emil Hesslow                      https://github.com/WizKid
+  Peter Björkman                    https://github.com/woody2
+  Joakim Andersson                  https://github.com/firetech
+  Mathias Åhsberg                   https://github.com/goober
+  Lars Wiklund                      https://github.com/lawi75
+  Fredrik Lindberg                  https://github.com/fredriklindberg
+  Erik Fredriksen                   https://github.com/erifre
+  Mats Karlsson                     https://github.com/MatsKarlsson
+  Snah                              https://github.com/Snaah
+  Jonas Björk                       https://github.com/bjooork
+  Anders Waldenborg                 https://github.com/wanders
+  Mattias Fagerström                https://github.com/mafa73
+  Jacob Siverskog                   https://github.com/jsiverskog
+  Andreas Gunnerås                  https://github.com/d95andek
+  Emil Andersson                    https://github.com/emilan
+  oskla129                          https://github.com/oskla129
+  Per Wigren                        https://github.com/Tuxie
+  Joakim Lundborg                   https://github.com/cortex
+  Jonathan Hjertström               https://github.com/nixi
+  Tim Jansson                       https://github.com/timtux
+  Christer Fletcher                 https://github.com/chrfle
+  Richard Ginzburg                  https://github.com/rickythefox
+ 
+--------------------------------------------------------------------------------
+Beta testing
+--------------------------------------------------------------------------------
+  Swedroid users                    http://goo.gl/9tJeH

commit b0e6ba7a44d9db99480d60bdd6faf16f756620f0
Author: liato <x@x00.us>
Date:   Sat Jun 22 19:16:20 2013 +0200

    Update changelog.

diff --git CHANGES.txt CHANGES.txt
index 1ad35f6..a8c66ef 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,13 @@
+v1.9.6.0: (2013-06-22)
+* Fix for PayPal
+* Fix for Hemköp
+* Fix for ICA
+* Fix for Volvofinans
++ Support for Forex Bank (thanks till rickythefox)
++ Support for BetterGlobe (thanks to Tuxie)
++ Support for Zidisha (thanks to Tuxie)
+
+
 v1.9.5.4: (2013-04-28)
 * Fix for Rikslunchen (thanks to chrfle)
 * Fix for Audikortet (maybe)
diff --git res/values/strings.xml res/values/strings.xml
index 5906b0b..448e910 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -205,6 +205,7 @@
 	\nd98rolb (Osuuspankki)
 	\nAndreas Gunnerås (Everydaycard)
 	\nEmil Andersson (Chalmrest)
+	\Richard Ginzburg (Forex Bank)
      </string>
      
      

commit 296bc911b2f639534871a3caface21afccddeee5
Author: liato <x@x00.us>
Date:   Sat Jun 22 15:45:42 2013 +0200

    Bump version. 1.9.6.0.

diff --git AndroidManifest.xml AndroidManifest.xml
index a225ac5..b34def7 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.0-RC4" android:versionCode="159">
+	android:versionName="1.9.6.0" android:versionCode="160">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit bcf8ae5d961253c6ad4b8536b32fde16446cb587
Author: liato <x@x00.us>
Date:   Sat Jun 22 15:37:51 2013 +0200

    Html decode rikskortet transactions.

diff --git src/com/liato/bankdroid/banking/banks/TicketRikskortet.java src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
index 1ef6125..0dbe98d 100644
--- src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
+++ src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -27,6 +27,7 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.text.Html;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -173,7 +174,7 @@ public class TicketRikskortet extends Bank {
                  * 
                  */
 
-                transactions.add(new Transaction(matcher.group(1), matcher.group(2).trim(), Helpers.parseBalance(matcher.group(3))));
+                transactions.add(new Transaction(matcher.group(1), Html.fromHtml(matcher.group(2).trim()).toString(), Helpers.parseBalance(matcher.group(3))));
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {

commit bb7ca32e23d5bf2bce72ba6bfdad74033bba687a
Author: liato <x@x00.us>
Date:   Thu Jun 20 19:46:38 2013 +0200

    Add all found Hemkop accounts to account list.

diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 8cf49b5..0b04c2a 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -177,6 +177,7 @@ public class Hemkop extends Bank {
             for (Element e : es) {
             	Account a = new Account(e.child(0).ownText().trim(), Helpers.parseBalance(e.child(1).ownText()), String.format("acc_cc_%d", i));
             	a.setAliasfor("acc_0");
+            	accounts.add(a);
             	i++;
             }
             

commit ddfd1419eafe65c41bdd77a9bdb01f7eeec910d0
Author: liato <x@x00.us>
Date:   Thu Jun 20 19:44:23 2013 +0200

    Fix for Volvofinans.

diff --git AndroidManifest.xml AndroidManifest.xml
index 06e7ad2..a225ac5 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.0-RC2" android:versionCode="157">
+	android:versionName="1.9.6.0-RC4" android:versionCode="159">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index e01e466..0f1c7c4 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -56,7 +56,7 @@ public class Volvofinans extends Bank {
 	private static final String TAG = "Volvofinans";
 	private static final String NAME = "Volvofinans";
 	private static final String NAME_SHORT = "volvofinans";
-	private static final String URL = "https://secure.volvokort.com/";
+	private static final String URL = "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html";
 	private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
@@ -88,9 +88,9 @@ public class Volvofinans extends Bank {
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
-        postData.add(new BasicNameValuePair("TARGET", "https://www.volvokort.com/privat/inloggning/redirect.html"));
-        postData.add(new BasicNameValuePair("REFERER", "https://www.volvokort.com/privat/inloggning/forenklad.html"));
-        return new LoginPackage(urlopen, postData, null, "https://secure.volvokort.com/neas/KodAuth");
+        postData.add(new BasicNameValuePair("TARGET", "https://inloggad.volvofinans.se/privat/inloggning/redirect.html"));
+        postData.add(new BasicNameValuePair("REFERER", "https://inloggad.volvofinans.se/privat/inloggning/forenklad.html"));
+        return new LoginPackage(urlopen, postData, null, "https://secure.volvofinans.se/neas/KodAuth");
     }
 
     @Override
@@ -125,7 +125,7 @@ public class Volvofinans extends Bank {
 		urlopen = login();
 		String response = null;
 		try {
-			response = urlopen.open("https://www.volvokort.com/privat/kund/kortkonto/oversikt/kortkonton.html");
+			response = urlopen.open("https://inloggad.volvofinans.se/privat/kund/kortkonto/oversikt/kortkonton.html");
 			try {
 				JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
 				JSONArray data = object.getJSONArray("data");
@@ -166,7 +166,7 @@ public class Volvofinans extends Bank {
         String url = mAccountUrlMappings.get(account.getId());
         if (url != null) {
             try {
-                response = urlopen.open("https://www.volvokort.com" + url);
+                response = urlopen.open("https://inloggad.volvofinans.se" + url);
                 ArrayList<Transaction> transactions = new ArrayList<Transaction>();
                 account.setTransactions(transactions);
                 JSONObject object = (JSONObject) new JSONTokener(response).nextValue();

commit 835c43d797ae895d275a957c99d6b0607b59f602
Merge: 9150e98 bb3f96f
Author: liato <x@x00.us>
Date:   Thu Jun 20 08:05:59 2013 +0200

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Forex - fix för konton utan disponibelt belopp

commit 9150e98384300eabba03994de94eaf59b01f18d6
Author: liato <x@x00.us>
Date:   Thu Jun 20 08:05:51 2013 +0200

    Disable separate transactions update for Hemkop.

diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index a056282..8cf49b5 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -21,7 +21,6 @@ import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Pattern;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
@@ -195,6 +194,7 @@ public class Hemkop extends Bank {
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
+        /*
         if (!"acc_0".equals(account.getId())) return;
         try {
             response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
@@ -221,5 +221,6 @@ public class Hemkop extends Bank {
         finally {
             super.updateComplete();
         }
+        */
     }
 }
\ No newline at end of file

commit bb3f96faca2df4351bd9e3f7c928ace69ec73461
Merge: 364a89a a3334e8
Author: liato <x@x00.us>
Date:   Wed Jun 19 15:47:19 2013 -0700

    Merge pull request #233 from rickythefox/master
    
    Add support for a second type of accounts

commit a3334e81f14bb9b7e92df8c503d945f8cb5f1e3c
Author: richard <richard@ginzburg.se>
Date:   Thu Jun 20 00:24:37 2013 +0200

    Forex - fix för konton utan disponibelt belopp

diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index 5774e90..719a869 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -45,7 +45,7 @@ public class ForexBank extends Bank {
     private Pattern reTranId = Pattern.compile("p_tranid\" value=\"(\\d+)\"", Pattern.MULTILINE);
     private Pattern reFallbackQuery = Pattern.compile("fallbackQuery\"\\svalue=\"(.*)\"", Pattern.MULTILINE);
 
-    private Pattern reAccountIds = Pattern.compile("ransactions\\?cvokey=(\\d+)", Pattern.MULTILINE);
+    private Pattern reAccountIds = Pattern.compile("ransactions\\?cvokey=(.\\d+)", Pattern.MULTILINE);
     private Pattern reAccountNumbers = Pattern.compile("account_number.*\\>(\\d+)", Pattern.MULTILINE);
     private Pattern reAccountName = Pattern.compile("account_name.*\\>(.+)<", Pattern.MULTILINE);
     private Pattern reAccountBalance = Pattern.compile("balance.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
@@ -175,13 +175,18 @@ public class ForexBank extends Bank {
             Matcher mAccountBalances = reAccountBalance.matcher(result);
             Matcher mDisposables = reDisposable.matcher(result);
 
-            if(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find() && mDisposables.find())  {
+            if(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find())  {
                 for (int i = 0; i < mAccountNumbers.groupCount() ; i++) {
                     mIdMappings.put(Integer.toString(i+1), mAccountIds.group(i+1));
-                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(mDisposables.group(i+1).trim()), Integer.toString(i+1)));
-                    Account account = new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Saldo)", Helpers.parseBalance(mAccountBalances.group(i+1).trim()), "a:" + i+1);
-                    account.setAliasfor(Integer.toString(i+1));
-                    accounts.add(account);
+                    if(mDisposables.find()) {
+                        accounts.add(new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(mDisposables.group(i+1).trim()), Integer.toString(i+1)));
+                        Account account = new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Saldo)", Helpers.parseBalance(mAccountBalances.group(i+1).trim()), "a:" + i+1);
+                        account.setAliasfor(Integer.toString(i+1));
+                        accounts.add(account);
+                    }
+                    else {
+                        accounts.add(new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim(), Helpers.parseBalance(mAccountBalances.group(i+1).trim()), Integer.toString(i+1)));
+                    }
 
                     balance = balance.add(Helpers.parseBalance(mAccountBalances.group(i+1)));
                 }

commit 364a89a53f980fbd4d9302af124ae88ac8ce72ac
Author: liato <x@x00.us>
Date:   Thu Jun 20 00:17:05 2013 +0200

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0c057d0..06e7ad2 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.6.0-RC1" android:versionCode="156">
+	android:versionName="1.9.6.0-RC2" android:versionCode="157">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index 5774e90..70d78a8 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -1,9 +1,23 @@
 package com.liato.bankdroid.banking.banks;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
+
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
@@ -13,20 +27,8 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
-import eu.nullbyte.android.urllib.Urllib;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.util.EntityUtils;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import eu.nullbyte.android.urllib.Urllib;
 
 public class ForexBank extends Bank {
     // Logon url: https://nettbank.edb.com/mobilepayment/index.jsp?n_bank=0087&nativeapp=android
@@ -208,7 +210,6 @@ public class ForexBank extends Bank {
         try {
             response = urlopen.open(BASE_URL + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey=" + accountId);
             response = response.replace("&nbsp;", "");
-            Log.d(TAG, response);
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
             while (matcher.find()) {

commit 86bfa9e872479a3eb9f576ed77db61b1fac28e48
Merge: 1d21dd5 ba03b1e
Author: liato <x@x00.us>
Date:   Wed Jun 19 15:12:54 2013 -0700

    Merge pull request #232 from rickythefox/master
    
    RegEx update for transactions in Forex bank

commit 1d21dd5792ca00954074b27cac375333ab514d7e
Author: liato <x@x00.us>
Date:   Thu Jun 20 00:11:42 2013 +0200

    Fix for ICA.

diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index f74d6d8..6522dd8 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -79,6 +79,7 @@ public class ICA extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
+        urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         String response = urlopen.open("https://www.ica.se/logga-in/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
@@ -99,8 +100,8 @@ public class ICA extends Bank {
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
         postData.add(new BasicNameValuePair("LoginView1$userName", username));
-        postData.add(new BasicNameValuePair("LoginView1$password", password));
-        
+        postData.add(new BasicNameValuePair("LoginView1$passWord", password));
+        postData.add(new BasicNameValuePair("LoginView1$RememberMe", "on"));
         return new LoginPackage(urlopen, postData, response, "https://www.ica.se/logga-in/");
     }
 

commit ba03b1e5abbd6a18220046654b78b1b3430802b1
Author: richard <richard@ginzburg.se>
Date:   Wed Jun 19 23:22:33 2013 +0200

    Forex - fix för transaktionshistoriken (RegEx)

diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
index 64cfa66..5774e90 100644
--- src/com/liato/bankdroid/banking/banks/ForexBank.java
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -51,7 +51,7 @@ public class ForexBank extends Bank {
     private Pattern reAccountBalance = Pattern.compile("balance.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
     private Pattern reDisposable = Pattern.compile("disposable.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
 
-    private Pattern reTransactions = Pattern.compile("item\\stransaction.*(\\d{4}-\\d{2}-\\d{2}).*>(\\d+,\\d{2}).*left\">\\s*(.*?)\\s*</div>", Pattern.MULTILINE | Pattern.DOTALL);
+    private Pattern reTransactions = Pattern.compile("item\\stransaction.+?(\\d{4}-\\d{2}-\\d{2}?).+?(-?\\d+,\\d{2}).*?left\">\\s+(.+?)\\s+</div>", Pattern.MULTILINE | Pattern.DOTALL);
 
     private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 
@@ -208,6 +208,7 @@ public class ForexBank extends Bank {
         try {
             response = urlopen.open(BASE_URL + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey=" + accountId);
             response = response.replace("&nbsp;", "");
+            Log.d(TAG, response);
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
             while (matcher.find()) {

commit 04d98e946e28bb3ed28912910203a907d9819ead
Author: liato <x@x00.us>
Date:   Wed Jun 19 20:46:34 2013 +0200

    Credit card values for Hemkop.

diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 4a9100a..a056282 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -156,6 +156,39 @@ public class Hemkop extends Bank {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
         
+        Account account = accounts.get(0);
+        try {
+            response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
+            d = Jsoup.parse(response);
+        	Elements es = d.select(".transactions tbody tr");
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            for (Element e : es) {
+                Transaction t = new Transaction(e.child(1).ownText().trim(),
+                					e.child(0).ownText().trim(),
+                        Helpers.parseBalance(e.child(3).ownText()));
+                if (!TextUtils.isEmpty(e.child(2).ownText())) {
+                    t.setCurrency(Helpers.parseCurrency(e.child(2).ownText().trim(), "SEK"));
+                }
+                transactions.add(t);
+        	}
+            account.setTransactions(transactions);
+            
+            es = d.select(".currentBalance,.disposable");
+            int i = 0;
+            for (Element e : es) {
+            	Account a = new Account(e.child(0).ownText().trim(), Helpers.parseBalance(e.child(1).ownText()), String.format("acc_cc_%d", i));
+            	a.setAliasfor("acc_0");
+            	i++;
+            }
+            
+        } catch (ClientProtocolException e) {
+        	e.printStackTrace();
+            Log.e(TAG, e.getMessage() != null ? e.getMessage() : "");
+        } catch (IOException e) {
+        	e.printStackTrace();
+            Log.e(TAG,  e.getMessage() != null ? e.getMessage() : "");
+        }        
+        
         super.updateComplete();
     }
 

commit c0a79238304146e9a98e57606516f7b04cddca95
Author: liato <x@x00.us>
Date:   Wed Jun 19 20:15:44 2013 +0200

    Fix for Avanza Mini login.

diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 55a2266..efe2fd6 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -25,6 +25,9 @@ import java.util.regex.Pattern;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
 
 import android.content.Context;
 import android.text.Html;
@@ -67,10 +70,27 @@ public class AvanzaMini extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true, true);
+        String response = urlopen.open("https://www.avanza.se/mini/logga_in/");
+        Document d = Jsoup.parse(response);
+        Element e = d.getElementById("javax.faces.ViewState");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String viewState = e.attr("value");
+        e = d.select("input[type=submit]").first();
+        if (e == null || e.attr("value") == null || e.attr("name") == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " SubmitValue.");
+        }
+        String submitButtonName = e.attr("name");
+        String submitButtonValue = e.attr("value");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("login", "login"));
         postData.add(new BasicNameValuePair("username", username));
         postData.add(new BasicNameValuePair("password", password));
-        return new LoginPackage(urlopen, postData, null, "https://www.avanza.se/aza/login/login.jsp");
+        postData.add(new BasicNameValuePair("conversationPropagation", "none"));
+        postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
+        postData.add(new BasicNameValuePair(submitButtonName, submitButtonValue));
+        return new LoginPackage(urlopen, postData, null, "https://www.avanza.se/mini/logga_in/");
     }
 
 	@Override
@@ -78,8 +98,9 @@ public class AvanzaMini extends Bank {
 		String response = null;
 		try {
 			LoginPackage lp = preLogin();
+			urlopen.addHeader("Referer", "https://www.avanza.se/mini/logga_in/");
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
+			if (response.contains("Felaktigt") && response.contains("Logga in")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			
@@ -100,7 +121,7 @@ public class AvanzaMini extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://www.avanza.se/mini/mitt_konto/index.html");
+			response = urlopen.open("https://www.avanza.se/mini/mitt_konto/");
 			matcher = reAvanzaMini.matcher(response);
 	        if (matcher.find()) {
 	            int count = 1;

commit 7dd9ff075eb54255dccce0fc18360b47ebde320b
Author: liato <x@x00.us>
Date:   Wed Jun 19 00:31:48 2013 +0200

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0002c58..0c057d0 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.4" android:versionCode="155">
+	android:versionName="1.9.6.0-RC1" android:versionCode="156">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 8ecf298b853382001f44c54a860186ff5fc40144
Author: liato <x@x00.us>
Date:   Wed Jun 19 00:23:43 2013 +0200

    Update Hemkop to work with new site design.

diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 50a13fd..4a9100a 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -18,20 +18,22 @@
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
 import java.util.List;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
 
 import android.content.Context;
-import android.text.Html;
 import android.text.InputType;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
@@ -50,18 +52,11 @@ public class Hemkop extends Bank {
     private static final String TAG = "Hemkop";
     private static final String NAME = "Hemköp Kundkort";
     private static final String NAME_SHORT = "hemkop";
-    private static final String URL = "https://kundkort.hemkop.se/showdoc.asp?docid=1209";
+    private static final String URL = "https://www.hemkop.se/Mina-sidor/Logga-in/";
     private static final int BANKTYPE_ID = IBankTypes.HEMKOP;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
 
-    private Pattern reBalance = Pattern.compile("<span id=\"ctl00_cpTop_lblAktuelltSaldoRubrik\">(.*):</span>\\s*<strong><span id=\"ctl00_cpTop_lbl(AktuelltSaldo)\">(.*)</span></strong>");
-    private Pattern reBonusIn = Pattern.compile("<span id=\"ctl00_cpTop_lblBonusInfoRubrik\">(.*):</span>\\s*<strong><span id=\"ctl00_cpTop_lbl(BonusInfo)\">(.*)</span></strong>");
-    private Pattern reBonusMonth = Pattern.compile("<span id=\"ctl00_cpTop_lblBonusInfoSumRubrik\">(.*):</span>\\s*<strong><span id=\"ctl00_cpTop_lbl(BonusInfoSum)\">(.*)</span></strong>");
-    private Pattern reTransaction = Pattern.compile("<tr class=\\s*\"transaction_row\">\\s*<td class=\"date\">\\s*(.*)\\s*</td>\\s*<td class=\"event\">\\s*(.*)\\s*</td>\\s*(<td class=\"currency\">\\s*(.*)\\s*</td>\\s*)?<td class=\"value\">\\s*(.*)\\s*</td>\\s*</tr>");
-    // space here due to a bug on the bonus transactions page -^^^^
-
     private String response = null;
 
     public Hemkop(Context context) {
@@ -72,7 +67,6 @@ public class Hemkop extends Bank {
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
@@ -86,23 +80,44 @@ public class Hemkop extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
+        urlopen = new Urllib(true, true);
+        response = urlopen.open("https://www.hemkop.se/Mina-sidor/Logga-in/");
+        
+        Document d = Jsoup.parse(response);
+        Element e = d.getElementById("__VIEWSTATE");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String viewState = e.attr("value");
+
+        e = d.getElementById("__EVENTVALIDATION");
+        if (e == null || e.attr("value") == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+        }
+        String eventValidation = e.attr("value");
+        
+        
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("hemkop_personnummer", username));
-        postData.add(new BasicNameValuePair("hemkop_password", password));
-        postData.add(new BasicNameValuePair("login", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, "https://kundkort.hemkop.se/scripts/cgiip.exe/WService=axfood/axfood/common/loginhemkopkundkort.p");
+        postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl00$MainContent$BtnLogin"));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__SCROLLPOSITIONX", "0"));
+        postData.add(new BasicNameValuePair("__SCROLLPOSITIONY", "266"));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair("ctl00$uiTopMenu$Search", ""));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$tbUsername", username));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$tbPassword", password));
+        return new LoginPackage(urlopen, postData, response, "https://www.hemkop.se/Mina-sidor/Logga-in/");
     }
 
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("status=failed")) {
+            if (!response.contains("Inloggad som")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
-            //Login result contains a meta redirect to this page.
-            response = urlopen.open("https://kundkort.hemkop.se/showdoc.asp?docid=780&show=minasidor");
+            response = urlopen.open("https://www.hemkop.se/Mina-sidor/Bonussaldo/");
         }
         catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
@@ -122,17 +137,19 @@ public class Hemkop extends Bank {
 
         urlopen = login();
         
-        ArrayList<Pattern> arrPat = new ArrayList<Pattern>();
-        arrPat.add(reBalance);    // Balance (for VISA only)
-        arrPat.add(reBonusIn);    // Collected bonus before this month
-        arrPat.add(reBonusMonth); // Collected bonus this month
-        
-        for (Pattern p : arrPat) {
-            Matcher matcher = p.matcher(response);
-            if (matcher.find()) {
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim()));
-                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-            }
+        Document d = Jsoup.parse(response);
+    	Elements amounts = d.select(".bonusStatement .amount");
+    	Elements names = d.select(".bonusStatement .label");
+        for (int i = 0; i < Math.min(amounts.size(), names.size()); i++) {
+        	Element amount = amounts.get(i);
+        	Element name = names.get(i);
+    		BigDecimal accountBalance = Helpers.parseBalance(amount.ownText());
+    		Account account = new Account(name.ownText().replace(":", "").trim(), accountBalance, String.format("acc_%d", i));
+    		if (i > 0) {
+    			account.setAliasfor("acc_0");
+    		}
+            accounts.add(account);
+            balance = balance.add(accountBalance);
         }
 
         if (accounts.isEmpty()) {
@@ -145,46 +162,28 @@ public class Hemkop extends Bank {
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
-     
+        if (!"acc_0".equals(account.getId())) return;
         try {
-            String url = null;
-            GregorianCalendar from = new GregorianCalendar();
-            GregorianCalendar tom = new GregorianCalendar();
-            if (account.getId().equals("AktuelltSaldo")) {
-                // Get a year's worth of card transactions (VISA only)
-                from.set(Calendar.YEAR, from.get(Calendar.YEAR) - 1);
-                url = String.format("https://kundkort.hemkop.se/showdoc.asp?docid=785&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
-            } else if (account.getId().equals("BonusInfo")) {
-                // Get a year's worth of bonus transactions (shopping within Hemköp) until the current month.
-                from.set(Calendar.YEAR, from.get(Calendar.YEAR) - 1);
-                tom.set(Calendar.DATE, 0);
-                url = String.format("https://kundkort.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
-            } else if (account.getId().equals("BonusInfoSum")) {
-                // Get a bonus transactions (shopping within Hemköp) during the current month.
-                from.set(Calendar.DATE, 1);
-                url = String.format("https://kundkort.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
-            }
-            
-            if (url != null) {
-                response = urlopen.open(url);
-    
-                Matcher matcher = reTransaction.matcher(response);
-                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                while (matcher.find()) {
-                    Transaction t = new Transaction(matcher.group(1).trim(),
-                            Html.fromHtml(matcher.group(2)).toString().trim(),
-                            Helpers.parseBalance(matcher.group(5)));
-                    if (matcher.group(4) != null && matcher.group(4).length() > 0) {
-                        t.setCurrency(Html.fromHtml(matcher.group(4)).toString().trim());
-                    }
-                    transactions.add(t);
+            response = urlopen.open("https://www.hemkop.se/Mina-sidor/Kontoutdrag/");
+            Document d = Jsoup.parse(response);
+        	Elements es = d.select(".transactions tbody tr");
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            for (Element e : es) {
+                Transaction t = new Transaction(e.child(1).ownText().trim(),
+                					e.child(0).ownText().trim(),
+                        Helpers.parseBalance(e.child(3).ownText()));
+                if (!TextUtils.isEmpty(e.child(2).ownText())) {
+                    t.setCurrency(Helpers.parseCurrency(e.child(2).ownText().trim(), "SEK"));
                 }
-                account.setTransactions(transactions);
-            }
+                transactions.add(t);
+        	}
+            account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
-            Log.e(TAG, e.getMessage());
+        	e.printStackTrace();
+            Log.e(TAG, e.getMessage() != null ? e.getMessage() : "");
         } catch (IOException e) {
-            Log.e(TAG, e.getMessage());
+        	e.printStackTrace();
+            Log.e(TAG,  e.getMessage() != null ? e.getMessage() : "");
         }
         finally {
             super.updateComplete();

commit 4051f84eb527977645d674fb4af0f18cb2d0c306
Author: liato <x@x00.us>
Date:   Tue Jun 18 22:26:01 2013 +0200

    User desktop user agent for PayPal to prevent redirect to mobile page.

diff --git project.properties project.properties
index cd9c350..fd44ee5 100644
--- project.properties
+++ project.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-15
+target=android-17
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 6e06498..cfb7524 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -29,7 +29,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -76,6 +75,7 @@ public class PayPal extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
+        urlopen.setUserAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36");
         //Get cookies and url to post to
         response = urlopen.open("https://www.paypal.com/en");
         Matcher matcher = reFormAction.matcher(response);

commit b94fb1af4de2b9e955e719e6af1914377bd029f2
Merge: 96a5575 a802448
Author: liato <x@x00.us>
Date:   Tue Jun 18 12:36:44 2013 -0700

    Merge pull request #231 from rickythefox/master
    
    Forex bank

commit a8024488da6196d5066444cdd147bb261dcf5e5d
Author: richard <richard@ginzburg.se>
Date:   Wed Jun 12 22:14:01 2013 +0200

    Forex logo

diff --git res/drawable/logo_forex.png res/drawable/logo_forex.png
new file mode 100644
index 0000000..7aaaadc
Binary files /dev/null and res/drawable/logo_forex.png differ

commit 8fb8943f3c9f303ac4525a793729283b93956855
Author: richard <richard@ginzburg.se>
Date:   Wed Jun 12 22:13:17 2013 +0200

    Added support for Forex bank

diff --git project.properties project.properties
index fd44ee5..cd9c350 100644
--- project.properties
+++ project.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-17
+target=android-15
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index b690197..7213f22 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -21,75 +21,9 @@ import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
 
-import com.liato.bankdroid.banking.banks.AkeliusInvest;
-import com.liato.bankdroid.banking.banks.AkeliusSpar;
-import com.liato.bankdroid.banking.banks.AmericanExpress;
-import com.liato.bankdroid.banking.banks.Audi;
-import com.liato.bankdroid.banking.banks.Avanza;
-import com.liato.bankdroid.banking.banks.AvanzaMini;
-import com.liato.bankdroid.banking.banks.BetterGlobe;
-import com.liato.bankdroid.banking.banks.Bioklubben;
-import com.liato.bankdroid.banking.banks.BrummerKF;
-import com.liato.bankdroid.banking.banks.CSN;
-import com.liato.bankdroid.banking.banks.Chalmrest;
-import com.liato.bankdroid.banking.banks.Chevrolet;
-import com.liato.bankdroid.banking.banks.Coop;
-import com.liato.bankdroid.banking.banks.DanskeBank;
-import com.liato.bankdroid.banking.banks.DinersClub;
-import com.liato.bankdroid.banking.banks.Djurgarden;
-import com.liato.bankdroid.banking.banks.EurobonusMastercard;
-import com.liato.bankdroid.banking.banks.Eurocard;
-import com.liato.bankdroid.banking.banks.Everydaycard;
-import com.liato.bankdroid.banking.banks.FirstCard;
-import com.liato.bankdroid.banking.banks.Handelsbanken;
-import com.liato.bankdroid.banking.banks.Hemkop;
-import com.liato.bankdroid.banking.banks.ICA;
-import com.liato.bankdroid.banking.banks.ICABanken;
-import com.liato.bankdroid.banking.banks.IKEA;
-import com.liato.bankdroid.banking.banks.IkanoBank;
-import com.liato.bankdroid.banking.banks.Jojo;
+import com.liato.bankdroid.banking.banks.*;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
-import com.liato.bankdroid.banking.banks.AppeakPoker;
-import com.liato.bankdroid.banking.banks.EasyCard;
-import com.liato.bankdroid.banking.banks.McDonalds;
-import com.liato.bankdroid.banking.banks.NordeaDK;
-import com.liato.bankdroid.banking.banks.Nordnet;
-import com.liato.bankdroid.banking.banks.Nordnetdirekt;
-import com.liato.bankdroid.banking.banks.OKQ8;
-import com.liato.bankdroid.banking.banks.Opel;
-import com.liato.bankdroid.banking.banks.Osuuspankki;
-import com.liato.bankdroid.banking.banks.PayPal;
-import com.liato.bankdroid.banking.banks.Payson;
-import com.liato.bankdroid.banking.banks.PlusGirot;
-import com.liato.bankdroid.banking.banks.Preem;
-import com.liato.bankdroid.banking.banks.Quintessentially;
-import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.TicketRikskortet;
-import com.liato.bankdroid.banking.banks.Rikslunchen;
-import com.liato.bankdroid.banking.banks.SEB;
-import com.liato.bankdroid.banking.banks.SJPrio;
-import com.liato.bankdroid.banking.banks.Saab;
-import com.liato.bankdroid.banking.banks.Seat;
-import com.liato.bankdroid.banking.banks.SevenDay;
-import com.liato.bankdroid.banking.banks.Shell;
-import com.liato.bankdroid.banking.banks.Skandiabanken;
-import com.liato.bankdroid.banking.banks.Skoda;
-import com.liato.bankdroid.banking.banks.SparbankenOresund;
-import com.liato.bankdroid.banking.banks.SparbankenSyd;
-import com.liato.bankdroid.banking.banks.Statoil;
-import com.liato.bankdroid.banking.banks.Swedbank;
-import com.liato.bankdroid.banking.banks.TestBank;
-import com.liato.bankdroid.banking.banks.TrustBuddy;
-import com.liato.bankdroid.banking.banks.Vasttrafik;
-import com.liato.bankdroid.banking.banks.Villabanken;
-import com.liato.bankdroid.banking.banks.Volkswagen;
-import com.liato.bankdroid.banking.banks.Volvofinans;
-import com.liato.bankdroid.banking.banks.Wallet;
-import com.liato.bankdroid.banking.banks.Meniga;
-import com.liato.bankdroid.banking.banks.Marginalen;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
-import com.liato.bankdroid.banking.banks.SvenskaSpel;
-import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
@@ -243,6 +177,8 @@ public class BankFactory {
        	    return new Zidisha(context);
         case IBankTypes.BETTERGLOBE:
         	return new BetterGlobe(context);
+        case IBankTypes.FOREX:
+            return new ForexBank(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -320,6 +256,7 @@ public class BankFactory {
         banks.add(new AppeakPoker(context));
         banks.add(new Zidisha(context));
         banks.add(new BetterGlobe(context));
+        banks.add(new ForexBank(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/ForexBank.java src/com/liato/bankdroid/banking/banks/ForexBank.java
new file mode 100644
index 0000000..64cfa66
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ForexBank.java
@@ -0,0 +1,226 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+import eu.nullbyte.android.urllib.Urllib;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ForexBank extends Bank {
+    // Logon url: https://nettbank.edb.com/mobilepayment/index.jsp?n_bank=0087&nativeapp=android
+    private static final String TAG = "ForexBank";
+    private static final String NAME = "Forex Bank";
+    private static final String NAME_SHORT = "forex";
+    private static final String URL = "https://www.forex.se/";
+    private static final int BANKTYPE_ID = IBankTypes.FOREX;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final boolean STATIC_BALANCE = false;
+    private static final String BASE_URL = "https://nettbank.edb.com";
+
+    private Pattern reFormAction = Pattern.compile("form action=\"(.*)\"\\s", Pattern.MULTILINE);
+    private Pattern reTranId = Pattern.compile("p_tranid\" value=\"(\\d+)\"", Pattern.MULTILINE);
+    private Pattern reFallbackQuery = Pattern.compile("fallbackQuery\"\\svalue=\"(.*)\"", Pattern.MULTILINE);
+
+    private Pattern reAccountIds = Pattern.compile("ransactions\\?cvokey=(\\d+)", Pattern.MULTILINE);
+    private Pattern reAccountNumbers = Pattern.compile("account_number.*\\>(\\d+)", Pattern.MULTILINE);
+    private Pattern reAccountName = Pattern.compile("account_name.*\\>(.+)<", Pattern.MULTILINE);
+    private Pattern reAccountBalance = Pattern.compile("balance.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
+    private Pattern reDisposable = Pattern.compile("disposable.*\\>(\\d+,\\d\\d)", Pattern.MULTILINE);
+
+    private Pattern reTransactions = Pattern.compile("item\\stransaction.*(\\d{4}-\\d{2}-\\d{2}).*>(\\d+,\\d{2}).*left\">\\s*(.*?)\\s*</div>", Pattern.MULTILINE | Pattern.DOTALL);
+
+    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
+
+    public ForexBank(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+    public ForexBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String baseUrl = "https://nettbank.edb.com";
+        String res = urlopen.open(baseUrl + "/mobilepayment/index.jsp?n_bank=0087&nativeapp=android");
+        String formAction = "";
+        String tranId = "";
+        String fallbackQuery = "";
+
+        // Get post action
+        Matcher mFormAction = reFormAction.matcher(res);
+        if(mFormAction.find())
+        {
+            formAction = mFormAction.group(1);
+            //System.err.println(mFormAction.group(1));
+        }
+
+        // Get transaction id hidden param
+        Matcher mTranId = reTranId.matcher(res);
+        if(mTranId.find())
+        {
+            tranId = mTranId.group(1);
+            //System.err.println(mTranId.group(1));
+        }
+
+        // Weird param, lets include it!
+        Matcher mFallbackQuery = reFallbackQuery.matcher(res);
+        if(mFallbackQuery.find())
+        {
+            fallbackQuery = mFallbackQuery.group(1);
+            //System.err.println(mTranId.group(1));
+        }
+
+        // Assemble param table
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("p_tranid", tranId));
+        postData.add(new BasicNameValuePair("user_id", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("submitButton", "Logga in"));
+        postData.add(new BasicNameValuePair("forcelayout", "touch"));
+        postData.add(new BasicNameValuePair("fallbackQuery", fallbackQuery));
+        postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
+
+        return new LoginPackage(urlopen, postData, null, formAction);
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+
+            // Post
+            HttpResponse httpResponse = urlopen.openAsHttpResponse(BASE_URL + lp.getLoginTarget(), lp.getPostData(), false);
+
+            String result = EntityUtils.toString(httpResponse.getEntity());
+
+            if(!result.contains("/mobilepayment/transigo/logon/logout")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            Log.e(TAG, "ClientProtocolException: " + e.getMessage());
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            Log.e(TAG, "IOException: "+e.getMessage());
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        try {
+            /*
+            "account_number.*\\>(\\d+)"; // Kontonummer
+            "account_name.*\\>(.+)<" // Kontonamn
+            "balance.*\>(\d+,\d\d)" // Saldo
+            "disposable.*\>(\d+,\d\d)" // Disponibelt
+
+            System.err.println("Kontonummer " + mAccountNumbers.group(i+1));
+            System.err.println("Kontonamn " + mAccountNames.group(i+1));
+            System.err.println("Saldo " + mAccountBalances.group(i+1));
+            System.err.println("Disponibelt " + mDisposables.group(i+1));
+             */
+            urlopen = login();
+
+            // Go to main menu
+            String result = urlopen.open("https://nettbank.edb.com/mobilepayment/transigo/menu/menu1");
+            result = result.replace("&nbsp;",""); // Remove non-breaking spaces, they fuck up balances
+
+            Matcher mAccountIds = reAccountIds.matcher(result);
+            Matcher mAccountNumbers = reAccountNumbers.matcher(result);
+            Matcher mAccountNames = reAccountName.matcher(result);
+            Matcher mAccountBalances = reAccountBalance.matcher(result);
+            Matcher mDisposables = reDisposable.matcher(result);
+
+            if(mAccountIds.find() && mAccountNumbers.find() && mAccountNames.find() && mAccountBalances.find() && mDisposables.find())  {
+                for (int i = 0; i < mAccountNumbers.groupCount() ; i++) {
+                    mIdMappings.put(Integer.toString(i+1), mAccountIds.group(i+1));
+                    accounts.add(new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(mDisposables.group(i+1).trim()), Integer.toString(i+1)));
+                    Account account = new Account(Html.fromHtml(mAccountNames.group(i+1)).toString().trim() + " (Saldo)", Helpers.parseBalance(mAccountBalances.group(i+1).trim()), "a:" + i+1);
+                    account.setAliasfor(Integer.toString(i+1));
+                    accounts.add(account);
+
+                    balance = balance.add(Helpers.parseBalance(mAccountBalances.group(i+1)));
+                }
+            }
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+        String accountId = mIdMappings.get(account.getId());
+        String response = null;
+        Matcher matcher;
+        try {
+            response = urlopen.open(BASE_URL + "/mobilepayment/transigo/account/overview/accountTransactions?cvokey=" + accountId);
+            response = response.replace("&nbsp;", "");
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                transactions.add(new Transaction(matcher.group(1).trim(), matcher.group(3).trim(), Helpers.parseBalance(matcher.group(2))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        finally {
+            super.updateComplete();
+        }
+    }
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 5118e16..e8a76b0 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -91,4 +91,5 @@ public interface IBankTypes {
     public static final int BRUMMER_KF = 67;
     public static final int ZIDISHA = 68;
     public static final int BETTERGLOBE = 69;
+    public static final int FOREX = 70;
 }
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 59ee4c2..a340e12 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -50,6 +50,7 @@ import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
@@ -105,17 +106,19 @@ public class Urllib {
     public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
     	return open(url, postData, false);
     }
-   
-    
     public String open(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+        return EntityUtils.toString(openAsHttpResponse(url, postData, forcePost).getEntity());
+    }
+
+    public HttpResponse openAsHttpResponse(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
         this.currentURI = url;
-        String response;
+        HttpResponse response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         ResponseHandler<String> responseHandler = new BasicResponseHandler();
         HttpUriRequest request;
         if ((postData == null || postData.isEmpty()) && !forcePost) {
-            //URL urli = new URL(url); 
+            //URL urli = new URL(url);
             request = new HttpGet(url);
         }
         else {
@@ -124,19 +127,21 @@ public class Urllib {
         }
         if (userAgent != null)
             request.addHeader("User-Agent", userAgent);
-        
+
         for (int i = 0; i < headerKeys.length; i++) {
             request.addHeader(headerKeys[i], headerVals[i]);
         }
-        response = httpclient.execute(request, responseHandler, context);
-        
+
+        response = httpclient.execute(request, context);
+
         //HttpUriRequest currentReq = (HttpUriRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
         //HttpHost currentHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
         //this.currentURI = currentHost.toURI() + currentReq.getURI();
         this.currentURI = request.getURI().toString();
-        
+
         return response;
-    }    
+    }
+
     public InputStream openStream(String url) throws ClientProtocolException, IOException {
         return openStream(url, new BasicHttpEntity(), false);
     }

commit 96a5575641c6862a43acb1afc45b26317c33a7d1
Merge: fa4583d b0f0198
Author: liato <x@x00.us>
Date:   Fri May 31 15:03:17 2013 -0700

    Merge pull request #228 from Tuxie/master
    
    Fix a misinterpretation

commit b0f019814d3663e29626f9176184592adb8007fb
Author: Per Wigren <per.wigren@gmail.com>
Date:   Thu May 30 13:19:51 2013 +0200

    "Balans" is a missleading interpretation of Impact.

diff --git src/com/liato/bankdroid/banking/banks/Zidisha.java src/com/liato/bankdroid/banking/banks/Zidisha.java
index 4083338..de3a5b2 100644
--- src/com/liato/bankdroid/banking/banks/Zidisha.java
+++ src/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -130,15 +130,15 @@ public class Zidisha extends Bank {
 			
 			while (matcher.find()) {
 				/*
-				 * 1: Insättningar
-				 * 2: Tillgängligt
-				 * 3: Utlånat
-				 * 4: Balans
+				 * 1: Funds uploaded
+				 * 2: Available for withdrawal
+				 * 3: Lent by me
+				 * 4: Total Impact
 				 */
 				Account insattningar = new Account("Insättningar", Helpers.parseBalance(matcher.group(1)), "insattningar");
 				Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(2)), "tillgangligt");
 				Account utlanat      = new Account("Utlånat",      Helpers.parseBalance(matcher.group(3)), "utlanat");
-				Account balans       = new Account("Balans",       Helpers.parseBalance(matcher.group(4)), "balans");
+				Account balans       = new Account("Påverkan",     Helpers.parseBalance(matcher.group(4)), "impact");
 
 				insattningar.setCurrency("USD");
 				tillgangligt.setCurrency("USD");

commit fa4583dedec99520ce717aa6ff618fc9994475b3
Merge: 844335e a86ac73
Author: liato <x@x00.us>
Date:   Sat May 18 10:37:29 2013 -0700

    Merge pull request #227 from chrfle/AIOOBE
    
    Fix ArrayIndexOutOfBoundsException for Rikslunchen

commit a86ac730843156d84d34a092e962f56c95adc390
Author: Christer Fletcher <git-projects@fletcher.se>
Date:   Tue May 14 21:12:23 2013 +0200

    Fix ArrayIndexOutOfBoundsException for Rikslunchen
    
    Apparently an empty list of cookies could be received which would
    cause a ArrayIndexOutOfBoundsException. Throw a BankException if
    this happens.

diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 18d3b23..a81e90f 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -108,7 +108,12 @@ public class Rikslunchen extends Bank {
 		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/check_balance.html");
 		HttpResponse response = httpclient.execute(httppost, httpContext);
 
-		Cookie c = cookieStore.getCookies().get(0);
+		List<Cookie> cookies = cookieStore.getCookies();
+		if (cookies.size() == 0) {
+			throw new BankException("No session cookie found, login will fail.");
+		}
+
+		Cookie c = cookies.get(0);
 		postData.add(new BasicNameValuePair("c0-param1", "string:" + c.getValue()));
 		postData.add(new BasicNameValuePair("httpSessionId", c.getValue()));
 

commit 844335eaac003ae23b54619060e66737ff2e449e
Merge: adf09b1 032050f
Author: liato <x@x00.us>
Date:   Wed May 1 06:51:01 2013 -0700

    Merge pull request #225 from Tuxie/master
    
    Avanza: Egendefinerade namn och nettobalans

commit adf09b1fb82d9fe493b4fb883510726c4c4ffc35
Merge: c2a5a80 2367925
Author: liato <x@x00.us>
Date:   Wed May 1 06:50:25 2013 -0700

    Merge pull request #224 from Tuxie/betterglobe
    
    Add support for Better Globe.

commit 032050fea3a72171d509779a53e74624de66e723
Author: Per Wigren <per.wigren@gmail.com>
Date:   Wed May 1 11:59:49 2013 +0200

    Add support for custom account names and net account balance

diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
index 00ab62d..eb52b03 100644
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -30,6 +30,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -50,8 +51,10 @@ public class Avanza extends Bank {
 	private static final String URL = "https://www.avanza.se/";
     private static final int BANKTYPE_ID = IBankTypes.AVANZA;
 	
-	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>(.+?)\\s(Private|Pro|Premium|Bas).*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>(.+?)\\s(Private|Pro|Premium|Bas).*?>.*?( - (.*?))?</span>.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reConnect = Pattern.compile("Kopplat till (\\d+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
 	public Avanza(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -113,13 +116,34 @@ public class Avanza extends Bank {
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
                  * 1: ID                3505060
-                 * 2: Type              Aktie- och fondkonto Premium Silver
-                 * 4: % since purchase  1,90
-                 * 5: Amount in SEK     820
-                 *    
-                 */    
-			    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+                 * 2: Type              Aktie- och fondkonto
+                 * 5: Custom name       ISK
+                 * 6: % since purchase  1,90
+                 * 7: Amount in SEK     820
+                 */
+				String account_name = matcher.group(5);
+				if (account_name == null) {
+					account_name = matcher.group(2);
+				}
+				else if (account_name.matches("Kopplat till \\d+")) {
+					Matcher mConnect = reConnect.matcher(account_name);
+					mConnect.matches();
+					String idConnect = mConnect.group(1);
+					account_name = matcher.group(2);
+					for(Account a : accounts) {
+						if (a.getId().equals(idConnect)) {
+							accounts.add(new Account(
+									a.getName() + " (netto)",
+									a.getBalance().add(Helpers.parseBalance(matcher.group(7))),
+									idConnect+"_netto"
+							));
+							break;
+						}
+					}
+				}
+				
+			    accounts.add(new Account(account_name.trim(), Helpers.parseBalance(matcher.group(7)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(7)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 2367925849b750f331369dce9adefea28229b2df
Author: Per Wigren <per.wigren@gmail.com>
Date:   Wed May 1 01:46:08 2013 +0200

    Add support for BetterGlobe.

diff --git res/drawable/logo_betterglobe.png res/drawable/logo_betterglobe.png
index 6517081..9fe18e0 100644
Binary files res/drawable/logo_betterglobe.png and res/drawable/logo_betterglobe.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index dbbf996..b690197 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -27,6 +27,7 @@ import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.BetterGlobe;
 import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
@@ -240,6 +241,8 @@ public class BankFactory {
        	    return new BrummerKF(context);
         case IBankTypes.ZIDISHA:
        	    return new Zidisha(context);
+        case IBankTypes.BETTERGLOBE:
+        	return new BetterGlobe(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -316,6 +319,7 @@ public class BankFactory {
         banks.add(new EasyCard(context));
         banks.add(new AppeakPoker(context));
         banks.add(new Zidisha(context));
+        banks.add(new BetterGlobe(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/BetterGlobe.java src/com/liato/bankdroid/banking/banks/BetterGlobe.java
new file mode 100644
index 0000000..34ad61f
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/BetterGlobe.java
@@ -0,0 +1,169 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>
+ * BetterGlobe support by Per Wigren <per.wigren@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class BetterGlobe extends Bank {
+	private static final String TAG = "BetterGlobe";
+	private static final String NAME = "Better Globe";
+	private static final String NAME_SHORT = "betterglobe";
+	private static final String URL = "http://betterglobe.com";
+	private static final int BANKTYPE_ID = IBankTypes.BETTERGLOBE;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "AID code";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reBalance  = Pattern.compile("Totalt på BG-kontot\\s*([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reForecast = Pattern.compile("Din totala bruttovinst:.*?€([^<]+).*Köpekostnader:.*?€([^<]+).*Din totala nettovinst:.*?€([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTrees    = Pattern.compile("Totalt? antal ägda träd:</td>\\s*<td.*?>(\\d+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	public BetterGlobe(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
+		super.currency = "EUR";
+	}
+
+	public BetterGlobe(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true,true);
+		HashMap<String, String> headers = urlopen.getHeaders();
+		headers.put("Referer","http://betterglobe.com/login.aspx?lang=sv-SE");
+    	List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("btnLogin", ""));
+        return new LoginPackage(urlopen, postData, "", "http://betterglobe.com/Login.aspx?rememberMe=False");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		Matcher matcher;
+		String response;
+		try {
+			response = urlopen.open("http://betterglobe.com/bgaccount.aspx/report");
+			matcher = reBalance.matcher(response);
+			
+			while (matcher.find()) {
+				Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(1)), "tillgangligt");
+				tillgangligt.setCurrency("EUR");
+				accounts.add(tillgangligt);
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			}
+			
+			response = urlopen.open("http://betterglobe.com/mytrees.aspx/Valueforecast");
+			matcher = reForecast.matcher(response);
+
+			while (matcher.find()) {
+				Account inkop  = new Account("Inköp",              Helpers.parseBalance(matcher.group(2)), "inkop");
+				Account netto  = new Account("Beräknad vinst",     Helpers.parseBalance(matcher.group(3)), "netto");
+				Account brutto = new Account("Beräknat slutvärde", Helpers.parseBalance(matcher.group(1)), "brutto");
+				inkop.setCurrency("EUR");
+				brutto.setCurrency("EUR");
+				netto.setCurrency("EUR");
+				accounts.add(inkop);
+				accounts.add(brutto);
+				accounts.add(netto);
+				balance = balance.add(Helpers.parseBalance(matcher.group(2)));;
+			}
+
+			response = urlopen.open("http://betterglobe.com/mytrees.aspx");
+			matcher = reTrees.matcher(response);
+
+			while (matcher.find()) {
+				Account trees = new Account("Innehav", Helpers.parseBalance(matcher.group(1)), "trees");
+				trees.setCurrency("träd");
+				accounts.add(trees);
+			}
+				
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 0a10f22..5118e16 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -90,4 +90,5 @@ public interface IBankTypes {
     public static final int TRUSTBUDDY = 66;    
     public static final int BRUMMER_KF = 67;
     public static final int ZIDISHA = 68;
+    public static final int BETTERGLOBE = 69;
 }

commit c2a5a80fa23c6ac5ebf48592c8307f2d81a849aa
Merge: df41fd9 81cb3ba
Author: liato <x@x00.us>
Date:   Tue Apr 30 15:21:20 2013 -0700

    Merge pull request #223 from Tuxie/zidisha
    
    Add support for Zidisha.

commit 9fbe84ae940f72839a41e347a7f4d4951fee0a66
Author: Per Wigren <per.wigren@gmail.com>
Date:   Tue Apr 30 22:30:55 2013 +0200

    Preparing to add BetterGlobe-support.

diff --git res/drawable/logo_betterglobe.png res/drawable/logo_betterglobe.png
new file mode 100644
index 0000000..6517081
Binary files /dev/null and res/drawable/logo_betterglobe.png differ

commit 81cb3baea626c90a60d0025d15109d9acdf31176
Author: Per Wigren <per.wigren@gmail.com>
Date:   Tue Apr 30 16:19:42 2013 +0200

    Add support for Zidisha.

diff --git res/drawable/logo_zidisha.png res/drawable/logo_zidisha.png
new file mode 100644
index 0000000..f62ec86
Binary files /dev/null and res/drawable/logo_zidisha.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index fac8929..dbbf996 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -88,6 +88,7 @@ import com.liato.bankdroid.banking.banks.Meniga;
 import com.liato.bankdroid.banking.banks.Marginalen;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
 import com.liato.bankdroid.banking.banks.SvenskaSpel;
+import com.liato.bankdroid.banking.banks.Zidisha;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
@@ -237,6 +238,8 @@ public class BankFactory {
             return new TrustBuddy(context);
         case IBankTypes.BRUMMER_KF:
        	    return new BrummerKF(context);
+        case IBankTypes.ZIDISHA:
+       	    return new Zidisha(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -312,6 +315,7 @@ public class BankFactory {
         banks.add(new SvenskaSpel(context));
         banks.add(new EasyCard(context));
         banks.add(new AppeakPoker(context));
+        banks.add(new Zidisha(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/Zidisha.java src/com/liato/bankdroid/banking/banks/Zidisha.java
new file mode 100644
index 0000000..4083338
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Zidisha.java
@@ -0,0 +1,167 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>
+ * Zidisha support by Per Wigren <per.wigren@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Zidisha extends Bank {
+	private static final String TAG = "Zidisha";
+	private static final String NAME = "Zidisha";
+	private static final String NAME_SHORT = "zidisha";
+	private static final String URL = "https://www.zidisha.org/";
+	private static final int BANKTYPE_ID = IBankTypes.ZIDISHA;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "Username";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reUserGuess = Pattern.compile("<input.*?name=\"user_guess\" value=\"([0-9a-f]+)\"", Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("Funds uploaded:</td>.*?USD ([^<]+).*Credit Available:.*?USD ([^<]+).*Amount Lent By Me:.*?USD ([^<]+).*Total Impact:.*?USD ([^<]+)",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	String response;
+	
+	public Zidisha(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+        super.currency = "USD";
+	}
+
+	public Zidisha(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true,true);
+        response = urlopen.open("https://www.zidisha.org/");
+        Matcher mUserGuess = reUserGuess.matcher(response);
+        if (!mUserGuess.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" user_guess.");
+        }
+        String user_guess = mUserGuess.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("textpassword", username));
+        postData.add(new BasicNameValuePair("userlogin", ""));
+        postData.add(new BasicNameValuePair("user_guess",user_guess));
+        return new LoginPackage(urlopen, postData, response, "https://www.zidisha.org/process.php");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.zidisha.org/index.php?p=19");
+			matcher = reAccounts.matcher(response);
+			
+			while (matcher.find()) {
+				/*
+				 * 1: Insättningar
+				 * 2: Tillgängligt
+				 * 3: Utlånat
+				 * 4: Balans
+				 */
+				Account insattningar = new Account("Insättningar", Helpers.parseBalance(matcher.group(1)), "insattningar");
+				Account tillgangligt = new Account("Tillgängligt", Helpers.parseBalance(matcher.group(2)), "tillgangligt");
+				Account utlanat      = new Account("Utlånat",      Helpers.parseBalance(matcher.group(3)), "utlanat");
+				Account balans       = new Account("Balans",       Helpers.parseBalance(matcher.group(4)), "balans");
+
+				insattningar.setCurrency("USD");
+				tillgangligt.setCurrency("USD");
+				utlanat.setCurrency("USD");
+				balans.setCurrency("USD");
+
+				accounts.add(insattningar);
+				accounts.add(tillgangligt);
+				accounts.add(utlanat);
+				accounts.add(balans);
+	            
+				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 01a1d64..0a10f22 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -89,4 +89,5 @@ public interface IBankTypes {
     public static final int APPEAKPOKER = 65;
     public static final int TRUSTBUDDY = 66;    
     public static final int BRUMMER_KF = 67;
+    public static final int ZIDISHA = 68;
 }

commit df41fd96a3d6d8beb1ded5d0460c04b6396e7056 (tag: v1.9.5.4)
Author: liato <x@x00.us>
Date:   Sun Apr 28 02:32:17 2013 +0200

    Bump version.

diff --git .classpath .classpath
index ae57319..f1a81f8 100644
--- .classpath
+++ .classpath
@@ -1,7 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 	<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
@@ -10,5 +8,7 @@
 	<classpathentry kind="lib" path="libs/jackson-core-2.1.0.jar"/>
 	<classpathentry kind="lib" path="libs/jackson-databind-2.1.0.jar"/>
 	<classpathentry kind="lib" path="libs/jsoup-1.7.2.jar"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index bbced64..0002c58 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.3" android:versionCode="154">
+	android:versionName="1.9.5.4" android:versionCode="155">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git CHANGES.txt CHANGES.txt
index 69346ae..1ad35f6 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,10 @@
+v1.9.5.4: (2013-04-28)
+* Fix for Rikslunchen (thanks to chrfle)
+* Fix for Audikortet (maybe)
++ Support for TrustBuddy (thanks to Tuxie)
++ Support for Brummer Privat KF (thanks to Tuxie)
+
+
 v1.9.5.3: (2013-04-02)
 * Fix for Skodakortet
 * Fix for Volvofinans transactions
diff --git project.properties project.properties
index 8f51418..fd44ee5 100644
--- project.properties
+++ project.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-14
+target=android-17

commit 0f10f6d4ba27768b2fec1231ac8cb56f6c59189c
Merge: 878ddac 5d72034
Author: liato <x@x00.us>
Date:   Sun Apr 21 13:12:04 2013 -0700

    Merge pull request #222 from chrfle/master
    
    Rikslunchen now handles session cookie.

commit 878ddace9d35117b2cde2f0c37236bb536a2cc2f
Merge: cd3ba1e e4a1cb0
Author: liato <x@x00.us>
Date:   Sun Apr 14 14:58:23 2013 -0700

    Merge pull request #220 from Tuxie/master
    
    Add support for TrustBuddy and Brummer Kapitalförsäkring

commit 5d72034049433ea6f335f4867d116fff3ac54cf7
Author: Christer Fletcher <git-projects@fletcher.se>
Date:   Sun Apr 14 00:09:24 2013 +0200

    Rikslunchen now handles session cookie.
    
    Rikslunchen added the use of a session cookie and new parameter
    which broke the implementation. This is now handled by first
    requesting the html page that sets the cookie before requesting the
    page with balance information.

diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 9464a04..18d3b23 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -27,14 +27,21 @@ import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpResponse;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.CookieStore;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
 
 import android.content.Context;
 import android.text.InputType;
+import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -90,14 +97,27 @@ public class Rikslunchen extends Bank {
 		postData.add(new BasicNameValuePair("c0-id", "0"));
 		postData.add(new BasicNameValuePair("batchId", "1"));
 		postData.add(new BasicNameValuePair("page", "%2Friks-cp%2Fcheck_balance.html"));
-		postData.add(new BasicNameValuePair("httpSessionId", ""));
 		postData.add(new BasicNameValuePair("scriptSessionId", ""));
 
 		HttpClient httpclient = new DefaultHttpClient();
-		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
+		CookieStore cookieStore = new BasicCookieStore();
+		HttpContext httpContext = new BasicHttpContext();
+		httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
+
+		// Connect to check_balance to get a session cookie
+		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/check_balance.html");
+		HttpResponse response = httpclient.execute(httppost, httpContext);
+
+		Cookie c = cookieStore.getCookies().get(0);
+		postData.add(new BasicNameValuePair("c0-param1", "string:" + c.getValue()));
+		postData.add(new BasicNameValuePair("httpSessionId", c.getValue()));
+
+		response.getEntity().consumeContent();
+
+		httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
 		httppost.setEntity(new UrlEncodedFormEntity(postData));
 
-		HttpResponse response = httpclient.execute(httppost);
+		response = httpclient.execute(httppost, httpContext);
 		InputStream streamResponse = response.getEntity().getContent();
 		StringWriter writer = new StringWriter();
 		IOUtils.copy(streamResponse, writer);
@@ -139,6 +159,8 @@ public class Rikslunchen extends Bank {
 			BigDecimal balance = Helpers.parseBalance(myResponse.substring(begin + 9, end - 2));
 
 			accounts.add(new Account("Rikslunchen", balance, "1"));
+		} catch (StringIndexOutOfBoundsException e) {
+			Log.e(TAG, "StringIndexOutOfBoundsException", e);
 		} finally {
 			super.updateComplete();
 		}

commit cd3ba1eb488e14cea51113a332f60a8c0a04e344
Author: liato <x@x00.us>
Date:   Tue Apr 2 22:44:29 2013 +0200

    Use new ikano implementation for Audi.

diff --git src/com/liato/bankdroid/banking/banks/Audi.java src/com/liato/bankdroid/banking/banks/Audi.java
index 386de4f..a75821d 100644
--- src/com/liato/bankdroid/banking/banks/Audi.java
+++ src/com/liato/bankdroid/banking/banks/Audi.java
@@ -23,7 +23,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Audi extends IkanoPartnerBase {
+public class Audi extends AbsIkanoPartner {
 	private static final String TAG = "Audi";
 	private static final String NAME = "AudiKortet";
 	private static final String NAME_SHORT = "audi";

commit 391cebc251d5144de5611d4c4b95a727732b48c6
Author: liato <x@x00.us>
Date:   Tue Apr 2 22:24:30 2013 +0200

    Free text input for svenska spel usernames.

diff --git CHANGES.txt CHANGES.txt
index 2773ba3..69346ae 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,20 +1,24 @@
 v1.9.5.3: (2013-04-02)
 * Fix for Skodakortet
 * Fix for Volvofinans transactions
-* Fix for reappearing Akelis spar/invest accounts
+* Fix for reappearing Akelius Spar/Invest accounts
+
 
 v1.9.5.2: (2013-03-27)
 * Fix for Coop
 * Show multiple Nordnet accounts
 
+
 v1.9.5.1: (2013-02-26)
 * Fix for Länsförsäkringar saving accounts
 
+
 v1.9.5: (2013-02-21)
 * Fix for Länsförsäkringar
 + Support for Svenska Spel (thanks to nixi)
 + Support for Appeak Poker
 
+
 1.9.4: (2013-01-04)
 * Fix for ICA Banken transactions (thanks to fruktsallad)
 * Fix for Länsförsäkringar
diff --git src/com/liato/bankdroid/banking/banks/SvenskaSpel.java src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
index e436104..53074a5 100644
--- src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
+++ src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -46,7 +46,7 @@ public class SvenskaSpel extends Bank {
 	private static final String NAME_SHORT = "svenskaspel";
 	private static final String URL = "https://m.svenskaspel.se/Customer/Login?returnUrl=/MinaSpel";
 	private static final int BANKTYPE_ID = Bank.SVENSKASPEL;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
 	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;
 
     private Pattern reBalance = Pattern.compile("Balance\\\":\\\"([^<]+)\\\",", Pattern.CASE_INSENSITIVE);

commit e7fa552ef144d560d6f8088d34c5d60a172c2fa3
Author: liato <x@x00.us>
Date:   Tue Apr 2 22:21:17 2013 +0200

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index cadfbaf..bbced64 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.3-RC2" android:versionCode="153">
+	android:versionName="1.9.5.3" android:versionCode="154">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git CHANGES.txt CHANGES.txt
index 7ca928f..2773ba3 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,8 @@
+v1.9.5.3: (2013-04-02)
+* Fix for Skodakortet
+* Fix for Volvofinans transactions
+* Fix for reappearing Akelis spar/invest accounts
+
 v1.9.5.2: (2013-03-27)
 * Fix for Coop
 * Show multiple Nordnet accounts

commit e4a1cb0c02b54db2931e5fcb4aaaee319f3bbe5c
Author: Per Wigren <per.wigren@gmail.com>
Date:   Sat Mar 30 10:17:26 2013 +0100

    Remove debugging statements

diff --git src/com/liato/bankdroid/banking/banks/BrummerKF.java src/com/liato/bankdroid/banking/banks/BrummerKF.java
index c03eb03..3cecbe3 100644
--- src/com/liato/bankdroid/banking/banks/BrummerKF.java
+++ src/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -114,7 +114,7 @@ public class BrummerKF extends Bank {
 		try {
 			LoginPackage lp = preLogin();
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Log.e(TAG,response);
+
 			Matcher matcher = reError.matcher(response);
 			if (matcher.find()) {
 			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
@@ -148,7 +148,6 @@ public class BrummerKF extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://www.brummer.se/sv/online/privat/");
-		 Log.e(TAG,response);
 			matcher = reAccounts.matcher(response);
 			
 			while (matcher.find()) {
@@ -177,4 +176,4 @@ public class BrummerKF extends Bank {
 		}
 	}
 
-}
\ No newline at end of file
+}

commit c1e21a7727929c8133f53edc1a79c8674ec16a6d
Author: Per Wigren <per.wigren@gmail.com>
Date:   Sat Mar 30 10:10:42 2013 +0100

    Some cleanup

diff --git src/com/liato/bankdroid/banking/banks/TrustBuddy.java src/com/liato/bankdroid/banking/banks/TrustBuddy.java
index d6b6d04..82330e6 100644
--- src/com/liato/bankdroid/banking/banks/TrustBuddy.java
+++ src/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -1,5 +1,5 @@
 /* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>, first version by Snah@Swedroid 2012-01-06
- * Modified for Akelius Spar by Per Wigren <per.wigren@gmail.com>
+ * Modified for TrustBuddy by Per Wigren <per.wigren@gmail.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -49,10 +49,10 @@ public class TrustBuddy extends Bank {
 	private static final String NAME_SHORT = "trustbuddy";
 	private static final String URL = "https://www.trustbuddy.com/";
 	private static final int BANKTYPE_ID = IBankTypes.TRUSTBUDDY;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
-    private static final String INPUT_HINT_USERNAME = "Your email";
-    private static final boolean STATIC_BALANCE = true;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+	private static final String INPUT_HINT_USERNAME = "Your email";
+	private static final boolean STATIC_BALANCE = true;
 
 	private Pattern reError = Pattern.compile("<h3>error\\s*:\\s*</h3>\\s*<p>\\s*(.*?)\\s*</p>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reAccounts = Pattern.compile("<h1>\\s*([^<]+).*?>Balans: ([0-9, ]+) ([A-Z]{3})<",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);	
@@ -64,10 +64,10 @@ public class TrustBuddy extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.STATIC_BALANCE = STATIC_BALANCE;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
 	public TrustBuddy(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -150,38 +150,4 @@ public class TrustBuddy extends Bank {
 			throw new BankException(e.getMessage());
 		}
 	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-/*		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+account.getId());
-			matcher = reTransactions.matcher(response);
-			// 				ICA-banken	Akelius Invest
-			// Beskrivning	1			2
-			// Datum		2			1
-			// Belopp		3			3
-			//
-			
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-        finally {
-            super.updateComplete();
-        }
-       */
-	}		
-}
\ No newline at end of file
+}

commit 9c0cbf74aa4a0c676eaac28d3bec2c6270f84210
Author: Per Wigren <per.wigren@gmail.com>
Date:   Sat Mar 30 02:53:42 2013 +0100

    Accidentally removed AkeliusSpar

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 35baea4..fac8929 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -246,6 +246,7 @@ public class BankFactory {
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
 		banks.add(new AkeliusInvest(context));
+		banks.add(new AkeliusSpar(context));
 		banks.add(new TrustBuddy(context));
 		banks.add(new BrummerKF(context));
 		banks.add(new Swedbank(context));

commit 730651d1a2f54c4868187fabf58efe85f05193ef
Merge: d5c6238 0bd3fff
Author: Per Wigren <per.wigren@gmail.com>
Date:   Sat Mar 30 02:05:22 2013 +0100

    Merge remote-tracking branch 'upstream/master'
    
    Conflicts:
            src/com/liato/bankdroid/banking/BankFactory.java
            src/com/liato/bankdroid/provider/IBankTypes.java

commit d5c623879e605295f2d63a9bc084756ec486686c
Author: Per Wigren <per.wigren@gmail.com>
Date:   Sat Mar 30 01:54:15 2013 +0100

    Add support for TrustBuddy and Brummer Privat KF

diff --git res/drawable/logo_brummer_kf.png res/drawable/logo_brummer_kf.png
new file mode 100644
index 0000000..1384039
Binary files /dev/null and res/drawable/logo_brummer_kf.png differ
diff --git res/drawable/logo_trustbuddy.png res/drawable/logo_trustbuddy.png
new file mode 100644
index 0000000..9ef035c
Binary files /dev/null and res/drawable/logo_trustbuddy.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 56c07dc..d998e38 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -28,6 +28,7 @@ import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.Bioklubben;
+import com.liato.bankdroid.banking.banks.BrummerKF;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
@@ -75,6 +76,7 @@ import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
+import com.liato.bankdroid.banking.banks.TrustBuddy;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
 import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
@@ -222,6 +224,10 @@ public class BankFactory {
         	return new Chalmrest(context);
         case IBankTypes.MARGINALEN:
             return new Marginalen(context);
+        case IBankTypes.TRUSTBUDDY:
+        	return new TrustBuddy(context);
+        case IBankTypes.BRUMMER_KF:
+        	return new BrummerKF(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -231,7 +237,8 @@ public class BankFactory {
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
 		banks.add(new AkeliusInvest(context));
-		banks.add(new AkeliusSpar(context));
+		banks.add(new TrustBuddy(context));
+		banks.add(new BrummerKF(context));
 		banks.add(new Swedbank(context));
 		banks.add(new Nordea(context));
 		banks.add(new ICABanken(context));
diff --git src/com/liato/bankdroid/banking/banks/BrummerKF.java src/com/liato/bankdroid/banking/banks/BrummerKF.java
new file mode 100644
index 0000000..c03eb03
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/BrummerKF.java
@@ -0,0 +1,180 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>
+ * Brummer Privat Kapitalförsäkring & Pension support by Per Wigren <per.wigren@gmail.com>
+ * Probably does not work with depå/ISK or company accounts as they have separate login pages.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class BrummerKF extends Bank {
+	private static final String TAG = "BrummerKF";
+	private static final String NAME = "Brummer KF & Pension";
+	private static final String NAME_SHORT = "brummer_kf";
+	private static final String URL = "https://www.brummer.se/";
+	private static final int BANKTYPE_ID = IBankTypes.BRUMMER_KF;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "YYYYMMDDNNNN";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reError = Pattern.compile("<li>(Personnummer och l.*?senord matchar ej\\.)</li>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reViewstate = Pattern.compile("\"__VIEWSTATE\"\\s+value=\"(.*?)\"", Pattern.DOTALL);
+	private Pattern reEventValidation = Pattern.compile("\"__EVENTVALIDATION\"\\s+value=\"(.*?)\"", Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("<td.*?>\\s*<a.*?>\\s*(.*?)&nbsp;(.*?)\\s*</a>\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*(.*?)\\s*</td>\\s*<td.*?>\\s*<a.*?>\\s*Avtalsinformation\\s*</a>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	String response;
+	
+	public BrummerKF(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public BrummerKF(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true,true);
+        response = urlopen.open("https://www.brummer.se/sv/online/privat/Login/");
+        
+        Matcher mViewstate = reViewstate.matcher(response);
+        if (!mViewstate.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" Viewstate.");
+        }
+        String viewstate       = mViewstate.group(1);
+        
+        Matcher mEventValidation = reEventValidation.matcher(response);
+        if (!mEventValidation.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String eventvalidation       = mEventValidation.group(1);
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewstate));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventvalidation));
+        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtUsername", username));
+        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$txtPassword", password));
+        postData.add(new BasicNameValuePair("ctl00$cphMainRegion$btnLogin", "Logga in"));
+        postData.add(new BasicNameValuePair("ctl00$ctl08", "sv"));
+        postData.add(new BasicNameValuePair("ctl00$ucHeader$ctl01$loginView$ctl01$ddlQuickMenu", "-1"));
+        return new LoginPackage(urlopen, postData, response, "https://www.brummer.se/sv/online/privat/Login/");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Log.e(TAG,response);
+			Matcher matcher = reError.matcher(response);
+			if (matcher.find()) {
+			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+			    if (errormsg.contains("Personnummer")) {
+			        throw new LoginException(errormsg);    
+			    }
+			    else {
+	                 throw new BankException(errormsg);    
+			    }
+			}
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.brummer.se/sv/online/privat/");
+		 Log.e(TAG,response);
+			matcher = reAccounts.matcher(response);
+			
+			while (matcher.find()) {
+                /*
+                 * 1: Kontonamn
+                 * 2: Kontonummer
+                 * 3: Avkastning under året
+                 * 4: Genomsnittlig årlig avkastning sedan start
+                 * 5: Avkastning sedan start
+                 * 6: Marknadsvärde (kronor)
+                 */
+				
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(6).trim()), matcher.group(2)));
+	            
+				balance = balance.add(Helpers.parseBalance(matcher.group(6)));
+			}
+						if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/TrustBuddy.java src/com/liato/bankdroid/banking/banks/TrustBuddy.java
new file mode 100644
index 0000000..d6b6d04
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/TrustBuddy.java
@@ -0,0 +1,187 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>, first version by Snah@Swedroid 2012-01-06
+ * Modified for Akelius Spar by Per Wigren <per.wigren@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class TrustBuddy extends Bank {
+	private static final String TAG = "TrustBuddy";
+	private static final String NAME = "TrustBuddy";
+	private static final String NAME_SHORT = "trustbuddy";
+	private static final String URL = "https://www.trustbuddy.com/";
+	private static final int BANKTYPE_ID = IBankTypes.TRUSTBUDDY;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "Your email";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reError = Pattern.compile("<h3>error\\s*:\\s*</h3>\\s*<p>\\s*(.*?)\\s*</p>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("<h1>\\s*([^<]+).*?>Balans: ([0-9, ]+) ([A-Z]{3})<",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);	
+
+	public TrustBuddy(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public TrustBuddy(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true,true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("logon", "Logga in"));
+        return new LoginPackage(urlopen, postData, null, "https://trustbuddy.com/se/logga_in/");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reError.matcher(response);
+			if (matcher.find()) {
+			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+			    if (errormsg.contains("Felaktigt")) {
+			        throw new LoginException(errormsg);    
+			    }
+			    else {
+	                 throw new BankException(errormsg);    
+			    }
+			}
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://trustbuddy.com/se/din_sida/");
+			matcher = reAccounts.matcher(response);
+			
+			while (matcher.find()) {
+                /*
+                 * 1: Land
+                 * 2: Saldo
+                 * 3: Valuta
+                 */
+				Account temp = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2).trim()), matcher.group(1).toLowerCase());
+				temp.setCurrency(matcher.group(3));
+				accounts.add(temp);
+	            
+				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+			}
+						if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+/*		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+account.getId());
+			matcher = reTransactions.matcher(response);
+			// 				ICA-banken	Akelius Invest
+			// Beskrivning	1			2
+			// Datum		2			1
+			// Belopp		3			3
+			//
+			
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        finally {
+            super.updateComplete();
+        }
+       */
+	}		
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 61541c2..30c20cf 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -84,4 +84,6 @@ public interface IBankTypes {
     public static final int CHALMREST = 60;
     public static final int MARGINALEN = 61;
     public static final int AKELIUSSPAR = 62;
+    public static final int TRUSTBUDDY = 63;    
+    public static final int BRUMMER_KF = 64;
 }

commit 0bd3fff733d1e98bcfba523175c6bcd93a08a222
Author: liato <x@x00.us>
Date:   Fri Mar 29 15:57:01 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 05da981..cadfbaf 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.3-RC1" android:versionCode="152">
+	android:versionName="1.9.5.3-RC2" android:versionCode="153">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit fad40763666757e31dbb1bfc90f8823fe0a06a10
Author: liato <x@x00.us>
Date:   Fri Mar 29 15:55:36 2013 +0100

    Fix parsing for AbsIkanoPartner.

diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 5f8ab7a..7ea103a 100644
--- src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -156,7 +156,7 @@ public abstract class AbsIkanoPartner extends Bank {
                 // last account in the list.
                 this.balance = accounts.get(accounts.size() - 1).getBalance();
                 ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                es = d.select("#ShowCustomerTransactionPurchasesInformationDiv table tr:has('td')");
+                es = d.select("#ShowCustomerTransactionPurchasesInformationDiv table tr:has(td)");
                 for (Element el : es) {
                     if (el.childNodeSize() == 6) {
                         Transaction transaction = new Transaction(el.child(0).text().trim(), el.child(1).text().trim(),

commit ac9138cfc171e0e7c77e0f801c40a604480e26f4
Author: liato <x@x00.us>
Date:   Fri Mar 29 15:31:11 2013 +0100

    Fix for Volvofinans transactions.

diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index b653b2a..e01e466 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2013 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,9 +17,13 @@
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
-import java.net.URLEncoder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
@@ -29,6 +33,9 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONTokener;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
 
 import android.content.Context;
 import android.text.InputType;
@@ -53,6 +60,9 @@ public class Volvofinans extends Bank {
 	private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+    private static SimpleDateFormat DATE_PARSER = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
+    private static SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd", new Locale("sv_SE"));
+    private HashMap<String, String> mAccountUrlMappings = new HashMap<String, String>();
     
 	public Volvofinans(Context context) {
 		super(context);
@@ -123,7 +133,12 @@ public class Volvofinans extends Bank {
 				int length = data.length();
 				for (int index = 0; index < length; index++) {
 					JSONObject account = data.getJSONObject(index);
-					accounts.add(new Account(account.getString("kontonummer"), Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(Helpers.parseBalance(account.getString("limit"))), "1"));
+					Document d = Jsoup.parse(account.getString("namnUrl"));
+					Element e = d.getElementsByTag("a").first();
+					if (e != null && e.attr("href") != null) {
+    					mAccountUrlMappings.put(account.getString("kontonummer"), e.attr("href").replace("/info.html", "/info/kontoutdrag.html"));
+					}
+					accounts.add(new Account(String.format("%s (%s)", account.getString("namn"), account.getString("kontonummer")), Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(Helpers.parseBalance(account.getString("limit"))), account.getString("kontonummer")));
 				}
 			}
 			catch (JSONException e) {
@@ -148,34 +163,44 @@ public class Volvofinans extends Bank {
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
         String response = null;
-        try {
-            response = urlopen.open("https://www.volvokort.com/privat/kund/kortkonto/info/kontoutdrag.html?kontonummer="
-                    + URLEncoder.encode(account.getId()));
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            account.setTransactions(transactions);
-            JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
-            JSONArray data = object.getJSONArray("data");
-
-            int length = data.length();
-            for (int index = 0; index < length; index++) {
-                JSONObject acc = data.getJSONObject(index);
-                transactions.add(new Transaction(acc.getString("datum"), acc.getString("text"), Helpers
-                        .parseBalance(acc.getString("belopp"))));
+        String url = mAccountUrlMappings.get(account.getId());
+        if (url != null) {
+            try {
+                response = urlopen.open("https://www.volvokort.com" + url);
+                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                account.setTransactions(transactions);
+                JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
+                JSONArray data = object.getJSONArray("data");
+
+                int length = data.length();
+                for (int index = 0; index < length; index++) {
+                    JSONObject acc = data.getJSONObject(index);
+                    String date = acc.getString("datum");
+                    try {
+                        Date d = DATE_PARSER.parse(date);
+                        date = DATE_FORMATTER.format(d);
+                    } catch (ParseException e) {
+                        e.printStackTrace();
+                    }
+                    
+                    transactions.add(new Transaction(date, acc.getString("text"), Helpers
+                            .parseBalance(acc.getString("belopp")).negate()));
+                }
+                account.setTransactions(transactions);
+                if (accounts.isEmpty()) {
+                    throw new BankException(res.getText(R.string.no_accounts_found).toString());
+                }
+
+            } catch (ClientProtocolException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (JSONException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
             }
-            account.setTransactions(transactions);
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-
-        } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
         }
     }
 }

commit c8effbebe98c86f34339e98cf8e231fd7a54e0f6
Author: liato <x@x00.us>
Date:   Thu Mar 28 00:17:24 2013 +0100

    Better account matching for AkeliusSpar.

diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index e9da8d4..010a3dc 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -57,7 +57,7 @@ public class AkeliusSpar extends Bank {
 
 	private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+><a[^?]+\\?selectedaccount=([^\"]+)\">([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]*>([^<]+)</td>\\s*<td[^>]*><a[^?]+\\?selectedaccount=([^\"]+)\"[^>]*>([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);

commit da124a6b330f0c07023c870d08012218bdc353d6
Author: liato <x@x00.us>
Date:   Wed Mar 27 23:58:36 2013 +0100

    Npe fix for AbsIkanoPartner.

diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
index 40e872c..5f8ab7a 100644
--- src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
+++ src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -69,19 +69,19 @@ public abstract class AbsIkanoPartner extends Bank {
         response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
         Document d = Jsoup.parse(response);
         Element e = d.getElementById("__VIEWSTATE");
-        if (e == null || e.attr("value", null) == null) {
+        if (e == null || e.attr("value") == null) {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
         }
         String viewState = e.attr("value");
 
         e = d.getElementById("__EVENTVALIDATION");
-        if (e == null || e.attr("value", null) == null) {
+        if (e == null || e.attr("value") == null) {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
         }
         String eventValidation = e.attr("value");
 
         e = d.select("#LoginCustomerDiv > div").first();
-        if (e == null || e.attr("id", null) == null || e.attr("id").split("_", 2).length < 2) {
+        if (e == null || e.attr("id") == null || e.attr("id").split("_", 2).length < 2) {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl.");
         }
         String ctl = e.attr("id").split("_", 2)[0];
@@ -104,7 +104,8 @@ public abstract class AbsIkanoPartner extends Bank {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
-                    || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")) {
+                    || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")
+                    || response.contains("elaktig självbetjäningskod")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
 
@@ -126,7 +127,7 @@ public abstract class AbsIkanoPartner extends Bank {
         urlopen = login();
         Document d = Jsoup.parse(response);
         Element element = d.select("#primary-nav > li:eq(1) > a").first();
-        if (element != null && element.attr("href", null) != null) {
+        if (element != null && element.attr("href") != null) {
             String myAccountUrl = element.attr("href");
             try {
                 response = urlopen.open("https://partner.ikanobank.se/" + myAccountUrl);

commit 265769e4f1136ab70de904ca2b3567a0455aba35
Author: liato <x@x00.us>
Date:   Wed Mar 27 23:48:51 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index b4766b8..05da981 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.2" android:versionCode="151">
+	android:versionName="1.9.5.3-RC1" android:versionCode="152">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 5e61af941eee371af788a5cc44059479b7a4d4f8
Author: liato <x@x00.us>
Date:   Wed Mar 27 23:48:04 2013 +0100

    Possible fix for disappearing Akelius settings.

diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 1882336..8cce888 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -180,6 +180,8 @@ public class AkeliusInvest extends Bank {
 		}
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
+		} finally {
+		    super.updateComplete();
 		}
 	}
 
@@ -212,8 +214,5 @@ public class AkeliusInvest extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-        finally {
-            super.updateComplete();
-        }
 	}		
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index da6348f..e9da8d4 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -180,7 +180,9 @@ public class AkeliusSpar extends Bank {
 		}
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
-		}
+		} finally {
+            super.updateComplete();
+        }
 	}
 
 	@Override
@@ -212,8 +214,5 @@ public class AkeliusSpar extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-        finally {
-            super.updateComplete();
-        }
 	}		
 }
\ No newline at end of file

commit fbae59eb9ea4b55f6ed25a483f48a83dc51d96b1
Author: liato <x@x00.us>
Date:   Wed Mar 27 23:46:56 2013 +0100

    Untested fix for Volvofinans transactions.

diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 555cf53..b653b2a 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -17,6 +17,7 @@
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -31,12 +32,12 @@ import org.json.JSONTokener;
 
 import android.content.Context;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -142,4 +143,39 @@ public class Volvofinans extends Bank {
 	      super.updateComplete();
 		}
 	}
+	
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        String response = null;
+        try {
+            response = urlopen.open("https://www.volvokort.com/privat/kund/kortkonto/info/kontoutdrag.html?kontonummer="
+                    + URLEncoder.encode(account.getId()));
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            account.setTransactions(transactions);
+            JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
+            JSONArray data = object.getJSONArray("data");
+
+            int length = data.length();
+            for (int index = 0; index < length; index++) {
+                JSONObject acc = data.getJSONObject(index);
+                transactions.add(new Transaction(acc.getString("datum"), acc.getString("text"), Helpers
+                        .parseBalance(acc.getString("belopp"))));
+            }
+            account.setTransactions(transactions);
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (JSONException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 }

commit 643441b0a87acae2f0acc0da5972919a89f34768
Author: liato <x@x00.us>
Date:   Wed Mar 27 22:56:56 2013 +0100

    New untested IkanoPartner implementation.

diff --git CHANGES.txt CHANGES.txt
index edb5e71..7ca928f 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,7 @@
+v1.9.5.2: (2013-03-27)
+* Fix for Coop
+* Show multiple Nordnet accounts
+
 v1.9.5.1: (2013-02-26)
 * Fix for Länsförsäkringar saving accounts
 
diff --git src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
new file mode 100644
index 0000000..40e872c
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/AbsIkanoPartner.java
@@ -0,0 +1,183 @@
+/*
+ *  Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public abstract class AbsIkanoPartner extends Bank {
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+
+    private String response = null;
+    protected String structId;
+
+    public AbsIkanoPartner(Context context) {
+        super(context);
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public AbsIkanoPartner(String username, String password, Context context) throws BankException, LoginException,
+            BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+        Document d = Jsoup.parse(response);
+        Element e = d.getElementById("__VIEWSTATE");
+        if (e == null || e.attr("value", null) == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ViewState.");
+        }
+        String viewState = e.attr("value");
+
+        e = d.getElementById("__EVENTVALIDATION");
+        if (e == null || e.attr("value", null) == null) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " EventValidation.");
+        }
+        String eventValidation = e.attr("value");
+
+        e = d.select("#LoginCustomerDiv > div").first();
+        if (e == null || e.attr("id", null) == null || e.attr("id").split("_", 2).length < 2) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " ctl.");
+        }
+        String ctl = e.attr("id").split("_", 2)[0];
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair(ctl
+                + "$LoginWebUserControl$SSNControl$SSNSimpleValueUsercontrol$editValueTextbox", username));
+        postData.add(new BasicNameValuePair(ctl
+                + "$LoginWebUserControl$passwordSimpleValueControl$passwordSimpleValueControl$editValueTextbox",
+                password));
+        postData.add(new BasicNameValuePair(ctl + "$LoginButton", ""));
+        return new LoginPackage(urlopen, postData, response,
+                "https://partner.ikanobank.se/web/engines/page.aspx?structid=" + structId);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
+                    || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Document d = Jsoup.parse(response);
+        Element element = d.select("#primary-nav > li:eq(1) > a").first();
+        if (element != null && element.attr("href", null) != null) {
+            String myAccountUrl = element.attr("href");
+            try {
+                response = urlopen.open("https://partner.ikanobank.se/" + myAccountUrl);
+                d = Jsoup.parse(response);
+                Elements es = d.select("#CustomerAccountInformationSpan > span > span");
+                int accId = 0;
+                for (Element el : es) {
+                    Element name = el.select("> span > span:eq(0)").first();
+                    Element balance = el.select("> span:eq(1)").first();
+                    Element currency = el.select("> span:eq(2)").first();
+                    if (name != null && balance != null && currency != null) {
+                        Account account = new Account(name.text().trim(), Helpers.parseBalance(balance.text()),
+                                Integer.toString(accId));
+                        account.setCurrency(Helpers.parseCurrency(currency.text(), "SEK"));
+                        if (accId > 0) {
+                            account.setAliasfor("0");
+                        }
+                        accounts.add(account);
+                        accId++;
+                    }
+                }
+                if (accounts.isEmpty()) {
+                    throw new BankException(res.getText(R.string.no_accounts_found).toString());
+                }
+                // Use the amount from "Kvar att handla för" which should be the
+                // last account in the list.
+                this.balance = accounts.get(accounts.size() - 1).getBalance();
+                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                es = d.select("#ShowCustomerTransactionPurchasesInformationDiv table tr:has('td')");
+                for (Element el : es) {
+                    if (el.childNodeSize() == 6) {
+                        Transaction transaction = new Transaction(el.child(0).text().trim(), el.child(1).text().trim(),
+                                Helpers.parseBalance(el.child(2).text()));
+                        transaction.setCurrency(Helpers.parseCurrency(el.child(3).text().trim(), "SEK"));
+                        transactions.add(transaction);
+                    }
+                }
+                accounts.get(0).setTransactions(transactions);
+            }
+
+            catch (ClientProtocolException e) {
+                throw new BankException(e.getMessage());
+            } catch (IOException e) {
+                throw new BankException(e.getMessage());
+            } finally {
+                super.updateComplete();
+            }
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+
+    }
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/Skoda.java src/com/liato/bankdroid/banking/banks/Skoda.java
index 9689d42..4f65c4c 100644
--- src/com/liato/bankdroid/banking/banks/Skoda.java
+++ src/com/liato/bankdroid/banking/banks/Skoda.java
@@ -23,7 +23,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Skoda extends IkanoPartnerBase {
+public class Skoda extends AbsIkanoPartner {
 	private static final String TAG = "Skoda";
 	private static final String NAME = "Skodakortet";
 	private static final String NAME_SHORT = "skoda";

commit 376125a09096455555724c1818a8b8d8391fa439
Author: liato <x@x00.us>
Date:   Wed Mar 27 21:19:54 2013 +0100

    Bump version-

diff --git AndroidManifest.xml AndroidManifest.xml
index 0a30758..b4766b8 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.2-RC2" android:versionCode="150">
+	android:versionName="1.9.5.2" android:versionCode="151">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 84dd3017957299d87acea7b4f0c42aeee5035011
Author: liato <x@x00.us>
Date:   Mon Mar 25 23:03:15 2013 +0100

    Multiple accounts for Nordnet.

diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index df6f8c1..d935eee 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -120,7 +120,7 @@ public class Nordnet extends Bank {
 		try {
 			Matcher matcher;
 			matcher = reBalance.matcher(response);
-			if (matcher.find()) {
+			while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA

commit 1e704875a08aadfba3d245f76f5cd2fac3f22b6c
Author: liato <x@x00.us>
Date:   Mon Mar 25 22:29:52 2013 +0100

    Allow all characters as username for Handelsbanken.

diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 97c6b4f..5111ade 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -52,7 +52,7 @@ public class Handelsbanken extends Bank {
 	private static final String NAME_SHORT = "handelsbanken";
 	private static final String URL = "https://m.handelsbanken.se/";
 	private static final int BANKTYPE_ID = IBankTypes.HANDELSBANKEN;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
 	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"[^\"]*?/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK(?:&nbsp;|\\s*)?([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

commit 3052be4a3a4dc64a04ac005e237970e80422c5c7
Author: liato <x@x00.us>
Date:   Mon Mar 25 21:00:56 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 24ac6dd..0a30758 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,11 +2,12 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.2-RC1" android:versionCode="149">
+	android:versionName="1.9.5.2-RC2" android:versionCode="150">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
-	    android:hardwareAccelerated="true">
+	    android:hardwareAccelerated="true"
+        android:allowBackup="true">
 		<activity
 			android:name=".MainActivity"
 			android:label="@string/app_name"

commit fca06b0bf7d409706d9fc1a097e1bf42a9daeff4
Author: liato <x@x00.us>
Date:   Mon Mar 25 20:59:46 2013 +0100

    Improved fix for reappearing akelius accounts.

diff --git AndroidManifest.xml AndroidManifest.xml
index 4ad566f..24ac6dd 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5.1" android:versionCode="148">
+	android:versionName="1.9.5.2-RC1" android:versionCode="149">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git CHANGES.txt CHANGES.txt
index 9cb1299..edb5e71 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -3,6 +3,7 @@ v1.9.5.1: (2013-02-26)
 
 v1.9.5: (2013-02-21)
 * Fix for Länsförsäkringar
++ Support for Svenska Spel (thanks to nixi)
 + Support for Appeak Poker
 
 1.9.4: (2013-01-04)
diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 37ce217..1882336 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -17,6 +17,7 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -60,6 +61,7 @@ public class AkeliusInvest extends Bank {
 	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 	
 	public AkeliusInvest(Context context) {
 		super(context);
@@ -159,6 +161,7 @@ public class AkeliusInvest extends Bank {
 //						matcher.group(1).replaceFirst("(", "(\n");
 //					}
                
+                mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());           
 				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
                 Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
                 account.setAliasfor(matcher.group(1).trim());
@@ -183,11 +186,12 @@ public class AkeliusInvest extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+        String accountId = mIdMappings.get(account.getId());
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="+account.getId());
+			response = urlopen.open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="+accountId);
 			matcher = reTransactions.matcher(response);
 			/* 				ICA-banken	Akelius Invest
 			 * Beskrivning	1			2
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index 8591a02..da6348f 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -61,6 +62,7 @@ public class AkeliusSpar extends Bank {
 	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 	
 	public AkeliusSpar(Context context) {
 		super(context);
@@ -160,6 +162,7 @@ public class AkeliusSpar extends Bank {
 //						matcher.group(1).replaceFirst("(", "(\n");
 //					}
                
+                mIdMappings.put(Integer.toString(accId), matcher.group(2).trim());           
 				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
                 Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
                 account.setAliasfor(matcher.group(1).trim());
@@ -183,11 +186,12 @@ public class AkeliusSpar extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+        String accountId = mIdMappings.get(account.getId());
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+account.getId());
+			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+accountId);
 			matcher = reTransactions.matcher(response);
 			/* 				ICA-banken	Akelius Invest
 			 * Beskrivning	1			2

commit ffdaed6d47f383e1f5b4597b95dccbb14981990d
Author: liato <x@x00.us>
Date:   Thu Mar 21 08:05:44 2013 +0100

    Fix login for Coop.

diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index 9d42df0..376c7fa 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -75,7 +75,10 @@ public class Coop extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib();
-        response = urlopen.open("https://www.coop.se/Mina-sidor/Logga-in-puffsida/");
+        urlopen.addHeader("Origin", "https://www.coop.se");
+        urlopen.addHeader("Referer", "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
+        response = urlopen.open("https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
+        
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
@@ -90,10 +93,9 @@ public class Coop extends Bank {
         postData.add(new BasicNameValuePair("TextBoxUserName", username));
         postData.add(new BasicNameValuePair("TextBoxPassword", password));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("ButtonLogin", ""));
 //        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Logga-in-puffsida/");
+        return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Logga-in-puffsida/?li=True");
     }
 
 

commit 3ccf052d927b9f3c82fdedf00bf0239e8d8c6c69
Author: liato <x@x00.us>
Date:   Thu Mar 21 05:59:57 2013 +0100

    Use index as account id for AkeliusInvest and AkeliusSpar.

diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
index 0a33a3d..37ce217 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -141,8 +141,8 @@ public class AkeliusInvest extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://online.akeliusinvest.com/AccountPortfolio.mws");
-			
 			matcher = reAccounts.matcher(response);
+            int accId = 0;
 			while (matcher.find()) {
                 /*
                  * Capture groups:
@@ -159,13 +159,14 @@ public class AkeliusInvest extends Bank {
 //						matcher.group(1).replaceFirst("(", "(\n");
 //					}
                
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), matcher.group(2).trim()));
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + matcher.group(2).trim());
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
                 account.setAliasfor(matcher.group(1).trim());
                 
                 accounts.add(account);      
 	                
                 balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+                accId++;
 			}
 						if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
index d21ef0d..8591a02 100644
--- src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -142,8 +142,8 @@ public class AkeliusSpar extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
-			
 			matcher = reAccounts.matcher(response);
+			int accId = 0;
 			while (matcher.find()) {
                 /*
                  * Capture groups:
@@ -160,13 +160,13 @@ public class AkeliusSpar extends Bank {
 //						matcher.group(1).replaceFirst("(", "(\n");
 //					}
                
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), matcher.group(2).trim()));
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + matcher.group(2).trim());
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), Integer.toString(accId)));
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + accId);
                 account.setAliasfor(matcher.group(1).trim());
                 
                 accounts.add(account);      
-	                
                 balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+                accId++;
 			}
 						if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit bd5548f7ac1bd4b0deb1c96810937f55dfccf7c0
Author: liato <x@x00.us>
Date:   Sat Mar 16 20:27:54 2013 +0100

    Fix username hint for ICA Banken.

diff --git CHANGES.txt CHANGES.txt
index 09e54bb..9cb1299 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,6 @@
+v1.9.5.1: (2013-02-26)
+* Fix for Länsförsäkringar saving accounts
+
 v1.9.5: (2013-02-21)
 * Fix for Länsförsäkringar
 + Support for Appeak Poker
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index 428c51f..5aa4f47 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -52,7 +52,7 @@ public class ICABanken extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
     private static final boolean STATIC_BALANCE = false;
 
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");

commit 1f52896b47cb248128cfcecedd50e82799aba765
Author: liato <x@x00.us>
Date:   Tue Feb 26 01:11:26 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index a42b79c..4ad566f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.5" android:versionCode="147">
+	android:versionName="1.9.5.1" android:versionCode="148">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit e82d1c2db549a33f549477a65db3384e23a9397b
Author: liato <x@x00.us>
Date:   Thu Feb 21 23:44:06 2013 +0100

    Use "balance" for lansforsakringar saving accounts as well. Fixes #215.

diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 9b4770c..e21f934 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -209,13 +209,13 @@ public class Lansforsakringar extends Bank {
         	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()), a.getAccountNumber()));
         	//a.getLedger() should be saved to database, used when fetching transactions
         	mAccountLedger.put(a.getAccountNumber(), a.getLedger());
-        	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
+        	balance = balance.add(new BigDecimal(a.getBalance()));
         }
         ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)), AccountsResponse.class);
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
-        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
+        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()), a.getAccountNumber()));
             mAccountLedger.put(a.getAccountNumber(), a.getLedger());
-        	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
+        	balance = balance.add(new BigDecimal(a.getBalance()));
         }        
         if (accounts.isEmpty()) {
         	throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 636ba2a0957003b55d9dc73b532cb055acf53343
Author: liato <x@x00.us>
Date:   Thu Feb 21 00:10:02 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 43aa3ea..a42b79c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.4" android:versionCode="146">
+	android:versionName="1.9.5" android:versionCode="147">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git CHANGES.txt CHANGES.txt
index 781c393..09e54bb 100644
--- CHANGES.txt
+++ CHANGES.txt
@@ -1,3 +1,7 @@
+v1.9.5: (2013-02-21)
+* Fix for Länsförsäkringar
++ Support for Appeak Poker
+
 1.9.4: (2013-01-04)
 * Fix for ICA Banken transactions (thanks to fruktsallad)
 * Fix for Länsförsäkringar

commit 58d04154382640a5444ce750a137c8e72aab5ef1
Author: liato <x@x00.us>
Date:   Wed Feb 20 23:54:23 2013 +0100

    New structid for Skoda.

diff --git src/com/liato/bankdroid/banking/banks/Skoda.java src/com/liato/bankdroid/banking/banks/Skoda.java
index 0abb90d..9689d42 100644
--- src/com/liato/bankdroid/banking/banks/Skoda.java
+++ src/com/liato/bankdroid/banking/banks/Skoda.java
@@ -27,7 +27,7 @@ public class Skoda extends IkanoPartnerBase {
 	private static final String TAG = "Skoda";
 	private static final String NAME = "Skodakortet";
 	private static final String NAME_SHORT = "skoda";
-	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1541";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2461";
 	private static final int BANKTYPE_ID = Bank.SKODA;
 
     public Skoda(Context context) {
@@ -37,7 +37,7 @@ public class Skoda extends IkanoPartnerBase {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
-        this.structId = "1541";
+        this.structId = "2461";
     }
 
     public Skoda(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {

commit 277c1eed583106244c35f1c9e92a6d41f3c55f6c
Author: liato <x@x00.us>
Date:   Wed Feb 20 23:15:21 2013 +0100

    Possible fix for Coop.

diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index 2b583b4..9d42df0 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -75,7 +75,7 @@ public class Coop extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib();
-        response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
+        response = urlopen.open("https://www.coop.se/Mina-sidor/Logga-in-puffsida/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
@@ -87,14 +87,13 @@ public class Coop extends Bank {
 //        }
 //        String strEventValidation = matcher.group(1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
-        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
-        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$ButtonLogin", "Logga in"));
+        postData.add(new BasicNameValuePair("TextBoxUserName", username));
+        postData.add(new BasicNameValuePair("TextBoxPassword", password));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
 //        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Oversikt/");
+        return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Logga-in-puffsida/");
     }
 
 
@@ -103,16 +102,7 @@ public class Coop extends Bank {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("forfarande logga in med ditt personnummer")) {
-                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-                if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_coop_sendmail", false)) {
-                    Intent i = new Intent(android.content.Intent.ACTION_SEND);
-                    i.setType("plain/text");
-                    i.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"android@nullbyte.eu"});
-                    i.putExtra(android.content.Intent.EXTRA_SUBJECT, "Bankdroid - Coop Error");
-                    i.putExtra(android.content.Intent.EXTRA_TEXT, response);
-                    context.startActivity(i);
-                }
+            if (response.contains("felaktiga")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         }

commit 2dc74a842bbf71d15a18b18767b357b98530c2b9
Author: liato <x@x00.us>
Date:   Wed Feb 20 22:19:47 2013 +0100

    Add support for Appeak Poker.

diff --git .classpath .classpath
index e42619e..ae57319 100644
--- .classpath
+++ .classpath
@@ -9,5 +9,6 @@
 	<classpathentry kind="lib" path="libs/jackson-annotations-2.1.0.jar"/>
 	<classpathentry kind="lib" path="libs/jackson-core-2.1.0.jar"/>
 	<classpathentry kind="lib" path="libs/jackson-databind-2.1.0.jar"/>
+	<classpathentry kind="lib" path="libs/jsoup-1.7.2.jar"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git libs/jsoup-1.7.2.jar libs/jsoup-1.7.2.jar
new file mode 100644
index 0000000..8eeb5c7
Binary files /dev/null and libs/jsoup-1.7.2.jar differ
diff --git res/drawable/logo_appeakpoker.png res/drawable/logo_appeakpoker.png
new file mode 100644
index 0000000..e5a7e90
Binary files /dev/null and res/drawable/logo_appeakpoker.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 6b2c72c..b75a98d 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -14,6 +14,7 @@
     <string name="menu_edit">Redigera</string>
     <string name="menu_remove">Radera</string>
     <string name="invalid_username_password">Användarnamn och lösenord stämmer ej.</string>
+    <string name="invalid_username">Ogiltigt användarnamn.</string>
     <string name="invalid_card_number">Ogiltigt kortnummer.</string>
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="no_accounts_found">Inga konton funna</string>
diff --git res/values/strings.xml res/values/strings.xml
index 157520a..5906b0b 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -13,6 +13,7 @@
     <string name="menu_edit">Edit</string>
     <string name="menu_remove">Remove</string>
     <string name="invalid_username_password">Invalid username or password.</string>
+    <string name="invalid_username">Invalid username.</string>
     <string name="invalid_card_number">Invalid card number.</string>
     <string name="unable_to_find">Unable to find</string>
     <string name="no_accounts_found">No accounts found</string>
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 01d6f78..4bba9cb 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -47,6 +47,7 @@ import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.AppeakPoker;
 import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.NordeaDK;
@@ -228,6 +229,8 @@ public class BankFactory {
             return new SvenskaSpel(context);
         case IBankTypes.EASYCARD:
             return new EasyCard(context);
+        case IBankTypes.APPEAKPOKER:
+            return new AppeakPoker(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -300,6 +303,7 @@ public class BankFactory {
         banks.add(new Marginalen(context));
         banks.add(new SvenskaSpel(context));
         banks.add(new EasyCard(context));
+        banks.add(new AppeakPoker(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/AppeakPoker.java src/com/liato/bankdroid/banking/banks/AppeakPoker.java
new file mode 100644
index 0000000..9618350
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/AppeakPoker.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: PMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AppeakPoker extends Bank {
+
+	private static final String TAG = "AppeakPoker";
+	private static final String NAME = "Appeak Poker";
+	private static final String NAME_SHORT = "appeakpoker";
+	private static final String URL = "http://poker.appeak.se/";
+	private static final int BANKTYPE_ID = Bank.APPEAKPOKER;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+	private static final boolean INPUT_HIDDEN_PASSWORD = true;
+	private String mChips = null;
+
+	public AppeakPoker(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME= INPUT_TYPE_USERNAME;
+		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
+        super.DISPLAY_DECIMALS = false;
+        currency = "chips";
+	}
+
+	public AppeakPoker(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+		urlopen = new Urllib();
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		return new LoginPackage(urlopen, postData, "", String.format("http://poker.appeak.se/playerInfo/?username=%s", username));
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            String response = urlopen.open(lp.getLoginTarget());
+            Document d = Jsoup.parse(response);
+            Element e = d.select("#content > table tr:eq(2) td:eq(1)").first();
+            if (e == null) {
+                throw new LoginException(res.getText(R.string.invalid_username).toString());
+            } else {
+            	mChips = e.html();
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;		
+	}
+
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null) {
+			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+		}
+		login();
+		if (mChips != null) {
+			Account account = new Account("Chips", Helpers.parseBalance(mChips.replaceAll("\\D", "")), "1");
+			account.setCurrency("chips");
+            balance = account.getBalance();
+            accounts.add(account);
+		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 7130007..c5400d6 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -86,4 +86,5 @@ public interface IBankTypes {
     public static final int AKELIUSSPAR = 62;
     public static final int SVENSKASPEL = 63;
     public static final int EASYCARD = 64;
+    public static final int APPEAKPOKER = 65;
 }

commit 799913b3cbcaa6fea2662d31f2b08bb9b04036c9
Author: liato <x@x00.us>
Date:   Wed Feb 20 21:41:11 2013 +0100

    Use "balance" for Lansforsakringar accounts as "disposableAmount" is no longer available.

diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index ea4012f..82ae807 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -28,9 +28,16 @@ import java.util.List;
 import org.apache.http.NameValuePair;
 
 import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.os.Build;
+import android.util.DisplayMetrics;
 import android.util.Log;
 
 public class Helpers {
+	private static String USER_AGENT;
     private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD",
         "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
         "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
@@ -222,5 +229,47 @@ public class Helpers {
     public static String formatDate(Date date) {
     	return DATE_FORMAT.format(date);
     }
+    
+    public static String getAppUserAgentString(Context context) {
+    	if (USER_AGENT != null) return USER_AGENT;
+        String appName = context.getResources().getString(R.string.app_name);
+        String appVersion = "";
+        int height = 0;
+        int width = 0;
+        DisplayMetrics display = context.getResources().getDisplayMetrics();
+        Configuration config = context.getResources().getConfiguration();
+ 
+        // Always send screen dimension for portrait mode
+        if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            height = display.widthPixels;
+            width = display.heightPixels;
+        } else {
+            width = display.widthPixels;
+            height = display.heightPixels;
+        }
+ 
+        try {
+            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_CONFIGURATIONS);
+            appVersion = packageInfo.versionName;
+        } catch (PackageManager.NameNotFoundException ignore) {
+            // this should never happen, we are looking up ourself
+        }
+ 
+        // Tries to conform to default android UA string without the Safari / webkit noise, plus adds the screen dimensions
+        USER_AGENT = String.format("%1$s/%2$s (%3$s; U; Android %4$s; %5$s-%6$s; %12$s Build/%7$s; %8$s) %9$dX%10$d %11$s %12$s"
+            , appName
+            , appVersion
+            , System.getProperty("os.name", "Linux")
+            , Build.VERSION.RELEASE
+            , config.locale.getLanguage().toLowerCase()
+            , config.locale.getCountry().toLowerCase()
+            , Build.ID
+            , Build.BRAND
+            , width
+            , height
+            , Build.MANUFACTURER
+            , Build.MODEL);
+        return USER_AGENT;
+    }    
 
 }
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 9e11f56..cdddcae 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -420,5 +420,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public boolean getDisplayDecimals() {
         return DISPLAY_DECIMALS;
     }
+    
+    protected Context getContext() {
+    	return context;
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index a908481..9b4770c 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -134,7 +134,7 @@ public class Lansforsakringar extends Bank {
         urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
         urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
         //TODO: Change user-agent to "lf-android-app" if they block Bankdroid
-        urlopen.setUserAgent("bankdroid");
+        urlopen.setUserAgent(Helpers.getAppUserAgentString(getContext()));
 
         NumberResponse nr = readJsonValue(API_BASEURL + "security/client", null, NumberResponse.class);
         ChallengeResponse cr = readJsonValue(API_BASEURL + "security/client", objectAsJson(new ChallengeRequest(nr.getNumber(), nr.getNumberPair(), generateChallenge(nr.getNumber()))), ChallengeResponse.class);
@@ -206,7 +206,7 @@ public class Lansforsakringar extends Bank {
         mAccountLedger.clear();
         AccountsResponse ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)), AccountsResponse.class);
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
-        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
+        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getBalance()), a.getAccountNumber()));
         	//a.getLedger() should be saved to database, used when fetching transactions
         	mAccountLedger.put(a.getAccountNumber(), a.getLedger());
         	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 2bdc28e..59ee4c2 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -50,9 +50,6 @@ import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.util.EntityUtils;
-
-import android.util.Log;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
@@ -238,8 +235,8 @@ public class Urllib {
     	return acceptInvalidCertificates;
     }
     
-    public void setUserAgent(String userAgent)
-    {
+    public void setUserAgent(String userAgent) {
     	this.userAgent = userAgent; 
     }
+    
 }
\ No newline at end of file

commit 268cb4fae7baca018148e39fd0c67eb5a542c7ba
Author: liato <x@x00.us>
Date:   Sun Jan 27 22:17:38 2013 +0100

    Old psd.

diff --git btn_check.psd btn_check.psd
new file mode 100644
index 0000000..6a0237f
Binary files /dev/null and btn_check.psd differ

commit f0576f24f00c4d048252b20393d7cb1abec73332
Author: liato <x@x00.us>
Date:   Sun Jan 27 22:17:20 2013 +0100

    Changelog.

diff --git CHANGES.txt CHANGES.txt
new file mode 100644
index 0000000..781c393
--- /dev/null
+++ CHANGES.txt
@@ -0,0 +1,356 @@
+1.9.4: (2013-01-04)
+* Fix for ICA Banken transactions (thanks to fruktsallad)
+* Fix for Länsförsäkringar
+* Fix for Skandiabanken accounts without transactions
+* Fix for Amex transactions (thanks to goober)
+* Fixes for Marginalen Bank (thanks to jsiverskog)
+
+
+1.9.3: (2012-11-29)
++ Support for Marginalen Bank (thanks to jsiverskog)
+* Fix for password saving in Android 4.2+ (thanks to gfu)
+* Fix for ICA (thanks to oskla129)
+* Fix reappearing accounts on ICA Banken
+
+
+1.9.2: (2012-10-21)
+* Fix for Länsförsäkringar - Now uses the same API as their official app
+
+
+1.9.1: (2012-10-11)
++ Support for Chalmrest (thanks to emilan)
+* Fix for Västtrafik (thanks to erifre)
+* Fix for Nordea captcha - login as many times as you want with the built in captcha breaker
+* Fix for Bioklubben
+* Fix for PayPal
+* Better auto updates with SEB
+* Fix for EverydayCard (thanks  to d95andek)
+* Fix for Volvofinans (thanks to d95andek)
+- Removed support for Steam Wallet
+
+
+1.9.0: (2012-06-25)
++ Support for Ticket Rikskortet
++ Support for Bioklubben
+* Fix for Meniga (thanks to bjooork)
+* Fix for Nordea DK (thanks to goober)
+* Fix for Västtrafik (thanks to erifre)
+* Fix for Statoil Mastercard
+* Fix for SAS Eurobonus Mastercard
+* Fix for Eurocard
+
+
+1.8.9: (2012-04-16)
++ New setting: Number of simultaneous notifications
+* Fix for graphical bug on devices running older versions of Android (sorry for the poor testing before release)
+
+
+1.8.8: (2012-04-13)
++ Support for Meniga (thanks to bjooork)
++ New notification setting: Display change only
++ Disable thumbnail in recent apps list (Honeycomb, ICS)
+* Fix for Skandiabanken, now using their internal JSON-api (thanks to woody)
+* Fix for Jojo (thanks to wanders)
+* Fix for Rikslunchen (thanks to mafa73)
+* Fix for IKEA
+
+
+1.8.7: (2012-01-29)
+* Fix for SEB
+* Fix for double lock pattern when opening transactions view from widget
+
+
+1.8.6: (2012-01-29)
+* Fix for SEB 
+* Fix for LED color picker on pre ICS devices
+
+
+1.8.5: (2012-01-27)
++ Support for LED notifications
++ Support for Akelius Invest
+* Fix for Coop
+* Fix for Hemköp
+* Fix for SEB
+* Fix for SevenDay
+* Fix for ICA
+
+
+1.8.4: (2011-12-04)
+* Fix for Coop
+* Fix for Länsförsäkringar (thanks to MatsKarlsson!)
++ Support for Everydaycard (thanks to d95andek!)
++ Hardware acceleration is now activated for Honeycomb and ICS
+* Smarter automatic updates
+
+
+1.8.3: (2011-11-13)
++ Support for American Express
++ Support for Västtrafik
+* Fix for SEB
+
+
+1.8.1: (2011-09-26)
++ Support for Danske Bank
++ Support for Nordea (Danmark) (thanks to goober!)
+* Fix for Skandiabanken (thanks to woody!)
+
+
+1.8.0: (2011-08-24)
++ Support for AudiKortet
++ Support for Chevrolet Big Plus Card
++ Support for Djurgårdskortet
++ Support for IKEA HANDLA Kort
++ Support for Nordnetdirekt
++ Support for PlusGirot
++ Support for Preem Privatkort
++ Support for Quintessentially Credit Card
++ Support for SaabKortet
++ Support for Seatkortet
++ Support for Shell MasterCard
++ Support for Skandiabanken (thanks to woody)
++ Support for Skodakortet
++ Support for Volkswagenkortet
++ Support for wallet MasterCard
+* Fix for ICA
++ Support for Sony Ericcson LiveView notifications (thanks to firetech)
++ New setting: Only update between user defined times (thanks to woody)
+* Fix for security bug where a user could circumvent the password protection
+* Calculate the total amount correctly
++ Donate button added
+
+
+1.7.3 (2011-05-04)
+* Fix for Jojo
++ Support for OpelKortet
++ Support for SJ Prio MasterCard
++ Support for Sparbanken Syd
++ Support for Sparbanken Öresund
++ Show old CSN loans
++ Multi-bank support for Swedbank
++ New setting: Display balance without decimals
++ New setting: Smallest change to trigger notification
+
+
+1.7.2: (2011-04-14)
+* Fix for Swedbank transactions (update account from app to see transactions)
+* Fix for Länsförsäkringar
++ New setting: Update transaction history from widget
+
+
+1.7.1: (2011-04-12)
+* Fix for Swedbank
+* For for Payson when using multiple currencies
+* Support for multiple currencies in DinersClub
+* Improved error handling for CSN
++ Progress bar in webview
++ Bank icons when choosing a bank
++ Setting: Disable visible pattern on pattern lock
+
+
+1.7.0: (2011-03-25)
++ Support for SevenDay
++ Support for Nordnet
++ Support for Osuuspankki/Andelsbanken
++ Support for Volvofinans
++ Support for Resurs Bank
++ Support for Länsförsäkringar Pension
++ Support for McDonald's Presentkort
++ New setting: Open main view or transactions view from widget
++ Loans information for Swedbank
++ Support for additional currencies for Nordea
+* Repayments to CSN are shown as transactions
+* Fixed FC-bug in Länsförsäkringar if user had pension account
+* Sort and display all transactions for SEB
+* New logo for Ikano Bank (after complaints from Ikano that the old one did not follow their graphic guidelines)
+* Fix for FirstCard
+* Sorted transactions for Statoil and Eurobonus
+* Show all transactions for Eurocard
+* "Home" button clears history stack
+
+
+1.6.3: (2011-02-06)
+* FC fix when opening settings
+
+
+1.6.2: (2011-02-05)
++ Support for SEB (automatic website login doesn't work yet)
++ Support for SAS EuroBonus Mastercard
++ Support for Rikslunchen
++ Support for Hemköp Kundkort
++ Transactions for Diners Club
+* PayPal business accounts are now supported
++ Content Provider - Lets other apps use data from Bankdroid after user confirmation
+
+
+1.6.1: (2010-12-29)
+* Fix for FC when using pattern lock in landscape mode
+* Larger hit box on "Home" button
+
+
+1.6.0: (2010-12-29)
++ Login to any of your banks website automatically by clicking the WWW-button.
+* Design changes
+* Eurocard widgetbug fixed
+* Fix for Ikano Bank
+
+
+1.5.3: (2010-12-21)
++ Support for Ikano Bank
++ MedMera Faktura for Coop 
+* Multiple accounts for Eurocard
+
+
+1.5.2: (2010-12-18)
++ Support for Diners Club
++ Transactions for Länsförsäkringar 
+
+
+1.5.1: (2010-12-15)
++ Funds and loans for Länsförsäkringar
+* MedMera Visa for Coop fixed
+* Fix for Handelsbanken
+* Password field show numeric keyboard if appropriate
+
+
+1.5.0: (2010-12-12)
++ Support for Jojo Reskassa
++ Support for Steam Wallet
++ Support for Avanza (again...)
++ New setting: Round balance on widgets
++ Clicking a widget shows transactions for that account.
+* Additional account information for OKQ8 and Statoil
+* Fix for ICA Banken
+* Fix for Coop
+
+
+1.4.4: (2010-11-26)
++ Support for Payson
+* Länsförsäkringar fixad
+* Coop login problems fixed/improved
++ New settings: Blur account balance on widgets
+
+
+1.4.3: (2010-11-19)
+- Support for Avanza removed
+* PayPal is working again
+* Show all transactions for Statoil
+* Fix for EuroCard
+* Fix for First Card
+* Hidden accounts are not counted towards the total sum
+* Replaced password lock with pattern lock
++ Support for Remote Notifier plugin
++ Support for OpenWatch plugin
++ Custom notification sound
++ New setting: Don't update transactions on automatic updates
+
+
+1.4.2: (2010-11-03)
+* Fixed username field for Avanza
+
+
+1.4.1: (2010-11-03)
+* Fix for Nordea
+
+
+1.4.0: (2010-11-02)
++ Support for OKQ8 (thanks to cola)
++ Support for PayPal
++ Support for Eurocard with transactions
++ Support for First Card with transactions
+* Avanza was split into Avanza and AvanzaMini
++ Nordea credit cards (Visa Gold and others)
++ Transactions for Coop MedMera Visa 
+* Statoil Mastercard fixed
+* Transactions for Handelsbanken fixed
+* A bit faster updates by skipping an unnecessary login when fetching transactions (thanks to DEGE)
+* Notifications show changes for accounts, not banks.
++ Encryption for passwords
++ Option to hide accounts
++ Option to disable notifications for accounts
++ New setting: Choose which notifications to display (funds, loands, credit cards)
+* Every bank has a pre defined keyboard layout (numeric for Nordea, email for PayPal)
+* Loans are not counted towards the total bank sum
+
+
+1.3.1: (2010-09-20)
+* Fix for Swedbank
+* Fix for Avanza
++ Support for Avanza mini
++ Support for Villabanken
+
+
+1.3.0: (2010-09-19)
+* Widgets with Handelsbanken accounts are working again
+* Transactions for ICA Banken
+* Coop now also works with "MedMera-kortet"
+* Transactions for Coop MedMera
+* Transactions for Handelsbanken
+* Hit box for updating from widgets is larger
+* Support for loans in Swedbank
+* Support for funds and loans in Nordea
+* Widget with transparent background
++ Support for ICA Kortet with transactions
++ Support for Statoil MasterCard with transactions
++ Support for Avanza
+
+
+1.2.1: (2010-07-13)
+* Added missing ICA Banken logo
+* Fix amount formatting
+
+
+1.2.0: (2010-07-12)
+* Fixed Nordea bug (login failed when user had an "e-faktura" waiting)
+* New design
+* Confirm password field
++ Link to the banks website
++ Support for Handelsbanken
++ Support for Coop
++ Transaction history for Nordea
++ Transaction history for Swedbank
+* Improved login error detection
++ Support for QVGA devices
+
+
+1.1.4: (2010-06-03)
+* Fix for Nordea
+
+
+1.1.3: (2010-06-02)
++ New widget size, 2x1
+* Widgets are updated on boot
+
+
+1.1.2: (2010-05-31)
+* Working fix for ICA Banken
+
+
+1.1.1: (2010-05-31)
+* Fix for FC bug with widgets
+* Fix for ICA Banken
+
+
+1.1.0: (2010-05-31)
++ Widgets
++ Automatic updates
++ Notifications on account changes
++ Support for Länsförsäkringar
++ Improved application lock
+
+
+1.0.3: (2010-05-16)
++ Option to password protect the application
+
+
+1.0.2: (2010-05-12)
+* Fix for Swedbank
+
+
+1.0.1: (2010-05-10)
++ Support for ICA Banken
+
+
+1.0.0: (2010-05-05)
++ First public release
++ Support for Nordea
++ Support for Swedbank

commit b6f9454777f81b1a5fa03f1ecdd9fe1375b8d53d
Merge: 3f85404 2cb2d1f
Author: liato <x@x00.us>
Date:   Thu Jan 24 20:45:26 2013 -0800

    Merge pull request #211 from timtux/master
    
    New card: EasyCard, Bugfix: (Handelsbanken|Skandiabanken) - Sort transactions

commit 2cb2d1f9279b7576aa5c03ce7e3293e4505853e9
Author: Tim Janssson <tim@timtux.net>
Date:   Thu Jan 24 23:15:17 2013 +0100

    account_number bug fix
    
    account_number bug fix… used saldo instead of account number.

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 3413338..34de1b2 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -124,14 +124,19 @@ public class EasyCard extends Bank {
 
         if (matcher.find()) {
             // Our data!
-            String account_number           = matcher.group(2).toString().trim(); // 123123123
+            String account_number           = matcher.group(1).toString().trim(); // 123123123
+            
+            if(!account_number.equalsIgnoreCase(this.username)) {
+                throw new BankException(res.getText(R.string.unable_to_login).toString());
+            }
+            
             BigDecimal credit_left_amount   = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3 748,87
             BigDecimal credit_amount        = Helpers.parseBalance(matcher.group(4).toString().trim()); // 30 000,00
             BigDecimal credit_spent_amount  = credit_amount.subtract(credit_left_amount).negate(); // 26 251,13
             
             // Construct accounts
-            Account credit_spent = new Account("Saldo", credit_spent_amount, account_number + ":saldo", Account.CCARD);
-            Account credit_left  = new Account("Kredit", credit_left_amount, account_number + ":kredit", Account.OTHER);
+            Account credit_spent = new Account("Saldo", credit_spent_amount, this.username + ":saldo", Account.CCARD);
+            Account credit_left  = new Account("Kredit", credit_left_amount, this.username + ":kredit", Account.OTHER);
             
             accounts.add(credit_spent);
             accounts.add(credit_left);

commit 86db1cd74436ecb1eaa9f1ee591cfd74ccbbf126
Author: Tim Janssson <tim@timtux.net>
Date:   Wed Jan 23 21:54:31 2013 +0100

    Transactions in updateTransactions. Cooler.

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 122feb5..3413338 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -110,6 +110,7 @@ public class EasyCard extends Bank {
 
     @Override
     public void update() throws BankException, LoginException, BankChoiceException {
+    
         super.update();
 
         if (username == null || password == null || username.length() != 9 || password.length() == 0) {
@@ -141,24 +142,33 @@ public class EasyCard extends Bank {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
 
+        super.updateComplete();
+    }
+    
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException 
+    {
+        super.updateTransactions(account, urlopen);
+        
         // Find transactions
-        Matcher tMatcher = reTransactions.matcher(response);
-
+        Matcher matcher                     = reTransactions.matcher(response);
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
      
-        while (tMatcher.find()) {
-            String date         = tMatcher.group(1).toString().trim(); // 2013-01-15
-            String transaction  = tMatcher.group(2).toString().trim(); // EBG HOSPITALITY
-            BigDecimal amount   = Helpers.parseBalance(tMatcher.group(3).toString()); // 214,00
+        while (matcher.find()) {
+            String date         = matcher.group(1).toString().trim(); // 2013-01-15
+            String transaction  = matcher.group(2).toString().trim(); // EBG HOSPITALITY
+            BigDecimal amount   = Helpers.parseBalance(matcher.group(3).toString()); // 214,00
 
             transactions.add(new Transaction(date, transaction, amount.negate()));
         }
-
-        // Add transactions to account.
-        for (Account account : accounts) {
-            account.setTransactions(transactions);
-        }
-
-        super.updateComplete();
+        
+        account.setTransactions(transactions);
+    }
+    
+    @Override
+    public void closeConnection() {
+        super.closeConnection();
+        response = null;
     }
-}
\ No newline at end of file
+}
+    
\ No newline at end of file

commit 2b129e245a0ae48420d5f095a15b76063d88679c
Author: Tim Janssson <tim@timtux.net>
Date:   Wed Jan 23 13:07:45 2013 +0100

    No need to have another else if
    
    Just throw the god damn exception.

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index af545c7..122feb5 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -96,9 +96,7 @@ public class EasyCard extends Bank {
             // The string "Valuta" is always present on successful login.
             if(response.contains("Inloggningen misslyckades")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            } else if (response.contains("sedan du")) {
-                throw new BankException(res.getText(R.string.bank_closed).toString());
-            } else if(!response.contains("Valuta")) {
+            } else if (response.contains("sedan du") || !response.contains("Valuta")) {
                 throw new BankException(res.getText(R.string.unable_to_login).toString());
             }
         } catch (ClientProtocolException e) {

commit d8512b809415b40d5c9d2edc8e6d6913a24454f1
Author: Tim Janssson <tim@timtux.net>
Date:   Wed Jan 23 13:03:10 2013 +0100

    Fix exception message.

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 816a360..af545c7 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -99,7 +99,7 @@ public class EasyCard extends Bank {
             } else if (response.contains("sedan du")) {
                 throw new BankException(res.getText(R.string.bank_closed).toString());
             } else if(!response.contains("Valuta")) {
-                throw new BankException("General error");
+                throw new BankException(res.getText(R.string.unable_to_login).toString());
             }
         } catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());

commit bd15cde47a8ecfa91f86b4138805aabd80bc4cc6
Author: Tim Janssson <tim@timtux.net>
Date:   Wed Jan 23 13:00:06 2013 +0100

    LoginException just throwed on actual LoginException
    
    LoginException disables the bank when thrown. Since the EasyCard
    "kundportal" is failing pretty on timeouts, general web server errors
    and stuff we should just throw it when the page tells us that the un/pw
    was incorrect.

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 27ffcd6..816a360 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -88,16 +88,19 @@ public class EasyCard extends Bank {
 
     @Override
     public Urllib login() throws LoginException, BankException {
-
+        
         try {
             LoginPackage lp = preLogin();
-            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            response        = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
             // The string "Valuta" is always present on successful login.
-            if (!response.contains("Valuta")) {
+            if(response.contains("Inloggningen misslyckades")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            } else if (response.contains("sedan du")) {
+                throw new BankException(res.getText(R.string.bank_closed).toString());
+            } else if(!response.contains("Valuta")) {
+                throw new BankException("General error");
             }
-
         } catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
         } catch (IOException e) {

commit 7b0d8061c32354b10313f33540aa2ac477214c48
Author: Tim Janssson <tim@timtux.net>
Date:   Tue Jan 22 21:28:47 2013 +0100

    Handelsbanken - Sort transactions
    
    - Indentations fixes
    - Handelsbanken - Sort transactions

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index b10171f..27ffcd6 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -27,34 +27,34 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class EasyCard extends Bank {
-    private static final String TAG = "EasyCard";
-    private static final String NAME = "EasyCard";
-    private static final String NAME_SHORT = "easycard";
-    private static final String URL = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
-    private static final int BANKTYPE_ID = IBankTypes.EASYCARD;
+    private static final String TAG         = "EasyCard";
+    private static final String NAME        = "EasyCard";
+    private static final String NAME_SHORT  = "easycard";
+    private static final String URL         = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
+    private static final int BANKTYPE_ID    = IBankTypes.EASYCARD;
 
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+    private static final int INPUT_TYPE_USERNAME    = InputType.TYPE_CLASS_NUMBER;
     private static final String INPUT_HINT_USERNAME = "XXXXXXXXX";
 
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_NUMBER;
 
-    private Pattern reAccounts = Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactions = Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
-    private Pattern rePostData = Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts      = Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactions  = Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
+    private Pattern rePostData      = Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
 
     private String response = null;
 
     public EasyCard(Context context) {
         super(context);
 
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.TAG                   = TAG;
+        super.NAME                  = NAME;
+        super.NAME_SHORT            = NAME_SHORT;
+        super.BANKTYPE_ID           = BANKTYPE_ID;
+        super.URL                   = URL;
+        super.INPUT_TYPE_USERNAME   = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME   = INPUT_HINT_USERNAME;
+        super.INPUT_TYPE_PASSWORD   = INPUT_TYPE_PASSWORD;
     }
 
     public EasyCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -65,9 +65,9 @@ public class EasyCard extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
 
-        urlopen = new Urllib(true);
-        response = urlopen.open(EasyCard.URL);
-        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        urlopen                         = new Urllib(true);
+        response                        = urlopen.open(EasyCard.URL);
+        List<NameValuePair> postData    = new ArrayList<NameValuePair>();
 
         // Find hidden required fields.
         Matcher matcher = rePostData.matcher(response);
@@ -122,10 +122,10 @@ public class EasyCard extends Bank {
 
         if (matcher.find()) {
             // Our data!
-            String account_number = matcher.group(2).toString().trim(); // 123123123
-            BigDecimal credit_left_amount = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3 748,87
-            BigDecimal credit_amount = Helpers.parseBalance(matcher.group(4).toString().trim()); // 30 000,00
-            BigDecimal credit_spent_amount = credit_amount.subtract(credit_left_amount).negate(); // 26 251,13
+            String account_number           = matcher.group(2).toString().trim(); // 123123123
+            BigDecimal credit_left_amount   = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3 748,87
+            BigDecimal credit_amount        = Helpers.parseBalance(matcher.group(4).toString().trim()); // 30 000,00
+            BigDecimal credit_spent_amount  = credit_amount.subtract(credit_left_amount).negate(); // 26 251,13
             
             // Construct accounts
             Account credit_spent = new Account("Saldo", credit_spent_amount, account_number + ":saldo", Account.CCARD);
@@ -146,9 +146,9 @@ public class EasyCard extends Bank {
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
      
         while (tMatcher.find()) {
-            String date = tMatcher.group(1).toString().trim(); // 2013-01-15
-            String transaction = tMatcher.group(2).toString().trim(); // EBG HOSPITALITY
-            BigDecimal amount = Helpers.parseBalance(tMatcher.group(3).toString()); // 214,00
+            String date         = tMatcher.group(1).toString().trim(); // 2013-01-15
+            String transaction  = tMatcher.group(2).toString().trim(); // EBG HOSPITALITY
+            BigDecimal amount   = Helpers.parseBalance(tMatcher.group(3).toString()); // 214,00
 
             transactions.add(new Transaction(date, transaction, amount.negate()));
         }
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 43641c2..97c6b4f 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -19,6 +19,8 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -167,6 +169,14 @@ public class Handelsbanken extends Bank {
 			while (matcher.find()) {
 				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 			}
+			
+			// Sort transactions by date
+			Collections.sort(transactions, new Comparator<Transaction>() {
+                public int compare(Transaction t1, Transaction t2) {
+                    return t2.compareTo(t1);
+                }
+            });
+			
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 8ec24d3..db12ee4 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -198,7 +198,8 @@ public class Skandiabanken extends Bank {
     				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
     				transactions.add(transaction);
     			}
-			    
+	            
+			    // Sort transactions by date
     			Collections.sort(transactions, new Comparator<Transaction>() {
     	            public int compare(Transaction t1, Transaction t2) {
     	                return t2.compareTo(t1);

commit 0bda5f691787e30b0a11a856d1a6e56286b3b328
Author: Tim Janssson <tim@timtux.net>
Date:   Tue Jan 22 21:21:05 2013 +0100

    Visar nu enl andra kreditkort med -

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 6d5818e..b10171f 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -38,7 +38,7 @@ public class EasyCard extends Bank {
 
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_NUMBER;
 
-    private Pattern reAccounts = Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccounts = Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reTransactions = Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
     private Pattern rePostData = Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
 
@@ -124,14 +124,15 @@ public class EasyCard extends Bank {
             // Our data!
             String account_number = matcher.group(2).toString().trim(); // 123123123
             BigDecimal credit_left_amount = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3 748,87
-            BigDecimal credit_spent_amount = Helpers.parseBalance(matcher.group(3).toString().trim()); // 1 083,63
-
+            BigDecimal credit_amount = Helpers.parseBalance(matcher.group(4).toString().trim()); // 30 000,00
+            BigDecimal credit_spent_amount = credit_amount.subtract(credit_left_amount).negate(); // 26 251,13
+            
             // Construct accounts
-            Account credit_left = new Account("Kredit", credit_left_amount, account_number + ":left", Account.CCARD);
-            Account credit_spent = new Account("└ Utnyttjad kredit", credit_spent_amount, account_number + ":spent", Account.OTHER);
-
-            accounts.add(credit_left);
+            Account credit_spent = new Account("Saldo", credit_spent_amount, account_number + ":saldo", Account.CCARD);
+            Account credit_left  = new Account("Kredit", credit_left_amount, account_number + ":kredit", Account.OTHER);
+            
             accounts.add(credit_spent);
+            accounts.add(credit_left);
         }
 
         // No accounts found no profit...
@@ -142,25 +143,19 @@ public class EasyCard extends Bank {
         // Find transactions
         Matcher tMatcher = reTransactions.matcher(response);
 
-        ArrayList<Transaction> credit_left_transactions = new ArrayList<Transaction>();
-        ArrayList<Transaction> credit_spent_transactions = new ArrayList<Transaction>();
-
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+     
         while (tMatcher.find()) {
             String date = tMatcher.group(1).toString().trim(); // 2013-01-15
             String transaction = tMatcher.group(2).toString().trim(); // EBG HOSPITALITY
             BigDecimal amount = Helpers.parseBalance(tMatcher.group(3).toString()); // 214,00
 
-            credit_left_transactions.add(new Transaction(date, transaction, amount.negate()));
-            credit_spent_transactions.add(new Transaction(date, transaction, amount));
+            transactions.add(new Transaction(date, transaction, amount.negate()));
         }
 
         // Add transactions to account.
         for (Account account : accounts) {
-            if (account.getType() == Account.CCARD) {
-                account.setTransactions(credit_left_transactions);
-            } else {
-                account.setTransactions(credit_spent_transactions);
-            }
+            account.setTransactions(transactions);
         }
 
         super.updateComplete();

commit ffcb717434209d7b0bdf56f753dc5428b606f33d
Author: Tim Janssson <tim@timtux.net>
Date:   Tue Jan 22 20:53:46 2013 +0100

    Skandiabanken - Sort transactions
    
    Skandiabanken - Sort transactions

diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index c2551e8..8ec24d3 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -2,6 +2,8 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 
@@ -196,6 +198,13 @@ public class Skandiabanken extends Bank {
     				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
     				transactions.add(transaction);
     			}
+			    
+    			Collections.sort(transactions, new Comparator<Transaction>() {
+    	            public int compare(Transaction t1, Transaction t2) {
+    	                return t2.compareTo(t1);
+    	            }
+    	        });
+    			
     			account.setTransactions(transactions);
 			}
 			

commit 8f0e5ed9b42a95c0d320275585af78c86d65f7e6
Author: Tim Janssson <tim@timtux.net>
Date:   Tue Jan 22 20:39:56 2013 +0100

    New Bank: EasyCard
    
    New Bank: EasyCard

diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 6e14632..6d5818e 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -123,10 +123,8 @@ public class EasyCard extends Bank {
         if (matcher.find()) {
             // Our data!
             String account_number = matcher.group(2).toString().trim(); // 123123123
-            BigDecimal credit_left_amount = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3
-                                                                                                      // 748,87
-            BigDecimal credit_spent_amount = Helpers.parseBalance(matcher.group(3).toString().trim()); // 1
-                                                                                                       // 083,63
+            BigDecimal credit_left_amount = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3 748,87
+            BigDecimal credit_spent_amount = Helpers.parseBalance(matcher.group(3).toString().trim()); // 1 083,63
 
             // Construct accounts
             Account credit_left = new Account("Kredit", credit_left_amount, account_number + ":left", Account.CCARD);
@@ -149,8 +147,7 @@ public class EasyCard extends Bank {
 
         while (tMatcher.find()) {
             String date = tMatcher.group(1).toString().trim(); // 2013-01-15
-            String transaction = tMatcher.group(2).toString().trim(); // EBG
-                                                                      // HOSPITALITY
+            String transaction = tMatcher.group(2).toString().trim(); // EBG HOSPITALITY
             BigDecimal amount = Helpers.parseBalance(tMatcher.group(3).toString()); // 214,00
 
             credit_left_transactions.add(new Transaction(date, transaction, amount.negate()));

commit 232f746032cf1ee5177a8dac273a25047223851a
Author: Tim Janssson <tim@timtux.net>
Date:   Tue Jan 22 20:38:34 2013 +0100

    New Bank: EasyCard
    
    New Bank: EasyCard

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index fa65f6f..01d6f78 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -227,7 +227,7 @@ public class BankFactory {
         case IBankTypes.SVENSKASPEL:
             return new SvenskaSpel(context);
         case IBankTypes.EASYCARD:
-        	return new EasyCard(context);
+            return new EasyCard(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
index 0f0d067..6e14632 100644
--- src/com/liato/bankdroid/banking/banks/EasyCard.java
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -27,156 +27,145 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class EasyCard extends Bank {
-	private static final String TAG = "EasyCard";
-	private static final String NAME = "EasyCard";
-	private static final String NAME_SHORT = "easycard";
-	private static final String URL = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
-	private static final int 	BANKTYPE_ID = IBankTypes.EASYCARD;
-	
-	private static final int 	INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+    private static final String TAG = "EasyCard";
+    private static final String NAME = "EasyCard";
+    private static final String NAME_SHORT = "easycard";
+    private static final String URL = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
+    private static final int BANKTYPE_ID = IBankTypes.EASYCARD;
+
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
     private static final String INPUT_HINT_USERNAME = "XXXXXXXXX";
-    
+
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_NUMBER;
-   
-	private Pattern reAccounts 		= Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTransactions 	= Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
-	private Pattern rePostData 		= Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
-		
-	private String response = null;
-	
-	/**
-	 * Construct.
-	 * 
-	 * @param context 
-	 */
-	public EasyCard(Context context) {
-		super(context);
-		
-		super.TAG 					= TAG;
-		super.NAME 					= NAME;
-		super.NAME_SHORT 			= NAME_SHORT;
-		super.BANKTYPE_ID 			= BANKTYPE_ID;
-		super.URL 					= URL;
-		super.INPUT_TYPE_USERNAME	= INPUT_TYPE_USERNAME;
-		super.INPUT_HINT_USERNAME 	= INPUT_HINT_USERNAME;
-		super.INPUT_TYPE_PASSWORD 	= INPUT_TYPE_PASSWORD;
-	}
-
-	/**
-	 * 
-	 * @param username
-	 * @param password
-	 * @param context
-	 * @throws BankException
-	 * @throws LoginException
-	 * @throws BankChoiceException
-	 */
-	public EasyCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+
+    private Pattern reAccounts = Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactions = Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
+    private Pattern rePostData = Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+
+    public EasyCard(Context context) {
+        super(context);
+
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+    }
+
+    public EasyCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
     @Override
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
-        
-    	urlopen 						= new Urllib(true);
-        response 						= urlopen.open(EasyCard.URL);
-        List <NameValuePair> postData 	= new ArrayList <NameValuePair>();
-       
+
+        urlopen = new Urllib(true);
+        response = urlopen.open(EasyCard.URL);
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+
         // Find hidden required fields.
-        Matcher matcher 	= rePostData.matcher(response);
-		
-		// Populate hidden fields
-		while (matcher.find()) {
-			// 1 == name, 2 == value
-	        postData.add(new BasicNameValuePair(matcher.group(1).toString(), matcher.group(2).toString()));			
-		}
-    
-		// Our data + button value
+        Matcher matcher = rePostData.matcher(response);
+
+        // Populate hidden fields
+        while (matcher.find()) {
+            // 1 == name, 2 == value
+            postData.add(new BasicNameValuePair(matcher.group(1).toString(), matcher.group(2).toString()));
+        }
+
+        // Our data + button value
         postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", username));
         postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$password", password));
         postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$ctl00", "Logga in"));
-        
-        return new LoginPackage(urlopen, postData, response, EasyCard.URL);        
+
+        return new LoginPackage(urlopen, postData, response, EasyCard.URL);
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+            // The string "Valuta" is always present on successful login.
+            if (!response.contains("Valuta")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+
+        } catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        } catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+
+        return urlopen;
     }
 
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		
-		try {
-			LoginPackage lp = preLogin();
-			response 		= urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			// The string "Valuta" is always present on successful login.
-			if (!response.contains("Valuta")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-			
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		
-		if (username == null || password == null || username.length() != 9 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		urlopen 				= login();
-		
-		// Find account info
-		Matcher matcher 	= reAccounts.matcher(response);
-		
-		if (matcher.find()) {
-			// Our data!
-			String 		account_number 		= matcher.group(2).toString().trim(); /* 123123123 */
-			BigDecimal 	credit_left_amount 	= Helpers.parseBalance(matcher.group(2).toString().trim()); /* 3 748,87 */
-			BigDecimal 	credit_spent_amount	= Helpers.parseBalance(matcher.group(3).toString().trim()); /* 1 083,63 */
-			
-			// Construct accounts
-			Account credit_left  = new Account("Kredit", 			 credit_left_amount, 	account_number + ":left", Account.CCARD);
-			Account credit_spent = new Account("└ Utnyttjad kredit", credit_spent_amount, 	account_number + ":spent", Account.OTHER);
-		
-			accounts.add(credit_left);
-			accounts.add(credit_spent);
-		}
-	
-		// No accounts found no profit...
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-		
-		// Find transactions
-		Matcher tMatcher 					= reTransactions.matcher(response);
-		
-		ArrayList<Transaction> credit_left_transactions 	= new ArrayList<Transaction>();
-		ArrayList<Transaction> credit_spent_transactions 	= new ArrayList<Transaction>();
-		
-		while (tMatcher.find()) {
-			String date 		= tMatcher.group(1).toString().trim(); /* 2013-01-15 */
-			String transaction 	= tMatcher.group(2).toString().trim(); /* EBG HOSPITALITY*/
-			BigDecimal amount 	= Helpers.parseBalance(tMatcher.group(3).toString()); /* 214,00 */
-			
-			credit_left_transactions.add(new Transaction(date, transaction, amount.negate()));
-			credit_spent_transactions.add(new Transaction(date, transaction, amount));
-		}
-		
-		// Add transactions to account.
-		for(Account account : accounts) {
-			if(account.getType() == Account.CCARD) {
-				account.setTransactions(credit_left_transactions);
-			} else {
-				account.setTransactions(credit_spent_transactions);
-			}
-		}
-		
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+
+        if (username == null || password == null || username.length() != 9 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+
+        // Find account info
+        Matcher matcher = reAccounts.matcher(response);
+
+        if (matcher.find()) {
+            // Our data!
+            String account_number = matcher.group(2).toString().trim(); // 123123123
+            BigDecimal credit_left_amount = Helpers.parseBalance(matcher.group(2).toString().trim()); // 3
+                                                                                                      // 748,87
+            BigDecimal credit_spent_amount = Helpers.parseBalance(matcher.group(3).toString().trim()); // 1
+                                                                                                       // 083,63
+
+            // Construct accounts
+            Account credit_left = new Account("Kredit", credit_left_amount, account_number + ":left", Account.CCARD);
+            Account credit_spent = new Account("└ Utnyttjad kredit", credit_spent_amount, account_number + ":spent", Account.OTHER);
+
+            accounts.add(credit_left);
+            accounts.add(credit_spent);
+        }
+
+        // No accounts found no profit...
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+
+        // Find transactions
+        Matcher tMatcher = reTransactions.matcher(response);
+
+        ArrayList<Transaction> credit_left_transactions = new ArrayList<Transaction>();
+        ArrayList<Transaction> credit_spent_transactions = new ArrayList<Transaction>();
+
+        while (tMatcher.find()) {
+            String date = tMatcher.group(1).toString().trim(); // 2013-01-15
+            String transaction = tMatcher.group(2).toString().trim(); // EBG
+                                                                      // HOSPITALITY
+            BigDecimal amount = Helpers.parseBalance(tMatcher.group(3).toString()); // 214,00
+
+            credit_left_transactions.add(new Transaction(date, transaction, amount.negate()));
+            credit_spent_transactions.add(new Transaction(date, transaction, amount));
+        }
+
+        // Add transactions to account.
+        for (Account account : accounts) {
+            if (account.getType() == Account.CCARD) {
+                account.setTransactions(credit_left_transactions);
+            } else {
+                account.setTransactions(credit_spent_transactions);
+            }
+        }
+
         super.updateComplete();
-	}
+    }
 }
\ No newline at end of file

commit fca990ce223b37520133fa4135c63754996a1fba
Author: Tim Janssson <tim@timtux.net>
Date:   Tue Jan 22 20:28:41 2013 +0100

    New bank: EasyCard
    
    New bank: EasyCard

diff --git res/drawable/logo_easycard.png res/drawable/logo_easycard.png
new file mode 100644
index 0000000..ee00936
Binary files /dev/null and res/drawable/logo_easycard.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 4fdc69b..fa65f6f 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -47,6 +47,7 @@ import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.EasyCard;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
@@ -225,6 +226,8 @@ public class BankFactory {
             return new Marginalen(context);
         case IBankTypes.SVENSKASPEL:
             return new SvenskaSpel(context);
+        case IBankTypes.EASYCARD:
+        	return new EasyCard(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -296,6 +299,7 @@ public class BankFactory {
         banks.add(new Chalmrest(context));
         banks.add(new Marginalen(context));
         banks.add(new SvenskaSpel(context));
+        banks.add(new EasyCard(context));
         
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
diff --git src/com/liato/bankdroid/banking/banks/EasyCard.java src/com/liato/bankdroid/banking/banks/EasyCard.java
new file mode 100644
index 0000000..0f0d067
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/EasyCard.java
@@ -0,0 +1,182 @@
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class EasyCard extends Bank {
+	private static final String TAG = "EasyCard";
+	private static final String NAME = "EasyCard";
+	private static final String NAME_SHORT = "easycard";
+	private static final String URL = "https://kundportal.cerdo.se/collectorpub/card/default.aspx";
+	private static final int 	BANKTYPE_ID = IBankTypes.EASYCARD;
+	
+	private static final int 	INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+    private static final String INPUT_HINT_USERNAME = "XXXXXXXXX";
+    
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_NUMBER;
+   
+	private Pattern reAccounts 		= Pattern.compile("<h2>MasterCard,\\s([0-9]*)[^:]*:[^:]*:[^:]*:[^:]*[^>]*>([0-9\\s,]*)[^:]*:[^:]*:[^:]*:[^>]*>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions 	= Pattern.compile("<td\\snowrap>([0-9-]*)<\\/td><td\\snowrap>[^,]*,\\s([^,]*)[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>[^<]*<\\/td><td\\snowrap\\sclass='cp-wp-td-right'>([0-9\\s,]*)", Pattern.CASE_INSENSITIVE);
+	private Pattern rePostData 		= Pattern.compile("<input\\stype=\"hidden\"\\sname=\"([0-9A-z_]*)\"\\sid=\"[0-9A-z_]*\"\\svalue=\"([^\"]*)\"\\s\\/>", Pattern.CASE_INSENSITIVE);
+		
+	private String response = null;
+	
+	/**
+	 * Construct.
+	 * 
+	 * @param context 
+	 */
+	public EasyCard(Context context) {
+		super(context);
+		
+		super.TAG 					= TAG;
+		super.NAME 					= NAME;
+		super.NAME_SHORT 			= NAME_SHORT;
+		super.BANKTYPE_ID 			= BANKTYPE_ID;
+		super.URL 					= URL;
+		super.INPUT_TYPE_USERNAME	= INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME 	= INPUT_HINT_USERNAME;
+		super.INPUT_TYPE_PASSWORD 	= INPUT_TYPE_PASSWORD;
+	}
+
+	/**
+	 * 
+	 * @param username
+	 * @param password
+	 * @param context
+	 * @throws BankException
+	 * @throws LoginException
+	 * @throws BankChoiceException
+	 */
+	public EasyCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+        
+    	urlopen 						= new Urllib(true);
+        response 						= urlopen.open(EasyCard.URL);
+        List <NameValuePair> postData 	= new ArrayList <NameValuePair>();
+       
+        // Find hidden required fields.
+        Matcher matcher 	= rePostData.matcher(response);
+		
+		// Populate hidden fields
+		while (matcher.find()) {
+			// 1 == name, 2 == value
+	        postData.add(new BasicNameValuePair(matcher.group(1).toString(), matcher.group(2).toString()));			
+		}
+    
+		// Our data + button value
+        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$accountNumber", username));
+        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$password", password));
+        postData.add(new BasicNameValuePair("ctl00$m$g_2e67c657_c88c_44e4_9e93_48efac2dab20$ctl00", "Logga in"));
+        
+        return new LoginPackage(urlopen, postData, response, EasyCard.URL);        
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		
+		try {
+			LoginPackage lp = preLogin();
+			response 		= urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
+			// The string "Valuta" is always present on successful login.
+			if (!response.contains("Valuta")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		
+		if (username == null || password == null || username.length() != 9 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		urlopen 				= login();
+		
+		// Find account info
+		Matcher matcher 	= reAccounts.matcher(response);
+		
+		if (matcher.find()) {
+			// Our data!
+			String 		account_number 		= matcher.group(2).toString().trim(); /* 123123123 */
+			BigDecimal 	credit_left_amount 	= Helpers.parseBalance(matcher.group(2).toString().trim()); /* 3 748,87 */
+			BigDecimal 	credit_spent_amount	= Helpers.parseBalance(matcher.group(3).toString().trim()); /* 1 083,63 */
+			
+			// Construct accounts
+			Account credit_left  = new Account("Kredit", 			 credit_left_amount, 	account_number + ":left", Account.CCARD);
+			Account credit_spent = new Account("└ Utnyttjad kredit", credit_spent_amount, 	account_number + ":spent", Account.OTHER);
+		
+			accounts.add(credit_left);
+			accounts.add(credit_spent);
+		}
+	
+		// No accounts found no profit...
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+		
+		// Find transactions
+		Matcher tMatcher 					= reTransactions.matcher(response);
+		
+		ArrayList<Transaction> credit_left_transactions 	= new ArrayList<Transaction>();
+		ArrayList<Transaction> credit_spent_transactions 	= new ArrayList<Transaction>();
+		
+		while (tMatcher.find()) {
+			String date 		= tMatcher.group(1).toString().trim(); /* 2013-01-15 */
+			String transaction 	= tMatcher.group(2).toString().trim(); /* EBG HOSPITALITY*/
+			BigDecimal amount 	= Helpers.parseBalance(tMatcher.group(3).toString()); /* 214,00 */
+			
+			credit_left_transactions.add(new Transaction(date, transaction, amount.negate()));
+			credit_spent_transactions.add(new Transaction(date, transaction, amount));
+		}
+		
+		// Add transactions to account.
+		for(Account account : accounts) {
+			if(account.getType() == Account.CCARD) {
+				account.setTransactions(credit_left_transactions);
+			} else {
+				account.setTransactions(credit_spent_transactions);
+			}
+		}
+		
+        super.updateComplete();
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 126b0da..7130007 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -85,4 +85,5 @@ public interface IBankTypes {
     public static final int MARGINALEN = 61;
     public static final int AKELIUSSPAR = 62;
     public static final int SVENSKASPEL = 63;
+    public static final int EASYCARD = 64;
 }

commit 3f8540448c68d14506eb9abac4c451fb83dfe9f9
Author: liato <x@x00.us>
Date:   Thu Jan 17 04:03:14 2013 +0100

    Update .gitignore.

diff --git .gitignore .gitignore
index edd78cb..c2f1d57 100644
--- .gitignore
+++ .gitignore
@@ -10,6 +10,7 @@ Thumbs.db
 Desktop.ini
 *~
 *.apk
+*.java.orig
 bin
 gen
 local.properties

commit fe4e0421420d77d671afe0432d07390c5238df7d
Merge: abf622b 9a241b3
Author: liato <x@x00.us>
Date:   Thu Jan 17 04:02:50 2013 +0100

    Resolve merge conflicts.

commit abf622b546046f9165d9278a14f2241f3916567b
Merge: cd8237c 03ac7c8
Author: liato <x@x00.us>
Date:   Thu Jan 17 03:56:44 2013 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Handle exception for uninitialized API key in pairing dialog

commit 03ac7c8d18b51157ed70294afc97cbccc3ec3ddf
Merge: 8ff319a c7e04e2
Author: liato <x@x00.us>
Date:   Wed Jan 16 18:56:15 2013 -0800

    Merge pull request #205 from cortex/master
    
    Fix handling of unititialized API key on pairing request

commit 9a241b36bedca870be2b3c3f548864c2bae827ad
Author: Jonathan Hjertström <jh@nixi.com>
Date:   Mon Jan 14 11:24:55 2013 +0100

    New bank: Svenska Spel

diff --git res/drawable/logo_svenskaspel.png res/drawable/logo_svenskaspel.png
new file mode 100644
index 0000000..3daad82
Binary files /dev/null and res/drawable/logo_svenskaspel.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 56c07dc..8fb0c04 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -1,461 +1,465 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.preference.PreferenceManager;
-
-import com.liato.bankdroid.banking.banks.AkeliusInvest;
-import com.liato.bankdroid.banking.banks.AkeliusSpar;
-import com.liato.bankdroid.banking.banks.AmericanExpress;
-import com.liato.bankdroid.banking.banks.Audi;
-import com.liato.bankdroid.banking.banks.Avanza;
-import com.liato.bankdroid.banking.banks.AvanzaMini;
-import com.liato.bankdroid.banking.banks.Bioklubben;
-import com.liato.bankdroid.banking.banks.CSN;
-import com.liato.bankdroid.banking.banks.Chalmrest;
-import com.liato.bankdroid.banking.banks.Chevrolet;
-import com.liato.bankdroid.banking.banks.Coop;
-import com.liato.bankdroid.banking.banks.DanskeBank;
-import com.liato.bankdroid.banking.banks.DinersClub;
-import com.liato.bankdroid.banking.banks.Djurgarden;
-import com.liato.bankdroid.banking.banks.EurobonusMastercard;
-import com.liato.bankdroid.banking.banks.Eurocard;
-import com.liato.bankdroid.banking.banks.Everydaycard;
-import com.liato.bankdroid.banking.banks.FirstCard;
-import com.liato.bankdroid.banking.banks.Handelsbanken;
-import com.liato.bankdroid.banking.banks.Hemkop;
-import com.liato.bankdroid.banking.banks.ICA;
-import com.liato.bankdroid.banking.banks.ICABanken;
-import com.liato.bankdroid.banking.banks.IKEA;
-import com.liato.bankdroid.banking.banks.IkanoBank;
-import com.liato.bankdroid.banking.banks.Jojo;
-import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
-import com.liato.bankdroid.banking.banks.McDonalds;
-import com.liato.bankdroid.banking.banks.NordeaDK;
-import com.liato.bankdroid.banking.banks.Nordnet;
-import com.liato.bankdroid.banking.banks.Nordnetdirekt;
-import com.liato.bankdroid.banking.banks.OKQ8;
-import com.liato.bankdroid.banking.banks.Opel;
-import com.liato.bankdroid.banking.banks.Osuuspankki;
-import com.liato.bankdroid.banking.banks.PayPal;
-import com.liato.bankdroid.banking.banks.Payson;
-import com.liato.bankdroid.banking.banks.PlusGirot;
-import com.liato.bankdroid.banking.banks.Preem;
-import com.liato.bankdroid.banking.banks.Quintessentially;
-import com.liato.bankdroid.banking.banks.ResursBank;
-import com.liato.bankdroid.banking.banks.TicketRikskortet;
-import com.liato.bankdroid.banking.banks.Rikslunchen;
-import com.liato.bankdroid.banking.banks.SEB;
-import com.liato.bankdroid.banking.banks.SJPrio;
-import com.liato.bankdroid.banking.banks.Saab;
-import com.liato.bankdroid.banking.banks.Seat;
-import com.liato.bankdroid.banking.banks.SevenDay;
-import com.liato.bankdroid.banking.banks.Shell;
-import com.liato.bankdroid.banking.banks.Skandiabanken;
-import com.liato.bankdroid.banking.banks.Skoda;
-import com.liato.bankdroid.banking.banks.SparbankenOresund;
-import com.liato.bankdroid.banking.banks.SparbankenSyd;
-import com.liato.bankdroid.banking.banks.Statoil;
-import com.liato.bankdroid.banking.banks.Swedbank;
-import com.liato.bankdroid.banking.banks.TestBank;
-import com.liato.bankdroid.banking.banks.Vasttrafik;
-import com.liato.bankdroid.banking.banks.Villabanken;
-import com.liato.bankdroid.banking.banks.Volkswagen;
-import com.liato.bankdroid.banking.banks.Volvofinans;
-import com.liato.bankdroid.banking.banks.Wallet;
-import com.liato.bankdroid.banking.banks.Meniga;
-import com.liato.bankdroid.banking.banks.Marginalen;
-import com.liato.bankdroid.banking.banks.Nordea.Nordea;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.db.Crypto;
-import com.liato.bankdroid.db.DBAdapter;
-import com.liato.bankdroid.provider.IBankTypes;
-import net.sf.andhsli.hotspotlogin.SimpleCrypto;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-
-public class BankFactory {
-
-	public static Bank fromBanktypeId(int id, Context context) throws BankException {
-		switch (id) {
-        case IBankTypes.TESTBANK:
-            return new TestBank(context);
-        case IBankTypes.AKELIUSINVEST:
-            return new AkeliusInvest(context);
-        case IBankTypes.AKELIUSSPAR:
-            return new AkeliusSpar(context);
-        case IBankTypes.SWEDBANK:
-            return new Swedbank(context);
-		case IBankTypes.NORDEA:
-			return new Nordea(context);
-		case IBankTypes.LANSFORSAKRINGAR:
-			return new Lansforsakringar(context);
-		case IBankTypes.ICABANKEN:
-			return new ICABanken(context);
-		case IBankTypes.HANDELSBANKEN:
-			return new Handelsbanken(context);
-		case IBankTypes.COOP:
-			return new Coop(context);
-		case IBankTypes.ICA:
-			return new ICA(context);
-		case IBankTypes.STATOIL:
-			return new Statoil(context);
-		case IBankTypes.AVANZA:
-			return new Avanza(context);
-		case IBankTypes.VILLABANKEN:
-			return new Villabanken(context);
-        case IBankTypes.AVANZAMINI:
-            return new AvanzaMini(context);
-        case IBankTypes.OKQ8:
-            return new OKQ8(context);
-        case IBankTypes.EUROCARD:
-            return new Eurocard(context);
-        case IBankTypes.FIRSTCARD:
-            return new FirstCard(context);
-        case IBankTypes.PAYPAL:
-            return new PayPal(context);
-        case IBankTypes.PAYSON:
-            return new Payson(context);
-        case IBankTypes.JOJO:
-            return new Jojo(context);
-        //case IBankTypes.STEAM:
-        //    return new Steam(context);
-        case IBankTypes.DINERSCLUB:
-            return new DinersClub(context);
-        case IBankTypes.IKANOBANK:
-            return new IkanoBank(context);
-        case IBankTypes.SASEUROBONUSMASTERCARD:
-        	return new EurobonusMastercard(context);
-        case IBankTypes.RIKSLUNCHEN:
-            return new Rikslunchen(context);            
-        case IBankTypes.HEMKOP:
-            return new Hemkop(context);            
-        case IBankTypes.SEB:
-            return new SEB(context);            
-        case IBankTypes.NORDNET:
-            return new Nordnet(context);            
-        case IBankTypes.SEVENDAY:
-            return new SevenDay(context);
-        case IBankTypes.OSUUSPANKKI:
-            return new Osuuspankki(context);
-        case IBankTypes.VOLVOFINANS:
-            return new Volvofinans(context);
-        case IBankTypes.CSN:
-            return new CSN(context);
-        case IBankTypes.RESURSBANK:
-            return new ResursBank(context);
-        case IBankTypes.AMERICANEXPRESS:
-            return new AmericanExpress(context);
-        case IBankTypes.MCDONALDS:
-            return new McDonalds(context);
-        case IBankTypes.SAAB:
-            return new Saab(context);
-        case IBankTypes.WALLET:
-            return new Wallet(context);
-        case IBankTypes.CHEVROLET:
-            return new Chevrolet(context);
-        case IBankTypes.SJPRIO:
-            return new SJPrio(context);
-        case IBankTypes.OPEL:
-            return new Opel(context);
-        case IBankTypes.DJURGARDEN:
-            return new Djurgarden(context);
-        case IBankTypes.QUINTESSENTIALLY:
-            return new Quintessentially(context);
-        case IBankTypes.PLUSGIROT:
-            return new PlusGirot(context);
-        case IBankTypes.SHELL:
-            return new Shell(context);
-        case IBankTypes.VOLKSWAGEN:
-            return new Volkswagen(context);
-        case IBankTypes.AUDI:
-            return new Audi(context);
-        case IBankTypes.PREEM:
-            return new Preem(context);
-        case IBankTypes.SEAT:
-            return new Seat(context);
-        case IBankTypes.SKODA:
-            return new Skoda(context);
-        case IBankTypes.IKEA:
-            return new IKEA(context);
-        case IBankTypes.SPARBANKEN_SYD:
-            return new SparbankenSyd(context);
-        case IBankTypes.SPARBANKEN_ORESUND:
-            return new SparbankenOresund(context);
-        case IBankTypes.NORDNETDIREKT:
-            return new Nordnetdirekt(context);
-        case IBankTypes.SKANDIABANKEN:
-            return new Skandiabanken(context);
-        case IBankTypes.DANSKEBANK:
-            return new DanskeBank(context);
-        case IBankTypes.NORDEA_DK:
-        	return new NordeaDK(context);
-        case IBankTypes.VASTTRAFIK:
-            return new Vasttrafik(context);
-        case IBankTypes.EVERYDAYCARD:
-            return new Everydaycard(context);
-        case IBankTypes.MENIGA:
-            return new Meniga(context);
-        case IBankTypes.RIKSKORTET:
-            return new TicketRikskortet(context);
-        case IBankTypes.BIOKLUBBEN:
-            return new Bioklubben(context);
-        case IBankTypes.CHALMREST:
-        	return new Chalmrest(context);
-        case IBankTypes.MARGINALEN:
-            return new Marginalen(context);
-		default:
-			throw new BankException("BankType id not found.");
-		}
-	}
-	
-
-	public static ArrayList<Bank> listBanks(Context context) {
-		ArrayList<Bank> banks = new ArrayList<Bank>();
-		banks.add(new AkeliusInvest(context));
-		banks.add(new AkeliusSpar(context));
-		banks.add(new Swedbank(context));
-		banks.add(new Nordea(context));
-		banks.add(new ICABanken(context));
-		banks.add(new Lansforsakringar(context));
-		banks.add(new Handelsbanken(context));
-		banks.add(new Coop(context));
-		banks.add(new ICA(context));
-		banks.add(new Statoil(context));
-		banks.add(new Avanza(context));
-		banks.add(new Villabanken(context));
-		banks.add(new AvanzaMini(context));
-        banks.add(new OKQ8(context));
-		banks.add(new Eurocard(context));
-        banks.add(new FirstCard(context));
-        banks.add(new PayPal(context));
-        banks.add(new Payson(context));
-        banks.add(new Jojo(context));
-        //banks.add(new Steam(context));
-        banks.add(new DinersClub(context));
-        banks.add(new IkanoBank(context));
-        banks.add(new EurobonusMastercard(context));
-        banks.add(new Rikslunchen(context));
-        banks.add(new Hemkop(context));
-        banks.add(new SEB(context));
-        banks.add(new Nordnet(context));
-        banks.add(new SevenDay(context));
-        banks.add(new Osuuspankki(context));
-        banks.add(new Volvofinans(context));
-        banks.add(new CSN(context));
-        banks.add(new ResursBank(context));
-        banks.add(new McDonalds(context));
-        banks.add(new SJPrio(context));
-        banks.add(new SparbankenSyd(context));
-        banks.add(new SparbankenOresund(context));
-        banks.add(new Opel(context));
-        banks.add(new Skandiabanken(context));
-        banks.add(new AmericanExpress(context));
-        banks.add(new PlusGirot(context));
-        banks.add(new Nordnetdirekt(context));
-        banks.add(new Saab(context));
-        banks.add(new Wallet(context));
-        banks.add(new Chevrolet(context));
-        banks.add(new Djurgarden(context));
-        banks.add(new Quintessentially(context));
-        banks.add(new Shell(context));
-        banks.add(new Volkswagen(context));
-        banks.add(new Audi(context));
-        banks.add(new Preem(context));
-        banks.add(new Seat(context));
-        banks.add(new Skoda(context));
-        banks.add(new IKEA(context));
-        banks.add(new DanskeBank(context));
-        banks.add(new NordeaDK(context));
-        banks.add(new Vasttrafik(context));
-        banks.add(new Everydaycard(context));
-        banks.add(new Meniga(context));
-        banks.add(new TicketRikskortet(context));
-        banks.add(new Bioklubben(context));
-        banks.add(new Chalmrest(context));
-        banks.add(new Marginalen(context));
-
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-        if (prefs.getBoolean("debug_mode", false)) { 
-            banks.add(new TestBank(context));
-        }
-		return banks;
-	}
-
-	public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
-		Bank bank = null;
-		DBAdapter db = new DBAdapter(context);
-		db.open();
-		Cursor c = db.getBank(id);
-
-		if (c != null) {
-			try {
-				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				String password = "";
-				try {
-					password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
-				} catch (Exception e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-				
-				bank.setData(c.getString(c.getColumnIndex("username")),
-							 password,
-							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-							 (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-							 c.getLong(c.getColumnIndex("_id")),
-							 c.getString(c.getColumnIndex("currency")),
-							 c.getString(c.getColumnIndex("custname")),
-							 c.getString(c.getColumnIndex("extras")));
-				if (loadAccounts) {
-					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
-				}
-			} catch (BankException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			finally {
-				c.close();
-			}
-		}
-		db.close();
-		return bank;
-	}
-
-	public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
-		ArrayList<Bank> banks = new ArrayList<Bank>();
-		DBAdapter db = new DBAdapter(context);
-		db.open();
-		Cursor c = db.fetchBanks();
-		if (c == null) {
-			db.close();
-			return banks;
-		}
-		while (!c.isLast() && !c.isAfterLast()) {
-			c.moveToNext();
-			try {
-				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				
-	            String password = "";
-                try {
-                    password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
-                } catch (Exception e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                }
-                bank.setData(c.getString(c.getColumnIndex("username")),
-				             password,
-				             new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-				             (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-				             c.getLong(c.getColumnIndex("_id")),
-				             c.getString(c.getColumnIndex("currency")),
-				             c.getString(c.getColumnIndex("custname")),
-                             c.getString(c.getColumnIndex("extras")));
-				if (loadAccounts) {
-					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
-				}
-				banks.add(bank);
-			} catch (BankException e) {
-				//e.printStackTrace();
-			}
-		}
-		c.close();
-		db.close();
-		return banks;
-	}
-	
-	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
-		DBAdapter db = new DBAdapter(context);
-		db.open();
-		Cursor c = db.getAccount(accountId);
-       
-		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
-			db.close();
-			return null;
-		}
-
-		Account account = new Account(c.getString(c.getColumnIndex("name")),
-                                      new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                      c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                                      c.getLong(c.getColumnIndex("bankid")),
-                                      c.getInt(c.getColumnIndex("acctype")));
-        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
-        account.setCurrency(c.getString(c.getColumnIndex("currency")));
-        account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
-		c.close();
-		if (loadTransactions) {
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			String fromAccount = accountId;
-			if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
-			    fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
-			}
-			c = db.fetchTransactions(fromAccount);
-			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
-				while (!c.isLast() && !c.isAfterLast()) {
-					c.moveToNext();
-					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")),
-                                     c.getString(c.getColumnIndex("btransaction")),
-                                     new BigDecimal(c.getString(c.getColumnIndex("amount"))),
-                                     c.getString(c.getColumnIndex("currency"))));
-				}
-				c.close();
-			}
-			account.setTransactions(transactions);
-		}
-		
-		db.close();
-		return account;
-	}
-	
-	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
-		ArrayList<Account> accounts = new ArrayList<Account>();
-		DBAdapter db = new DBAdapter(context);
-		db.open();
-		Cursor c = db.fetchAccounts(bankId);
-		if (c == null) {
-			db.close();
-			return accounts;
-		}
-		while (!c.isLast() && !c.isAfterLast()) {
-			c.moveToNext();
-			try {
-    			Account account = new Account(c.getString(c.getColumnIndex("name")),
-                                              new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                              c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                                              c.getLong(c.getColumnIndex("bankid")),
-                                              c.getInt(c.getColumnIndex("acctype")));
-    	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
-                account.setCurrency(c.getString(c.getColumnIndex("currency")));
-                account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
-    			accounts.add(account);
-			}
-			catch (ArrayIndexOutOfBoundsException e) {
-			    // Attempted to load an account without and ID, probably an old Avanza account.
-			}
-		}
-		c.close();
-		db.close();
-		return accounts;
-	}
-	
-}
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.preference.PreferenceManager;
+
+import com.liato.bankdroid.banking.banks.AkeliusInvest;
+import com.liato.bankdroid.banking.banks.AkeliusSpar;
+import com.liato.bankdroid.banking.banks.AmericanExpress;
+import com.liato.bankdroid.banking.banks.Audi;
+import com.liato.bankdroid.banking.banks.Avanza;
+import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.Bioklubben;
+import com.liato.bankdroid.banking.banks.CSN;
+import com.liato.bankdroid.banking.banks.Chalmrest;
+import com.liato.bankdroid.banking.banks.Chevrolet;
+import com.liato.bankdroid.banking.banks.Coop;
+import com.liato.bankdroid.banking.banks.DanskeBank;
+import com.liato.bankdroid.banking.banks.DinersClub;
+import com.liato.bankdroid.banking.banks.Djurgarden;
+import com.liato.bankdroid.banking.banks.EurobonusMastercard;
+import com.liato.bankdroid.banking.banks.Eurocard;
+import com.liato.bankdroid.banking.banks.Everydaycard;
+import com.liato.bankdroid.banking.banks.FirstCard;
+import com.liato.bankdroid.banking.banks.Handelsbanken;
+import com.liato.bankdroid.banking.banks.Hemkop;
+import com.liato.bankdroid.banking.banks.ICA;
+import com.liato.bankdroid.banking.banks.ICABanken;
+import com.liato.bankdroid.banking.banks.IKEA;
+import com.liato.bankdroid.banking.banks.IkanoBank;
+import com.liato.bankdroid.banking.banks.Jojo;
+import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.McDonalds;
+import com.liato.bankdroid.banking.banks.NordeaDK;
+import com.liato.bankdroid.banking.banks.Nordnet;
+import com.liato.bankdroid.banking.banks.Nordnetdirekt;
+import com.liato.bankdroid.banking.banks.OKQ8;
+import com.liato.bankdroid.banking.banks.Opel;
+import com.liato.bankdroid.banking.banks.Osuuspankki;
+import com.liato.bankdroid.banking.banks.PayPal;
+import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.PlusGirot;
+import com.liato.bankdroid.banking.banks.Preem;
+import com.liato.bankdroid.banking.banks.Quintessentially;
+import com.liato.bankdroid.banking.banks.ResursBank;
+import com.liato.bankdroid.banking.banks.TicketRikskortet;
+import com.liato.bankdroid.banking.banks.Rikslunchen;
+import com.liato.bankdroid.banking.banks.SEB;
+import com.liato.bankdroid.banking.banks.SJPrio;
+import com.liato.bankdroid.banking.banks.Saab;
+import com.liato.bankdroid.banking.banks.Seat;
+import com.liato.bankdroid.banking.banks.SevenDay;
+import com.liato.bankdroid.banking.banks.Shell;
+import com.liato.bankdroid.banking.banks.Skandiabanken;
+import com.liato.bankdroid.banking.banks.Skoda;
+import com.liato.bankdroid.banking.banks.SparbankenOresund;
+import com.liato.bankdroid.banking.banks.SparbankenSyd;
+import com.liato.bankdroid.banking.banks.Statoil;
+import com.liato.bankdroid.banking.banks.Swedbank;
+import com.liato.bankdroid.banking.banks.TestBank;
+import com.liato.bankdroid.banking.banks.Vasttrafik;
+import com.liato.bankdroid.banking.banks.Villabanken;
+import com.liato.bankdroid.banking.banks.Volkswagen;
+import com.liato.bankdroid.banking.banks.Volvofinans;
+import com.liato.bankdroid.banking.banks.Wallet;
+import com.liato.bankdroid.banking.banks.Meniga;
+import com.liato.bankdroid.banking.banks.Marginalen;
+import com.liato.bankdroid.banking.banks.Nordea.Nordea;
+import com.liato.bankdroid.banking.banks.SvenskaSpel;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.db.Crypto;
+import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.provider.IBankTypes;
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+
+public class BankFactory {
+
+	public static Bank fromBanktypeId(int id, Context context) throws BankException {
+		switch (id) {
+        case IBankTypes.TESTBANK:
+            return new TestBank(context);
+        case IBankTypes.AKELIUSINVEST:
+            return new AkeliusInvest(context);
+        case IBankTypes.AKELIUSSPAR:
+            return new AkeliusSpar(context);
+        case IBankTypes.SWEDBANK:
+            return new Swedbank(context);
+		case IBankTypes.NORDEA:
+			return new Nordea(context);
+		case IBankTypes.LANSFORSAKRINGAR:
+			return new Lansforsakringar(context);
+		case IBankTypes.ICABANKEN:
+			return new ICABanken(context);
+		case IBankTypes.HANDELSBANKEN:
+			return new Handelsbanken(context);
+		case IBankTypes.COOP:
+			return new Coop(context);
+		case IBankTypes.ICA:
+			return new ICA(context);
+		case IBankTypes.STATOIL:
+			return new Statoil(context);
+		case IBankTypes.AVANZA:
+			return new Avanza(context);
+		case IBankTypes.VILLABANKEN:
+			return new Villabanken(context);
+        case IBankTypes.AVANZAMINI:
+            return new AvanzaMini(context);
+        case IBankTypes.OKQ8:
+            return new OKQ8(context);
+        case IBankTypes.EUROCARD:
+            return new Eurocard(context);
+        case IBankTypes.FIRSTCARD:
+            return new FirstCard(context);
+        case IBankTypes.PAYPAL:
+            return new PayPal(context);
+        case IBankTypes.PAYSON:
+            return new Payson(context);
+        case IBankTypes.JOJO:
+            return new Jojo(context);
+        //case IBankTypes.STEAM:
+        //    return new Steam(context);
+        case IBankTypes.DINERSCLUB:
+            return new DinersClub(context);
+        case IBankTypes.IKANOBANK:
+            return new IkanoBank(context);
+        case IBankTypes.SASEUROBONUSMASTERCARD:
+        	return new EurobonusMastercard(context);
+        case IBankTypes.RIKSLUNCHEN:
+            return new Rikslunchen(context);            
+        case IBankTypes.HEMKOP:
+            return new Hemkop(context);            
+        case IBankTypes.SEB:
+            return new SEB(context);            
+        case IBankTypes.NORDNET:
+            return new Nordnet(context);            
+        case IBankTypes.SEVENDAY:
+            return new SevenDay(context);
+        case IBankTypes.OSUUSPANKKI:
+            return new Osuuspankki(context);
+        case IBankTypes.VOLVOFINANS:
+            return new Volvofinans(context);
+        case IBankTypes.CSN:
+            return new CSN(context);
+        case IBankTypes.RESURSBANK:
+            return new ResursBank(context);
+        case IBankTypes.AMERICANEXPRESS:
+            return new AmericanExpress(context);
+        case IBankTypes.MCDONALDS:
+            return new McDonalds(context);
+        case IBankTypes.SAAB:
+            return new Saab(context);
+        case IBankTypes.WALLET:
+            return new Wallet(context);
+        case IBankTypes.CHEVROLET:
+            return new Chevrolet(context);
+        case IBankTypes.SJPRIO:
+            return new SJPrio(context);
+        case IBankTypes.OPEL:
+            return new Opel(context);
+        case IBankTypes.DJURGARDEN:
+            return new Djurgarden(context);
+        case IBankTypes.QUINTESSENTIALLY:
+            return new Quintessentially(context);
+        case IBankTypes.PLUSGIROT:
+            return new PlusGirot(context);
+        case IBankTypes.SHELL:
+            return new Shell(context);
+        case IBankTypes.VOLKSWAGEN:
+            return new Volkswagen(context);
+        case IBankTypes.AUDI:
+            return new Audi(context);
+        case IBankTypes.PREEM:
+            return new Preem(context);
+        case IBankTypes.SEAT:
+            return new Seat(context);
+        case IBankTypes.SKODA:
+            return new Skoda(context);
+        case IBankTypes.IKEA:
+            return new IKEA(context);
+        case IBankTypes.SPARBANKEN_SYD:
+            return new SparbankenSyd(context);
+        case IBankTypes.SPARBANKEN_ORESUND:
+            return new SparbankenOresund(context);
+        case IBankTypes.NORDNETDIREKT:
+            return new Nordnetdirekt(context);
+        case IBankTypes.SKANDIABANKEN:
+            return new Skandiabanken(context);
+        case IBankTypes.DANSKEBANK:
+            return new DanskeBank(context);
+        case IBankTypes.NORDEA_DK:
+        	return new NordeaDK(context);
+        case IBankTypes.VASTTRAFIK:
+            return new Vasttrafik(context);
+        case IBankTypes.EVERYDAYCARD:
+            return new Everydaycard(context);
+        case IBankTypes.MENIGA:
+            return new Meniga(context);
+        case IBankTypes.RIKSKORTET:
+            return new TicketRikskortet(context);
+        case IBankTypes.BIOKLUBBEN:
+            return new Bioklubben(context);
+        case IBankTypes.CHALMREST:
+        	return new Chalmrest(context);
+        case IBankTypes.MARGINALEN:
+            return new Marginalen(context);
+        case IBankTypes.SVENSKASPEL:
+            return new SvenskaSpel(context);
+		default:
+			throw new BankException("BankType id not found.");
+		}
+	}
+	
+
+	public static ArrayList<Bank> listBanks(Context context) {
+		ArrayList<Bank> banks = new ArrayList<Bank>();
+		banks.add(new AkeliusInvest(context));
+		banks.add(new AkeliusSpar(context));
+		banks.add(new Swedbank(context));
+		banks.add(new Nordea(context));
+		banks.add(new ICABanken(context));
+		banks.add(new Lansforsakringar(context));
+		banks.add(new Handelsbanken(context));
+		banks.add(new Coop(context));
+		banks.add(new ICA(context));
+		banks.add(new Statoil(context));
+		banks.add(new Avanza(context));
+		banks.add(new Villabanken(context));
+		banks.add(new AvanzaMini(context));
+        banks.add(new OKQ8(context));
+		banks.add(new Eurocard(context));
+        banks.add(new FirstCard(context));
+        banks.add(new PayPal(context));
+        banks.add(new Payson(context));
+        banks.add(new Jojo(context));
+        //banks.add(new Steam(context));
+        banks.add(new DinersClub(context));
+        banks.add(new IkanoBank(context));
+        banks.add(new EurobonusMastercard(context));
+        banks.add(new Rikslunchen(context));
+        banks.add(new Hemkop(context));
+        banks.add(new SEB(context));
+        banks.add(new Nordnet(context));
+        banks.add(new SevenDay(context));
+        banks.add(new Osuuspankki(context));
+        banks.add(new Volvofinans(context));
+        banks.add(new CSN(context));
+        banks.add(new ResursBank(context));
+        banks.add(new McDonalds(context));
+        banks.add(new SJPrio(context));
+        banks.add(new SparbankenSyd(context));
+        banks.add(new SparbankenOresund(context));
+        banks.add(new Opel(context));
+        banks.add(new Skandiabanken(context));
+        banks.add(new AmericanExpress(context));
+        banks.add(new PlusGirot(context));
+        banks.add(new Nordnetdirekt(context));
+        banks.add(new Saab(context));
+        banks.add(new Wallet(context));
+        banks.add(new Chevrolet(context));
+        banks.add(new Djurgarden(context));
+        banks.add(new Quintessentially(context));
+        banks.add(new Shell(context));
+        banks.add(new Volkswagen(context));
+        banks.add(new Audi(context));
+        banks.add(new Preem(context));
+        banks.add(new Seat(context));
+        banks.add(new Skoda(context));
+        banks.add(new IKEA(context));
+        banks.add(new DanskeBank(context));
+        banks.add(new NordeaDK(context));
+        banks.add(new Vasttrafik(context));
+        banks.add(new Everydaycard(context));
+        banks.add(new Meniga(context));
+        banks.add(new TicketRikskortet(context));
+        banks.add(new Bioklubben(context));
+        banks.add(new Chalmrest(context));
+        banks.add(new Marginalen(context));
+        banks.add(new SvenskaSpel(context));
+        
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (prefs.getBoolean("debug_mode", false)) { 
+            banks.add(new TestBank(context));
+        }
+		return banks;
+	}
+
+	public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
+		Bank bank = null;
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.getBank(id);
+
+		if (c != null) {
+			try {
+				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+				String password = "";
+				try {
+					password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
+				} catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				
+				bank.setData(c.getString(c.getColumnIndex("username")),
+							 password,
+							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+							 (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+							 c.getLong(c.getColumnIndex("_id")),
+							 c.getString(c.getColumnIndex("currency")),
+							 c.getString(c.getColumnIndex("custname")),
+							 c.getString(c.getColumnIndex("extras")));
+				if (loadAccounts) {
+					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+				}
+			} catch (BankException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			finally {
+				c.close();
+			}
+		}
+		db.close();
+		return bank;
+	}
+
+	public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
+		ArrayList<Bank> banks = new ArrayList<Bank>();
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.fetchBanks();
+		if (c == null) {
+			db.close();
+			return banks;
+		}
+		while (!c.isLast() && !c.isAfterLast()) {
+			c.moveToNext();
+			try {
+				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+				
+	            String password = "";
+                try {
+                    password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
+                } catch (Exception e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                bank.setData(c.getString(c.getColumnIndex("username")),
+				             password,
+				             new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+				             (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+				             c.getLong(c.getColumnIndex("_id")),
+				             c.getString(c.getColumnIndex("currency")),
+				             c.getString(c.getColumnIndex("custname")),
+                             c.getString(c.getColumnIndex("extras")));
+				if (loadAccounts) {
+					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+				}
+				banks.add(bank);
+			} catch (BankException e) {
+				//e.printStackTrace();
+			}
+		}
+		c.close();
+		db.close();
+		return banks;
+	}
+	
+	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.getAccount(accountId);
+       
+		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
+			db.close();
+			return null;
+		}
+
+		Account account = new Account(c.getString(c.getColumnIndex("name")),
+                                      new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                                      c.getString(c.getColumnIndex("id")).split("_", 2)[1],
+                                      c.getLong(c.getColumnIndex("bankid")),
+                                      c.getInt(c.getColumnIndex("acctype")));
+        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
+        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
+        account.setCurrency(c.getString(c.getColumnIndex("currency")));
+        account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
+		c.close();
+		if (loadTransactions) {
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			String fromAccount = accountId;
+			if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
+			    fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
+			}
+			c = db.fetchTransactions(fromAccount);
+			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
+				while (!c.isLast() && !c.isAfterLast()) {
+					c.moveToNext();
+					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")),
+                                     c.getString(c.getColumnIndex("btransaction")),
+                                     new BigDecimal(c.getString(c.getColumnIndex("amount"))),
+                                     c.getString(c.getColumnIndex("currency"))));
+				}
+				c.close();
+			}
+			account.setTransactions(transactions);
+		}
+		
+		db.close();
+		return account;
+	}
+	
+	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
+		ArrayList<Account> accounts = new ArrayList<Account>();
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.fetchAccounts(bankId);
+		if (c == null) {
+			db.close();
+			return accounts;
+		}
+		while (!c.isLast() && !c.isAfterLast()) {
+			c.moveToNext();
+			try {
+    			Account account = new Account(c.getString(c.getColumnIndex("name")),
+                                              new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                                              c.getString(c.getColumnIndex("id")).split("_", 2)[1],
+                                              c.getLong(c.getColumnIndex("bankid")),
+                                              c.getInt(c.getColumnIndex("acctype")));
+    	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
+    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
+                account.setCurrency(c.getString(c.getColumnIndex("currency")));
+                account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
+    			accounts.add(account);
+			}
+			catch (ArrayIndexOutOfBoundsException e) {
+			    // Attempted to load an account without and ID, probably an old Avanza account.
+			}
+		}
+		c.close();
+		db.close();
+		return accounts;
+	}
+	
+}
diff --git src/com/liato/bankdroid/banking/banks/SvenskaSpel.java src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
new file mode 100644
index 0000000..e436104
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/SvenskaSpel.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: Jonathan Hjertström (jh@nixi.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class SvenskaSpel extends Bank {
+
+	private static final String TAG = "SvenskaSpel";
+	private static final String NAME = "Svenska Spel";
+	private static final String NAME_SHORT = "svenskaspel";
+	private static final String URL = "https://m.svenskaspel.se/Customer/Login?returnUrl=/MinaSpel";
+	private static final int BANKTYPE_ID = Bank.SVENSKASPEL;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;
+
+    private Pattern reBalance = Pattern.compile("Balance\\\":\\\"([^<]+)\\\",", Pattern.CASE_INSENSITIVE);
+	private String response = "";
+
+	public SvenskaSpel(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME= INPUT_TYPE_USERNAME;
+		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+	}
+
+	public SvenskaSpel(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+		urlopen = new Urllib();
+
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		postData.add(new BasicNameValuePair("username", username));
+	    postData.add(new BasicNameValuePair("password", password));
+	    postData.add(new BasicNameValuePair("loginbutton", "Logga in"));
+
+		return new LoginPackage(urlopen, postData, response, "https://m.svenskaspel.se/Customer/Login?returnUrl=/MinaSpel");
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+        try {
+        	 LoginPackage lp = preLogin();
+             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());    
+             if (response.contains("Felaktigt anv")) {
+                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+             }
+         }
+         catch (ClientProtocolException e) {
+             throw new BankException(e.getMessage());
+         }
+         catch (IOException e) {
+             throw new BankException(e.getMessage());
+         }
+         return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+      
+        Matcher matcher = reBalance.matcher(response);
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: balance               845
+             * 
+             */    		    
+		   Account account = new Account("Saldo", Helpers.parseBalance(matcher.group(1)), "1");
+           balance = Helpers.parseBalance(matcher.group(1));
+           balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+           accounts.add(account);
+		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 61541c2..9b35ab4 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -1,87 +1,88 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.liato.bankdroid.provider;
-
-/**
- * Defines what types banks are supported.
- * 
- * @since 8 jan 2011
- */
-public interface IBankTypes {
-	public final static int TESTBANK = 0;
-	public final static int SWEDBANK = 1;
-	public final static int NORDEA = 2;
-	public final static int ICABANKEN = 3;
-	public final static int LANSFORSAKRINGAR = 4;
-	public final static int HANDELSBANKEN = 5;
-	public final static int COOP = 6;
-	public final static int ICA = 7;
-	public final static int STATOIL = 8;
-	public final static int AVANZA = 9;
-	public final static int VILLABANKEN = 10;
-	public final static int AVANZAMINI = 11;
-	public final static int OKQ8 = 12;
-	public final static int EUROCARD = 13;
-	public final static int FIRSTCARD = 14;
-	public final static int PAYPAL = 15;
-	public final static int PAYSON = 16;
-	public final static int JOJO = 17;
-	public final static int IKANOBANK = 18;
-	public final static int STEAM = 19;
-	public final static int DINERSCLUB = 20;
-    public final static int SASEUROBONUSMASTERCARD = 21;
-    public final static int RIKSLUNCHEN = 22;
-    public final static int HEMKOP = 23;
-    public final static int SEB = 24;
-    public final static int NORDNET = 25;
-    public final static int SEVENDAY = 26;
-    public final static int OSUUSPANKKI = 27;
-    public final static int VOLVOFINANS = 28;
-    public final static int CSN = 29;
-    public final static int RESURSBANK = 30;
-    public final static int AMERICANEXPRESS = 31;
-    public final static int MCDONALDS = 32;
-    public final static int SAAB = 33;
-    public final static int WALLET = 34;
-    public final static int CHEVROLET = 35;
-    public final static int SJPRIO = 36;
-    public final static int OPEL = 37;
-    public final static int DJURGARDEN = 38;
-    public final static int QUINTESSENTIALLY = 39;
-    public final static int PLUSGIROT = 40;
-    public final static int SHELL = 41;
-    public final static int VOLKSWAGEN = 42;
-    public final static int AUDI = 43;
-    public final static int PREEM = 44;
-    public final static int SEAT = 45;
-    public final static int SKODA = 46;
-    public final static int IKEA = 47;
-    public final static int SPARBANKEN_SYD = 48;
-    public final static int SPARBANKEN_ORESUND = 49;
-    public final static int NORDNETDIREKT = 50;
-    public final static int SKANDIABANKEN = 51;
-    public final static int DANSKEBANK = 52;
-    public final static int NORDEA_DK = 53;
-    public final static int VASTTRAFIK = 54;
-    public final static int EVERYDAYCARD = 55;
-	public static final int AKELIUSINVEST = 56;
-    public static final int MENIGA = 57;
-    public static final int RIKSKORTET = 58;
-    public static final int BIOKLUBBEN = 59;
-    public static final int CHALMREST = 60;
-    public static final int MARGINALEN = 61;
-    public static final int AKELIUSSPAR = 62;
-}
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.provider;
+
+/**
+ * Defines what types banks are supported.
+ * 
+ * @since 8 jan 2011
+ */
+public interface IBankTypes {
+	public final static int TESTBANK = 0;
+	public final static int SWEDBANK = 1;
+	public final static int NORDEA = 2;
+	public final static int ICABANKEN = 3;
+	public final static int LANSFORSAKRINGAR = 4;
+	public final static int HANDELSBANKEN = 5;
+	public final static int COOP = 6;
+	public final static int ICA = 7;
+	public final static int STATOIL = 8;
+	public final static int AVANZA = 9;
+	public final static int VILLABANKEN = 10;
+	public final static int AVANZAMINI = 11;
+	public final static int OKQ8 = 12;
+	public final static int EUROCARD = 13;
+	public final static int FIRSTCARD = 14;
+	public final static int PAYPAL = 15;
+	public final static int PAYSON = 16;
+	public final static int JOJO = 17;
+	public final static int IKANOBANK = 18;
+	public final static int STEAM = 19;
+	public final static int DINERSCLUB = 20;
+    public final static int SASEUROBONUSMASTERCARD = 21;
+    public final static int RIKSLUNCHEN = 22;
+    public final static int HEMKOP = 23;
+    public final static int SEB = 24;
+    public final static int NORDNET = 25;
+    public final static int SEVENDAY = 26;
+    public final static int OSUUSPANKKI = 27;
+    public final static int VOLVOFINANS = 28;
+    public final static int CSN = 29;
+    public final static int RESURSBANK = 30;
+    public final static int AMERICANEXPRESS = 31;
+    public final static int MCDONALDS = 32;
+    public final static int SAAB = 33;
+    public final static int WALLET = 34;
+    public final static int CHEVROLET = 35;
+    public final static int SJPRIO = 36;
+    public final static int OPEL = 37;
+    public final static int DJURGARDEN = 38;
+    public final static int QUINTESSENTIALLY = 39;
+    public final static int PLUSGIROT = 40;
+    public final static int SHELL = 41;
+    public final static int VOLKSWAGEN = 42;
+    public final static int AUDI = 43;
+    public final static int PREEM = 44;
+    public final static int SEAT = 45;
+    public final static int SKODA = 46;
+    public final static int IKEA = 47;
+    public final static int SPARBANKEN_SYD = 48;
+    public final static int SPARBANKEN_ORESUND = 49;
+    public final static int NORDNETDIREKT = 50;
+    public final static int SKANDIABANKEN = 51;
+    public final static int DANSKEBANK = 52;
+    public final static int NORDEA_DK = 53;
+    public final static int VASTTRAFIK = 54;
+    public final static int EVERYDAYCARD = 55;
+	public static final int AKELIUSINVEST = 56;
+    public static final int MENIGA = 57;
+    public static final int RIKSKORTET = 58;
+    public static final int BIOKLUBBEN = 59;
+    public static final int CHALMREST = 60;
+    public static final int MARGINALEN = 61;
+    public static final int AKELIUSSPAR = 62;
+    public static final int SVENSKASPEL = 63;
+}

commit 692de329941056ae2d9d94c507764d3ce07ef1bc
Author: liato <x@x00.us>
Date:   Sun Jan 13 03:10:41 2013 +0100

    Fix Testbank URLs. Closes #198.

diff --git src/com/liato/bankdroid/banking/banks/TestBank.java src/com/liato/bankdroid/banking/banks/TestBank.java
index cd05ea6..defe192 100644
--- src/com/liato/bankdroid/banking/banks/TestBank.java
+++ src/com/liato/bankdroid/banking/banks/TestBank.java
@@ -86,7 +86,7 @@ public class TestBank extends Bank {
 		Matcher matcher;
 		try {
 		    
-            response = urlopen.open("http://www.nullbyte.eu/static/bankdroid/tests/testbank/accounts.htm");
+            response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/accounts.htm");
             matcher = reAccounts.matcher(response);
             while (matcher.find()) {
                 /*
@@ -134,7 +134,7 @@ public class TestBank extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("http://www.nullbyte.eu/static/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
+			response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit 3155c2960b86e3c656b993287780199015af5803
Author: Per Wigren <per.wigren@gmail.com>
Date:   Fri Jan 11 19:35:41 2013 +0100

    Display account type instead of numeric ID
    
    Instead of the numeric ID of the account, use its account type.
    Before: 98123621
    After: Investeringssparkonto

diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
index 03ca970..00ab62d 100644
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -50,7 +50,7 @@ public class Avanza extends Bank {
 	private static final String URL = "https://www.avanza.se/";
     private static final int BANKTYPE_ID = IBankTypes.AVANZA;
 	
-	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>([^<]+)<.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>(.+?)\\s(Private|Pro|Premium|Bas).*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	public Avanza(Context context) {
 		super(context);
@@ -114,12 +114,12 @@ public class Avanza extends Bank {
                  * GROUP                EXAMPLE DATA
                  * 1: ID                3505060
                  * 2: Type              Aktie- och fondkonto Premium Silver
-                 * 3: % since purchase  1,90
-                 * 4: Amount in SEK     820
+                 * 4: % since purchase  1,90
+                 * 5: Amount in SEK     820
                  *    
                  */    
-			    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+			    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(5)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 117911645e5ebb02ec9ebb89061ec142b7a2d1b3
Author: Per Wigren <per.wigren@gmail.com>
Date:   Fri Jan 11 11:43:23 2013 +0100

    New bank: Akelius Spar
    
    This is pretty much a search-replace change of the Akelius Invest
    support as they are very similar.

diff --git res/drawable/logo_akeliusspar.png res/drawable/logo_akeliusspar.png
new file mode 100644
index 0000000..00c3999
Binary files /dev/null and res/drawable/logo_akeliusspar.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 22dbf77..56c07dc 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -22,6 +22,7 @@ import android.database.Cursor;
 import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
+import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
@@ -99,6 +100,8 @@ public class BankFactory {
             return new TestBank(context);
         case IBankTypes.AKELIUSINVEST:
             return new AkeliusInvest(context);
+        case IBankTypes.AKELIUSSPAR:
+            return new AkeliusSpar(context);
         case IBankTypes.SWEDBANK:
             return new Swedbank(context);
 		case IBankTypes.NORDEA:
@@ -228,6 +231,7 @@ public class BankFactory {
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
 		banks.add(new AkeliusInvest(context));
+		banks.add(new AkeliusSpar(context));
 		banks.add(new Swedbank(context));
 		banks.add(new Nordea(context));
 		banks.add(new ICABanken(context));
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
new file mode 100644
index 0000000..d21ef0d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -0,0 +1,215 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>, first version by Snah@Swedroid 2012-01-06
+ * Modified for Akelius Spar by Per Wigren <per.wigren@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AkeliusSpar extends Bank {
+	private static final String TAG = "AkeliusSpar";
+	private static final String NAME = "Akelius Spar";
+	private static final String NAME_SHORT = "akeliusspar";
+	private static final String URL = "https://www.online.akeliusspar.se/";
+	private static final int BANKTYPE_ID = IBankTypes.AKELIUSSPAR;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "YYYYMMDDNNNN";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
+	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+><a[^?]+\\?selectedaccount=([^\"]+)\">([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	public AkeliusSpar(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public AkeliusSpar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String response = urlopen.open("https://www.online.akeliusspar.se/login.mws");
+        Matcher matcher = reLogintoken.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" logintoken.");
+        }
+        String strLogintoken = matcher.group(1);
+        
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("action", "login"));
+        postData.add(new BasicNameValuePair("logintoken", strLogintoken));
+        postData.add(new BasicNameValuePair("df_username", username));
+        postData.add(new BasicNameValuePair("df_password", password));
+        postData.add(new BasicNameValuePair("Language", "SV"));
+        postData.add(new BasicNameValuePair("IdleTime", "900"));
+   
+        return new LoginPackage(urlopen, postData, response, "https://www.online.akeliusspar.se/login.mws");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reError.matcher(response);
+			if (matcher.find()) {
+			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+			        throw new LoginException(errormsg);    
+			    }
+			    else {
+	                 throw new BankException(errormsg);    
+			    }
+			}
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
+			
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                ICA					AKELIUSINVEST
+                 * 1: ID                0000000000			Kontonamn
+                 * 2: Name              ICA KONTO			KontoID
+                 * 3: Disponibelt       00.000,00			Kontonummer
+                 * 4: Saldo             1.655,71			Valuta
+                 * 5: 										Tillgängligt belopp
+                 * 6: 										Saldo
+                 */			    
+//				Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//					if (matcher.group(1).length() > 24)  {
+//						matcher.group(1).replaceFirst("(", "(\n");
+//					}
+               
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), matcher.group(2).trim()));
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + matcher.group(2).trim());
+                account.setAliasfor(matcher.group(1).trim());
+                
+                accounts.add(account);      
+	                
+                balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+			}
+						if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+account.getId());
+			matcher = reTransactions.matcher(response);
+			/* 				ICA-banken	Akelius Invest
+			 * Beskrivning	1			2
+			 * Datum		2			1
+			 * Belopp		3			3
+			 */
+			
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        finally {
+            super.updateComplete();
+        }
+	}		
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 39fce5f..61541c2 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -83,4 +83,5 @@ public interface IBankTypes {
     public static final int BIOKLUBBEN = 59;
     public static final int CHALMREST = 60;
     public static final int MARGINALEN = 61;
+    public static final int AKELIUSSPAR = 62;
 }

commit 1f7cd9a465117051d8b4ec3b7dfcccedeedd790b
Author: Per Wigren <per.wigren@klarna.com>
Date:   Fri Jan 11 09:58:14 2013 +0100

    Add a negated balance entry.
    
    The reason for this is that with OKQ8-VISA, "Saldo" (balance) means
    "used credit" which is kind of backwards compared to how most other
    accounts work.

diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index 7c50886..9110fae 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -193,6 +193,7 @@ public class OKQ8 extends Bank {
 			if(matcher.find())
 			{
 			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2"));
+			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)).negate(), "4"));
 			}
 			/*
 			 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.

commit 243f6862ed9345ec12753e4bc115b222ed3176f8
Author: liato <x@x00.us>
Date:   Fri Jan 4 20:07:55 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 97215cf..43aa3ea 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.4-RC1" android:versionCode="144">
+	android:versionName="1.9.4" android:versionCode="146">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit cd8237c046e29708856ff1e4948cf1dcf7dba827
Author: liato <x@x00.us>
Date:   Sun Jan 13 22:59:50 2013 +0100

    Fix alias for seconday ICA Banken account.

diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index 37825ba..428c51f 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -158,7 +158,7 @@ public class ICABanken extends Bank {
                 mIdMappings.put(Integer.toString(accid), matcher.group(1).trim());           
                 accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), Integer.toString(accid)));
                 Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + accid);
-                account.setAliasfor(matcher.group(1).trim());
+                account.setAliasfor(Integer.toString(accid));
                 accounts.add(account);
 
                 balance = balance.add(Helpers.parseBalance(matcher.group(3)));

commit c7e04e23861ad68003e4dc49e50064291a8e1ec0
Author: Joakim Lundborg <lundborg@wrapp.com>
Date:   Sun Jan 13 22:04:37 2013 +0100

    Handle exception for uninitialized API key in pairing dialog

diff --git src/com/liato/bankdroid/PairApplicationsActivity.java src/com/liato/bankdroid/PairApplicationsActivity.java
index f785a2b..d78a77d 100644
--- src/com/liato/bankdroid/PairApplicationsActivity.java
+++ src/com/liato/bankdroid/PairApplicationsActivity.java
@@ -107,13 +107,16 @@ public class PairApplicationsActivity extends LockableActivity {
 		Editor editor = pref.edit();
 		editor.putBoolean("content_provider_enabled", true);
 		editor.commit();
-
-		String apiKey = BankTransactionsProvider.getApiKey(ctx);
-
-		// Make sure we actually have an generated API-key
-		if(apiKey == null || apiKey.equals("")) {
-			initialSetupApiKey(ctx);
-		}
+        String apiKey;
+
+        try{
+		    apiKey = BankTransactionsProvider.getApiKey(ctx);
+        }
+        catch (IllegalArgumentException e){
+            //Initialize API key if it is not set
+            initialSetupApiKey(ctx);
+            apiKey = BankTransactionsProvider.getApiKey(ctx);
+        }
 
 		intent.putExtra(IBankTransactionsProvider.API_KEY,apiKey);
 		setResult(RESULT_OK, intent);

commit 8ff319a6b4783ee95129799725fb4e26b5b2dcc5
Author: liato <x@x00.us>
Date:   Sun Jan 13 03:10:41 2013 +0100

    Fix Testbank URLs. Closes #198.

diff --git src/com/liato/bankdroid/banking/banks/TestBank.java src/com/liato/bankdroid/banking/banks/TestBank.java
index cd05ea6..defe192 100644
--- src/com/liato/bankdroid/banking/banks/TestBank.java
+++ src/com/liato/bankdroid/banking/banks/TestBank.java
@@ -86,7 +86,7 @@ public class TestBank extends Bank {
 		Matcher matcher;
 		try {
 		    
-            response = urlopen.open("http://www.nullbyte.eu/static/bankdroid/tests/testbank/accounts.htm");
+            response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/accounts.htm");
             matcher = reAccounts.matcher(response);
             while (matcher.find()) {
                 /*
@@ -134,7 +134,7 @@ public class TestBank extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("http://www.nullbyte.eu/static/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
+			response = urlopen.open("http://www.nullbyte.eu/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit e72201e9dbebd9cae3668e7f49d0f2bc51da46d2
Merge: cc5df8f 86e4bad
Author: liato <x@x00.us>
Date:   Sat Jan 12 17:43:42 2013 -0800

    Merge pull request #202 from Tuxie/master
    
    Add a negated "Saldo" to OKQ8-VISA.

commit 86e4badeef2b5bda039a98fb25761614ebdf047a
Author: Per Wigren <per.wigren@gmail.com>
Date:   Fri Jan 11 19:35:41 2013 +0100

    Display account type instead of numeric ID
    
    Instead of the numeric ID of the account, use its account type.
    Before: 98123621
    After: Investeringssparkonto

diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
index 03ca970..00ab62d 100644
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -50,7 +50,7 @@ public class Avanza extends Bank {
 	private static final String URL = "https://www.avanza.se/";
     private static final int BANKTYPE_ID = IBankTypes.AVANZA;
 	
-	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>([^<]+)<.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>(.+?)\\s(Private|Pro|Premium|Bas).*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	public Avanza(Context context) {
 		super(context);
@@ -114,12 +114,12 @@ public class Avanza extends Bank {
                  * GROUP                EXAMPLE DATA
                  * 1: ID                3505060
                  * 2: Type              Aktie- och fondkonto Premium Silver
-                 * 3: % since purchase  1,90
-                 * 4: Amount in SEK     820
+                 * 4: % since purchase  1,90
+                 * 5: Amount in SEK     820
                  *    
                  */    
-			    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+			    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(5)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit fbaba18f153d2942a5a9e676d9168f3d870beb13
Author: Per Wigren <per.wigren@gmail.com>
Date:   Fri Jan 11 11:43:23 2013 +0100

    New bank: Akelius Spar
    
    This is pretty much a search-replace change of the Akelius Invest
    support as they are very similar.

diff --git res/drawable/logo_akeliusspar.png res/drawable/logo_akeliusspar.png
new file mode 100644
index 0000000..00c3999
Binary files /dev/null and res/drawable/logo_akeliusspar.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 22dbf77..56c07dc 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -22,6 +22,7 @@ import android.database.Cursor;
 import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.banking.banks.AkeliusInvest;
+import com.liato.bankdroid.banking.banks.AkeliusSpar;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
@@ -99,6 +100,8 @@ public class BankFactory {
             return new TestBank(context);
         case IBankTypes.AKELIUSINVEST:
             return new AkeliusInvest(context);
+        case IBankTypes.AKELIUSSPAR:
+            return new AkeliusSpar(context);
         case IBankTypes.SWEDBANK:
             return new Swedbank(context);
 		case IBankTypes.NORDEA:
@@ -228,6 +231,7 @@ public class BankFactory {
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
 		banks.add(new AkeliusInvest(context));
+		banks.add(new AkeliusSpar(context));
 		banks.add(new Swedbank(context));
 		banks.add(new Nordea(context));
 		banks.add(new ICABanken(context));
diff --git src/com/liato/bankdroid/banking/banks/AkeliusSpar.java src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
new file mode 100644
index 0000000..d21ef0d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/AkeliusSpar.java
@@ -0,0 +1,215 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>, first version by Snah@Swedroid 2012-01-06
+ * Modified for Akelius Spar by Per Wigren <per.wigren@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AkeliusSpar extends Bank {
+	private static final String TAG = "AkeliusSpar";
+	private static final String NAME = "Akelius Spar";
+	private static final String NAME_SHORT = "akeliusspar";
+	private static final String URL = "https://www.online.akeliusspar.se/";
+	private static final int BANKTYPE_ID = IBankTypes.AKELIUSSPAR;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "YYYYMMDDNNNN";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
+	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+><a[^?]+\\?selectedaccount=([^\"]+)\">([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	public AkeliusSpar(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public AkeliusSpar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String response = urlopen.open("https://www.online.akeliusspar.se/login.mws");
+        Matcher matcher = reLogintoken.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" logintoken.");
+        }
+        String strLogintoken = matcher.group(1);
+        
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("action", "login"));
+        postData.add(new BasicNameValuePair("logintoken", strLogintoken));
+        postData.add(new BasicNameValuePair("df_username", username));
+        postData.add(new BasicNameValuePair("df_password", password));
+        postData.add(new BasicNameValuePair("Language", "SV"));
+        postData.add(new BasicNameValuePair("IdleTime", "900"));
+   
+        return new LoginPackage(urlopen, postData, response, "https://www.online.akeliusspar.se/login.mws");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reError.matcher(response);
+			if (matcher.find()) {
+			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+			        throw new LoginException(errormsg);    
+			    }
+			    else {
+	                 throw new BankException(errormsg);    
+			    }
+			}
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.online.akeliusspar.se/AccountPortfolio.mws");
+			
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                ICA					AKELIUSINVEST
+                 * 1: ID                0000000000			Kontonamn
+                 * 2: Name              ICA KONTO			KontoID
+                 * 3: Disponibelt       00.000,00			Kontonummer
+                 * 4: Saldo             1.655,71			Valuta
+                 * 5: 										Tillgängligt belopp
+                 * 6: 										Saldo
+                 */			    
+//				Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//					if (matcher.group(1).length() > 24)  {
+//						matcher.group(1).replaceFirst("(", "(\n");
+//					}
+               
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), matcher.group(2).trim()));
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + matcher.group(2).trim());
+                account.setAliasfor(matcher.group(1).trim());
+                
+                accounts.add(account);      
+	                
+                balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+			}
+						if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.online.akeliusspar.se/AccountStatement.mws?selectedaccount="+account.getId());
+			matcher = reTransactions.matcher(response);
+			/* 				ICA-banken	Akelius Invest
+			 * Beskrivning	1			2
+			 * Datum		2			1
+			 * Belopp		3			3
+			 */
+			
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        finally {
+            super.updateComplete();
+        }
+	}		
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 39fce5f..61541c2 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -83,4 +83,5 @@ public interface IBankTypes {
     public static final int BIOKLUBBEN = 59;
     public static final int CHALMREST = 60;
     public static final int MARGINALEN = 61;
+    public static final int AKELIUSSPAR = 62;
 }

commit 445aff85cd78aa0fac87121331b4cff3afa10bb6
Author: Per Wigren <per.wigren@klarna.com>
Date:   Fri Jan 11 09:58:14 2013 +0100

    Add a negated balance entry.
    
    The reason for this is that with OKQ8-VISA, "Saldo" (balance) means
    "used credit" which is kind of backwards compared to how most other
    accounts work.

diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index 7c50886..9110fae 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -193,6 +193,7 @@ public class OKQ8 extends Bank {
 			if(matcher.find())
 			{
 			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2"));
+			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)).negate(), "4"));
 			}
 			/*
 			 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.

commit cc5df8ff4fb058f43806ffd83fb7b8eeb08295ad
Author: liato <x@x00.us>
Date:   Fri Jan 4 20:07:55 2013 +0100

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index 97215cf..43aa3ea 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.4-RC1" android:versionCode="144">
+	android:versionName="1.9.4" android:versionCode="146">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 65dd2c035a7803aaf5314833b54673d2203e7888
Merge: 5e14ed3 bf03f21
Author: liato <x@x00.us>
Date:   Wed Jan 2 21:20:43 2013 -0800

    Merge pull request #200 from jsiverskog/master
    
    Bug fixes for Marginalen bank

commit bf03f21bb3aeeee3eeca2fd2ecd82f7b114e675d
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Wed Jan 2 15:09:59 2013 +0100

    Improve transaction regex to handle more messages and negative transaction values.

diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java src/com/liato/bankdroid/banking/banks/Marginalen.java
index f0054e4..906eec3 100644
--- src/com/liato/bankdroid/banking/banks/Marginalen.java
+++ src/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -41,7 +41,7 @@ public class Marginalen extends Bank {
 	private Pattern reGuid = Pattern.compile("name=\"guid\" value=\"([a-zA-Z0-9]+)\"");
 	private Pattern reAccountLink = Pattern.compile("href=\"(engine\\?[a-zA-Z0-9;=&._]+menuid=15[a-zA-Z0-9;=&._]+)\"");
 	private Pattern reAccounts = Pattern.compile("<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td>\\s*<a href=\"(engine\\?usecase=account[a-zA-Z0-9;=&._]+)\">([0-9]+)</a>\\s*</td>\\s*<td class=\"aright\">\\s*([0-9.,]+)\\s*[a-zA-Z&;]+\\s*</td>");
-	private Pattern reTransactions = Pattern.compile("href=\"engine\\?usecase=transactiondetails.*tabindex=\"4\">([0-9\\-]+)</a>\\s*</td>\\s*<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td class=\"aright\">\\s*([0-9\\.,]+)&nbsp;");
+	private Pattern reTransactions = Pattern.compile("href=\"engine\\?usecase=transactiondetails.*tabindex=\"4\">([0-9\\-]+)</a>\\s*</td>\\s*<td>\\s*(.*?)\\s*</td>\\s*<td class=\"aright\">\\s*([\\-0-9\\.,]+)&nbsp;");
 	
 	private String accountUrl = "";
     

commit 5e14ed32bebe45f4dc90b8f458ea80431f6e07b4
Author: liato <x@x00.us>
Date:   Sun Dec 30 03:58:01 2012 +0100

    Don't expect an account to have transactions.

diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index b17e5ba..c2551e8 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -186,19 +186,19 @@ public class Skandiabanken extends Bank {
 			
 			String accountJsonString = urlopen.open(accountTransactionsUrl);
 			JSONObject accountJSONObj = new JSONObject(accountJsonString);
-			JSONArray transactionsJSONArray = accountJSONObj.getJSONArray("transactions");
-			for (int i = 0; i< transactionsJSONArray.length(); i++)
-			{
-				JSONObject transactionJsonObj = transactionsJSONArray.getJSONObject(i);
-				String date = transactionJsonObj.getString("date"); // time and timestamp also exists in JSON
-				String ammountString = transactionJsonObj.getString("amount");
-				String description = transactionJsonObj.getString("merchant");
-				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
-				transactions.add(transaction);
+			JSONArray transactionsJSONArray = accountJSONObj.optJSONArray("transactions");
+			if (transactionsJSONArray != null) {
+			for (int i = 0; i< transactionsJSONArray.length(); i++) {
+    				JSONObject transactionJsonObj = transactionsJSONArray.getJSONObject(i);
+    				String date = transactionJsonObj.getString("date"); // time and timestamp also exists in JSON
+    				String ammountString = transactionJsonObj.getString("amount");
+    				String description = transactionJsonObj.getString("merchant");
+    				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
+    				transactions.add(transaction);
+    			}
+    			account.setTransactions(transactions);
 			}
 			
-			account.setTransactions(transactions);
-			
 		} catch (IOException e) {
 			throw new BankException("IOException " + e.getMessage());
 		} catch (JSONException e) {

commit 2593f5ab821c0de7747066ed92512eeb92b1bf8f
Merge: f59463b b0e0d51
Author: liato <x@x00.us>
Date:   Sat Dec 29 00:36:07 2012 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid
    
    * 'master' of github.com:liato/android-bankdroid:
      Fixes issue #113 Transactions over 1 000 SEK are now shown correct.

commit f59463bca260cb6068e67eb5f8c4d4807d15c23d
Author: liato <x@x00.us>
Date:   Sat Dec 29 00:35:54 2012 +0100

    Bump version. Update username hint for lansforsakringar.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8fd080e..97215cf 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.3" android:versionCode="143">
+	android:versionName="1.9.4-RC1" android:versionCode="144">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 51e426d..a908481 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -70,7 +70,7 @@ public class Lansforsakringar extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
     
     private static final String API_BASEURL = "https://mobil.lansforsakringar.se/appoutlet/";
 

commit b0e0d5190d6b552ae77707f494f827a9cbf4c052
Merge: c12a805 81421a2
Author: liato <x@x00.us>
Date:   Fri Dec 28 15:34:29 2012 -0800

    Merge pull request #195 from goober/master
    
    Fixes issue #113

commit c12a8055711bf09ff1d5f5deab6bf9c43d69f8c0
Author: liato <x@x00.us>
Date:   Fri Dec 28 19:27:31 2012 +0100

    Fix for Lansforsakringar.

diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 358fb05..51e426d 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -24,6 +24,7 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.UUID;
 import java.util.regex.Matcher;
@@ -31,6 +32,7 @@ import java.util.regex.Pattern;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.conn.EofSensorInputStream;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
@@ -75,6 +77,7 @@ public class Lansforsakringar extends Bank {
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reLoginToken = Pattern.compile("login:loginToken\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private ObjectMapper mObjectMapper = new ObjectMapper();
+    private HashMap<String, String> mAccountLedger = new HashMap<String, String>();
 
     public Lansforsakringar(Context context) {
         super(context);
@@ -200,15 +203,18 @@ public class Lansforsakringar extends Bank {
 
         urlopen = login();
 
+        mAccountLedger.clear();
         AccountsResponse ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)), AccountsResponse.class);
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
         	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
         	//a.getLedger() should be saved to database, used when fetching transactions
+        	mAccountLedger.put(a.getAccountNumber(), a.getLedger());
         	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
         }
         ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)), AccountsResponse.class);
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
         	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
+            mAccountLedger.put(a.getAccountNumber(), a.getLedger());
         	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
         }        
         if (accounts.isEmpty()) {
@@ -226,14 +232,20 @@ public class Lansforsakringar extends Bank {
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         //TODO: Get upcoming transactions?
         //TransactionsResponse tr = readJsonValue(API_BASEURL + "account/upcoming", objectAsJson(new UpcomingTransactionsRequest(account.getId())), TransactionsResponse.class);
-        TransactionsResponse tr = readJsonValue(API_BASEURL + "account/transaction", objectAsJson(new TransactionsRequest(0, "DEPIOSIT", account.getId())), TransactionsResponse.class);
         
-        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transaction t : tr.getTransactions()) {
-        	//TODO: Set locale to Europe/Stockholm on date?
-        	transactions.add(new Transaction(Helpers.formatDate(new Date(t.getTransactiondate())), t.getText(), new BigDecimal(t.getAmmount())));
+        try {
+            TransactionsResponse tr = readJsonValue(API_BASEURL + "account/transaction", objectAsJson(new TransactionsRequest(0, mAccountLedger.containsKey(account.getId()) ? mAccountLedger.get(account.getId()) : "DEPIOSIT", account.getId())), TransactionsResponse.class);
+            for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transaction t : tr.getTransactions()) {
+                //TODO: Set locale to Europe/Stockholm on date?
+                transactions.add(new Transaction(Helpers.formatDate(new Date(t.getTransactiondate())), t.getText(), new BigDecimal(t.getAmmount())));
+            }
+            account.setTransactions(transactions);        
+        } catch (BankException e) {
+            // No transactions for account if this fails.
+            // readJsonValue will print the stack trace
         }
-
-        account.setTransactions(transactions);        
+        
+        
         super.updateComplete();
     }       	
 }
\ No newline at end of file

commit d367892d85c4d83086d85fdc0985bd9cf91578de
Author: liato <x@x00.us>
Date:   Thu Dec 27 01:18:15 2012 +0100

    More spaces everywhere

diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index 2759068..37825ba 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -45,40 +45,40 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
-	private static final String TAG = "ICABanken";
-	private static final String NAME = "ICA Banken";
-	private static final String NAME_SHORT = "icabanken";
-	private static final String URL = "https://mobil.icabanken.se/";
-	private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
+    private static final String TAG = "ICABanken";
+    private static final String NAME = "ICA Banken";
+    private static final String NAME_SHORT = "icabanken";
+    private static final String URL = "https://mobil.icabanken.se/";
+    private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
     private static final boolean STATIC_BALANCE = false;
 
-	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private HashMap<String, String> mIdMappings = new HashMap<String, String>();
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 
-	public ICABanken(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
+    public ICABanken(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
         super.STATIC_BALANCE = STATIC_BALANCE;
-	}
+    }
 
-	public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
+    public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
 
     
     @Override
@@ -105,47 +105,47 @@ public class ICABanken extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://mobil2.icabanken.se/login/login.aspx");
     }
 
-	public Urllib login() throws LoginException, BankException {
-		try {
-			LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Matcher matcher = reError.matcher(response);
-			if (matcher.find()) {
-			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
-			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
-			        throw new LoginException(errormsg);    
-			    }
-			    else {
-	                 throw new BankException(errormsg);    
-			    }
-			}
-		}
-		catch (ClientProtocolException e) {
-			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			Log.e(TAG, "IOException: "+e.getMessage());
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}	
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            Matcher matcher = reError.matcher(response);
+            if (matcher.find()) {
+                String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+                if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+                    throw new LoginException(errormsg);    
+                }
+                else {
+                     throw new BankException(errormsg);    
+                }
+            }
+        }
+        catch (ClientProtocolException e) {
+            Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            Log.e(TAG, "IOException: "+e.getMessage());
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }    
+    
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
 
-		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
-			matcher = reBalance.matcher(response);
-			int accid = 0;
-			while (matcher.find()) {
+        urlopen = login();
+        String response = null;
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
+            matcher = reBalance.matcher(response);
+            int accid = 0;
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
@@ -154,8 +154,8 @@ public class ICABanken extends Bank {
                  * 3: Disponibelt       00.000,00
                  * 4: Saldo             1.655,71
                  *  
-                 */			    
-			    mIdMappings.put(Integer.toString(accid), matcher.group(1).trim());           
+                 */                
+                mIdMappings.put(Integer.toString(accid), matcher.group(1).trim());           
                 accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), Integer.toString(accid)));
                 Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + accid);
                 account.setAliasfor(matcher.group(1).trim());
@@ -163,43 +163,43 @@ public class ICABanken extends Bank {
 
                 balance = balance.add(Helpers.parseBalance(matcher.group(3)));
                 accid++;
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-	}
+            }
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+    }
 
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-		if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
-		String accountId = mIdMappings.get(account.getId());
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://mobil2.icabanken.se/account/account.aspx?id="+accountId);
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction(matcher.group(2).trim().substring(8), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+        String accountId = mIdMappings.get(account.getId());
+        String response = null;
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://mobil2.icabanken.se/account/account.aspx?id="+accountId);
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                transactions.add(new Transaction(matcher.group(2).trim().substring(8), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
         finally {
             super.updateComplete();
         }
-	}		
+    }
 }
\ No newline at end of file

commit c5fb71dd878c8729c145766587052dfde83f5e95
Author: liato <x@x00.us>
Date:   Thu Dec 27 01:14:03 2012 +0100

    Fix for ICA Banken maybe.

diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index 6441481..2759068 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -59,6 +60,7 @@ public class ICABanken extends Bank {
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private HashMap<String, String> mIdMappings = new HashMap<String, String>();
 
 	public ICABanken(Context context) {
 		super(context);
@@ -153,6 +155,7 @@ public class ICABanken extends Bank {
                  * 4: Saldo             1.655,71
                  *  
                  */			    
+			    mIdMappings.put(Integer.toString(accid), matcher.group(1).trim());           
                 accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), Integer.toString(accid)));
                 Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + accid);
                 account.setAliasfor(matcher.group(1).trim());
@@ -176,11 +179,12 @@ public class ICABanken extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+		if (account.getId().startsWith("a:") || !mIdMappings.containsKey(account.getId())) return; // No transactions for "saldo"-accounts
+		String accountId = mIdMappings.get(account.getId());
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil2.icabanken.se/account/account.aspx?id="+account.getId());
+			response = urlopen.open("https://mobil2.icabanken.se/account/account.aspx?id="+accountId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit 81421a2f2c5659976d5ee7838f3e2552e71cd083
Author: Mathias Åhsberg <mathias.ahsberg@gmail.com>
Date:   Sun Dec 2 18:26:06 2012 +0100

    Fixes issue #113 Transactions over 1 000 SEK are now shown correct.
    
    Fixes issue # 113 that transactions over 1 000 SEK are cropped.

diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 3f97c8c..c906006 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -1,193 +1,196 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-
-import android.content.Context;
-import android.text.Html;
-import android.util.Log;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.Urllib;
-
-public class AmericanExpress extends Bank {
-	private static final String TAG = "AmericanExpress";
-	private static final String NAME = "American Express";
-	private static final String NAME_SHORT = "americanexpress";
-	private static final String URL = "https://home.americanexpress.com/home/se/home_c.shtml";
-	private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
-	
-	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?(\\d{1,},?\\d{1,}\\s*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
-	private String response = null;
-
-	public AmericanExpress(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-		this(context);
-		this.update(username, password);
-	}
-
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(true, true);
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-
-        postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
-        postData.add(new BasicNameValuePair("DestPage", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
-        postData.add(new BasicNameValuePair("Face", "sv_SE"));
-        postData.add(new BasicNameValuePair("brandname", ""));
-        postData.add(new BasicNameValuePair("TARGET", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
-        postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
-        postData.add(new BasicNameValuePair("Logon", "Continue..."));
-        postData.add(new BasicNameValuePair("devicePrint", "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
-        postData.add(new BasicNameValuePair("REMEMBERME", "on"));
-        postData.add(new BasicNameValuePair("manage", "option1"));
-        postData.add(new BasicNameValuePair("UserID", username));
-        postData.add(new BasicNameValuePair("USERID", username));
-        postData.add(new BasicNameValuePair("Password", password));
-        postData.add(new BasicNameValuePair("PWD", password));
-
-        return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
-    }
-
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		try {
-		    LoginPackage lp = preLogin();
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			if (!response.contains("Your Personal Cards")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		
-		Log.d(TAG, "Logging in...");
-		urlopen = login();
-        Log.d(TAG, "Url after login: " + urlopen.getCurrentURI());
-		
-		Matcher matcher = reAccounts.matcher(response);
-		
-		while (matcher.find()) {
-            /*
-             * Capture groups:
-             * GROUP                    EXAMPLE DATA
-             * 1: Account number        XXX-11111
-             * 2: ID                    0
-             * 3: Name                  SAS EuroBonus American Express&reg; Card
-             * 4: Amount                1.111,11 kr
-             * 
-             */   			    
-			accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
-			        Helpers.parseBalance(matcher.group(4)).negate(),
-			        matcher.group(2).trim()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
-		}
-		
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	    super.updateComplete();
-	}
-
-	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
-
-		try {
-			response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
-			Matcher matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Date                  17 jan 2011
-                 * 2: Specification         xx
-                 * 3: Amount                2,00&nbsp;kr
-                 * 
-                 */
-                SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
-                SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
-                Date transactionDate;
-                try {
-                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
-                    String strDate = sdfTo.format(transactionDate);
-                    transactions.add(new Transaction(strDate,
-                                                     Html.fromHtml(matcher.group(2)).toString().trim(),
-                                                     Helpers.parseBalance(matcher.group(3).trim()).negate()));
-                }
-                catch (ParseException e) {
-                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
-                }
-			}
-			account.setTransactions(transactions);
-		} catch (ClientProtocolException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}	
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AmericanExpress extends Bank {
+	private static final String TAG = "AmericanExpress";
+	private static final String NAME = "American Express";
+	private static final String NAME_SHORT = "americanexpress";
+	private static final String URL = "https://home.americanexpress.com/home/se/home_c.shtml";
+	private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
+	
+	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?([0-9.,\\s]*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	private String response = null;
+
+	public AmericanExpress(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true, true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+
+        postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
+        postData.add(new BasicNameValuePair("DestPage", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("Face", "sv_SE"));
+        postData.add(new BasicNameValuePair("brandname", ""));
+        postData.add(new BasicNameValuePair("TARGET", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
+        postData.add(new BasicNameValuePair("Logon", "Continue..."));
+        postData.add(new BasicNameValuePair("devicePrint", "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
+        postData.add(new BasicNameValuePair("REMEMBERME", "on"));
+        postData.add(new BasicNameValuePair("manage", "option1"));
+        postData.add(new BasicNameValuePair("UserID", username));
+        postData.add(new BasicNameValuePair("USERID", username));
+        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("PWD", password));
+
+        return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
+			if (!response.contains("Your Personal Cards")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		Log.d(TAG, "Logging in...");
+		urlopen = login();
+        Log.d(TAG, "Url after login: " + urlopen.getCurrentURI());
+		
+		Matcher matcher = reAccounts.matcher(response);
+		
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Account number        XXX-11111
+             * 2: ID                    0
+             * 3: Name                  SAS EuroBonus American Express&reg; Card
+             * 4: Amount                1.111,11 kr
+             * 
+             */   			    
+			accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
+			        Helpers.parseBalance(matcher.group(4)).negate(),
+			        matcher.group(2).trim()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
+		}
+		
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	    super.updateComplete();
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		try {
+			response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
+			Matcher matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			
+			SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy", new Locale("sv-SE"));
+            SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
+            Date transactionDate;
+			
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Date                  17 jan 2011
+                 * 2: Specification         xx
+                 * 3: Amount                1.582,00&nbsp;kr
+                 * 
+                 */
+                try {
+                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
+                    String strDate = sdfTo.format(transactionDate);
+                    transactions.add(new Transaction(strDate,
+                                                     Html.fromHtml(matcher.group(2)).toString().trim(),
+                                                     Helpers.parseBalance(matcher.group(3).trim()).negate()));
+                }
+                catch (ParseException e) {
+                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                }
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}	
 }
\ No newline at end of file

commit 8f608f8dde273b64065646e0c769e99d6c90f525
Merge: 8c708d1 b05c93e
Author: liato <x@x00.us>
Date:   Thu Nov 29 02:09:14 2012 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid

commit 8c708d1db2dbf293f04946c49609d79d32547439
Author: liato <x@x00.us>
Date:   Thu Nov 29 02:08:49 2012 +0100

    Bump version code.

diff --git AndroidManifest.xml AndroidManifest.xml
index 647a9e2..8fd080e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.2" android:versionCode="141">
+	android:versionName="1.9.3" android:versionCode="143">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 537462e4a444a7017b1e983f585de18d3622e5e0
Author: liato <x@x00.us>
Date:   Thu Nov 29 01:51:25 2012 +0100

    Bump version code.

diff --git AndroidManifest.xml AndroidManifest.xml
index 73cec8f..647a9e2 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.1" android:versionCode="140">
+	android:versionName="1.9.2" android:versionCode="141">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit e35efd70c1bd31bfe43511cde6af939d9016601f
Author: liato <x@x00.us>
Date:   Thu Nov 29 01:36:48 2012 +0100

    Fix username hint for Lansforsakringar. Closes #185.

diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index d6131ea..358fb05 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -68,7 +68,7 @@ public class Lansforsakringar extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
     
     private static final String API_BASEURL = "https://mobil.lansforsakringar.se/appoutlet/";
 

commit 4a2b2ec4330f973c4c25516f6a16fdd3768cd9aa
Author: liato <x@x00.us>
Date:   Thu Nov 29 01:34:19 2012 +0100

    Use counter as account id for ICA Banken. Closes #83.

diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index f4d8edc..6441481 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -52,13 +52,11 @@ public class ICABanken extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-    private static final boolean STATIC_BALANCE = true;
+    private static final boolean STATIC_BALANCE = false;
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
@@ -144,22 +142,24 @@ public class ICABanken extends Bank {
 		try {
 			response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
 			matcher = reBalance.matcher(response);
+			int accid = 0;
 			while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
-                 * 1: ID                0000000000
+                 * 1: ID                0000000000 - not static?
                  * 2: Name              ICA KONTO
                  * 3: Disponibelt       00.000,00
                  * 4: Saldo             1.655,71
                  *  
                  */			    
-                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
-                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + matcher.group(1).trim());
+                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), Integer.toString(accid)));
+                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + accid);
                 account.setAliasfor(matcher.group(1).trim());
                 accounts.add(account);
 
                 balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+                accid++;
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit f9b645e4158dc4e1f2d9e4ddac916c8ff8b8e913
Author: liato <x@x00.us>
Date:   Thu Nov 29 01:14:33 2012 +0100

    Fix password encryption for 4.2+. Closes #194.

diff --git src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
index 4c067f6..5648b38 100644
--- src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
+++ src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -38,7 +38,12 @@ public class SimpleCrypto {
 
 	private static byte[] getRawKey(byte[] seed) throws Exception {
 		KeyGenerator kgen = KeyGenerator.getInstance("AES");
-		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+		SecureRandom sr;
+		if (android.os.Build.VERSION.SDK_INT >= 17) {
+			sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
+		} else {
+			sr = SecureRandom.getInstance("SHA1PRNG");
+		}
 		sr.setSeed(seed);
 	    kgen.init(128, sr); // 192 and 256 bits may not be available
 	    SecretKey skey = kgen.generateKey();

commit b05c93eb1277d54808fb8dbcc0f4b0e8ffe7f006
Merge: 0cf8fab a638f2a
Author: liato <x@x00.us>
Date:   Thu Nov 15 16:02:40 2012 -0800

    Merge pull request #191 from jsiverskog/master
    
    Support for Marginalen Bank

commit a638f2af7ddf56912844e2d8bbd0f475b0a61718
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Mon Nov 12 21:19:16 2012 +0100

    Revert some lines that were messed up by previous merge.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 1aeb5fd..22dbf77 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -72,7 +72,6 @@ import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
-import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
@@ -246,7 +245,7 @@ public class BankFactory {
         banks.add(new PayPal(context));
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
-        banks.add(new Steam(context));
+        //banks.add(new Steam(context));
         banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
         banks.add(new EurobonusMastercard(context));

commit 4d48233a2acbff13ec6071df30b3ccf1dff01e59
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Mon Nov 12 21:15:27 2012 +0100

    Remove unused import, update logo.

diff --git res/drawable/logo_marginalen.png res/drawable/logo_marginalen.png
index 89a9272..5573a3b 100644
Binary files res/drawable/logo_marginalen.png and res/drawable/logo_marginalen.png differ
diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java src/com/liato/bankdroid/banking/banks/Marginalen.java
index 1a88817..f0054e4 100644
--- src/com/liato/bankdroid/banking/banks/Marginalen.java
+++ src/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -14,7 +14,6 @@ import org.apache.http.protocol.HTTP;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -146,7 +145,7 @@ public class Marginalen extends Bank {
                  * 1: Name              Högräntekonto
                  * 2: URL               engine?usecase=account&amp;command=transactions&amp;guid=mCmupGvnAAJuC76MGuuRnwCC&amp;commandorigin=0.account_private_viewhandler&amp;account_table=0&amp;hash=Be2HxFargpk2m0BI2tShAACC
                  * 3: ID                92351124972
-                 * 4: Amount            200.000,00
+                 * 4: Amount            100.000,00
                  *  
                  */
 				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2), Long.parseLong(matcher.group(3)));

commit b612037c5b6b2fe7e9ebee46f987114f4aaf2812
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Mon Nov 12 21:00:35 2012 +0100

    Marginalen bank now working.

diff --git res/drawable/logo_marginalen.png res/drawable/logo_marginalen.png
index 00c3999..89a9272 100644
Binary files res/drawable/logo_marginalen.png and res/drawable/logo_marginalen.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index aa2419e..1aeb5fd 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -28,6 +28,7 @@ import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.CSN;
+import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.Coop;
 import com.liato.bankdroid.banking.banks.DanskeBank;
@@ -44,7 +45,7 @@ import com.liato.bankdroid.banking.banks.ICABanken;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
-import com.liato.bankdroid.banking.banks.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java src/com/liato/bankdroid/banking/banks/Marginalen.java
index cd4cc72..1a88817 100644
--- src/com/liato/bankdroid/banking/banks/Marginalen.java
+++ src/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -1,32 +1,198 @@
 package com.liato.bankdroid.banking.banks;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
 import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Marginalen extends Bank {
 	private static final String TAG = "Marginalen";
     private static final String NAME = "Marginalen Bank";
     private static final String NAME_SHORT = "marginalen";
-    private static final String URL = "https://secure1.marginalen.se/marginalen/engine";
+    private static final String BASE_URL = "https://secure1.marginalen.se/marginalen/";
+	private static final int BANKTYPE_ID = IBankTypes.MARGINALEN;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+	
+	private Pattern reLoginLink = Pattern.compile("href=\"(engine\\?usecase=pin&[a-zA-Z0-9;=&._]+)");
+	private Pattern reHash = Pattern.compile("name=\"hash\" value=\"([a-zA-Z0-9]+)\"");
+	private Pattern reGuid = Pattern.compile("name=\"guid\" value=\"([a-zA-Z0-9]+)\"");
+	private Pattern reAccountLink = Pattern.compile("href=\"(engine\\?[a-zA-Z0-9;=&._]+menuid=15[a-zA-Z0-9;=&._]+)\"");
+	private Pattern reAccounts = Pattern.compile("<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td>\\s*<a href=\"(engine\\?usecase=account[a-zA-Z0-9;=&._]+)\">([0-9]+)</a>\\s*</td>\\s*<td class=\"aright\">\\s*([0-9.,]+)\\s*[a-zA-Z&;]+\\s*</td>");
+	private Pattern reTransactions = Pattern.compile("href=\"engine\\?usecase=transactiondetails.*tabindex=\"4\">([0-9\\-]+)</a>\\s*</td>\\s*<td>\\s*([a-zA-ZåäöÅÄÖ0-9]+)\\s*</td>\\s*<td class=\"aright\">\\s*([0-9\\.,]+)&nbsp;");
+	
+	private String accountUrl = "";
     
+	String response;
     public Marginalen(Context context) {
         super(context);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
-//        super.BANKTYPE_ID = BANKTYPE_ID;
-//        super.URL = URL;
-//        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-//        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-//        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+    
+    public Marginalen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        Matcher matcher;
+        response = urlopen.open(BASE_URL + "engine");
+        matcher = reLoginLink.matcher(response);
+
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " login link.");
+        }
+        String url = BASE_URL + matcher.group(1);
+        url = url.replaceAll("&amp;", "&");
+        response = urlopen.open(url);
+
+        matcher = reHash.matcher(response);
+        if (!matcher.find())
+        	throw new BankException(res.getText(R.string.unable_to_find).toString() + " hash value.");
+
+        String hash = matcher.group(1);
+
+        matcher = reGuid.matcher(response);
+        if (!matcher.find())
+        	throw new BankException(res.getText(R.string.unable_to_find).toString() + " GUID value.");
+
+        String guid = matcher.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("usecase", "base"));
+        postData.add(new BasicNameValuePair("command", "formcommand"));
+        postData.add(new BasicNameValuePair("commandorigin", "0.pin_logon_step1_view_handler"));
+        postData.add(new BasicNameValuePair("guid", guid));
+        postData.add(new BasicNameValuePair("hash", hash));
+        postData.add(new BasicNameValuePair("userId", username));
+        postData.add(new BasicNameValuePair("pin", password));
+
+        return new LoginPackage(urlopen, postData, response, BASE_URL + "engine");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+    	try {
+    		LoginPackage lp = preLogin();
+    		response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+    		
+    		if (response.contains("Felmeddelande")) {
+    			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+    		}
+    		
+    		Matcher matcher;
+    		matcher = reAccountLink.matcher(response);
+    		if (!matcher.find())
+            	throw new BankException(res.getText(R.string.unable_to_find).toString() + " accounts link.");
+    		accountUrl = BASE_URL + matcher.group(1).replaceAll("&amp;", "&");
+    	}
+    	catch (ClientProtocolException e) {
+    		throw new BankException("ClientProtolException:" + e.getMessage());
+    	}
+    	catch (IOException e) {
+    		throw new BankException("IOException:" + e.getMessage());
+    	}
+    	return urlopen;
     }
     
     @Override
     public void update() throws BankException, LoginException, BankChoiceException {
-        super.update();
+    	super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		Matcher matcher;
+		
+		try {
+	        response = urlopen.open(accountUrl);
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Name              Högräntekonto
+                 * 2: URL               engine?usecase=account&amp;command=transactions&amp;guid=mCmupGvnAAJuC76MGuuRnwCC&amp;commandorigin=0.account_private_viewhandler&amp;account_table=0&amp;hash=Be2HxFargpk2m0BI2tShAACC
+                 * 3: ID                92351124972
+                 * 4: Amount            200.000,00
+                 *  
+                 */
+				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2), Long.parseLong(matcher.group(3)));
+				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+				accounts.add(account);
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+	      super.updateComplete();
+		}
+		
     }
+    
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		Matcher matcher;
+		try {
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            response = urlopen.open(BASE_URL + account.getId().replaceAll("&amp;", "&"));
+
+            matcher = reTransactions.matcher(response);
+            while (matcher.find()) {
+            	/*
+            	 * Capture groups:
+            	 * GROUP                    EXAMPLE DATA
+            	 * 1: Date                  2011-04-06
+            	 * 2: Specification         Pressbyran
+            	 * 3: Amount                -20
+            	 * 
+            	 */	                
+            	transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+            }
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
 }

commit c24399e4e40a9b58e44bcaa3c2b4131fbab62532
Merge: 0b155e7 0cf8fab
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Mon Nov 12 20:54:30 2012 +0100

    Merge branch 'master' of git://github.com/liato/android-bankdroid
    
    Conflicts:
            src/com/liato/bankdroid/banking/BankFactory.java
            src/com/liato/bankdroid/provider/IBankTypes.java

commit 0cf8fabdc5c6e58bd1fd9c5397e52e1c30f3a93b
Merge: a07622c b490a7e
Author: liato <x@x00.us>
Date:   Thu Nov 1 14:32:23 2012 -0700

    Merge pull request #188 from oskla129/master
    
    Fix for ICA

commit b490a7ea22e4f2f6d35d3d3ac02599cd3f3a9ab6
Author: oskla129 <osk.larsson@gmail.com>
Date:   Sun Oct 28 19:11:31 2012 +0100

    Fix for ICA

diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index 6a772ee..f74d6d8 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -51,10 +51,13 @@ public class ICA extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
-	private Pattern reAccounts = Pattern.compile("lblAvaibleAmount\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>\\s*([^<]+).*?amount\">([^<]+)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("<td><span>Saldo</span></td>\\s*<td class=\"td_right\"><span>([^\\s]+)\\s*kr", Pattern.CASE_INSENSITIVE);
+	private Pattern rePreTransactions = Pattern.compile("<h2>Transaktioner</h2>(.*?)<h2>Information om kredit</h2>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<td><span>(\\d{4}-\\d{2}-\\d{2})</span></td>\\s*<td><span>([^<]+)</span></td>\\s*<td class=\"td_right\"><span>([^<]+)</span></td>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reLoginError = Pattern.compile("login-error[^>]+>(.+?)<");
+	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+	private Pattern reLoginError = Pattern.compile("loginError\">([^<]+)</span>");
+	
 	public ICA(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -76,28 +79,29 @@ public class ICA extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
-        String response = urlopen.open("https://www.ica.se/Logga-in/");
+        String response = urlopen.open("https://www.ica.se/logga-in/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
         }
         String strViewState = matcher.group(1);
+        
+        // Find __EVENTVALIDATION
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+        	throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation");
+        }
+        String strEventValidation = matcher.group(1);
+        
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", "LoginView1$btnModalLogin"));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ctl00$fakie", "0"));
-        postData.add(new BasicNameValuePair("q", "Sök"));
-        postData.add(new BasicNameValuePair("appendUrlString", ""));
-        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$btnLogin", "Logga in"));
-        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$txtCivicRegistrationNumber", ""));
-        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$txtEmail", ""));
-        postData.add(new BasicNameValuePair("footer-q", "Sök"));
-        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPersno", username));
-        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPasswd", password));
-
-        return new LoginPackage(urlopen, postData, response, "https://www.ica.se/Logga-in/");
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        postData.add(new BasicNameValuePair("LoginView1$userName", username));
+        postData.add(new BasicNameValuePair("LoginView1$password", password));
+        
+        return new LoginPackage(urlopen, postData, response, "https://www.ica.se/logga-in/");
     }
 
 	@Override
@@ -105,6 +109,7 @@ public class ICA extends Bank {
 		try {
 			LoginPackage lp = preLogin();
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
 			Matcher matcher = reLoginError.matcher(response);
 			if (matcher.find()) {
 				throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
@@ -129,18 +134,22 @@ public class ICA extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://www.ica.se/Mina-sidor/Konto--Saldo/");
+			response = urlopen.open("https://www.ica.se/mina-sidor/");
 			matcher = reAccounts.matcher(response);
 			if (matcher.find()) {
 				Account account = new Account("ICA Kort", Helpers.parseBalance(matcher.group(1)), "1");
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-				matcher = reTransactions.matcher(response);
-				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-				while (matcher.find()) {
-					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+				matcher = rePreTransactions.matcher(response);
+				if (matcher.find()) {
+					String temp = matcher.group(1);
+					matcher = reTransactions.matcher(temp);
+					ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+					while (matcher.find()) {
+						transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+					}
+					account.setTransactions(transactions);
+					accounts.add(account);
 				}
-				account.setTransactions(transactions);
-				accounts.add(account);
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit a07622c069109a5015ce269c7ecd52e6f291334c
Author: liato <x@x00.us>
Date:   Sat Oct 20 17:41:27 2012 +0200

    Fix weblogin for Lansforsakringar. Maybe.

diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
index 8d5fe7e..d6131ea 100644
--- src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -34,15 +34,10 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
-import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationConfig;
 import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -74,25 +69,11 @@ public class Lansforsakringar extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    
+    private static final String API_BASEURL = "https://mobil.lansforsakringar.se/appoutlet/";
 
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+>([^<]+)<.*?<td class=\"right\"[^>]+>([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountsLoans = Pattern.compile("LoanNumber=[^>]+>([^<]+)</a></td><td class=\"left\" width=\"25%\">([0-9.]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern rePension = Pattern.compile("class=\"portlet-menu-item\" [^>]+>(.*)</a></td><td class=\"left\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
-    private Pattern reHiddenToken = Pattern.compile("name=\"_token\" value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reUrl = Pattern.compile("<li class=\"bank\\s*\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("[^>]+>(\\d{4}-\\d{2}-\\d{2})<.*(\\d{4}-\\d{2}-\\d{2})<.*<span title=\"([^\"]+)\".*</span></td><td class=\"left\"><span title=\"([^\"]+)\".*</span></td><td class=\"right nowrap\" style=\"width:90px\">([^<]+)</td>.*style=\"width:90px\">([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private String accountsUrl = null;
-    private String mRequestToken = null;
-    private String mViewState = null;
-    private String host = null;
-    private boolean mFirstTransactionPage = true;
-    
-    
-    
+    private Pattern reLoginToken = Pattern.compile("login:loginToken\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private ObjectMapper mObjectMapper = new ObjectMapper();
 
     public Lansforsakringar(Context context) {
@@ -120,72 +101,50 @@ public class Lansforsakringar extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib(false, true);
-        String response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
+        Urllib weblogin = new Urllib(false, true);
+        String response = weblogin.open("https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
         }
-        mViewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
+        String viewState = matcher.group(1);
+        matcher = reLoginToken.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" LoginToken.");
         }
-        String strEventValidation = matcher.group(1);
+        String loginToken = matcher.group(1);
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("inputPersonalNumber", username));
-        postData.add(new BasicNameValuePair("inputPinCode", password));
-        postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", mViewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
-        postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-        return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
+        postData.add(new BasicNameValuePair("login:userId", username));
+        postData.add(new BasicNameValuePair("login:pin", password));
+        postData.add(new BasicNameValuePair("login", "login"));
+        postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
+        postData.add(new BasicNameValuePair("login:time", Long.toString(System.currentTimeMillis())));
+        postData.add(new BasicNameValuePair("login:loginToken", loginToken));
+        postData.add(new BasicNameValuePair("login:loginButton", "login:loginButton"));
+        return new LoginPackage(weblogin, postData, response, weblogin.getCurrentURI());
     }
 
     public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Felaktig inloggning")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-
-            Matcher matcher = reToken.matcher(response);
-            if (!matcher.find()) {
-                //throw new BankException(res.getText(R.string.unable_to_find).toString()+" token0.");
-            } else {
-            	mRequestToken = matcher.group(1);
-            }
-
-            matcher = reUrl.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
-            }
-
-            host = urlopen.getCurrentURI().split("/")[2];
-            accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + getRequestToken();
-            if (!accountsUrl.contains("https://")) {
-                accountsUrl = "https://" + host + accountsUrl;
-            }
+        urlopen = new Urllib();
+        urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
+        urlopen.addHeader("DeviceId", UUID.randomUUID().toString());
+        urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
+        //TODO: Change user-agent to "lf-android-app" if they block Bankdroid
+        urlopen.setUserAgent("bankdroid");
 
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
+        NumberResponse nr = readJsonValue(API_BASEURL + "security/client", null, NumberResponse.class);
+        ChallengeResponse cr = readJsonValue(API_BASEURL + "security/client", objectAsJson(new ChallengeRequest(nr.getNumber(), nr.getNumberPair(), generateChallenge(nr.getNumber()))), ChallengeResponse.class);
+        urlopen.addHeader("Ctoken", cr.getToken());
+        try {
+        	LoginResponse lr = readJsonValue(API_BASEURL + "security/user", objectAsJson(new LoginRequest(username, password)), LoginResponse.class);
+        	urlopen.addHeader("Utoken", lr.getTicket());
+		} catch (Exception e) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
         return urlopen;
     }
     
-    private String getRequestToken() {
-    	return mRequestToken != null ? mRequestToken : "";
-    }
     
     private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
         try {
@@ -239,25 +198,15 @@ public class Lansforsakringar extends Bank {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
         }
 
-        urlopen = new Urllib();
-        urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
-        urlopen.addHeader("DeviceId", UUID.randomUUID().toString());//"9ba6991346f2f8e9");
-        urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
-        urlopen.setUserAgent("bankdroid"); // Android app uses "lf-android-app"
-
-        NumberResponse nr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/security/client", null, NumberResponse.class);
-        ChallengeResponse cr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/security/client", objectAsJson(new ChallengeRequest(nr.getNumber(), nr.getNumberPair(), generateChallenge(nr.getNumber()))), ChallengeResponse.class);
-        urlopen.addHeader("Ctoken", cr.getToken());
-        LoginResponse lr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/security/user", objectAsJson(new LoginRequest(username, password)), LoginResponse.class);
-        urlopen.addHeader("Utoken", lr.getTicket());
+        urlopen = login();
 
-        AccountsResponse ar = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)), AccountsResponse.class);
+        AccountsResponse ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)), AccountsResponse.class);
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
         	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
         	//a.getLedger() should be saved to database, used when fetching transactions
         	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
         }
-        ar = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)), AccountsResponse.class);
+        ar = readJsonValue(API_BASEURL + "account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)), AccountsResponse.class);
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
         	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
         	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
@@ -276,11 +225,11 @@ public class Lansforsakringar extends Bank {
         
         ArrayList<Transaction> transactions = new ArrayList<Transaction>();
         //TODO: Get upcoming transactions?
-        //TransactionsResponse tr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/upcoming", objectAsJson(new UpcomingTransactionsRequest(account.getId())), TransactionsResponse.class);
-        TransactionsResponse tr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/transaction", objectAsJson(new TransactionsRequest(0, "DEPIOSIT", account.getId())), TransactionsResponse.class);
+        //TransactionsResponse tr = readJsonValue(API_BASEURL + "account/upcoming", objectAsJson(new UpcomingTransactionsRequest(account.getId())), TransactionsResponse.class);
+        TransactionsResponse tr = readJsonValue(API_BASEURL + "account/transaction", objectAsJson(new TransactionsRequest(0, "DEPIOSIT", account.getId())), TransactionsResponse.class);
         
         for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transaction t : tr.getTransactions()) {
-        	//TODO: Set locale on date?
+        	//TODO: Set locale to Europe/Stockholm on date?
         	transactions.add(new Transaction(Helpers.formatDate(new Date(t.getTransactiondate())), t.getText(), new BigDecimal(t.getAmmount())));
         }
 

commit 6dd58b51671b10600ad0ad6676e31222797a7ef7
Author: liato <x@x00.us>
Date:   Sat Oct 20 05:17:50 2012 +0200

    Rewrite Lansforsakringar to use their internal api instead. Automatic website login is not fixed.

diff --git .classpath .classpath
index a139d9f..e42619e 100644
--- .classpath
+++ .classpath
@@ -6,5 +6,8 @@
 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 	<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
 	<classpathentry kind="lib" path="libs/google-collect-1.0.jar"/>
+	<classpathentry kind="lib" path="libs/jackson-annotations-2.1.0.jar"/>
+	<classpathentry kind="lib" path="libs/jackson-core-2.1.0.jar"/>
+	<classpathentry kind="lib" path="libs/jackson-databind-2.1.0.jar"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index 0cd1a5d..73cec8f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.1-RC1" android:versionCode="139">
+	android:versionName="1.9.1" android:versionCode="140">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git libs/jackson-annotations-2.1.0.jar libs/jackson-annotations-2.1.0.jar
new file mode 100644
index 0000000..e4ca559
Binary files /dev/null and libs/jackson-annotations-2.1.0.jar differ
diff --git libs/jackson-core-2.1.0.jar libs/jackson-core-2.1.0.jar
new file mode 100644
index 0000000..6899eda
Binary files /dev/null and libs/jackson-core-2.1.0.jar differ
diff --git libs/jackson-databind-2.1.0.jar libs/jackson-databind-2.1.0.jar
new file mode 100644
index 0000000..5eceb00
Binary files /dev/null and libs/jackson-databind-2.1.0.jar differ
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 1898be3..ea4012f 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -22,6 +22,7 @@ import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
+import java.util.Date;
 import java.util.List;
 
 import org.apache.http.NameValuePair;
@@ -75,6 +76,8 @@ public class Helpers {
         {"₮", "MNT"}, {"₱", "CUP"}, {"₴", "UAH"},
         {"﷼", "SAR"}, 
     }; 
+    
+    private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 
     public static BigDecimal parseBalance(String balance) {
         balance = balance.replaceAll("[^0-9,.-]*", "");
@@ -215,5 +218,9 @@ public class Helpers {
     public static String removeHtml(String text) {
         return text.replaceAll("<[^>]+>", "");
     }
+    
+    public static String formatDate(Date date) {
+    	return DATE_FORMAT.format(date);
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 7fe60dd..0a2e5fd 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -45,7 +45,7 @@ import com.liato.bankdroid.banking.banks.ICABanken;
 import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
-import com.liato.bankdroid.banking.banks.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.lansforsakringar.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
@@ -72,7 +72,6 @@ import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
-import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.Vasttrafik;
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
deleted file mode 100644
index c45f791..0000000
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.banking.banks;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.text.Html;
-import android.text.InputType;
-import android.util.Log;
-
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.exceptions.BankChoiceException;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.provider.IBankTypes;
-
-import eu.nullbyte.android.urllib.Urllib;
-
-public class Lansforsakringar extends Bank {
-    private static final String TAG = "Lansforsakringar";
-    private static final String NAME = "Länsförsäkringar";
-    private static final String NAME_SHORT = "lansforsakringar";
-    private static final String URL = "https://secure246.lansforsakringar.se/lfportal/login/privat";
-    private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+>([^<]+)<.*?<td class=\"right\"[^>]+>([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountsLoans = Pattern.compile("LoanNumber=[^>]+>([^<]+)</a></td><td class=\"left\" width=\"25%\">([0-9.]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern rePension = Pattern.compile("class=\"portlet-menu-item\" [^>]+>(.*)</a></td><td class=\"left\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
-    private Pattern reHiddenToken = Pattern.compile("name=\"_token\" value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reUrl = Pattern.compile("<li class=\"bank\\s*\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("[^>]+>(\\d{4}-\\d{2}-\\d{2})<.*(\\d{4}-\\d{2}-\\d{2})<.*<span title=\"([^\"]+)\".*</span></td><td class=\"left\"><span title=\"([^\"]+)\".*</span></td><td class=\"right nowrap\" style=\"width:90px\">([^<]+)</td>.*style=\"width:90px\">([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private String accountsUrl = null;
-    private String mRequestToken = null;
-    private String mViewState = null;
-    private String host = null;
-    private boolean mFirstTransactionPage = true;
-
-    public Lansforsakringar(Context context) {
-        super(context);
-        super.TAG = TAG;
-        super.NAME = NAME;
-        super.NAME_SHORT = NAME_SHORT;
-        super.BANKTYPE_ID = BANKTYPE_ID;
-        super.URL = URL;
-        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-    }
-
-    public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
-        this(context);
-        this.update(username, password);
-    }
-
-
-    
-    @Override
-    protected LoginPackage preLogin() throws BankException,
-            ClientProtocolException, IOException {
-        urlopen = new Urllib(false, true);
-        String response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-        }
-        mViewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-        }
-        String strEventValidation = matcher.group(1);
-
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("inputPersonalNumber", username));
-        postData.add(new BasicNameValuePair("inputPinCode", password));
-        postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
-        postData.add(new BasicNameValuePair("__VIEWSTATE", mViewState));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
-        postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-        return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
-    }
-
-    public Urllib login() throws LoginException, BankException {
-        try {
-            LoginPackage lp = preLogin();
-            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Felaktig inloggning")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-            }
-
-            Matcher matcher = reToken.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token0.");
-            }
-            mRequestToken = matcher.group(1);
-
-            matcher = reUrl.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
-            }
-
-            host = urlopen.getCurrentURI().split("/")[2];
-            accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + mRequestToken;
-            if (!accountsUrl.contains("https://")) {
-                accountsUrl = "https://" + host + accountsUrl;
-            }
-
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
-        return urlopen;
-    }
-
-    @Override
-    public void update() throws BankException, LoginException, BankChoiceException {
-        super.update();
-        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-        }
-
-        urlopen = login();
-        String response = null;
-        Matcher matcher;
-        try {
-            if (accountsUrl == null) {
-                return;
-            }
-            response = urlopen.open(accountsUrl);
-            matcher = reAccountsReg.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Account number        125486547
-                 * 2: Name                  Personkonto
-                 * 3: Amount                25 000 000
-                 * 
-                 */
-                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
-                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-            }
-            //TODO: Don't have funds.
-            matcher = reAccountsFunds.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Name                  Fonder
-                 * 2: ID                    idJsp165
-                 * 3: Amount                0,00
-                 * 
-                 */
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim(), Account.FUNDS));
-            }
-            matcher = reAccountsLoans.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Name                  Privatl&#229;n
-                 * 2: ID                    idJsp207
-                 * 3: Amount                25 000 000
-                 * 4: Debt                  1,00
-                 * 
-                 */                
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()).negate(), matcher.group(2).trim(), Account.LOANS));
-            }
-
-            // Save token for next request
-            matcher = reToken.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token1.");
-            }
-            mRequestToken = matcher.group(1);
-
-            response = urlopen.open("https://" + host + "/im/im/pension.jsf?newUc=true&_token=" + mRequestToken);
-            matcher = rePension.matcher(response);
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                    EXAMPLE DATA
-                 * 1: Name                  Avtalspension ITP - Fond
-                 * 2: ID                    00835742_0
-                 * 3: Amount                10 587,40
-                 * 4: Amount?				10 587,40
-                 */
-                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim());
-                account.setType(Account.OTHER);
-                accounts.add(account);
-            }            
-
-            // Save token for next request
-            //Helpers.slowDebug(TAG, response, 20);
-            matcher = reToken.matcher(response);
-            if (!matcher.find()) {
-                matcher = reHiddenToken.matcher(response);
-                if (!matcher.find()) {
-                    throw new BankException(res.getText(R.string.unable_to_find).toString()+" token2.");
-                }
-            }
-            mRequestToken = matcher.group(1);
-            
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        }
-        catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
-        }
-        catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
-        finally {
-            super.updateComplete();
-        }
-    }
-
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-        super.updateTransactions(account, urlopen);
-        // No transaction history for funds and loans
-        if (account.getType() != Account.REGULAR) return;
-        String response = null;
-        Matcher matcher;
-
-        if (mFirstTransactionPage) {
-            try {
-                response = urlopen.open("https://" + host + "/im/index_account.jsf?dialog=dialog:account.viewAccountTransactions&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
-                matcher = reViewState.matcher(response);
-                if (!matcher.find()) {
-                    Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
-                    return;
-                }
-                mViewState = matcher.group(1);
-
-                matcher = reHiddenToken.matcher(response);
-                if (!matcher.find()) {
-                    Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
-                    return;
-                }
-                mRequestToken = matcher.group(1);                  
-            }
-            catch (ClientProtocolException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            } catch (IOException e) {
-                // TODO Auto-generated catch block
-                e.printStackTrace();
-            }            
-        }
-
-        try {
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            if (mFirstTransactionPage) {
-                postData.add(new BasicNameValuePair("dialog-account_viewAccountTransactions", "Submit Query"));            
-                postData.add(new BasicNameValuePair("_token", mRequestToken));            
-                postData.add(new BasicNameValuePair("loginForm_SUBMIT", "1"));            
-                postData.add(new BasicNameValuePair("loginForm:_idcl", ""));            
-                postData.add(new BasicNameValuePair("loginForm:_link_hidden_", ""));            
-                postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
-                response = urlopen.open("https://" + host + "/im/index_account.jsf", postData);
-                mFirstTransactionPage = false;
-            }
-            else {
-                postData.add(new BasicNameValuePair("_token", mRequestToken));            
-                postData.add(new BasicNameValuePair("viewAccountListTransactionsForm_SUBMIT", "1"));            
-                postData.add(new BasicNameValuePair("viewAccountListTransactionsForm:_idcl", ""));            
-                postData.add(new BasicNameValuePair("viewAccountListTransactionsForm:_link_hidden_", ""));            
-                postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
-                postData.add(new BasicNameValuePair("accountList", account.getId()));
-                response = urlopen.open("https://" + host + "/im/jsp/account/view/viewAccountTransactions.jsf", postData);
-            }
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Book. date        2009-05-03
-                 * 2: Trans. date       2009-05-03
-                 * 3: Specification     &Ouml;verf&ouml;ring internet ...
-                 * 4: Note              829909945928712
-                 * 5: Amount            -54,00
-                 * 6: Remaining         0,00
-                 *   
-                 */                    
-                transactions.add(new Transaction(matcher.group(2).trim(),
-                        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " (" + Html.fromHtml(matcher.group(4)).toString().trim() + ")" : ""),
-                        Helpers.parseBalance(matcher.group(5))));
-            }
-            account.setTransactions(transactions);
-
-            // Save token and viewstate for next request
-            matcher = reViewState.matcher(response);
-            // We need the second match, disregard the first one.
-            matcher.find();
-            if (!matcher.find()) {
-                Log.e(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L334.");
-                return;
-            }
-            mViewState = matcher.group(1);
-
-
-            matcher = reToken.matcher(response);
-            if (!matcher.find()) {
-                Log.w(TAG, res.getText(R.string.unable_to_find).toString()+" token. L342.");
-                return;
-            }
-            mRequestToken = matcher.group(1);            
-        } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        finally {
-            super.updateComplete();
-        }
-    }       	
-}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
new file mode 100644
index 0000000..8d5fe7e
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/Lansforsakringar.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks.lansforsakringar;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationConfig;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.request.AccountsRequest;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.request.ChallengeRequest;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.request.LoginRequest;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.request.TransactionsRequest;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.response.AccountsResponse;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.response.ChallengeResponse;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.response.LoginResponse;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.response.NumberResponse;
+import com.liato.bankdroid.banking.banks.lansforsakringar.model.response.TransactionsResponse;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Lansforsakringar extends Bank {
+    private static final String TAG = "Lansforsakringar";
+    private static final String NAME = "Länsförsäkringar";
+    private static final String NAME_SHORT = "lansforsakringar";
+    private static final String URL = "https://mobil.lansforsakringar.se/lf-mobile/pages/login.faces";
+    private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+>([^<]+)<.*?<td class=\"right\"[^>]+>([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountsLoans = Pattern.compile("LoanNumber=[^>]+>([^<]+)</a></td><td class=\"left\" width=\"25%\">([0-9.]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern rePension = Pattern.compile("class=\"portlet-menu-item\" [^>]+>(.*)</a></td><td class=\"left\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
+    private Pattern reHiddenToken = Pattern.compile("name=\"_token\" value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reUrl = Pattern.compile("<li class=\"bank\\s*\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("[^>]+>(\\d{4}-\\d{2}-\\d{2})<.*(\\d{4}-\\d{2}-\\d{2})<.*<span title=\"([^\"]+)\".*</span></td><td class=\"left\"><span title=\"([^\"]+)\".*</span></td><td class=\"right nowrap\" style=\"width:90px\">([^<]+)</td>.*style=\"width:90px\">([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private String accountsUrl = null;
+    private String mRequestToken = null;
+    private String mViewState = null;
+    private String host = null;
+    private boolean mFirstTransactionPage = true;
+    
+    
+    
+    private ObjectMapper mObjectMapper = new ObjectMapper();
+
+    public Lansforsakringar(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        mObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mObjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
+        mObjectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+    }
+
+    public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(false, true);
+        String response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        mViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String strEventValidation = matcher.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("inputPersonalNumber", username));
+        postData.add(new BasicNameValuePair("inputPinCode", password));
+        postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", mViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
+        postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
+        return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("Felaktig inloggning")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+
+            Matcher matcher = reToken.matcher(response);
+            if (!matcher.find()) {
+                //throw new BankException(res.getText(R.string.unable_to_find).toString()+" token0.");
+            } else {
+            	mRequestToken = matcher.group(1);
+            }
+
+            matcher = reUrl.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
+            }
+
+            host = urlopen.getCurrentURI().split("/")[2];
+            accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + getRequestToken();
+            if (!accountsUrl.contains("https://")) {
+                accountsUrl = "https://" + host + accountsUrl;
+            }
+
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+    
+    private String getRequestToken() {
+    	return mRequestToken != null ? mRequestToken : "";
+    }
+    
+    private <T> T readJsonValue(InputStream is, Class<T> valueType) throws BankException {
+        try {
+			return mObjectMapper.readValue(is, valueType);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new BankException(e.getMessage());
+		}
+    }
+
+    private <T> T readJsonValue(String url, String postData, Class<T> valueType) throws BankException {
+    	try {
+			return readJsonValue(urlopen.openStream(url, postData, false), valueType);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new BankException(e.getMessage());
+		}
+    }
+    
+    public String objectAsJson(Object value) {
+    	try {
+			return mObjectMapper.writeValueAsString(value);
+		} catch (JsonProcessingException e) {
+			e.printStackTrace();
+		}
+    	return null;
+    }
+    
+    private String generateChallenge(int originalChallenge) {
+		try {
+			String h = Integer.toHexString(originalChallenge + (1000 * 20 / 4) + 100 * (18 / 3) + 10 * (2 / 2) + 6);
+			MessageDigest md = MessageDigest.getInstance("SHA-1");
+			byte[] messageDigest = md.digest(h.getBytes());
+			BigInteger number = new BigInteger(1,messageDigest);
+			String md5 = number.toString(16);
+			while(md5.length() < 40)
+				md5 = "0" + md5;        
+			return md5;
+		} catch (NoSuchAlgorithmException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return "";
+    		
+    }
+    
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = new Urllib();
+        urlopen.addHeader("Content-Type", "application/json; charset=UTF-8");
+        urlopen.addHeader("DeviceId", UUID.randomUUID().toString());//"9ba6991346f2f8e9");
+        urlopen.addHeader("deviceInfo", "Galaxy Nexus;4.1.1;1.8;Portrait");
+        urlopen.setUserAgent("bankdroid"); // Android app uses "lf-android-app"
+
+        NumberResponse nr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/security/client", null, NumberResponse.class);
+        ChallengeResponse cr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/security/client", objectAsJson(new ChallengeRequest(nr.getNumber(), nr.getNumberPair(), generateChallenge(nr.getNumber()))), ChallengeResponse.class);
+        urlopen.addHeader("Ctoken", cr.getToken());
+        LoginResponse lr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/security/user", objectAsJson(new LoginRequest(username, password)), LoginResponse.class);
+        urlopen.addHeader("Utoken", lr.getTicket());
+
+        AccountsResponse ar = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.CHECKING)), AccountsResponse.class);
+        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
+        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
+        	//a.getLedger() should be saved to database, used when fetching transactions
+        	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
+        }
+        ar = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/bytype", objectAsJson(new AccountsRequest(AccountsRequest.Type.SAVING)), AccountsResponse.class);
+        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Account a : ar.getAccounts()) {
+        	accounts.add(new Account(a.getAccountName(), new BigDecimal(a.getDispoibleAmount()), a.getAccountNumber()));
+        	balance = balance.add(new BigDecimal(a.getDispoibleAmount()));
+        }        
+        if (accounts.isEmpty()) {
+        	throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        // No transaction history for funds and loans
+        if (account.getType() != Account.REGULAR) return;
+        
+        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+        //TODO: Get upcoming transactions?
+        //TransactionsResponse tr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/upcoming", objectAsJson(new UpcomingTransactionsRequest(account.getId())), TransactionsResponse.class);
+        TransactionsResponse tr = readJsonValue("https://mobil.lansforsakringar.se/appoutlet/account/transaction", objectAsJson(new TransactionsRequest(0, "DEPIOSIT", account.getId())), TransactionsResponse.class);
+        
+        for (com.liato.bankdroid.banking.banks.lansforsakringar.model.response.Transaction t : tr.getTransactions()) {
+        	//TODO: Set locale on date?
+        	transactions.add(new Transaction(Helpers.formatDate(new Date(t.getTransactiondate())), t.getText(), new BigDecimal(t.getAmmount())));
+        }
+
+        account.setTransactions(transactions);        
+        super.updateComplete();
+    }       	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
new file mode 100644
index 0000000..54b0de9
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/AccountsRequest.java
@@ -0,0 +1,32 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class AccountsRequest {
+	public enum Type {
+		CHECKING("CHECKING"),
+		SAVING("SAVING");
+		
+		private String name;
+		private Type(String name) {
+			this.name = name;
+		}
+		
+		@Override
+		public String toString() {
+			return this.name;
+		}
+	}
+    private String mAccountType;
+
+
+    public AccountsRequest (Type accountType) {
+        mAccountType = accountType.toString();
+    }
+
+    @JsonSetter("accountType")
+    public void setAccountType(String a) { mAccountType = a; }
+    @JsonProperty("accountType")
+    public String getAccountType() { return mAccountType; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
new file mode 100644
index 0000000..0a24a38
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/ChallengeRequest.java
@@ -0,0 +1,32 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class ChallengeRequest {
+    private int mOriginalChallenge;
+    private String mChallengePair;
+    private String mHash;
+
+
+    public ChallengeRequest (int originalChallenge, String challengePair, String hash) {
+        mOriginalChallenge = originalChallenge;
+        mChallengePair = challengePair;
+        mHash = hash;
+    }
+
+    @JsonSetter("originalChallenge")
+    public void setOriginalChallenge(int o) { mOriginalChallenge = o; }
+    @JsonProperty("originalChallenge")
+    public int getOriginalChallenge() { return mOriginalChallenge; }
+
+    @JsonSetter("challengePair")
+    public void setChallengePair(String c) { mChallengePair = c; }
+    @JsonProperty("challengePair")
+    public String getChallengePair() { return mChallengePair; }
+
+    @JsonSetter("hash")
+    public void setHash(String h) { mHash = h; }
+    @JsonProperty("hash")
+    public String getHash() { return mHash; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
new file mode 100644
index 0000000..c1ccade
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/LoginRequest.java
@@ -0,0 +1,25 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class LoginRequest {
+    private String mSsn;
+    private String mPin;
+
+
+    public LoginRequest (String ssn, String pin) {
+        mSsn = ssn;
+        mPin = pin;
+    }
+
+    @JsonSetter("ssn")
+    public void setSsn(String s) { mSsn = s; }
+    @JsonProperty("ssn")
+    public String getSsn() { return mSsn; }
+
+    @JsonSetter("pin")
+    public void setPin(String p) { mPin = p; }
+    @JsonProperty("pin")
+    public String getPin() { return mPin; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
new file mode 100644
index 0000000..e684069
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/TransactionsRequest.java
@@ -0,0 +1,32 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class TransactionsRequest {
+    private int mRequestedPage;
+    private String mLedger;
+    private String mAccountNumber;
+
+
+    public TransactionsRequest (int requestedPage, String ledger, String accountNumber) {
+        mRequestedPage = requestedPage;
+        mLedger = ledger;
+        mAccountNumber = accountNumber;
+    }
+
+    @JsonSetter("requestedPage")
+    public void setRequestedPage(int r) { mRequestedPage = r; }
+    @JsonProperty("requestedPage")
+    public int getRequestedPage() { return mRequestedPage; }
+
+    @JsonSetter("ledger")
+    public void setLedger(String l) { mLedger = l; }
+    @JsonProperty("ledger")
+    public String getLedger() { return mLedger; }
+
+    @JsonSetter("accountNumber")
+    public void setAccountNumber(String a) { mAccountNumber = a; }
+    @JsonProperty("accountNumber")
+    public String getAccountNumber() { return mAccountNumber; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
new file mode 100644
index 0000000..a31b757
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/request/UpcomingTransactionsRequest.java
@@ -0,0 +1,18 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.request;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class UpcomingTransactionsRequest {
+    private String mAccountNumber;
+
+
+    public UpcomingTransactionsRequest (String accountNumber) {
+        mAccountNumber = accountNumber;
+    }
+
+    @JsonSetter("accountNumber")
+    public void setAccountNumber(String a) { mAccountNumber = a; }
+    @JsonProperty("accountNumber")
+    public String getAccountNumber() { return mAccountNumber; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
new file mode 100644
index 0000000..a2a09e2
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Account.java
@@ -0,0 +1,69 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class Account {
+	private boolean mTransferTo;
+	private String mProductCode;
+	private boolean mYouthAccount;
+	private String mAccountNumber;
+	private String mClearingNumber;
+	private boolean mTransferFrom;
+	private String mLedger;
+	private String mAccountName;
+	private float mDispoibleAmount;
+	private float mBalance;
+
+
+	@JsonSetter("transferTo")
+	public void setTransferTo(boolean t) { mTransferTo = t; }
+	@JsonProperty("transferTo")
+	public boolean getTransferTo() { return mTransferTo; }
+
+	@JsonSetter("productCode")
+	public void setProductCode(String p) { mProductCode = p; }
+	@JsonProperty("productCode")
+	public String getProductCode() { return mProductCode; }
+
+	@JsonSetter("youthAccount")
+	public void setYouthAccount(boolean y) { mYouthAccount = y; }
+	@JsonProperty("youthAccount")
+	public boolean getYouthAccount() { return mYouthAccount; }
+
+	@JsonSetter("accountNumber")
+	public void setAccountNumber(String a) { mAccountNumber = a; }
+	@JsonProperty("accountNumber")
+	public String getAccountNumber() { return mAccountNumber; }
+
+	@JsonSetter("clearingNumber")
+	public void setClearingNumber(String c) { mClearingNumber = c; }
+	@JsonProperty("clearingNumber")
+	public String getClearingNumber() { return mClearingNumber; }
+
+	@JsonSetter("transferFrom")
+	public void setTransferFrom(boolean t) { mTransferFrom = t; }
+	@JsonProperty("transferFrom")
+	public boolean getTransferFrom() { return mTransferFrom; }
+
+	@JsonSetter("ledger")
+	public void setLedger(String l) { mLedger = l; }
+	@JsonProperty("ledger")
+	public String getLedger() { return mLedger; }
+
+	@JsonSetter("accountName")
+	public void setAccountName(String a) { mAccountName = a; }
+	@JsonProperty("accountName")
+	public String getAccountName() { return mAccountName; }
+
+	@JsonSetter("dispoibleAmount")
+	public void setDispoibleAmount(float d) { mDispoibleAmount = d; }
+	@JsonProperty("dispoibleAmount")
+	public float getDispoibleAmount() { return mDispoibleAmount; }
+
+	@JsonSetter("balance")
+	public void setBalance(float b) { mBalance = b; }
+	@JsonProperty("balance")
+	public float getBalance() { return mBalance; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
new file mode 100644
index 0000000..c77a851
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/AccountsResponse.java
@@ -0,0 +1,17 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+import java.util.ArrayList;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class AccountsResponse {
+
+	private ArrayList<Account> mAccounts = new ArrayList<Account>();
+
+
+	@JsonSetter("accounts")
+	public void setAccounts(ArrayList<Account> a) { mAccounts = a; }
+	@JsonProperty("accounts")
+	public ArrayList<Account> getAccounts() { return mAccounts; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
new file mode 100644
index 0000000..98b0507
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/ChallengeResponse.java
@@ -0,0 +1,20 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class ChallengeResponse {
+    private int mLifetime;
+    private String mToken;
+
+
+    @JsonSetter("lifetime")
+    public void setLifetime(int l) { mLifetime = l; }
+    @JsonProperty("lifetime")
+    public int getLifetime() { return mLifetime; }
+
+    @JsonSetter("token")
+    public void setToken(String t) { mToken = t; }
+    @JsonProperty("token")
+    public String getToken() { return mToken; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
new file mode 100644
index 0000000..41c6b82
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/LoginResponse.java
@@ -0,0 +1,44 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class LoginResponse {
+    private String mName;
+    private String mLfCompanyBelonging;
+    private String mSsn;
+    private int mTicketLifetime;
+    private boolean mPinPadAvailable;
+    private String mTicket;
+
+
+    @JsonSetter("name")
+    public void setName(String n) { mName = n; }
+    @JsonProperty("name")
+    public String getName() { return mName; }
+
+    @JsonSetter("lfCompanyBelonging")
+    public void setLfCompanyBelonging(String l) { mLfCompanyBelonging = l; }
+    @JsonProperty("lfCompanyBelonging")
+    public String getLfCompanyBelonging() { return mLfCompanyBelonging; }
+
+    @JsonSetter("ssn")
+    public void setSsn(String s) { mSsn = s; }
+    @JsonProperty("ssn")
+    public String getSsn() { return mSsn; }
+
+    @JsonSetter("ticketLifetime")
+    public void setTicketLifetime(int t) { mTicketLifetime = t; }
+    @JsonProperty("ticketLifetime")
+    public int getTicketLifetime() { return mTicketLifetime; }
+
+    @JsonSetter("pinPadAvailable")
+    public void setPinPadAvailable(boolean p) { mPinPadAvailable = p; }
+    @JsonProperty("pinPadAvailable")
+    public boolean getPinPadAvailable() { return mPinPadAvailable; }
+
+    @JsonSetter("ticket")
+    public void setTicket(String t) { mTicket = t; }
+    @JsonProperty("ticket")
+    public String getTicket() { return mTicket; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
new file mode 100644
index 0000000..d22a6c8
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/NumberResponse.java
@@ -0,0 +1,20 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class NumberResponse {
+    private int mNumber;
+    private String mNumberPair;
+
+
+    @JsonSetter("number")
+    public void setNumber(int n) { mNumber = n; }
+    @JsonProperty("number")
+    public int getNumber() { return mNumber; }
+
+    @JsonSetter("numberPair")
+    public void setNumberPair(String n) { mNumberPair = n; }
+    @JsonProperty("numberPair")
+    public String getNumberPair() { return mNumberPair; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
new file mode 100644
index 0000000..63b0e98
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/Transaction.java
@@ -0,0 +1,27 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class Transaction {
+	private String mText;
+	private long mTransactiondate;
+	private float mAmmount;
+
+
+	@JsonSetter("text")
+	public void setText(String t) { mText = t; }
+	@JsonProperty("text")
+	public String getText() { return mText; }
+
+	@JsonSetter("transactiondate")
+	public void setTransactiondate(long t) { mTransactiondate = t; }
+	@JsonProperty("transactiondate")
+	public long getTransactiondate() { return mTransactiondate; }
+
+	@JsonSetter("ammount")
+	public void setAmmount(float a) { mAmmount = a; }
+	@JsonProperty("ammount")
+	public float getAmmount() { return mAmmount; }
+
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
new file mode 100644
index 0000000..7170ec0
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/lansforsakringar/model/response/TransactionsResponse.java
@@ -0,0 +1,28 @@
+package com.liato.bankdroid.banking.banks.lansforsakringar.model.response;
+import java.util.ArrayList;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+
+public class TransactionsResponse {
+	private boolean mHasMore;
+	private int mNextSequenceNumber;
+	private ArrayList<Transaction> mTransactions = new ArrayList<Transaction>();
+
+
+	@JsonSetter("hasMore")
+	public void setHasMore(boolean h) { mHasMore = h; }
+	@JsonProperty("hasMore")
+	public boolean getHasMore() { return mHasMore; }
+
+	@JsonSetter("nextSequenceNumber")
+	public void setNextSequenceNumber(int n) { mNextSequenceNumber = n; }
+	@JsonProperty("nextSequenceNumber")
+	public int getNextSequenceNumber() { return mNextSequenceNumber; }
+
+	@JsonSetter("transactions")
+	public void setTransactions(ArrayList<Transaction> t) { mTransactions = t; }
+	@JsonProperty("transactions")
+	public ArrayList<Transaction> getTransactions() { return mTransactions; }
+
+}
\ No newline at end of file
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index d639fbc..2bdc28e 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -18,6 +18,7 @@ package eu.nullbyte.android.urllib;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -38,6 +39,8 @@ 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.ssl.SSLSocketFactory;
+import org.apache.http.entity.BasicHttpEntity;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
@@ -47,6 +50,9 @@ import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
+import org.apache.http.util.EntityUtils;
+
+import android.util.Log;
 
 public class Urllib {
     public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
@@ -135,24 +141,43 @@ public class Urllib {
         return response;
     }    
     public InputStream openStream(String url) throws ClientProtocolException, IOException {
-        return openStream(url, null, false);
+        return openStream(url, new BasicHttpEntity(), false);
+    }
+    
+    public HttpEntity toEntity(List<NameValuePair> postData) {
+    	if (postData != null && !postData.isEmpty()) {
+    		try {
+				return new UrlEncodedFormEntity(postData, this.charset);
+			} catch (UnsupportedEncodingException e) {
+				e.printStackTrace();
+			} 
+    	}
+    	return null;
     }
     
     public InputStream openStream(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+    	return openStream(url, toEntity(postData), forcePost);
+    }
+    
+    public InputStream openStream(String url, String postData, boolean forcePost) throws ClientProtocolException, IOException {
+    	return openStream(url, postData != null ? new StringEntity(postData, this.charset) : null, forcePost);
+    }
+    
+    public InputStream openStream(String url, HttpEntity postData, boolean forcePost) throws ClientProtocolException, IOException {
         this.currentURI = url;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
         HttpUriRequest request;
-        if ((postData == null || postData.isEmpty()) && !forcePost) {
-            //URL urli = new URL(url); 
+        if (postData == null && !forcePost) {
             request = new HttpGet(url);
         }
         else {
             request = new HttpPost(url);
-            ((HttpPost)request).setEntity(new UrlEncodedFormEntity(postData, this.charset));
+            ((HttpPost)request).setEntity(postData);
         }
-        if (userAgent != null)
+        if (userAgent != null) {
             request.addHeader("User-Agent", userAgent);
+        }
         
         for (int i = 0; i < headerKeys.length; i++) {
             request.addHeader(headerKeys[i], headerVals[i]);
@@ -161,7 +186,7 @@ public class Urllib {
         HttpResponse response = httpclient.execute(request);
         HttpEntity entity = response.getEntity();
         return entity.getContent();
-    }        
+    }      
     
     public void close() {
         httpclient.getConnectionManager().shutdown();

commit c005ba8d711b62ad863e1a895902b47e9e268138
Author: liato <x@x00.us>
Date:   Mon Oct 1 02:58:03 2012 +0200

    Update version.

diff --git AndroidManifest.xml AndroidManifest.xml
index a95be08..0cd1a5d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.0" android:versionCode="138">
+	android:versionName="1.9.1-RC1" android:versionCode="139">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 10bc4296609c8c939c3f06aba6bffb8c8b7e9096
Author: liato <x@x00.us>
Date:   Mon Oct 1 02:05:38 2012 +0200

    Remove steam wallet.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 573908f..7fe60dd 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -243,7 +243,7 @@ public class BankFactory {
         banks.add(new PayPal(context));
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
-        banks.add(new Steam(context));
+        //banks.add(new Steam(context));
         banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
         banks.add(new EurobonusMastercard(context));

commit ba993cf652eb9079ebf47c2c6816ad40b23412b0
Author: liato <x@x00.us>
Date:   Mon Oct 1 01:59:50 2012 +0200

    Fix hints for Swedbank and Nordea.

diff --git src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
index a87e192..6e0f52e 100644
--- src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
@@ -54,7 +54,7 @@ public class Nordea extends Bank {
 	private static final int BANKTYPE_ID = IBankTypes.NORDEA;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
 
     private Pattern reCurrency = Pattern.compile("list-left\">\\s*Valuta\\s*</dt>\\s*<dd[^>]+>([^<]+)</dd>", Pattern.CASE_INSENSITIVE);
     private Pattern reBalance = Pattern.compile("list-left\">\\s*Summa\\s*([a-zA-Z]{3})\\s*</dt>\\s*<dd[^>]+>([^<]+)</", Pattern.CASE_INSENSITIVE);
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 379fb81..a0ed9c5 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -53,7 +53,7 @@ public class Swedbank extends Bank {
 	private static final String URL = "https://mobilbank.swedbank.se/";
 	private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
     
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\"[^>]*>\\s*(?:<span\\sclass=\"icon\">[^<]*</span>\\s*)?<span\\s*class=\"name\">([^<]+)</span>\\s*(?:<br/>\\s*)?<span\\s*class=\"amount\">([^<]+)</");

commit 2263744968870c594d8b75f543848f00f760837f
Merge: bb5bdc3 3acaf28
Author: liato <x@x00.us>
Date:   Mon Oct 1 01:50:57 2012 +0200

    Merge emilans chalmrest patch.

commit bb5bdc3e1ef56ef44dc672a3dadd4992d5fc298f
Merge: a08067e 965d697
Author: liato <x@x00.us>
Date:   Mon Oct 1 01:48:33 2012 +0200

    Merge branch 'master' of github.com:liato/android-bankdroid

commit 965d697e219df35e61d705980058dccefc99e357
Merge: 8eed778 62ed9a7
Author: liato <x@x00.us>
Date:   Sun Sep 30 16:45:21 2012 -0700

    Merge pull request #165 from d95andek/master
    
    Fix Everydaycard balance and make Volvofinans show balance

commit 8eed778e43c1416b442a39e977a23f92b673d0e9
Merge: 6e8cfdc 0a83dd9
Author: liato <x@x00.us>
Date:   Sun Sep 30 16:43:48 2012 -0700

    Merge pull request #157 from jsiverskog/0a83dd9d1fe59a360ae433720db937b67c472a64
    
    Compare banks by name

commit 62ed9a7bec9b3de36a1a2c9e4308718cdbccf132
Author: Andreas Gunnerås <andreas@gunneras.se>
Date:   Thu Sep 20 23:07:17 2012 +0200

    Make Volvofinans show balance instead of "left until limit is hit". See Issue #162.

diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index edef11c..555cf53 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -122,7 +122,7 @@ public class Volvofinans extends Bank {
 				int length = data.length();
 				for (int index = 0; index < length; index++) {
 					JSONObject account = data.getJSONObject(index);
-					accounts.add(new Account(account.getString("kontonummer"), Helpers.parseBalance(account.getString("disponibeltBelopp")), "1"));
+					accounts.add(new Account(account.getString("kontonummer"), Helpers.parseBalance(account.getString("disponibeltBelopp")).subtract(Helpers.parseBalance(account.getString("limit"))), "1"));
 				}
 			}
 			catch (JSONException e) {

commit c8662e20583910bec177666aacf45ba574f1395d
Author: Andreas Gunnerås <andreas@gunneras.se>
Date:   Thu Sep 20 23:00:29 2012 +0200

    Fix Everydaycard balance. Unfortunately loosing transactions. Added me to list of contributors.

diff --git res/values/strings.xml res/values/strings.xml
index 51a6522..300b43b 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -202,6 +202,7 @@
 	\ncork (Volvofinans)
 	\nmarijo (Eurocard)
 	\nd98rolb (Osuuspankki)
+	\nAndreas Gunnerås (Everydaycard)
      </string>
      
      
diff --git src/com/liato/bankdroid/banking/banks/Everydaycard.java src/com/liato/bankdroid/banking/banks/Everydaycard.java
index a9d9339..c20efda 100644
--- src/com/liato/bankdroid/banking/banks/Everydaycard.java
+++ src/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
- * Copyright (C) 2011 Andreas Gunnerås
+ * Copyright (C) 2011, 2012 Andreas Gunnerås
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
+//import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -52,10 +52,10 @@ public class Everydaycard extends Bank {
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
-	private Pattern reSaldo = Pattern.compile("Utnyttjad kredit \\(sek\\)</td>\\s*<td class=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reBonus = Pattern.compile("Aktuell bonus \\(sek\\)</strong></td>\\s*<td class=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reAccountTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	private Pattern reBonusTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reSaldo = Pattern.compile("Utnyttjad kredit \\(sek\\)</td>\\s*<td></td>\\s*<td>([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reBonus = Pattern.compile("Aktuell bonus \\(sek\\)</td>\\s*<td>.*</td>\\s*<td>([^<]+)<", Pattern.CASE_INSENSITIVE);
+//	private Pattern reAccountTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+//	private Pattern reBonusTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	public Everydaycard(Context context) {
 		super(context);
@@ -79,10 +79,10 @@ public class Everydaycard extends Bank {
     	return preLoginInternal("http://valuta.g2solutions.se/mobil/web/logonSubmit.do");
     }
     
-    private LoginPackage preLoginNonMobile() throws BankException,
-            ClientProtocolException, IOException {
-    	return preLoginInternal("https://valuta.g2solutions.se/valuta/web/logonSubmit.do");
-    }
+//    private LoginPackage preLoginNonMobile() throws BankException,
+//            ClientProtocolException, IOException {
+//    	return preLoginInternal("https://valuta.g2solutions.se/valuta/web/logonSubmit.do");
+//    }
 
     private LoginPackage preLoginInternal(String url) throws BankException,
     		ClientProtocolException, IOException {
@@ -97,7 +97,8 @@ public class Everydaycard extends Bank {
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		try {
-			LoginPackage lp = preLoginNonMobile();
+			//LoginPackage lp = preLoginNonMobile();
+			LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("Felaktigt Login")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -140,47 +141,47 @@ public class Everydaycard extends Bank {
         super.updateComplete();
 	}
 
-	@Override
-    public void updateAllTransactions() throws LoginException, BankException {
-		if (urlopen == null) {
-			urlopen = login();
-        }
-		try {
-			response = urlopen.open("https://valuta.g2solutions.se/valuta/web/manageCustomer.do?action=account");
-			for (Account account: accounts) {
-				Matcher matcher;
-				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            
-				switch (account.getType()) {
-				case Account.CCARD:
-					matcher = reAccountTransactions.matcher(response);
-					while (matcher.find()) {
-						transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate()));
-					}
-					break;
-				// Bonus account
-				case Account.OTHER:
-					matcher = reBonusTransactions.matcher(response);
-					while (matcher.find()) {
-						if (!matcher.group(4).equals("0,00")) {
-							transactions.add(new Transaction(matcher.group(1), matcher.group(2) + " (-" + matcher.group(3) + ")", Helpers.parseBalance(matcher.group(4))));
-						}
-					}
-					break;
-				default:
-					return;
-				}
-
-				account.setTransactions(transactions);
-			}
-		} catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		} finally {
-			if (urlopen != null) {
-				urlopen.close();
-			}
-        }
-	}
+//	@Override
+//    public void updateAllTransactions() throws LoginException, BankException {
+//		if (urlopen == null) {
+//			urlopen = login();
+//        }
+//		try {
+//			response = urlopen.open("https://valuta.g2solutions.se/valuta/web/manageCustomer.do?action=account");
+//			for (Account account: accounts) {
+//				Matcher matcher;
+//				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+//            
+//				switch (account.getType()) {
+//				case Account.CCARD:
+//					matcher = reAccountTransactions.matcher(response);
+//					while (matcher.find()) {
+//						transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate()));
+//					}
+//					break;
+//				// Bonus account
+//				case Account.OTHER:
+//					matcher = reBonusTransactions.matcher(response);
+//					while (matcher.find()) {
+//						if (!matcher.group(4).equals("0,00")) {
+//							transactions.add(new Transaction(matcher.group(1), matcher.group(2) + " (-" + matcher.group(3) + ")", Helpers.parseBalance(matcher.group(4))));
+//						}
+//					}
+//					break;
+//				default:
+//					return;
+//				}
+//
+//				account.setTransactions(transactions);
+//			}
+//		} catch (ClientProtocolException e) {
+//			throw new BankException(e.getMessage());
+//		} catch (IOException e) {
+//			throw new BankException(e.getMessage());
+//		} finally {
+//			if (urlopen != null) {
+//				urlopen.close();
+//			}
+//        }
+//	}
 }

commit 3acaf285ca45198e0714447a0e1cfb7b1a1e5485
Author: Emil Andersson <emil.jo.andersson@gmail.com>
Date:   Fri Sep 14 11:00:30 2012 +0200

    Added support for Chalmrest (Chalmers Konferens & Restauranger) cards

diff --git res/drawable/logo_chalmrest.png res/drawable/logo_chalmrest.png
new file mode 100644
index 0000000..f3a46eb
Binary files /dev/null and res/drawable/logo_chalmrest.png differ
diff --git res/values/strings.xml res/values/strings.xml
index 51a6522..a1bee7e 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -202,6 +202,7 @@
 	\ncork (Volvofinans)
 	\nmarijo (Eurocard)
 	\nd98rolb (Osuuspankki)
+	\nEmil Andersson (Chalmrest)
      </string>
      
      
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index cd2b6aa..573908f 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -28,6 +28,7 @@ import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.CSN;
+import com.liato.bankdroid.banking.banks.Chalmrest;
 import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.Coop;
 import com.liato.bankdroid.banking.banks.DanskeBank;
@@ -214,6 +215,8 @@ public class BankFactory {
             return new TicketRikskortet(context);
         case IBankTypes.BIOKLUBBEN:
             return new Bioklubben(context);
+        case IBankTypes.CHALMREST:
+        	return new Chalmrest(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -281,6 +284,8 @@ public class BankFactory {
         banks.add(new Meniga(context));
         banks.add(new TicketRikskortet(context));
         banks.add(new Bioklubben(context));
+        banks.add(new Chalmrest(context));
+        
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Chalmrest.java src/com/liato/bankdroid/banking/banks/Chalmrest.java
new file mode 100644
index 0000000..626283a
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Chalmrest.java
@@ -0,0 +1,101 @@
+package com.liato.bankdroid.banking.banks;
+
+import java.math.BigDecimal;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+public class Chalmrest extends Bank {
+	private static final String TAG = "Chalmrest";
+	private static final String NAME = "Chalmrest";
+	private static final String NAME_SHORT = "chalmrest";
+	private static final int BANKTYPE_ID = IBankTypes.CHALMREST;
+
+	public Chalmrest(Context context) {
+		super(context);
+
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.INPUT_TITLETEXT_USERNAME = R.string.card_number;
+		super.INPUT_HINT_USERNAME = "XXXXXXXXXXXXXXXX";
+		super.INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_NUMBER;
+		super.INPUT_HIDDEN_PASSWORD = true;
+	}
+
+	public Chalmrest(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || username.length() == 0) 
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		
+		try {
+			String cardNr = username;
+			
+			HttpClient httpclient = new DefaultHttpClient();
+			HttpGet httpget = new HttpGet("http://kortladdning.chalmerskonferens.se/bgw.aspx?type=getCardAndArticles&card=" + cardNr);
+			HttpResponse response = httpclient.execute(httpget);
+			HttpEntity entity = response.getEntity();
+			if (entity == null)
+				throw new BankException("Couldn't connect!");
+			
+		    String s1 = EntityUtils.toString(entity);		    
+		    Pattern pattern = Pattern.compile("<ExtendedInfo Name=\"Kortvarde\" Type=\"System.Double\" >(.*?)</ExtendedInfo>");
+		    Matcher matcher = pattern.matcher(s1);
+		    
+		    if (!matcher.find()) 
+		    	throw new BankException("Couldn't parse value!"); 
+
+		    String value = matcher.group(1);
+		    
+		    StringBuilder sb = new StringBuilder();
+		    int last = 0;
+		    Matcher match = Pattern.compile("_x([0-9A-Fa-f]{4})_").matcher(value);
+		    while (match.find()) {
+		    	sb.append(value.substring(last, Math.max(match.start() - 1, 0)));
+		    	int i = Integer.parseInt(match.group(1), 16);
+		    	sb.append((char)i);
+		    	last = match.end();
+		    }
+		    sb.append(value.substring(last));
+		    value = sb.toString();
+		    
+		    matcher = Pattern.compile("<CardInfo id=\"" + cardNr + "\" Name=\"(.*?)\"").matcher(s1);
+		    if (!matcher.find())
+		    	throw new BankException("Coldn't parse name!");
+		    String name = matcher.group(1);
+		    
+		    accounts.add(new Account(name, BigDecimal.valueOf(Double.parseDouble(value)), "1"));
+		}
+		catch (Exception e)
+		{
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			super.updateComplete();
+		}
+	}
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 0a8beb2..df2028e 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -81,4 +81,5 @@ public interface IBankTypes {
     public static final int MENIGA = 57;
     public static final int RIKSKORTET = 58;
     public static final int BIOKLUBBEN = 59;
+    public static final int CHALMREST = 60;
 }

commit 0b155e7bfc0d990f38ae23053a16309f181e32c9
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Mon Aug 6 21:15:01 2012 +0200

    Add skeleton for Marginalen bank.

diff --git res/drawable/logo_marginalen.png res/drawable/logo_marginalen.png
new file mode 100644
index 0000000..00c3999
Binary files /dev/null and res/drawable/logo_marginalen.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index cd2b6aa..e1c1b04 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -80,6 +80,7 @@ import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Meniga;
+import com.liato.bankdroid.banking.banks.Marginalen;
 import com.liato.bankdroid.banking.banks.Nordea.Nordea;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
@@ -214,6 +215,8 @@ public class BankFactory {
             return new TicketRikskortet(context);
         case IBankTypes.BIOKLUBBEN:
             return new Bioklubben(context);
+        case IBankTypes.MARGINALEN:
+            return new Marginalen(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -281,6 +284,7 @@ public class BankFactory {
         banks.add(new Meniga(context));
         banks.add(new TicketRikskortet(context));
         banks.add(new Bioklubben(context));
+        banks.add(new Marginalen(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Marginalen.java src/com/liato/bankdroid/banking/banks/Marginalen.java
new file mode 100644
index 0000000..cd4cc72
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Marginalen.java
@@ -0,0 +1,32 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+public class Marginalen extends Bank {
+	private static final String TAG = "Marginalen";
+    private static final String NAME = "Marginalen Bank";
+    private static final String NAME_SHORT = "marginalen";
+    private static final String URL = "https://secure1.marginalen.se/marginalen/engine";
+    
+    public Marginalen(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+//        super.BANKTYPE_ID = BANKTYPE_ID;
+//        super.URL = URL;
+//        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+//        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+//        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+    
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+    }
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 0a8beb2..3efb17d 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -81,4 +81,5 @@ public interface IBankTypes {
     public static final int MENIGA = 57;
     public static final int RIKSKORTET = 58;
     public static final int BIOKLUBBEN = 59;
+    public static final int MARGINALEN = 60;
 }

commit 0a83dd9d1fe59a360ae433720db937b67c472a64
Author: Jacob Siverskog <jacob.siverskog#gh@gmail.com>
Date:   Mon Aug 6 21:09:17 2012 +0200

    Compare banks by name.
    
    Compare banks by name to get a better ordering of the list of banks.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index f73b0b8..bddc6f3 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -310,7 +310,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public int compareTo(Bank another) {
-        return this.toString().compareToIgnoreCase(another.getName());
+        return this.getName().compareToIgnoreCase(another.getName());
     }
 
     public void updateComplete() {

commit a08067e948faa7693c8e8b3bdad24db47d92767c
Author: liato <x@x00.us>
Date:   Sun Jul 8 13:17:53 2012 +0200

    Fix for SEB.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 7cb2c1a..e234427 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -94,7 +94,7 @@ public class SEB extends Bank {
 		try {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (!response.contains("passwordLoginOK")) {
+			if (response.contains("elaktig inloggning")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		} catch (ClientProtocolException e) {

commit f6ff810065ddc3ad0c8b6c4fbc1349a59b41e1c6
Author: liato <x@x00.us>
Date:   Sun Jul 8 12:44:01 2012 +0200

    Fix for PayPal.

diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 0bdb09f..6e06498 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -51,7 +51,7 @@ public class PayPal extends Bank {
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 	private static final boolean STATIC_BALANCE = true;
 	
-	private Pattern reFormAction = Pattern.compile("<form.*?login_form.*?action=\"([^\"]+)\".*?>", Pattern.CASE_INSENSITIVE);
+	private Pattern reFormAction = Pattern.compile("<form.*?action=\"([^\"]+)\".*?login_form.*?>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
 	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
 	private String response = null;

commit 63c741af00e5b866ecc546b0fbb52b7944e7d7c9
Author: liato <x@x00.us>
Date:   Sun Jul 8 12:35:20 2012 +0200

    Don't display decimals for Bioklubben.

diff --git src/com/liato/bankdroid/adapters/AccountsAdapter.java src/com/liato/bankdroid/adapters/AccountsAdapter.java
index 438d0a7..4470598 100644
--- src/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ src/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -85,7 +85,11 @@ public class AccountsAdapter extends BaseAdapter {
 		ImageView icon = (ImageView)convertView.findViewById(R.id.imgListitemAccountsGroup);
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(bank.getDisplayName());
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(bank.getName());
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(bank.getBalance(), bank.getCurrency(), prefs.getBoolean("round_balance", false)));
+        ((TextView) convertView
+                .findViewById(R.id.txtListitemAccountsGroupTotal))
+                .setText(Helpers.formatBalance(bank.getBalance(),
+                        bank.getCurrency(),
+                        prefs.getBoolean("round_balance", false) || !bank.getDisplayDecimals()));
 		icon.setImageResource(bank.getImageResource());
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
 		if (bank.isDisabled()) {
@@ -109,7 +113,10 @@ public class AccountsAdapter extends BaseAdapter {
         TextView txtBalance = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance));
 		txtAccountName.setText(account.getName());
 		txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
-        txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency(), prefs.getBoolean("round_balance", false)));
+        txtBalance
+                .setText(Helpers.formatBalance(account.getBalance(),
+                        account.getCurrency(),
+                        prefs.getBoolean("round_balance", false) || !account.getBank().getDisplayDecimals()));
 		if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
             txtBalance.setTextColor(Color.argb(255, 191, 191, 191));		    
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index f73b0b8..afaf4e3 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -61,6 +61,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     protected int INPUT_TITLETEXT_EXTRAS = R.string.extras_field;
     protected boolean STATIC_BALANCE = false;
     protected boolean BROKEN = false;
+    protected boolean DISPLAY_DECIMALS = true;
 
     protected Context context;
     protected Resources res;
@@ -415,5 +416,9 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             return loginTarget;
         }
     }    
+    
+    public boolean getDisplayDecimals() {
+        return DISPLAY_DECIMALS;
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
index 808f350..42128cd 100644
--- src/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -32,7 +32,6 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -45,9 +44,8 @@ public class Bioklubben extends Bank {
 	private static final String NAME_SHORT = "bioklubben";
 	private static final String URL = "http://bioklubben.sfbio.se/user/login";
 	private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
+	private static final boolean DISPLAY_DECIMALS = false;
 
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("pointsblock-bignumber-bn\">([^<]+)</div>");
 
     private String response = null;
@@ -59,6 +57,8 @@ public class Bioklubben extends Bank {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
+        super.DISPLAY_DECIMALS = DISPLAY_DECIMALS;
+        
         currency = context.getString(R.string.points);
     }
 

commit 6e8cfdc2ca98347287c9f577ae5dfb360e33caea
Merge: 8e70928 aafdc65
Author: liato <x@x00.us>
Date:   Sun Jul 8 08:00:32 2012 +0200

    Merge branch 'master' of github.com:liato/android-bankdroid

commit 8e709283ccc7a4c242391fa9d85f5b1a187d341a
Author: liato <x@x00.us>
Date:   Sun Jul 8 08:00:11 2012 +0200

    Add a stupid captcha breaker to Nordea and a tool to easily update the captcha data if the appearance of the captcha changes. Closes #152.

diff --git AndroidManifest.xml AndroidManifest.xml
index fccb2c3..a95be08 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.0" android:versionCode="136">
+	android:versionName="1.9.0" android:versionCode="138">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 784e63c..3f9bb63 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -32,8 +32,8 @@ import android.widget.Toast;
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.Swedbank;
+import com.liato.bankdroid.banking.banks.Nordea.Nordea;
 import com.liato.bankdroid.lockpattern.ChooseLockPattern;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index e782d82..cd2b6aa 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -46,7 +46,6 @@ import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.McDonalds;
-import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.Nordnetdirekt;
@@ -81,6 +80,7 @@ import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.banks.Meniga;
+import com.liato.bankdroid.banking.banks.Nordea.Nordea;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
diff --git src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreaker.java src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreaker.java
new file mode 100644
index 0000000..f3b9503
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreaker.java
@@ -0,0 +1,85 @@
+package com.liato.bankdroid.banking.banks.Nordea;
+
+import java.util.ArrayList;
+
+import android.graphics.Bitmap;
+
+public class CaptchaBreaker {
+    private final static int[][][] NUMBERS = CaptchaBreakerNumbers.NUMBERS;
+    
+    public static String iMustBreakYou(Bitmap bitmap) {
+        int width = bitmap.getWidth();
+        int height = bitmap.getHeight();
+        
+        ArrayList<Segment> segments = new ArrayList<Segment>();
+
+        boolean numberpart = false;
+        Segment segment = new Segment();
+        for (int x = 0; x < width; x++) {
+            boolean numberpartcol = false;
+            for (int y = 0; y < height; y++) {
+                int color = bitmap.getPixel(x, y);
+                if (color != 0xffffffff) {
+                    if (!numberpart) {
+                        segment.start = x;
+                    }
+                    numberpart = numberpartcol = true;
+                    break;
+                }
+            }
+            if (numberpart && !numberpartcol) {            
+                numberpart = false;
+                segment.end = x-1;
+                segments.add(segment);
+                segment = new Segment();
+            }
+        }
+        if (segment.end == -1 && segment.start >= 0) {
+            segment.end = width-1;
+            segments.add(segment);
+        }
+        StringBuilder sb = new StringBuilder(segments.size());
+        for (Segment s : segments) {
+            Bitmap numberSegment = Bitmap.createBitmap(bitmap, s.start, 0, s.end-s.start, height);
+            sb.append(extractNumber(numberSegment));
+            numberSegment.recycle();
+            numberSegment = null;
+        }
+        return sb.toString();
+
+    }
+    
+    private final static String extractNumber(Bitmap bitmap) {
+        int width = bitmap.getWidth();
+        for (int i = 0; i < NUMBERS.length; i++) {
+            int matches = 0;
+            int[][] number = NUMBERS[i];
+            for (int pi = 0; pi < number.length; pi++) {
+                int[] point = number[pi];
+                if (point[0] >= width) {
+                    break;
+                }
+                int color = bitmap.getPixel(point[0], point[1]);
+                if ((color == 0xffffffff && point[2] == 0) || (color != 0xffffffff && point[2] == 1)) {
+                    matches ++;
+                }
+            }
+            if (matches == number.length) {
+                return Integer.toString(i);
+            }
+        }
+        return "?";
+    }
+    
+
+}
+    
+class Segment {
+    public int start = -1;
+    public int end = -1;
+    
+    @Override
+    public String toString() {
+        return String.format("Segment {start=%d, end=%d}", start, end);
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreakerNumbers.java src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreakerNumbers.java
new file mode 100644
index 0000000..f292edd
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Nordea/CaptchaBreakerNumbers.java
@@ -0,0 +1,90 @@
+package com.liato.bankdroid.banking.banks.Nordea;
+
+/**
+ * Autogenerated captcha numbers for Nordea.
+ * 
+ * @since 2012-07-08 05:51:25
+ */
+public class CaptchaBreakerNumbers {
+    public final static int[][][] NUMBERS = {
+            { { 7, 12, 0 }, { 6, 22, 1 }, { 11, 18, 0 }, { 4, 9, 1 },
+                    { 0, 14, 1 }, { 5, 27, 0 }, { 2, 27, 0 }, { 5, 17, 1 },
+                    { 9, 17, 0 }, { 17, 1, 0 }, { 8, 9, 0 }, { 11, 15, 0 },
+                    { 1, 15, 1 }, { 15, 1, 0 }, { 15, 3, 1 }, { 8, 0, 1 },
+                    { 4, 0, 0 }, { 9, 3, 0 }, { 14, 1, 1 }, { 16, 20, 1 },
+                    { 9, 6, 0 }, { 9, 18, 0 }, { 15, 5, 1 }, { 0, 13, 1 },
+                    { 5, 18, 1 }, { 15, 17, 1 }, { 12, 25, 1 }, { 6, 16, 0 },
+                    { 11, 16, 0 }, { 16, 28, 0 }, { 16, 27, 0 }, { 6, 1, 1 } },
+            { { 7, 27, 0 }, { 8, 4, 1 }, { 5, 5, 1 }, { 12, 25, 1 },
+                    { 0, 25, 1 }, { 11, 16, 0 }, { 8, 26, 0 }, { 3, 27, 0 },
+                    { 2, 27, 0 }, { 9, 4, 1 }, { 5, 0, 0 }, { 7, 7, 1 },
+                    { 10, 20, 0 }, { 12, 11, 0 }, { 1, 11, 0 }, { 3, 1, 1 },
+                    { 4, 18, 0 }, { 0, 24, 1 }, { 1, 16, 0 }, { 9, 27, 0 },
+                    { 3, 22, 0 }, { 7, 21, 1 }, { 11, 18, 0 }, { 6, 24, 1 },
+                    { 0, 20, 0 }, { 13, 16, 0 }, { 7, 11, 1 }, { 8, 12, 1 },
+                    { 10, 22, 0 }, { 3, 24, 1 }, { 3, 12, 0 }, { 8, 27, 0 } },
+            { { 3, 10, 0 }, { 12, 18, 0 }, { 14, 25, 1 }, { 13, 10, 1 },
+                    { 10, 19, 0 }, { 11, 21, 0 }, { 1, 15, 0 }, { 1, 27, 0 },
+                    { 10, 10, 1 }, { 0, 14, 0 }, { 10, 21, 0 }, { 12, 1, 1 },
+                    { 5, 9, 0 }, { 9, 27, 0 }, { 7, 18, 1 }, { 12, 0, 1 },
+                    { 11, 18, 0 }, { 2, 10, 0 }, { 1, 7, 0 }, { 6, 27, 0 },
+                    { 3, 25, 1 }, { 9, 25, 1 }, { 12, 23, 1 }, { 2, 1, 1 },
+                    { 8, 25, 1 }, { 0, 20, 1 }, { 12, 16, 0 }, { 8, 8, 0 },
+                    { 11, 5, 1 }, { 11, 17, 0 }, { 0, 3, 0 }, { 1, 18, 0 } },
+            { { 10, 9, 1 }, { 3, 11, 1 }, { 2, 2, 1 }, { 7, 20, 0 },
+                    { 8, 24, 1 }, { 5, 14, 1 }, { 12, 25, 1 }, { 1, 17, 0 },
+                    { 0, 15, 0 }, { 2, 18, 0 }, { 6, 27, 0 }, { 0, 22, 1 },
+                    { 13, 8, 1 }, { 2, 21, 0 }, { 13, 23, 1 }, { 11, 7, 1 },
+                    { 13, 26, 0 }, { 2, 18, 0 }, { 5, 27, 0 }, { 2, 27, 0 },
+                    { 0, 1, 1 }, { 4, 18, 0 }, { 4, 7, 0 }, { 13, 27, 0 },
+                    { 10, 17, 0 }, { 9, 2, 1 }, { 7, 1, 1 }, { 8, 20, 0 },
+                    { 13, 25, 0 }, { 13, 26, 0 }, { 6, 0, 1 }, { 2, 0, 1 } },
+            { { 10, 5, 1 }, { 18, 3, 0 }, { 6, 16, 1 }, { 16, 6, 1 },
+                    { 17, 20, 0 }, { 16, 22, 1 }, { 3, 19, 0 }, { 15, 28, 0 },
+                    { 10, 7, 1 }, { 16, 23, 1 }, { 11, 9, 0 }, { 13, 24, 1 },
+                    { 15, 7, 1 }, { 3, 19, 0 }, { 9, 12, 0 }, { 3, 8, 0 },
+                    { 10, 10, 0 }, { 13, 0, 1 }, { 15, 3, 1 }, { 12, 2, 1 },
+                    { 13, 8, 1 }, { 16, 3, 1 }, { 2, 14, 1 }, { 9, 9, 0 },
+                    { 8, 23, 0 }, { 6, 27, 0 }, { 8, 0, 0 }, { 0, 16, 1 },
+                    { 10, 2, 1 }, { 13, 13, 1 }, { 13, 10, 1 }, { 8, 5, 1 } },
+            { { 2, 14, 0 }, { 3, 20, 0 }, { 3, 4, 0 }, { 13, 13, 1 },
+                    { 1, 15, 0 }, { 2, 13, 0 }, { 6, 21, 0 }, { 3, 20, 0 },
+                    { 11, 0, 1 }, { 4, 16, 0 }, { 13, 14, 1 }, { 11, 2, 1 },
+                    { 2, 23, 1 }, { 0, 22, 1 }, { 7, 20, 0 }, { 11, 9, 0 },
+                    { 0, 23, 1 }, { 14, 7, 0 }, { 9, 8, 0 }, { 8, 22, 1 },
+                    { 6, 2, 1 }, { 1, 0, 1 }, { 13, 19, 1 }, { 7, 20, 0 },
+                    { 9, 14, 1 }, { 4, 5, 0 }, { 8, 25, 1 }, { 0, 26, 0 },
+                    { 3, 5, 0 }, { 11, 17, 1 }, { 4, 18, 0 }, { 4, 3, 1 } },
+            { { 0, 5, 0 }, { 2, 3, 1 }, { 10, 0, 1 }, { 4, 8, 1 }, { 3, 6, 1 },
+                    { 12, 10, 1 }, { 13, 1, 1 }, { 7, 12, 1 }, { 5, 7, 1 },
+                    { 9, 21, 0 }, { 0, 4, 0 }, { 3, 28, 0 }, { 13, 9, 1 },
+                    { 10, 12, 1 }, { 4, 4, 1 }, { 13, 22, 1 }, { 13, 10, 1 },
+                    { 7, 1, 1 }, { 6, 22, 1 }, { 11, 16, 0 }, { 4, 9, 1 },
+                    { 15, 14, 1 }, { 12, 18, 0 }, { 13, 1, 1 }, { 4, 27, 0 },
+                    { 9, 0, 1 }, { 12, 13, 1 }, { 4, 13, 1 }, { 17, 4, 0 },
+                    { 16, 6, 0 }, { 14, 12, 1 }, { 7, 23, 1 } },
+            { { 12, 3, 1 }, { 0, 22, 0 }, { 8, 27, 0 }, { 15, 19, 0 },
+                    { 12, 3, 1 }, { 9, 7, 0 }, { 4, 6, 0 }, { 7, 4, 0 },
+                    { 9, 23, 0 }, { 14, 0, 1 }, { 2, 15, 0 }, { 7, 0, 1 },
+                    { 6, 18, 1 }, { 11, 11, 1 }, { 6, 10, 0 }, { 11, 20, 0 },
+                    { 13, 10, 0 }, { 13, 2, 1 }, { 15, 5, 1 }, { 5, 13, 0 },
+                    { 10, 8, 1 }, { 10, 16, 0 }, { 4, 19, 1 }, { 8, 28, 0 },
+                    { 8, 16, 1 }, { 13, 4, 1 }, { 15, 22, 0 }, { 15, 10, 0 },
+                    { 3, 12, 0 }, { 13, 6, 1 }, { 3, 5, 0 }, { 12, 23, 0 } },
+            { { 5, 27, 0 }, { 5, 3, 1 }, { 5, 24, 1 }, { 17, 18, 1 },
+                    { 8, 13, 1 }, { 1, 14, 1 }, { 9, 19, 0 }, { 2, 26, 0 },
+                    { 3, 13, 1 }, { 4, 19, 1 }, { 12, 15, 1 }, { 7, 28, 0 },
+                    { 13, 0, 1 }, { 8, 22, 1 }, { 11, 25, 1 }, { 11, 5, 0 },
+                    { 6, 23, 1 }, { 0, 16, 1 }, { 4, 0, 0 }, { 17, 25, 0 },
+                    { 12, 22, 1 }, { 6, 13, 1 }, { 7, 19, 0 }, { 9, 19, 0 },
+                    { 11, 23, 1 }, { 11, 8, 0 }, { 17, 11, 0 }, { 12, 25, 1 },
+                    { 1, 26, 0 }, { 15, 5, 1 }, { 0, 18, 1 }, { 7, 11, 1 } },
+            { { 6, 24, 1 }, { 14, 13, 1 }, { 0, 3, 0 }, { 8, 6, 0 },
+                    { 3, 12, 1 }, { 7, 21, 0 }, { 7, 26, 0 }, { 10, 28, 0 },
+                    { 3, 23, 1 }, { 7, 1, 1 }, { 6, 0, 1 }, { 13, 0, 1 },
+                    { 12, 28, 0 }, { 15, 15, 1 }, { 6, 24, 1 }, { 11, 5, 0 },
+                    { 3, 20, 0 }, { 9, 12, 0 }, { 2, 15, 1 }, { 4, 21, 0 },
+                    { 13, 11, 1 }, { 3, 8, 1 }, { 17, 16, 1 }, { 13, 9, 0 },
+                    { 3, 1, 1 }, { 14, 10, 1 }, { 3, 19, 0 }, { 14, 7, 1 },
+                    { 15, 19, 1 }, { 3, 1, 1 }, { 8, 19, 0 }, { 11, 13, 1 } } };
+}
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
similarity index 86%
rename from src/com/liato/bankdroid/banking/banks/Nordea.java
rename to src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
index 58f326a..a87e192 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea/Nordea.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banking.banks;
+package com.liato.bankdroid.banking.banks.Nordea;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -27,6 +28,8 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
@@ -104,6 +107,32 @@ public class Nordea extends Bank {
 			if (response.contains("felaktiga uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
+			else if (response.contains("nloggningar med ditt personnummer idag")) {
+		        Matcher matcher = reCSRF.matcher(response);
+		        if (!matcher.find()) {
+		            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+		        }
+		        String csrftoken = matcher.group(1);
+		        Iterator<NameValuePair> it = lp.getPostData().iterator();
+		        while (it.hasNext()) {
+		            NameValuePair nv = it.next();
+                    if (nv.getName().equals("_csrf_token")) {
+                        it.remove();
+                        break;
+                    }
+		        }
+		        lp.getPostData().add(new BasicNameValuePair("_csrf_token", csrftoken));
+			    //Too many logins, we need to solve a captcha.
+			    Bitmap bm = BitmapFactory.decodeStream(urlopen.openStream("https://mobil.nordea.se/banking-nordea/nordea-c3/captcha.png"));
+			    String captcha = CaptchaBreaker.iMustBreakYou(bm);
+			    bm.recycle();
+			    bm = null;
+			    lp.getPostData().add(new BasicNameValuePair("captcha", captcha));
+	            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+	            if (response.contains("felaktiga uppgifter")) {
+	                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+	            }
+			}
 			
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index afc7eff..d639fbc 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -17,11 +17,12 @@
 package eu.nullbyte.android.urllib;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
-import org.apache.http.HttpHost;
+import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.NameValuePair;
@@ -44,7 +45,6 @@ import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 
@@ -103,44 +103,66 @@ public class Urllib {
     	return open(url, postData, false);
     }
    
+    
     public String open(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
-            	this.currentURI = url;
-    	String response;
+        this.currentURI = url;
+        String response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
-    	ResponseHandler<String> responseHandler = new BasicResponseHandler();
-    	if (postData.isEmpty() && !forcePost) {
-    		//URL urli = new URL(url); 
-    		HttpGet urlConnection = new HttpGet(url);
-
-    		if (userAgent != null)
-    			urlConnection.addHeader("User-Agent", userAgent);
-            
-    		for (int i = 0; i < headerKeys.length; i++) {
-                urlConnection.addHeader(headerKeys[i], headerVals[i]);
-            }
-    		response = httpclient.execute(urlConnection, responseHandler, context);
-    	}
-    	else {
-    		HttpPost urlConnection = new HttpPost(url);
-    		urlConnection.setEntity(new UrlEncodedFormEntity(postData, this.charset));
-    		
-    		if (userAgent != null)
-    			urlConnection.addHeader("User-Agent", userAgent);
-            
-    		for (int i = 0; i < headerKeys.length; i++) {
-                urlConnection.addHeader(headerKeys[i], headerVals[i]);
-            }
-    		response = httpclient.execute(urlConnection, responseHandler, context); 
-    	}
-
-        HttpUriRequest currentReq = (HttpUriRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
-        HttpHost currentHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
-        this.currentURI = currentHost.toURI() + currentReq.getURI();
+        ResponseHandler<String> responseHandler = new BasicResponseHandler();
+        HttpUriRequest request;
+        if ((postData == null || postData.isEmpty()) && !forcePost) {
+            //URL urli = new URL(url); 
+            request = new HttpGet(url);
+        }
+        else {
+            request = new HttpPost(url);
+            ((HttpPost)request).setEntity(new UrlEncodedFormEntity(postData, this.charset));
+        }
+        if (userAgent != null)
+            request.addHeader("User-Agent", userAgent);
+        
+        for (int i = 0; i < headerKeys.length; i++) {
+            request.addHeader(headerKeys[i], headerVals[i]);
+        }
+        response = httpclient.execute(request, responseHandler, context);
+        
+        //HttpUriRequest currentReq = (HttpUriRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
+        //HttpHost currentHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+        //this.currentURI = currentHost.toURI() + currentReq.getURI();
+        this.currentURI = request.getURI().toString();
         
-    	return response;
+        return response;
+    }    
+    public InputStream openStream(String url) throws ClientProtocolException, IOException {
+        return openStream(url, null, false);
     }
     
+    public InputStream openStream(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+        this.currentURI = url;
+        String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
+        String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
+        HttpUriRequest request;
+        if ((postData == null || postData.isEmpty()) && !forcePost) {
+            //URL urli = new URL(url); 
+            request = new HttpGet(url);
+        }
+        else {
+            request = new HttpPost(url);
+            ((HttpPost)request).setEntity(new UrlEncodedFormEntity(postData, this.charset));
+        }
+        if (userAgent != null)
+            request.addHeader("User-Agent", userAgent);
+        
+        for (int i = 0; i < headerKeys.length; i++) {
+            request.addHeader(headerKeys[i], headerVals[i]);
+        }
+        this.currentURI = request.getURI().toString();
+        HttpResponse response = httpclient.execute(request);
+        HttpEntity entity = response.getEntity();
+        return entity.getContent();
+    }        
+    
     public void close() {
         httpclient.getConnectionManager().shutdown();
     }
diff --git tools/nordea_captcha_breaker/captchabreaker.py tools/nordea_captcha_breaker/captchabreaker.py
new file mode 100644
index 0000000..1120224
--- /dev/null
+++ tools/nordea_captcha_breaker/captchabreaker.py
@@ -0,0 +1,187 @@
+import datetime
+import os
+import random
+import subprocess
+import urllib2
+
+from PIL import Image
+
+confirmed = {}
+imgdata = {}
+
+def guess_number(img):
+    width, height = img.size
+    img = img.load()
+    for number in confirmed.values():
+        matches = 0
+        for point in number.points:
+            if point[0] >= width:
+                break
+            color = img[point[0], point[1]]
+            color = (color[0] << 16) + (color[1] << 8) + color[2]
+            if (color == 0xffffff and not point[2]) or (color != 0xffffff and point[2]):
+                matches += 1
+        #print "matches: %d " % matches
+        if matches == len(number.points):
+            return number.number
+    return None
+
+def getCaptcha():
+    print "Downloading new captcha..."
+    r = urllib2.urlopen("https://mobil.nordea.se/banking-nordea/nordea-c3/captcha.png")
+    f = open("captcha.png", "wb")
+    f.write(r.read())
+    f.close()
+    img = Image.open("captcha.png")
+    print "Captcha downloaded."
+    return img
+
+def extract_numbers(img):
+    pixels = img.load()
+    width, height = img.size
+    numbers = []
+
+    numberpart = False
+    current_start = None
+    current_end = None
+    for x in range(width-1):
+        numberpartcol = False
+        for y in range(height-1):
+            color = pixels[x, y]
+            color = (color[0] << 16) + (color[1] << 8) + color[2]
+            if color != 0xffffff:
+                if not numberpart:
+                    #print "Start at %d" % x
+                    current_start = x
+                numberpart = numberpartcol = True
+                break
+
+        if numberpart and not numberpartcol:            
+            numberpart = False
+            #print "End at %d" % (x-1,)
+            current_end = x-1
+            numbers.append((current_start, current_end))
+
+    if current_end is None:
+        numbers.append((current_start, width-1))
+
+    return numbers
+
+def numbers2text(img, numbers):
+    text = []
+    width, height = img.size
+    for i, slice in enumerate(numbers):
+        number = img.crop((slice[0], 0, slice[1], height-1))
+        numguess = guess_number(number)
+        text.append(numguess)
+    return "".join(text)
+
+
+
+class CaptchaNumber(object):
+    def __init__(self, number, points):
+        self.number = number
+        self.points = points
+
+    def __repr__(self):
+        return '<CaptchaNumber(%d)>' % number
+        
+
+def main():
+    while True:
+        img = getCaptcha()
+        width, height = img.size
+        print "Image size: %dx%d" % (width, height)
+        numbers = extract_numbers(img)
+        print "Found %d numbers in captcha" % len(numbers)
+        for i, slice in enumerate(numbers):
+            number = img.crop((slice[0], 0, slice[1], height-1))
+
+            fname = "tempslice.png"
+            number.save(fname)
+            #print "Number: width: %d, height: %d" % number.size
+            pixels = number.load()
+            numguess = guess_number(number)
+            #os.system(fname)
+            #if numguess is not None:
+            #    correct = raw_input("Does the image display number %s? y/n: " % numguess)
+            #    if not correct.startswith("y"):
+            #        numguess = None
+
+
+            if numguess is None:
+                os.system(fname)
+                num = raw_input("Number in image?: ")
+                points = []
+                for j in range(32):
+                    x = random.randint(0, number.size[0]-1)
+                    y = random.randint(0, number.size[1]-1)
+                    color = pixels[x, y]
+                    color = (color[0] << 16) + (color[1] << 8) + color[2]
+                    points.append((x, y, color != 0xffffff))
+                confirmed[num] = CaptchaNumber(num, points)
+                imgdata[num] = number
+
+                if len(confirmed) < 10:
+                    confirmed_sorted = confirmed.keys()
+                    confirmed_sorted.sort()
+                    print "Confirmed numbers: %s" % confirmed_sorted
+                else:
+                    break
+
+        if len(confirmed) == 10:
+            print "All numbers collected. Creating html and java files."
+            break
+
+
+def create_html():
+    print "Downloading 100 captchas for testing..."
+    date = str(datetime.datetime.today())[:19]
+    dir = os.path.join(os.getcwd(), date.replace("-","").replace(":","").replace(" ", ""))
+    os.makedirs(dir)
+    for i in range(100):
+        f = open(os.path.join(dir, "captcha%03d.png" % (i+1)), "wb")
+        r = urllib2.urlopen("https://mobil.nordea.se/banking-nordea/nordea-c3/captcha.png")
+        f.write(r.read())
+        f.close()
+    print "Done."
+    html = open("captchas_template.html", "r").read()
+    html_item = open("captchas_item_template.html", "r").read()
+    captchas = []
+    for i in range(100):
+        img = Image.open(os.path.join(dir, "captcha%03d.png" % (i+1)))
+        captcha_item = html_item
+        captcha_item = captcha_item.replace("%decaptcha%", numbers2text(img, extract_numbers(img))).replace("%number%", "%03d" % (i+1))
+        captchas.append(captcha_item)
+    html = html.replace("%captchas%", "\n".join(captchas)).replace("%date%", date)
+    f = open(os.path.join(dir, "captchas.html"), "w")
+    f.write(html)
+    f.close()
+    os.system(os.path.join(dir, "captchas.html"))
+    javadata = []
+    for x in range(len(confirmed.keys())):
+        points = []
+        captcha_number = confirmed[str(x)];
+        for point in captcha_number.points:
+            points.append((int(point[0]), int(point[1]), 1 if point[2] else 0))
+        javadata.append(points)
+    javadata = str(javadata).replace("[","{").replace("]","}").replace("(","{").replace(")","}")
+    javadata = """
+/**
+ * Autogenerated captcha numbers for Nordea.
+ *
+ * @since %s
+ */
+public class CaptchaBreakerNumbers {
+    public final static int[][][] NUMBERS = %s;
+}
+""" % (date, javadata)
+    f = open(os.path.join(dir, "CaptchaBreakerNumbers.java"), "w")
+    f.write(javadata)
+    f.close()
+    print "CaptchaBreakerNumbers.java generated."
+    print "All done."
+
+if __name__ == '__main__':
+    main()
+    create_html()
\ No newline at end of file
diff --git tools/nordea_captcha_breaker/captchas_item_template.html tools/nordea_captcha_breaker/captchas_item_template.html
new file mode 100644
index 0000000..c420269
--- /dev/null
+++ tools/nordea_captcha_breaker/captchas_item_template.html
@@ -0,0 +1,5 @@
+        <div class="captcha-block">
+            <div class="number">%number%</div>
+            <div class="captcha"><img src="captcha%number%.png"></div>
+            <div class="decaptcha">%decaptcha%</div>
+        </div>
\ No newline at end of file
diff --git tools/nordea_captcha_breaker/captchas_template.html tools/nordea_captcha_breaker/captchas_template.html
new file mode 100644
index 0000000..929b794
--- /dev/null
+++ tools/nordea_captcha_breaker/captchas_template.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+    <title>Nordea Captchas</title>
+    <style type="text/css">
+    body {
+        font-family: Arial, helvetica, sans-serif;
+        background: #f8f8f8;
+        color: #363636;
+    }
+    .captcha-block {
+        display: inline-block;
+        padding: 10px;
+        border-bottom: solid #e3e3e3 1px; 
+        border-right: solid #e3e3e3 1px; 
+    }
+    .decaptcha {
+        font-family: monospace;
+        font-size: 40px;
+        font-weight: bold;
+        background-color: #fff;
+        display: inline-block;
+    }
+    .captcha {
+        margin-top: 3px;
+    }
+    .number {
+        background-color: #72a3f3;
+        color: #fff;
+        display: table-cell;
+        padding: 2px 4px;
+    }
+    .container {
+        max-width: 900px;
+    }
+    p {
+        font-size: 11px;
+
+    }
+    </style>
+</head>
+<body>
+    <h1>Nordea Captchas</h1>
+    <div class="container">
+        %captchas%
+    </div>
+    <p>Generated on %date%</p>
+</body>
\ No newline at end of file

commit 1418b14ea839a47313401b781c054ca5179c46b0
Author: liato <x@x00.us>
Date:   Sun Jul 8 07:07:26 2012 +0200

    SSL fix for Bioklubben.

diff --git logos.psd logos.psd
index 8e92825..5bd6fc6 100644
Binary files logos.psd and logos.psd differ
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
index ffd8e9b..808f350 100644
--- src/com/liato/bankdroid/banking/banks/Bioklubben.java
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -71,7 +71,7 @@ public class Bioklubben extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(true);
         /*
         response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
         Matcher matcher = reViewState.matcher(response);

commit aafdc65084cf0d2d686a7d3deff9400ef1e258c0
Merge: 50ebd2e a91fa33
Author: liato <x@x00.us>
Date:   Tue Jul 3 11:00:30 2012 -0700

    Merge pull request #154 from erifre/master
    
    Västtrafik changed their html

commit a91fa332961e681ba03a16edeeeb57ee23c09f23
Author: Erik Fredriksen <erik@fredriksen.se>
Date:   Tue Jul 3 04:50:00 2012 +0200

    Västtrafik changed their html. Fixes the parser.

diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
index a293a9b..63d5819 100644
--- src/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -48,7 +48,7 @@ public class Vasttrafik extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("<div class=\"myCardsItemContainer\" data-cardnumber=\"\\d+\">.*?<h3 class=\"cardName grid_12 clearMargin\">(.*?)</h3>.*?<span class=\"cardNumber\">(\\d+)</span>.*?<div class=\"clearfix cardCharges\">(.*?)<div class=\"clearfix paddingBottom grid_12 cardOptions\">", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("<div class=\"myCardsItemContainer\" data-cardnumber=\"(.*?)\">.*?<h3 class=\"cardName grid_12 clearMargin\">(.*?)</h3>.*?<div class=\"clearfix cardCharges\">(.*?)<div class=\"clearfix paddingBottom grid_12 cardOptions(.*?)\">", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
 	private Pattern reBalance = Pattern.compile("<span class=\"chargeType boldType\">(.*?): (.*?)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
 	private String response = null;
 
@@ -66,7 +66,6 @@ public class Vasttrafik extends Bank {
         this.update(username, password);
     }
 
-
     @Override
     protected LoginPackage preLogin() throws BankException,
     ClientProtocolException, IOException {
@@ -124,11 +123,15 @@ public class Vasttrafik extends Bank {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
-                 * 1: Name              Nytt
-                 * 2: Card number       1111111111
+                 * 1: Card number       1111111111
+                 * 2: Name              Nytt
                  * 3: Balance information
                  */
 
+				if ("".equals(matcher.group(1))) {
+					continue;
+				}
+
                 matcher_b = reBalance.matcher(matcher.group(3));
                 if (matcher_b.find()) {
                     /*
@@ -140,7 +143,7 @@ public class Vasttrafik extends Bank {
 
 					String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
 
-					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(2)));
+					accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(1)));
 					balance = balance.add(Helpers.parseBalance(balanceString));
                 }
             }

commit 0cb51eac01866b908308a74d7856db61b8fa01c8
Author: Erik Fredriksen <erik@fredriksen.se>
Date:   Tue Jul 3 04:48:46 2012 +0200

    Fixed the login error message

diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
index e3e5cc2..a293a9b 100644
--- src/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -89,11 +89,12 @@ public class Vasttrafik extends Bank {
         return new LoginPackage(urlopen, postData, response, "https://www.vasttrafik.se/mina-sidor/logga-in/?ReturnUrl=/mina-sidor-inloggad/mina-kort/");
     }
 
+    @Override
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (!response.contains("Inloggad som:")) {
+            if (!response.contains("<span class=\"loggedInAs\">")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         }

commit 50ebd2e433dd78ab12301242bb3a208a2be26d97
Author: liato <x@x00.us>
Date:   Mon Jun 25 20:50:49 2012 +0200

    Add support for Bioklubben. Closes #142.

diff --git AndroidManifest.xml AndroidManifest.xml
index e451db3..fccb2c3 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.9.0-RC1" android:versionCode="135">
+	android:versionName="1.9.0" android:versionCode="136">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/drawable/logo_bioklubben.png res/drawable/logo_bioklubben.png
new file mode 100644
index 0000000..0860acb
Binary files /dev/null and res/drawable/logo_bioklubben.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index e1b0a69..6b2c72c 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -252,4 +252,6 @@
     <!-- Color Picker -->
     <string name="dialog_color_picker">Färgväljare</string>
     <string name="press_color_to_apply">Tryck på färgen för att välja</string>    
+    
+    <string name="points">poäng</string>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index f9b0b50..51a6522 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -304,4 +304,6 @@
     <!-- Color Picker -->
     <string name="dialog_color_picker">Color Picker</string>
     <string name="press_color_to_apply">Press on Color to apply</string>    
+    
+    <string name="points">points</string>
 </resources>
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 1789cff..e782d82 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -26,6 +26,7 @@ import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.Bioklubben;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.Coop;
@@ -211,6 +212,8 @@ public class BankFactory {
             return new Meniga(context);
         case IBankTypes.RIKSKORTET:
             return new TicketRikskortet(context);
+        case IBankTypes.BIOKLUBBEN:
+            return new Bioklubben(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -277,6 +280,7 @@ public class BankFactory {
         banks.add(new Everydaycard(context));
         banks.add(new Meniga(context));
         banks.add(new TicketRikskortet(context));
+        banks.add(new Bioklubben(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Bioklubben.java src/com/liato/bankdroid/banking/banks/Bioklubben.java
new file mode 100644
index 0000000..ffd8e9b
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Bioklubben.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Bioklubben extends Bank {
+	private static final String TAG = "Bioklubben";
+	private static final String NAME = "Bioklubben";
+	private static final String NAME_SHORT = "bioklubben";
+	private static final String URL = "http://bioklubben.sfbio.se/user/login";
+	private static final int BANKTYPE_ID = Bank.BIOKLUBBEN;
+
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reBalance = Pattern.compile("pointsblock-bignumber-bn\">([^<]+)</div>");
+
+    private String response = null;
+    
+    public Bioklubben(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        currency = context.getString(R.string.points);
+    }
+
+    public Bioklubben(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        /*
+        response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String viewState = matcher.group(1);
+
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String eventValidation = matcher.group(1);            
+        */
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("name", username));
+        postData.add(new BasicNameValuePair("pass", password));
+        postData.add(new BasicNameValuePair("form_build_id", "form-5fab45c2b5bcacfe564ef96cf8329a82"));
+        postData.add(new BasicNameValuePair("form_id", "user_login"));
+        postData.add(new BasicNameValuePair("op", "Logga in"));
+        postData.add(new BasicNameValuePair("persistent_login", "1"));
+        return new LoginPackage(urlopen, postData, response, "https://bioklubben.sfbio.se/user/login");
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());         
+            if (response.contains("Felaktigt anv")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Balance           218
+             * 
+             */
+            BigDecimal b = Helpers.parseBalance(matcher.group(1));
+            Account a = new Account("Poäng", b, "1");
+            a.setCurrency(context.getString(R.string.points));
+            accounts.add(a);
+            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 1ed82c3..0a8beb2 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -80,4 +80,5 @@ public interface IBankTypes {
 	public static final int AKELIUSINVEST = 56;
     public static final int MENIGA = 57;
     public static final int RIKSKORTET = 58;
+    public static final int BIOKLUBBEN = 59;
 }

commit bea587c8d8e83b72a128b2da63c12f52da54c3f2
Author: liato <x@x00.us>
Date:   Mon Jun 25 20:47:44 2012 +0200

    Move all external libraries to libs directory.

diff --git .classpath .classpath
index 708a8ce..a139d9f 100644
--- .classpath
+++ .classpath
@@ -3,8 +3,8 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
-	<classpathentry kind="lib" path="lib/google-collect-1.0.jar"/>
 	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry kind="lib" path="libs/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="libs/google-collect-1.0.jar"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index e1e31b9..e451db3 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -6,7 +6,6 @@
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
-		android:debuggable="false"
 	    android:hardwareAccelerated="true">
 		<activity
 			android:name=".MainActivity"
diff --git lib/commons-io-2.0.1.jar libs/commons-io-2.0.1.jar
similarity index 100%
rename from lib/commons-io-2.0.1.jar
rename to libs/commons-io-2.0.1.jar
diff --git lib/google-collect-1.0.jar libs/google-collect-1.0.jar
similarity index 100%
rename from lib/google-collect-1.0.jar
rename to libs/google-collect-1.0.jar

commit 2084dce816a7418519a9e7f9840fdc200c9b6cd8
Author: liato <x@x00.us>
Date:   Mon Jun 25 03:57:45 2012 +0200

    Rename Eurobonus Mastercard to SAS EuroBonus MasterCard.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 749d216..f73b0b8 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -310,7 +310,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public int compareTo(Bank another) {
-        return this.toString().compareToIgnoreCase(another.toString());
+        return this.toString().compareToIgnoreCase(another.getName());
     }
 
     public void updateComplete() {
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 25e4aaa..1789cff 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -137,7 +137,7 @@ public class BankFactory {
             return new DinersClub(context);
         case IBankTypes.IKANOBANK:
             return new IkanoBank(context);
-        case IBankTypes.EUROBONUSMASTERCARD:
+        case IBankTypes.SASEUROBONUSMASTERCARD:
         	return new EurobonusMastercard(context);
         case IBankTypes.RIKSLUNCHEN:
             return new Rikslunchen(context);            
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 566c724..2cb141a 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -26,9 +26,9 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 public class EurobonusMastercard extends SEBKortBase {
 	private static final String TAG = "EurobonusMastercard";
-	private static final String NAME = "Eurobonus Mastercard";
+	private static final String NAME = "SAS EuroBonus MasterCard";
 	private static final String NAME_SHORT = "ebmaster";
-	private static final int BANKTYPE_ID = Bank.EUROBONUSMASTERCARD;
+	private static final int BANKTYPE_ID = Bank.SASEUROBONUSMASTERCARD;
 
 	public EurobonusMastercard(Context context) {
 		super(context, "sase", "0102");
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 27970f9..1ed82c3 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -42,7 +42,7 @@ public interface IBankTypes {
 	public final static int IKANOBANK = 18;
 	public final static int STEAM = 19;
 	public final static int DINERSCLUB = 20;
-    public final static int EUROBONUSMASTERCARD = 21;
+    public final static int SASEUROBONUSMASTERCARD = 21;
     public final static int RIKSLUNCHEN = 22;
     public final static int HEMKOP = 23;
     public final static int SEB = 24;

commit 5858e6fd6d4e9938f1f89f4f1c485d6b1d8643d0
Author: liato <x@x00.us>
Date:   Mon Jun 25 03:40:20 2012 +0200

    Update version number and code.

diff --git .classpath .classpath
index 7229329..708a8ce 100644
--- .classpath
+++ .classpath
@@ -5,5 +5,6 @@
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 	<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
 	<classpathentry kind="lib" path="lib/google-collect-1.0.jar"/>
+	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index 6ffc719..e1e31b9 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.9" android:versionCode="134">
+	android:versionName="1.9.0-RC1" android:versionCode="135">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 5c9eaee9db14e9332aacb0e81b7445434dcff498
Author: liato <x@x00.us>
Date:   Mon Jun 25 03:39:23 2012 +0200

    Add support for Ticket Rikskortet.

diff --git res/drawable/logo_rikskortet.png res/drawable/logo_rikskortet.png
new file mode 100644
index 0000000..84be5c2
Binary files /dev/null and res/drawable/logo_rikskortet.png differ
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3e72de9..25d2814 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -32,7 +32,6 @@ import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.text.InputType;
 import android.text.method.PasswordTransformationMethod;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index a353e9e..25e4aaa 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -58,6 +58,7 @@ import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
+import com.liato.bankdroid.banking.banks.TicketRikskortet;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
 import com.liato.bankdroid.banking.banks.SJPrio;
@@ -208,6 +209,8 @@ public class BankFactory {
             return new Everydaycard(context);
         case IBankTypes.MENIGA:
             return new Meniga(context);
+        case IBankTypes.RIKSKORTET:
+            return new TicketRikskortet(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -273,6 +276,7 @@ public class BankFactory {
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
         banks.add(new Meniga(context));
+        banks.add(new TicketRikskortet(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/TicketRikskortet.java src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
new file mode 100644
index 0000000..1ef6125
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/TicketRikskortet.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class TicketRikskortet extends Bank {
+
+	private static final String TAG = "Rikskortet";
+	private static final String NAME = "Ticket Rikskortet";
+	private static final String NAME_SHORT = "rikskortet";
+	private static final String URL = "https://www.edenred.se/sv/System/Logga-in/";
+	private static final int BANKTYPE_ID = Bank.RIKSKORTET;
+
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reBalance = Pattern.compile("EmployeeBalanceLabel\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s\\d{2}:\\d{2}:\\d{2}</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+
+    private String response = null;
+    
+    public TicketRikskortet(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public TicketRikskortet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        response = urlopen.open("https://www.edenred.se/sv/System/Logga-in/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String viewState = matcher.group(1);
+
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String eventValidation = matcher.group(1);            
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("ctl00$CorporateHeaderArea$CorporateHeaderID$QuickSearch$SearchText", "Sök här"));
+        postData.add(new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$UserName", username));
+        postData.add(new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$Password", password));
+        postData.add(new BasicNameValuePair("ctl00$StartpageArea$ApplicationArea$LoginControl$LoginButton", "Logga in"));
+        return new LoginPackage(urlopen, postData, response, "https://www.edenred.se/sv/System/Logga-in/");
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());         
+            if (response.contains("Inloggningen misslyckades")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        if (!"https://www.edenred.se/sv/Apps/Employee/Start/".equalsIgnoreCase(urlopen.getCurrentURI())) {
+            try {
+                response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/");
+            }
+            catch (ClientProtocolException e) {
+                throw new BankException(e.getMessage());
+            }
+            catch (IOException e) {
+                throw new BankException(e.getMessage());
+            }
+        }
+
+        Matcher matcher = reBalance.matcher(response);
+        if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Balance           590,22 kr
+             * 
+             */
+            BigDecimal b = Helpers.parseBalance(matcher.group(1));
+            accounts.add(new Account("Saldo", b, "1"));
+            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+        }
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        String response = null;
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://www.edenred.se/sv/Apps/Employee/Start/Transaktioner/");
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Trans. date       2012-06-01
+                 * 2: Specification     DANMARKSG  KISTA
+                 * 3: Amount            - 85 kr
+                 * 
+                 */
+
+                transactions.add(new Transaction(matcher.group(1), matcher.group(2).trim(), Helpers.parseBalance(matcher.group(3))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index d1ba2cb..27970f9 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -79,4 +79,5 @@ public interface IBankTypes {
     public final static int EVERYDAYCARD = 55;
 	public static final int AKELIUSINVEST = 56;
     public static final int MENIGA = 57;
+    public static final int RIKSKORTET = 58;
 }

commit 92431a580a623c729d2344ccbef4152327977715
Author: liato <x@x00.us>
Date:   Mon Jun 25 01:48:03 2012 +0200

    Fix for Eurocard.

diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 897c9f8..4222c01 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -30,7 +30,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -48,7 +47,7 @@ public class Eurocard extends Bank {
 	private static final String TAG = "Eurocard";
 	private static final String NAME = "Eurocard";
 	private static final String NAME_SHORT = "eurocard";
-	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
+	private static final String URL = "https://secure.eurocard.se/nis/external/ecse/login.do";
 	private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
@@ -80,14 +79,23 @@ public class Eurocard extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));                
-        postData.add(new BasicNameValuePair("prodgroup", "0005"));              
-        postData.add(new BasicNameValuePair("USERNAME", "0005"+username));              
-        postData.add(new BasicNameValuePair("METHOD", "LOGIN"));                
-        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));              
-        postData.add(new BasicNameValuePair("uname", username));
+        response = urlopen.open("https://secure.eurocard.se/nis/external/ecse/login.do");
+        urlopen.addHeader("Referer", String.format("https://secure.eurocard.se/nis/external/ecse/login.do"));
+        response = urlopen.open(String.format("https://secure.eurocard.se/nis/external/hidden.jsp?USERNAME=%s&CURRENT_METHOD=&referer=login.jsp", "0005"+username.toUpperCase()));
+        urlopen.removeHeader("Referer");
+        
+        postData.clear();
+        postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
+        postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
+        postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));
+        postData.add(new BasicNameValuePair("prodgroup", "0005"));
+        postData.add(new BasicNameValuePair("UID", "0005"+username.toUpperCase()));
+        postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
+        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
+        postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
         postData.add(new BasicNameValuePair("PASSWORD", password));
-        return new LoginPackage(urlopen, postData, response, "https://e-saldo.eurocard.se/siteminderagent/forms/generic.fcc");
+        
+        return new LoginPackage(urlopen, postData, response, "https://secure.eurocard.se/auth4/Authentication/select.jsp");        
     }
 
 	@Override
@@ -135,7 +143,7 @@ public class Eurocard extends Bank {
 		}
 
 		try {
-            response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getBillingUnits.do");
+            response = urlopen.open("https://secure.eurocard.se/nis/ecse/getBillingUnits.do");
             matcher = reSaldo.matcher(response);
             int i = 0;
             while (matcher.find()) {
@@ -174,7 +182,7 @@ public class Eurocard extends Bank {
 		if (account.getType() == Account.OTHER) return;
 		try {
 		    String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
+			response = urlopen.open("https://secure.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index f77ebad..267d406 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -74,7 +74,7 @@ public abstract class SEBKortBase extends Bank {
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         response = urlopen.open(String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
         urlopen.addHeader("Referer", String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
-        response = urlopen.open("https://application.sebkort.com/nis/external/hidden.jsp");
+        response = urlopen.open(String.format("https://application.sebkort.com/nis/external/hidden.jsp?USERNAME=%s&CURRENT_METHOD=&referer=login.jsp", prodgroup+username.toUpperCase()));
         urlopen.removeHeader("Referer");
         
         postData.clear();

commit fc7d7843659b8e5f02fc166a77b1467ff0da2e75
Author: liato <x@x00.us>
Date:   Mon Jun 25 01:19:58 2012 +0200

    Fix for Statoil, SAS and other SEB issued cards.

diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index f64ccae..f77ebad 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -30,7 +30,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -60,7 +59,7 @@ public abstract class SEBKortBase extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 		this.provider_part = provider_part;
 		this.prodgroup = prodgroup;
-		super.URL = String.format("https://applications.sebkort.com/nis/external/%s/login.do", provider_part);
+		super.URL = String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part);
 	}
 
 	public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException, BankChoiceException {
@@ -73,24 +72,23 @@ public abstract class SEBKortBase extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        response = urlopen.open(String.format("https://applications.sebkort.com/nis/external/%s/login.do", provider_part));
-        List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
-        parameters.add(new BasicNameValuePair("USERNAME", prodgroup+username.toUpperCase()));
-        parameters.add(new BasicNameValuePair("referer", "login.jsp"));
-        response = urlopen.open("https://applications.sebkort.com/nis/external/hidden.jsp", postData);
+        response = urlopen.open(String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
+        urlopen.addHeader("Referer", String.format("https://application.sebkort.com/nis/external/%s/login.do", provider_part));
+        response = urlopen.open("https://application.sebkort.com/nis/external/hidden.jsp");
+        urlopen.removeHeader("Referer");
         
         postData.clear();
-        postData.add(new BasicNameValuePair("choice", "PWD"));
-        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
-        postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
-        postData.add(new BasicNameValuePair("PASSWORD", password));
+        postData.add(new BasicNameValuePair("SEB_Referer", "/nis"));
+        postData.add(new BasicNameValuePair("SEB_Auth_Mechanism", "5"));
         postData.add(new BasicNameValuePair("target", String.format("/nis/%s/main.do", provider_part)));
         postData.add(new BasicNameValuePair("prodgroup", prodgroup));
-        postData.add(new BasicNameValuePair("USERNAME", prodgroup+username.toUpperCase()));
-        postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
+        postData.add(new BasicNameValuePair("UID", prodgroup+username.toUpperCase()));
+        postData.add(new BasicNameValuePair("TYPE", "LOGIN"));
         postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-        return new LoginPackage(urlopen, postData, response, "https://applications.sebkort.com/siteminderagent/forms/generic.fcc");
+        postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
+        postData.add(new BasicNameValuePair("PASSWORD", password));
+        
+        return new LoginPackage(urlopen, postData, response, "https://application.sebkort.com/auth4/Authentication/select.jsp");
     }
 
 	@Override
@@ -120,8 +118,8 @@ public abstract class SEBKortBase extends Bank {
 		urlopen = login();
 		Matcher matcher;
 		try {
-			if (!String.format("https://applications.sebkort.com/nis/%s/main.do", provider_part).equals(urlopen.getCurrentURI())) {
-				response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/main.do", provider_part));
+			if (!String.format("https://application.sebkort.com/nis/%s/main.do", provider_part).equals(urlopen.getCurrentURI())) {
+				response = urlopen.open(String.format("https://application.sebkort.com/nis/%s/main.do", provider_part));
 			}
 			matcher = reAccounts.matcher(response);
             /*
@@ -133,11 +131,13 @@ public abstract class SEBKortBase extends Bank {
 			if (matcher.find()) {
 			    Account account = new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3");
 			    account.setType(Account.OTHER);
+                account.setAliasfor("1");
 			    accounts.add(account);
 			}
             if (matcher.find()) {
                 Account account = new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2");
                 account.setType(Account.OTHER);
+                account.setAliasfor("1");
                 accounts.add(account);
             }
             if (matcher.find()) {
@@ -172,7 +172,7 @@ public abstract class SEBKortBase extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
+			response = urlopen.open(String.format("https://application.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit bc440a16a3a227f2f5a73021371d03f9b297c678
Merge: f94f763 56e8808
Author: liato <x@x00.us>
Date:   Thu Jun 21 15:06:06 2012 -0700

    Merge pull request #150 from erifre/master
    
    Fix för Västtrafik

commit 56e88089bcb9f3eb9ea7779b8651ed45cc0d4b18
Author: Erik Fredriksen <erik@fredriksen.se>
Date:   Mon Jun 4 19:17:29 2012 +0200

    Fix for Västtrafik

diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 4b566da..e3e5cc2 100644
--- src/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -44,13 +44,13 @@ public class Vasttrafik extends Bank {
     private static final String TAG = "Västtrafik";
     private static final String NAME = "Västtrafik";
     private static final String NAME_SHORT = "vasttrafik";
-    private static final String URL = "http://vasttrafik.se/Mina-Sidor/";
+    private static final String URL = "https://www.vasttrafik.se/mina-sidor/";
     private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("<td class=\"HeadingTop Col2of3\">\\s+([^<]+)\\s+</td>.*?<td class=\"Col2of3\">\\s+([^<]+)\\s+</td>.*?<div id=\"ctl00_FullRegion_MainAndFooterRegion_MainRegion_HandleCardsFormControl_TabContainerCards_TabPanelCards_ListViewActiveCards_ctrl\\d{0,3}_PanelDetail\" class=\"RowColor collapsePanel\" style=\"height:0px;\">(.*?)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);;
-	private Pattern reBalance = Pattern.compile("<tr class=\"(RowColor|AlternatingColor)\">\\s+<td>\\s+Kontoladdning\\s+</td>.*?<td>(.*?)<br />.*?</td>.*?</tr>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
-    private String response = null;
+	private Pattern reAccounts = Pattern.compile("<div class=\"myCardsItemContainer\" data-cardnumber=\"\\d+\">.*?<h3 class=\"cardName grid_12 clearMargin\">(.*?)</h3>.*?<span class=\"cardNumber\">(\\d+)</span>.*?<div class=\"clearfix cardCharges\">(.*?)<div class=\"clearfix paddingBottom grid_12 cardOptions\">", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalance = Pattern.compile("<span class=\"chargeType boldType\">(.*?): (.*?)</span>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+	private String response = null;
 
     public Vasttrafik(Context context) {
         super(context);
@@ -70,30 +70,30 @@ public class Vasttrafik extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
     ClientProtocolException, IOException {
-        urlopen = new Urllib(true);
-        response = urlopen.open("https://www.vasttrafik.se/CustomerUtil/Common/Security/Login.aspx");
-        Matcher matcher = reViewState.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-        }
-        String strViewState = matcher.group(1);
+		urlopen = new Urllib(true);
+		response = urlopen.open("https://www.vasttrafik.se/mina-sidor/logga-in/");
+
+		Matcher matcher = reViewState.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+		}
+		String strViewState = matcher.group(1);
+
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-		postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-		postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
 		postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-		postData.add(new BasicNameValuePair("LoginFormControl$TextBoxUsername", username));
-		postData.add(new BasicNameValuePair("LoginFormControl$TextBoxPassword", password));
-		postData.add(new BasicNameValuePair("LoginFormControl_CheckBoxPersistantLogin", ""));
-		postData.add(new BasicNameValuePair("LoginFormControl$LoginButton", "Logga in"));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$TextBoxUserName", username));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$TextBoxPassword", password));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$CheckBoxPersistent", "on"));
+		postData.add(new BasicNameValuePair("ctl00$ctl00$SiteRegion$SiteRegion$ContentRegion$RoundedCorners43$MainContentRegion$AddContentRegion$ctl00$ButtonLogin", "Logga in"));
 
-        return new LoginPackage(urlopen, postData, response, "https://www.vasttrafik.se/CustomerUtil/Common/Security/Login.aspx");
+        return new LoginPackage(urlopen, postData, response, "https://www.vasttrafik.se/mina-sidor/logga-in/?ReturnUrl=/mina-sidor-inloggad/mina-kort/");
     }
 
     public Urllib login() throws LoginException, BankException {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Felaktig inloggning")) {
+            if (!response.contains("Inloggad som:")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         }
@@ -114,14 +114,9 @@ public class Vasttrafik extends Bank {
         }
         urlopen = login();
         try {
-            response = urlopen.open("https://www.vasttrafik.se/sv/Mina-sidor-inloggad/Mina-Vasttrafikskort/");
+            response = urlopen.open("https://www.vasttrafik.se/mina-sidor-inloggad/mina-kort/");
             Matcher matcher;
             Matcher matcher_b;
-            matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }			
-            String strViewState = matcher.group(1);
 
             matcher = reAccounts.matcher(response);
             while (matcher.find()) {
@@ -131,7 +126,6 @@ public class Vasttrafik extends Bank {
                  * 1: Name              Nytt
                  * 2: Card number       1111111111
                  * 3: Balance information
-                 * 
                  */
 
                 matcher_b = reBalance.matcher(matcher.group(3));
@@ -139,14 +133,14 @@ public class Vasttrafik extends Bank {
                     /*
                      * Capture groups:
                      * GROUP                EXAMPLE DATA
+                     * 1: Type              Kontoladdning
                      * 2: Amount            592,80 kr
-                     * 
                      */
 
 					String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
-						
-                    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(2)));
-                    balance = balance.add(Helpers.parseBalance(balanceString));
+
+					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(2)));
+					balance = balance.add(Helpers.parseBalance(balanceString));
                 }
             }
 
@@ -161,7 +155,7 @@ public class Vasttrafik extends Bank {
         catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
-        }		
+        }
         finally {
             super.updateComplete();
         }

commit f94f763b9e338bfa4ef1fb124a8ebd067f3e483d
Merge: c056755 091ccce
Author: liato <x@x00.us>
Date:   Sat Jun 2 14:55:22 2012 -0700

    Merge pull request #139 from bjooork/091ccce3c454f75bb6302b47400b804c33094ccb
    
    Fix for meniga.

commit c0567559b9f85b4162e61ed90aa23fcb15a6e319
Merge: d0742fc bc15191
Author: liato <x@x00.us>
Date:   Sun May 20 09:10:02 2012 -0700

    Merge pull request #140 from goober/master
    
    Fixes login problem for Nordea DK

commit bc151917ee41fe288797944c1c1f9ce199cf4df3
Author: Mathias Aahsberg <mathias.ahsberg@gmail.com>
Date:   Sun May 20 18:07:12 2012 +0200

    Fixes login problems for Nordea DK

diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java src/com/liato/bankdroid/banking/banks/NordeaDK.java
index a796310..1a8e89d 100644
--- src/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ src/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -94,6 +94,7 @@ public class NordeaDK extends Bank {
 		}
 		response = urlopen
 				.open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
+		response = urlopen.open("https://www.netbank.nordea.dk/mnetbank/logon.jsp");
 		Matcher matcher = reLoginUrl.matcher(response);
 		if (!matcher.find()) {
 			throw new BankException(res.getText(R.string.unable_to_find)

commit 091ccce3c454f75bb6302b47400b804c33094ccb
Author: Jonas Björk <jonas@vulkanlandet.se>
Date:   Sat May 12 23:44:26 2012 +0000

    Changes in the meniga account page

diff --git src/com/liato/bankdroid/banking/banks/Meniga.java src/com/liato/bankdroid/banking/banks/Meniga.java
index efea9ad..dc28255 100644
--- src/com/liato/bankdroid/banking/banks/Meniga.java
+++ src/com/liato/bankdroid/banking/banks/Meniga.java
@@ -34,7 +34,7 @@ public class Meniga extends Bank{
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
     private static final String INPUT_HINT_USERNAME = "name@company.com";
 
-    private Pattern reAccounts = Pattern.compile("\\?account=([^']+)'[^>]*>\\s*<div\\s*class=\"account-info\">[^<]*<span\\s*class=\"bold\">([^<]+)</span>\\s*(?:</div>\\s*<div\\s*class=\"account-status\">)\\s*<span\\s*class=\"(minus|plus)\">([^k]+)kr");
+    private Pattern reAccounts = Pattern.compile("\\?account=([^']+)'[^>]*>\\s*<div\\s*class=\"account-info\">[^<]*<span\\s*class=\"bold\">([^<]+)</span>\\s*(?:</div>\\s*<div\\s*class=\"account-status\">)\\s*<span\\s*class=\"(minus|plus)\">([^<]+)</span>");
     private Pattern reTransactions = Pattern.compile("\"Id\":([^,]*),.*?\"Text\":\"([^\"]*)\".*?\"OriginalDate\":\".?.?Date\\(([^\\)]*)\\).*?\"Amount\":([^,]*),");
 
     String response;
@@ -86,7 +86,7 @@ public class Meniga extends Bank{
         }
 
         try{
-            response = urlopen.open("https://www.meniga.is/mobile/language/?lang=sv-SE");
+            response = urlopen.open("https://www.meniga.is/mobile/language/?lang=is-IS");
         }
         catch (ClientProtocolException e){
             //Do nothing
@@ -120,7 +120,9 @@ public class Meniga extends Bank{
                  * 4: Balance            5 678
                  *
                  */
-                Account account = new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim());
+                String balanceString ;
+                balanceString = matcher.group(4) + ".00";
+                Account account = new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(balanceString), matcher.group(1).trim());
                 account.setCurrency("ISK");
                 balance = balance.add(Helpers.parseBalance(matcher.group(4)));
                 accounts.add(account);

commit d0742fc779d6d87b8e5d27359cff149d658983a4
Author: liato <x@x00.us>
Date:   Mon Apr 16 03:24:58 2012 +0200

    Add setting for number of simultaneous notifications. Closes #49.

diff --git AndroidManifest.xml AndroidManifest.xml
index aad4340..6ffc719 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.7" android:versionCode="131">
+	android:versionName="1.8.9" android:versionCode="134">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git logos.psd logos.psd
index 1f99362..8e92825 100644
Binary files logos.psd and logos.psd differ
diff --git res/values-sv/array.xml res/values-sv/array.xml
index c0c6314..0cab40e 100644
--- res/values-sv/array.xml
+++ res/values-sv/array.xml
@@ -22,4 +22,11 @@
 		<item>15 sekunder</item>
 		<item>20 sekunder</item>
 	</string-array>	
+	<string-array
+		name="numNotificationsNames">
+		<item>En</item>
+   		<item>En per bank</item>
+		<item>En per konto</item>
+		<item>En per kontoändring</item>
+	</string-array>	
 </resources>
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 78e2a0f..e1b0a69 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -56,6 +56,8 @@
 	<string name="update_stop_title">Sluttid uppdatering</string>
 	<string name="update_transaction_history_title">Uppdatera kontoutdrag</string>
 	<string name="update_transaction_history_summary">Uppdatera kontoutdrag vid automatiska uppdateringar</string>
+	<string name="number_of_notifications_title">Antal notifieringar</string>
+	<string name="number_of_notifications_summary">Antal notifieringa som visas samtidigt</string>
 	<string name="appearance_title">Utseende</string>
 	<string name="widgets_title">Widgets</string>
 	<string name="round_widget_balance_title">Avrunda saldo på widgets</string>
diff --git res/values/array.xml res/values/array.xml
index 2f542db..f5046c5 100644
--- res/values/array.xml
+++ res/values/array.xml
@@ -44,4 +44,18 @@
 		<item>15</item>
 		<item>20</item>
 	</string-array>
+	<string-array
+		name="numNotificationsNames">
+		<item>One</item>
+   		<item>One per bank</item>
+		<item>One per account</item>
+		<item>One per change</item>
+	</string-array>
+	<string-array
+		name="numNotificationsValues">
+		<item>total</item>
+		<item>bank</item>
+		<item>account</item>
+		<item>change</item>
+	</string-array>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index ef471dd..f9b0b50 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -58,6 +58,8 @@
 	<string name="update_stop_title">Update end time</string>
 	<string name="update_transaction_history_title">Update transaction history</string>
 	<string name="update_transaction_history_summary">Update transaction history when updating automatically</string>
+	<string name="number_of_notifications_title">Number of notifications</string>
+	<string name="number_of_notifications_summary">Number of notifications to display simultaneously</string>
 	<string name="appearance_title">Appearance</string>
 	<string name="widgets_title">Widgets</string>
 	<string name="round_widget_balance_title">Round widget balance</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index 5137924..b85e57f 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -117,6 +117,14 @@
 		    android:defaultValue="@color/default_led_color"
 		    android:dependency="notify_with_led"
 		/>
+		<ListPreference
+			android:title="@string/number_of_notifications_title"
+			android:summary="@string/number_of_notifications_summary"
+			android:key="num_notifications"
+			android:defaultValue="total"
+			android:entries="@array/numNotificationsNames"
+			android:entryValues="@array/numNotificationsValues"
+			android:dependency="notify_on_change" />
 		<CheckBoxPreference
 			android:key="notify_delta_only"
 			android:defaultValue="false"
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 6e91ee3..17517df 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -23,23 +23,18 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.BlurMaskFilter;
-import android.graphics.Color;
-import android.graphics.BlurMaskFilter.Blur;
 import android.graphics.Canvas;
-import android.graphics.MaskFilter;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
 import android.graphics.RectF;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
-import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 8cb0d80..784e63c 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -30,6 +30,10 @@ import android.util.Log;
 import android.widget.Toast;
 
 import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.banks.Nordea;
+import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.lockpattern.ChooseLockPattern;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
@@ -116,15 +120,18 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		}
 		else if ("test_notification".equals(prefKey)) {
             Log.d(TAG, "Sending test notification.");
-            AutoRefreshService.showNotification(
-                    "Personkonto",
-                    new BigDecimal(-143.50),
-                    new BigDecimal(8351.00),
-                    "SEK",
-                    R.drawable.logo_swedbank,
-                    "Familjekonto",
-                    "Swedbank",
-                    this);      
+            Account account1 = new Account("Personkonto", new BigDecimal(8351.00), "22");
+            Bank bank1 = new Swedbank(this);
+            bank1.setDbid(21);
+            bank1.setCustomName("800416-0001");
+
+            Account account2 = new Account("Personkonto", new BigDecimal(8341.00), "23");
+            Bank bank2 = new Nordea(this);
+            bank2.setDbid(22);
+            bank2.setCustomName("800416-0002");
+
+            AutoRefreshService.showNotification(bank1, account1, new BigDecimal(-143.50), this);      
+            AutoRefreshService.showNotification(bank2, account2, new BigDecimal(-123.50), this);      
 		    return true;
 		}
 		return false;
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index d685358..82cf92a 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -35,6 +35,7 @@ import android.net.ConnectivityManager;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.IBinder;
+import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
@@ -116,23 +117,22 @@ public class AutoRefreshService extends Service {
 		return null;
 	}
 
-    public static void showNotification(final String accountName,
-            final BigDecimal diff, final BigDecimal accountBalance,
-            final String currency, final int icon, final String title,
-            final String bank, Context context) {
+    public static void showNotification(final Bank bank, final Account account,
+            final BigDecimal diff, Context context) {
+        
 		final SharedPreferences prefs = PreferenceManager
 				.getDefaultSharedPreferences(context);
 		if (!prefs.getBoolean("notify_on_change", true)) {
 			return;
 		}
         
-        String text = String.format("%s: %s%s", accountName, ((diff.compareTo(new BigDecimal(0)) == 1) ? "+": ""), Helpers.formatBalance(diff, currency));
+        String text = String.format("%s: %s%s", account.getName(), ((diff.compareTo(new BigDecimal(0)) == 1) ? "+": ""), Helpers.formatBalance(diff, account.getCurrency()));
         if (!prefs.getBoolean("notify_delta_only", false)) {
-            text = String.format("%s (%s)", text, Helpers.formatBalance(accountBalance, currency));
+            text = String.format("%s (%s)", text, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
         }
 
         final NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
-		final Notification notification = new Notification(icon, text,
+		final Notification notification = new Notification(bank.getImageResource(), text,
 				System.currentTimeMillis());
 		// Remove notification from statusbar when clicked
 		notification.flags |= Notification.FLAG_AUTO_CANCEL;
@@ -161,15 +161,17 @@ public class AutoRefreshService extends Service {
 		final PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
 				new Intent(context, MainActivity.class), 0);
 
-		notification.setLatestEventInfo(context, title, text, contentIntent);
+		notification.setLatestEventInfo(context, bank.getDisplayName(), text, contentIntent);
 
-		notificationManager.notify(R.id.about, notification);
+		String numNotifications = prefs.getString("num_notifications", "total");
+		int notificationId = (int) (numNotifications.equals("total") ? 0 : numNotifications.equals("bank") ? bank.getDbId() : numNotifications.equals("account") ? account.getId().hashCode() : SystemClock.elapsedRealtime());
+		notificationManager.notify(notificationId, notification);
 
 		// Broadcast to Remote Notifier if enabled
 		// http://code.google.com/p/android-notifier/
 		if (prefs.getBoolean("notify_remotenotifier", false)) {
 			final Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
-			i.putExtra("title", String.format("%s (%s)", bank, title));
+			i.putExtra("title", String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
 			i.putExtra("description", text);
 			context.sendBroadcast(i);
 		}
@@ -183,7 +185,7 @@ public class AutoRefreshService extends Service {
 			} else {
 				i = new Intent(BROADCAST_OPENWATCH_TEXT);
 			}
-			i.putExtra("line1", String.format("%s (%s)", bank, title));
+			i.putExtra("line1", String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
 			i.putExtra("line2", text);
 			context.sendBroadcast(i);
 		}
@@ -193,7 +195,7 @@ public class AutoRefreshService extends Service {
 		if (prefs.getBoolean("notify_liveview", false)) {
 			final Intent i = new Intent(context, LiveViewService.class);
 			i.putExtra(LiveViewService.INTENT_EXTRA_ANNOUNCE, true);
-			i.putExtra(LiveViewService.INTENT_EXTRA_TITLE, String.format("%s (%s)", bank, title));
+			i.putExtra(LiveViewService.INTENT_EXTRA_TITLE, String.format("%s (%s)", bank.getName(), bank.getDisplayName()));
 			i.putExtra(LiveViewService.INTENT_EXTRA_TEXT, text);
 			context.startService(i);
 		}
@@ -288,15 +290,7 @@ public class AutoRefreshService extends Service {
 									if (notify) {
 										diff = account.getBalance().subtract(
 												oldAccount.getBalance());
-										showNotification(
-										        account.getName(),
-										        diff,
-										        account.getBalance(),
-										        account.getCurrency(),
-												bank.getImageResource(),
-												bank.getDisplayName(),
-												bank.getName(),
-												AutoRefreshService.this);
+										showNotification(bank, account, diff, AutoRefreshService.this);
 									}
 
 									refreshWidgets = true;
@@ -370,7 +364,7 @@ public class AutoRefreshService extends Service {
 	public static void broadcastTransactionUpdate(final Context context,
 			final long bankId, final String accountId) {
 		final Intent i = new Intent(BROADCAST_TRANSACTIONS_UPDATED);
-		i.putExtra("accountId", new Long(bankId).toString() + "_" + accountId);
+		i.putExtra("accountId", Long.toString(bankId) + "_" + accountId);
 		context.sendBroadcast(i);
 	}
 
diff --git src/com/liato/bankdroid/banking/Account.java src/com/liato/bankdroid/banking/Account.java
index 8d8d670..998d309 100644
--- src/com/liato/bankdroid/banking/Account.java
+++ src/com/liato/bankdroid/banking/Account.java
@@ -24,7 +24,7 @@ import com.liato.bankdroid.provider.IAccountTypes;
 public class Account implements IAccountTypes {
 	private String name;
 	private BigDecimal balance;
-	private final String id;
+	private String id;
 	private Bank bank = null;
 	private long bankId = -1;
 	private int type = Account.REGULAR;
@@ -104,6 +104,10 @@ public class Account implements IAccountTypes {
 	public String getId() {
 		return id;
 	}
+	
+	public void setId(String id) {
+	    this.id = id;
+	}
 
 	public Bank getBank() {
 		return bank;

commit 7a22790871969f123ebe240a4087a843329f8f82
Author: liato <x@x00.us>
Date:   Mon Apr 16 02:37:04 2012 +0200

    Use onCreateThumbnail instead of FLAG_SECURE. FLAG_SECURE doesn't work on all pre ICS devices.

diff --git res/drawable-nodpi/lock.png res/drawable-nodpi/lock.png
new file mode 100644
index 0000000..99bc113
Binary files /dev/null and res/drawable-nodpi/lock.png differ
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index d97875d..6e91ee3 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -22,9 +22,15 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BlurMaskFilter;
+import android.graphics.Color;
+import android.graphics.BlurMaskFilter.Blur;
 import android.graphics.Canvas;
+import android.graphics.MaskFilter;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.RectF;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
@@ -68,7 +74,6 @@ public class LockableActivity extends Activity {
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
     }
 	
 	@Override
@@ -248,17 +253,78 @@ public class LockableActivity extends Activity {
     }
     
     
-    //Not always called?
-    /*
     @Override
     public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) {
+        View decorview = getWindow().getDecorView();
+        if (decorview == null) {
+            return true;
+        }
+
+        final int vw = decorview.getWidth();
+        final int vh = decorview.getHeight();
+        final int dw = outBitmap.getWidth();
+        final int dh = outBitmap.getHeight();
+
+        Bitmap bluredBitmap = Bitmap.createBitmap(outBitmap.getWidth(), outBitmap.getHeight(), outBitmap.getConfig());
+        Canvas c = new Canvas(bluredBitmap);
+        
+        c.save();
+        c.scale(((float)dw)/vw, ((float)dh)/vh);
+        decorview.draw(c);
+        c.restore();        
+
+        canvas.drawBitmap(pixelate(bluredBitmap, 5), 0, 0, null);
+        Bitmap lockbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lock);
+
         Paint p = new Paint();
-        p.setStyle(Style.FILL);
-        p.setColor(0xff64E366);
-        canvas.drawCircle(outBitmap.getWidth()/2, outBitmap.getHeight()/2, outBitmap.getWidth()/3, p);
-        //return super.onCreateThumbnail(outBitmap, canvas);
+        p.setAntiAlias(true);
+        p.setDither(true);
+        p.setFilterBitmap(true);
+        
+        canvas.drawBitmap(lockbitmap, null, new RectF(dw*0.25f,dh*0.25f,dw*0.75f,dh*0.75f), p);
+        
         return true;
     }
-    */
+    
+    private Bitmap pixelate(Bitmap bitmap, int size) {
+        Bitmap bm = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
+        Canvas c = new Canvas(bm);
+        Paint p = new Paint();
+        p.setStyle(Style.FILL);
+        int w = bm.getWidth();
+        int h = bm.getHeight();
+        
+        int[] pixels = new int[w*h];
+        bitmap.getPixels(pixels, 0, w, 0, 0, w, h);
+        for (int i = 0; i < h; i = i+size) {
+            for (int j = 0; j < w; j = j+size) {
+                int a = 0;
+                int r = 0;
+                int g = 0;
+                int b = 0;
+                int pc = 0;
+                for (int k = 0; k < size; k++) {
+                    for (int l = 0; l < size; l++) {
+                        int pxp = (i+k)*w+j+l;
+                        if (pxp < pixels.length) {
+                            int pixel = pixels[pxp];
+                            a += Color.alpha(pixel);
+                            r += Color.red(pixel);
+                            g += Color.green(pixel);
+                            b += Color.blue(pixel);
+                            pc++;
+                        }
+                    }
+                }
+                a /= pc;
+                r /= pc;
+                g /= pc;
+                b /= pc;
+                p.setColor(Color.argb(a, r, g, b));
+                c.drawRect(j, i, j+size, i+size, p);
+            }
+        }
+        return bm;
+    }    
     
 }
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index f4f2e2f..ca9e34f 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -44,7 +44,6 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		mLockPatternUtils = new LockPatternUtils(this);
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
 	}
 
 	@Override

commit b3a58e8647863a19cd7cd3ebb9d30055b29b6255
Author: liato <x@x00.us>
Date:   Tue Apr 10 01:16:28 2012 +0200

    Fix IKEA to Skoda bank transformation.

diff --git src/com/liato/bankdroid/banking/banks/IKEA.java src/com/liato/bankdroid/banking/banks/IKEA.java
index 8c9cc3b..47e1e2a 100644
--- src/com/liato/bankdroid/banking/banks/IKEA.java
+++ src/com/liato/bankdroid/banking/banks/IKEA.java
@@ -28,7 +28,7 @@ public class IKEA extends IkanoPartnerBase {
 	private static final String NAME = "IKEA HANDLA kort";
 	private static final String NAME_SHORT = "ikea";
 	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
-	private static final int BANKTYPE_ID = Bank.SKODA;
+	private static final int BANKTYPE_ID = Bank.IKEA;
 
     public IKEA(Context context) {
         super(context);

commit 5dab344359f9bed9be00e0ce85e92075a0be8883
Author: liato <x@x00.us>
Date:   Tue Apr 10 01:14:25 2012 +0200

    Disable thumbnail in recent apps list.

diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index f72f329..d97875d 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -21,6 +21,10 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
@@ -29,6 +33,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
+import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
@@ -63,6 +68,7 @@ public class LockableActivity extends Activity {
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
     }
 	
 	@Override
@@ -199,7 +205,6 @@ public class LockableActivity extends Activity {
 		long currentTime = SystemClock.elapsedRealtime();
 		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
 		long timedif = Math.abs(currentTime - lockedAt);
-        Log.d("Lock", "timedif: " + timedif);
 		if (timedif > 2000) {
             mHasLoaded = false;         
 		    launchPatternLock();
@@ -241,4 +246,19 @@ public class LockableActivity extends Activity {
     protected void skipLockOnce() {
         mSkipLockOnce = true;
     }
+    
+    
+    //Not always called?
+    /*
+    @Override
+    public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) {
+        Paint p = new Paint();
+        p.setStyle(Style.FILL);
+        p.setColor(0xff64E366);
+        canvas.drawCircle(outBitmap.getWidth()/2, outBitmap.getHeight()/2, outBitmap.getWidth()/3, p);
+        //return super.onCreateThumbnail(outBitmap, canvas);
+        return true;
+    }
+    */
+    
 }
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index bfac519..f4f2e2f 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -27,6 +27,8 @@ import android.os.SystemClock;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceManager;
 import android.util.Log;
+import android.view.Window;
+import android.view.WindowManager;
 
 public class LockablePreferenceActivity extends PreferenceActivity {
     private static int PATTERNLOCK_UNLOCK = 42;
@@ -42,12 +44,13 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		mLockPatternUtils = new LockPatternUtils(this);
         mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
         mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
 	}
 
 	@Override
 	protected void onPause() {
 		super.onPause();
-		// Don't do anything if not lock pattern is set
+		// Don't do anything if no lock pattern is set
 		if (!mLockPatternUtils.isLockPatternEnabled()) return;
         /*
         Save the current time If a lock pattern has been set
@@ -80,7 +83,6 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		long currentTime = SystemClock.elapsedRealtime();
 		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
 		long timedif = Math.abs(currentTime - lockedAt);
-		Log.d("Lock", "timedif: " + timedif);
 		if (timedif > 2000) {
 		    launchPatternLock();
 		}
@@ -115,6 +117,7 @@ public class LockablePreferenceActivity extends PreferenceActivity {
     protected boolean isLockEnabled() {
         return mPrefs.getBoolean("lock_enabled", true);       
     }	
+    
     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         super.onActivityResult(requestCode, resultCode, data);

commit f81301bb8402acbb917f5c4b62c377858008852c
Author: liato <x@x00.us>
Date:   Tue Apr 10 00:50:26 2012 +0200

    Add setting to only display account change in notification (without the account balance).

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 8aa13fa..78e2a0f 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -79,6 +79,8 @@
    	<string name="notification_sound_title">Notifieringsljud</string>
 	<string name="notification_sound_summary">Välj ett notifieringsljud</string>
 	<string name="notification_sound_name">Välj ljud</string>
+	<string name="notify_delta_only_title">Visa endast ändring</string>
+	<string name="notify_delta_only_summary">Visa inte kontosaldo i notifiering</string>
 	<string name="account_types_title">Kontotyper</string>
 	<string name="account_types_summary">Visa endast notifieringar för valda kontotyper</string>
 	<string name="remote_notifier_title">Remote Notifier-integrering</string>
diff --git res/values/strings.xml res/values/strings.xml
index cfc6817..ef471dd 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -81,6 +81,8 @@
    	<string name="notification_sound_title">Notification sound</string>
 	<string name="notification_sound_summary">Select notification sound</string>
 	<string name="notification_sound_name">Select sound</string>
+	<string name="notify_delta_only_title">Display change only</string>
+	<string name="notify_delta_only_summary">Don\'t display the account balance in the notification</string>
 	<string name="account_types_title">Account types</string>
 	<string name="account_types_summary">Only show notifications for selected account types</string>
 	<string name="remote_notifier_title">Remote Notifier Integration</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index 96ab6fa..5137924 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -117,12 +117,12 @@
 		    android:defaultValue="@color/default_led_color"
 		    android:dependency="notify_with_led"
 		/>
-		<!--  <CheckBoxPreference
+		<CheckBoxPreference
 			android:key="notify_delta_only"
 			android:defaultValue="false"
-			android:title="@string/vibrate_title"
-			android:summary="@string/vibrate_summary"
-			android:dependency="notify_on_change" />-->
+			android:title="@string/notify_delta_only_title"
+			android:summary="@string/notify_delta_only_summary"
+			android:dependency="notify_on_change" />
 		<EditTextPreference
 			android:key="notify_min_delta"
 			android:defaultValue="0"
@@ -250,12 +250,12 @@
 					android:title="Testbank only"
 					android:summary="Only auto update 'Testbank' banks"
 					android:dependency="debug_mode" />
-				<CheckBoxPreference
+				<!-- <CheckBoxPreference
 					android:key="debug_coop_sendmail"
 					android:defaultValue="false"
 					android:title="Coop - Mail on error"
 					android:summary="Open your email client with the html response when Bankdroid fails to login to your Coop account."
-					android:dependency="debug_mode" />
+					android:dependency="debug_mode" /> -->
 			<Preference
 				android:title="Test notification"
 				android:summary="A demo notification"
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index aebe4f2..f72f329 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -24,6 +24,7 @@ import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -197,7 +198,8 @@ public class LockableActivity extends Activity {
 		// will have to enter the lock pattern to continue.
 		long currentTime = SystemClock.elapsedRealtime();
 		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
-		long timedif = currentTime - lockedAt;
+		long timedif = Math.abs(currentTime - lockedAt);
+        Log.d("Lock", "timedif: " + timedif);
 		if (timedif > 2000) {
             mHasLoaded = false;         
 		    launchPatternLock();
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index 13146c2..bfac519 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -23,8 +23,10 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceManager;
+import android.util.Log;
 
 public class LockablePreferenceActivity extends PreferenceActivity {
     private static int PATTERNLOCK_UNLOCK = 42;
@@ -61,7 +63,7 @@ public class LockablePreferenceActivity extends PreferenceActivity {
         if (mHasLoaded) {
             writeLockTime();
         } else {
-            writeLockTime(System.currentTimeMillis()-10000);
+            writeLockTime(SystemClock.elapsedRealtime()-10000);
         }
     }
 
@@ -75,9 +77,10 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		// If a lock pattern is set we need to check the time for when the last
 		// activity was open. If it's been more than two seconds the user
 		// will have to enter the lock pattern to continue.
-		long currentTime = System.currentTimeMillis();
+		long currentTime = SystemClock.elapsedRealtime();
 		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
-		long timedif = currentTime - lockedAt;
+		long timedif = Math.abs(currentTime - lockedAt);
+		Log.d("Lock", "timedif: " + timedif);
 		if (timedif > 2000) {
 		    launchPatternLock();
 		}
@@ -94,7 +97,7 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 	}
 	
     private void writeLockTime() {
-        writeLockTime(System.currentTimeMillis());
+        writeLockTime(SystemClock.elapsedRealtime());
     }
 
     private void writeLockTime(long time) {
@@ -130,4 +133,5 @@ public class LockablePreferenceActivity extends PreferenceActivity {
         super.onStop();
         setLockEnabled(true);
     }   	
+    
 }
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 1eb74db..8cb0d80 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -16,6 +16,8 @@
 
 package com.liato.bankdroid;
 
+import java.math.BigDecimal;
+
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
@@ -115,7 +117,10 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		else if ("test_notification".equals(prefKey)) {
             Log.d(TAG, "Sending test notification.");
             AutoRefreshService.showNotification(
-                    "Personkonto: -143,50 SEK (8 351,00 SEK)",
+                    "Personkonto",
+                    new BigDecimal(-143.50),
+                    new BigDecimal(8351.00),
+                    "SEK",
                     R.drawable.logo_swedbank,
                     "Familjekonto",
                     "Swedbank",
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 16c315d..d685358 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -116,13 +116,20 @@ public class AutoRefreshService extends Service {
 		return null;
 	}
 
-	public static void showNotification(final String text, final int icon,
-			final String title, final String bank, Context context) {
+    public static void showNotification(final String accountName,
+            final BigDecimal diff, final BigDecimal accountBalance,
+            final String currency, final int icon, final String title,
+            final String bank, Context context) {
 		final SharedPreferences prefs = PreferenceManager
 				.getDefaultSharedPreferences(context);
 		if (!prefs.getBoolean("notify_on_change", true)) {
 			return;
 		}
+        
+        String text = String.format("%s: %s%s", accountName, ((diff.compareTo(new BigDecimal(0)) == 1) ? "+": ""), Helpers.formatBalance(diff, currency));
+        if (!prefs.getBoolean("notify_delta_only", false)) {
+            text = String.format("%s (%s)", text, Helpers.formatBalance(accountBalance, currency));
+        }
 
         final NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
 		final Notification notification = new Notification(icon, text,
@@ -282,21 +289,10 @@ public class AutoRefreshService extends Service {
 										diff = account.getBalance().subtract(
 												oldAccount.getBalance());
 										showNotification(
-												account.getName()
-														+ ": "
-														+ ((diff.compareTo(new BigDecimal(
-																0)) == 1) ? "+"
-																: "")
-														+ Helpers
-																.formatBalance(
-																		diff,
-																		account.getCurrency())
-														+ " ("
-														+ Helpers
-																.formatBalance(
-																		account.getBalance(),
-																		account.getCurrency())
-														+ ")",
+										        account.getName(),
+										        diff,
+										        account.getBalance(),
+										        account.getCurrency(),
 												bank.getImageResource(),
 												bank.getDisplayName(),
 												bank.getName(),

commit 282eb4f2898d466b45d3dd19f0db90b4956acd55
Merge: 9295d87 ce33ef3
Author: liato <x@x00.us>
Date:   Wed Apr 4 21:50:25 2012 -0700

    Merge pull request #136 from mafa73/master
    
    Fix för Rikslunchen

commit ce33ef31081f6e9e3e35c9922dc74964ff915fab
Author: mafa73 <mattias.fagerstrom@gmail.com>
Date:   Wed Apr 4 19:37:43 2012 +0300

    Changed URL to "http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr".
    Set the "page" value to "%2Friks-cp%2Fcheck_balance.html".

diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 9701fa2..9464a04 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -89,12 +89,12 @@ public class Rikslunchen extends Bank {
 		postData.add(new BasicNameValuePair("c0-methodName", "getCardData"));
 		postData.add(new BasicNameValuePair("c0-id", "0"));
 		postData.add(new BasicNameValuePair("batchId", "1"));
-		postData.add(new BasicNameValuePair("page", "%2Findex.html"));
+		postData.add(new BasicNameValuePair("page", "%2Friks-cp%2Fcheck_balance.html"));
 		postData.add(new BasicNameValuePair("httpSessionId", ""));
 		postData.add(new BasicNameValuePair("scriptSessionId", ""));
 
 		HttpClient httpclient = new DefaultHttpClient();
-		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/dwr/call/plaincall/cardUtil.getCardData.dwr");
+		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
 		httppost.setEntity(new UrlEncodedFormEntity(postData));
 
 		HttpResponse response = httpclient.execute(httppost);
@@ -102,7 +102,7 @@ public class Rikslunchen extends Bank {
 		StringWriter writer = new StringWriter();
 		IOUtils.copy(streamResponse, writer);
 
-		return new LoginPackage(urlopen, postData, writer.toString(), "http://www.rikslunchen.se/dwr/call/plaincall/cardUtil.getCardData.dwr");
+		return new LoginPackage(urlopen, postData, writer.toString(), "http://www.rikslunchen.se/riks-cp/dwr/call/plaincall/cardUtil.getCardData.dwr");
 	}
 
 	@Override

commit 9295d87fd65774d9cde0a0e500862304c6de6324
Merge: 7c83995 301263c
Author: liato <x@x00.us>
Date:   Sun Apr 1 04:23:55 2012 -0700

    Merge pull request #134 from wanders/master
    
    Please pull the fix for "Jojo"

commit 301263c3f9f64c8e45d966697213bca0ee38d63c
Author: Anders Waldenborg <anders@0x63.nu>
Date:   Thu Mar 29 23:28:53 2012 +0200

    Fix Jojo login

diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index 70da853..14ee765 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -81,9 +81,9 @@ public class Jojo extends Bank {
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ctl00$ctl01$UsernameTextBox", username));
-        postData.add(new BasicNameValuePair("ctl00$ctl01$PasswordTextBox", password));
-        postData.add(new BasicNameValuePair("ctl00$ctl01$LoginButton", "Logga in"));
+        postData.add(new BasicNameValuePair("ctl00$ctl00$UsernameTextBox", username));
+        postData.add(new BasicNameValuePair("ctl00$ctl00$PasswordTextBox", password));
+        postData.add(new BasicNameValuePair("ctl00$ctl00$LoginButton", "Logga in"));
 
         return new LoginPackage(urlopen, postData, response, "https://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
     }

commit 7c839956b651156615bbae8f16b6f0228accbb19
Merge: 89c2ba3 d8758ff
Author: liato <x@x00.us>
Date:   Mon Mar 19 13:56:36 2012 -0700

    Merge pull request #129 from bjooork/master
    
    Added www.meniga.is

commit 89c2ba32ff3c514252121751721f5deb56d207d3
Merge: e6582cc f0afdf4
Author: liato <x@x00.us>
Date:   Mon Mar 19 13:55:35 2012 -0700

    Merge pull request #132 from woody2/master
    
    Fix for Skandiabanken

commit f0afdf4eee4a46d68d9ce8f0b9d16f601bc1bfa2
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun Mar 18 17:47:19 2012 +0100

    Remove unused classes in the se.smartrefill namespace

diff --git src/se/smartrefill/ad/bank/domain/AdAccount.java src/se/smartrefill/ad/bank/domain/AdAccount.java
deleted file mode 100644
index 13f2459..0000000
--- src/se/smartrefill/ad/bank/domain/AdAccount.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class AdAccount implements Serializable {
-	public static final String KIND_AiE = "AiE";
-	public static final String KIND_DebitCreditCard = "DebitCreditCard";
-	public static final String KIND_Euro = "Euro";
-	public static final String KIND_FixedInterest = "FixedInterest";
-	public static final String KIND_Personal = "Personal";
-	public static final String KIND_Savings = "Savings";
-	private static final long serialVersionUID = 1L;
-	private String accountNumber;
-	private String accountTypeDescription;
-	private String alias;
-	private String amount;
-	private String bookingNumber;
-	private String bwdKey;
-	private int currentPage;
-	private String disposableAmount;
-	private String endDate;
-	private String fwdKey;
-	private String id;
-	private String interest;
-	private String kind;
-	private int messageLengthRecipient;
-	private int messageLengthStatement;
-	private String messageValidCharactersDisplay;
-	private String messageValidCharactersExpression;
-	private int order;
-	private String startDate;
-	private String tax;
-	private List<AdBalanceInformationTransaction> transactions;
-	private boolean validOverview;
-	private List<String> validRecevingAccounts;
-
-	public AdAccount() {
-		this.transactions = new ArrayList<AdBalanceInformationTransaction>();
-		this.validRecevingAccounts = new ArrayList<String>();
-	}
-
-	public String getAccountNumber() {
-		return this.accountNumber;
-	}
-
-	public String getAccountTypeDescription() {
-		return this.accountTypeDescription;
-	}
-
-	public String getAlias() {
-		return this.alias;
-	}
-
-	public String getAmount() {
-		return this.amount;
-	}
-
-	public String getBookingNumber() {
-		return this.bookingNumber;
-	}
-
-	public String getBwdKey() {
-		return this.bwdKey;
-	}
-
-	public int getCurrentPage() {
-		return this.currentPage;
-	}
-
-	public String getDisposableAmount() {
-		return this.disposableAmount;
-	}
-
-	public String getEndDate() {
-		return this.endDate;
-	}
-
-	public String getFwdKey() {
-		return this.fwdKey;
-	}
-
-	public String getId() {
-		return this.id;
-	}
-
-	public String getInterest() {
-		return this.interest;
-	}
-
-	public String getKind() {
-		return this.kind;
-	}
-
-	public int getMessageLengthRecipient() {
-		return this.messageLengthRecipient;
-	}
-
-	public int getMessageLengthStatement() {
-		return this.messageLengthStatement;
-	}
-
-	public String getMessageValidCharactersDisplay() {
-		return this.messageValidCharactersDisplay;
-	}
-
-	public String getMessageValidCharactersExpression() {
-		return this.messageValidCharactersExpression;
-	}
-
-	public String getNameNumber() {
-		if (isBlank(alias))
-			return accountNumber;
-		else
-			return alias;
-	}
-
-	public String getNameType() {
-		if (isBlank(alias))
-			return accountTypeDescription;
-		else
-			return alias;
-	}
-
-	public int getOrder() {
-		return this.order;
-	}
-
-	public String getStartDate() {
-		return this.startDate;
-	}
-
-	public String getTax() {
-		return this.tax;
-	}
-
-	public List<AdBalanceInformationTransaction> getTransactions() {
-		return this.transactions;
-	}
-
-	public List<String> getValidRecevingAccounts() {
-		return this.validRecevingAccounts;
-	}
-
-	public boolean hasMoreTransactions() {
-		return !isBlank(fwdKey);
-	}
-
-	public boolean isFixedInterest() {
-		return "FixedInterest".equals(kind);
-	}
-
-	public boolean isNotFixedInterest() {
-		return (!isFixedInterest());
-	}
-
-	public boolean isOtherBank() {
-		return "Personal".equals(kind);
-	}
-
-	public boolean isValidFromAccount() {
-		return (this.validRecevingAccounts.size() > 0);
-	}
-
-	public boolean isValidOverview() {
-		return this.validOverview;
-	}
-
-	private static boolean isBlank(String str) {
-		return str == null || str.contains("");
-	}
-}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceInformation.java src/se/smartrefill/ad/bank/domain/AdBalanceInformation.java
deleted file mode 100644
index ca95937..0000000
--- src/se/smartrefill/ad/bank/domain/AdBalanceInformation.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class AdBalanceInformation implements Serializable {
-	public static int CODE_ERROR = 1;
-	public static int CODE_INTENTIONALLY_BLANK = 2;
-	public static int CODE_OK = 0;
-	private static final long serialVersionUID = 1L;
-	private String amountSpent;
-	private List<AdBalanceInformationTransaction> balanceInformationTransactions;
-	private String disposableAmount;
-	private int statusCode;
-
-	public AdBalanceInformation() {
-		this.balanceInformationTransactions = new ArrayList<AdBalanceInformationTransaction>();
-	}
-
-	public String getAmountSpent() {
-		return amountSpent;
-	}
-
-	public List<AdBalanceInformationTransaction> getBalanceInformationTransactions() {
-		return balanceInformationTransactions;
-	}
-
-	public String getDisposableAmount() {
-		return disposableAmount;
-	}
-
-	public int getStatusCode() {
-		return statusCode;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceInformationTransaction.java src/se/smartrefill/ad/bank/domain/AdBalanceInformationTransaction.java
deleted file mode 100644
index 93a6858..0000000
--- src/se/smartrefill/ad/bank/domain/AdBalanceInformationTransaction.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-
-public class AdBalanceInformationTransaction implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private String amount;
-	private String id;
-	private String merchant;
-	private int order;
-	private int page;
-	private String time;
-
-	public AdBalanceInformationTransaction() {
-	}
-
-	public String getAmount() {
-		return this.amount;
-	}
-
-	public String getId() {
-		return this.id;
-	}
-
-	public String getMerchant() {
-		return this.merchant;
-	}
-
-	public int getOrder() {
-		return this.order;
-	}
-
-	public int getPage() {
-		return this.page;
-	}
-
-	public String getTime() {
-		return this.time;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceService.java src/se/smartrefill/ad/bank/domain/AdBalanceService.java
deleted file mode 100644
index 95930ee..0000000
--- src/se/smartrefill/ad/bank/domain/AdBalanceService.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.util.ArrayList;
-import java.util.List;
-import se.smartrefill.ad.domain.AdService;
-
-public class AdBalanceService extends AdService {
-	private static final long serialVersionUID = 1L;
-	private List<AdBalanceServiceCard> balanceServiceCards;
-	private int dayOfMonthForBalance;
-	private int dayOfWeekForBalance;
-	private int endHourForBalance;
-	private boolean monthlySubscription;
-	private int startHourForBalance;
-	private boolean weeklySubscription;
-
-	public AdBalanceService() {
-		this.balanceServiceCards = new ArrayList<AdBalanceServiceCard>();
-	}
-
-	public List<AdBalanceServiceCard> getBalanceServiceCards() {
-		return balanceServiceCards;
-	}
-
-	public int getDayOfMonthForBalance() {
-		return dayOfMonthForBalance;
-	}
-
-	public int getDayOfWeekForBalance() {
-		return dayOfWeekForBalance;
-	}
-
-	public int getEndHourForBalance() {
-		return endHourForBalance;
-	}
-
-	public boolean isMonthlySubscription() {
-		return monthlySubscription;
-	}
-
-	public int getStartHourForBalance() {
-		return startHourForBalance;
-	}
-
-	public boolean isWeeklySubscription() {
-		return weeklySubscription;
-	}
-}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceServiceCard.java src/se/smartrefill/ad/bank/domain/AdBalanceServiceCard.java
deleted file mode 100644
index 4eab1cd..0000000
--- src/se/smartrefill/ad/bank/domain/AdBalanceServiceCard.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import se.smartrefill.ad.domain.AdPaymentCard;
-
-public class AdBalanceServiceCard
-  implements Serializable
-{
-  private static final long serialVersionUID = 1L;
-  private AdBalanceInformation balanceInformation;
-  private int dayOfMonthForBalance;
-  private int dayOfWeekForBalance;
-  private Integer id;
-  private int monthlyBalanceEndHour;
-  private int monthlyBalanceStartHour;
-  private boolean monthlySubscription;
-  private AdPaymentCard paymentCard;
-  private int weeklyBalanceEndHour;
-  private int weeklyBalanceStartHour;
-  private boolean weeklySubscription;
-
-  public AdBalanceInformation getBalanceInformation()
-  {
-    return this.balanceInformation;
-  }
-
-  public int getDayOfMonthForBalance()
-  {
-    return this.dayOfMonthForBalance;
-  }
-
-  public int getDayOfWeekForBalance()
-  {
-    return this.dayOfWeekForBalance;
-  }
-
-  public Integer getId()
-  {
-    return this.id;
-  }
-
-  public int getMonthlyBalanceEndHour()
-  {
-    return this.monthlyBalanceEndHour;
-  }
-
-  public int getMonthlyBalanceStartHour()
-  {
-    return this.monthlyBalanceStartHour;
-  }
-
-  public AdPaymentCard getPaymentCard()
-  {
-    return this.paymentCard;
-  }
-
-  public int getWeeklyBalanceEndHour()
-  {
-    return this.weeklyBalanceEndHour;
-  }
-
-  public int getWeeklyBalanceStartHour()
-  {
-    return this.weeklyBalanceStartHour;
-  }
-
-  public boolean isMonthlySubscription()
-  {
-    return this.monthlySubscription;
-  }
-
-  public boolean isWeeklySubscription()
-  {
-    return this.weeklySubscription;
-  }
-}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdCekabNotificationService.java src/se/smartrefill/ad/bank/domain/AdCekabNotificationService.java
deleted file mode 100644
index 5d9ea97..0000000
--- src/se/smartrefill/ad/bank/domain/AdCekabNotificationService.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.util.ArrayList;
-import java.util.List;
-import se.smartrefill.ad.domain.AdService;
-
-public class AdCekabNotificationService extends AdService {
-	private static final long serialVersionUID = 1L;
-	private List<AdCekabPan> pans;
-
-	public AdCekabNotificationService() {
-		this.pans = new ArrayList<AdCekabPan>();
-	}
-
-	public List<AdCekabPan> getPans() {
-		return pans;
-	}
-
-}
diff --git src/se/smartrefill/ad/bank/domain/AdCekabPan.java src/se/smartrefill/ad/bank/domain/AdCekabPan.java
deleted file mode 100644
index 42e482d..0000000
--- src/se/smartrefill/ad/bank/domain/AdCekabPan.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import se.smartrefill.ad.domain.AdPaymentCard;
-
-public class AdCekabPan implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private int alertMeLowLimit;
-	private List<AdCekabPanNotificationLog> cekabPanNotificationLogs;
-	private Integer id;
-	private AdPaymentCard paymentCard;
-	private String status;
-
-	public AdCekabPan() {
-		this.cekabPanNotificationLogs = new ArrayList<AdCekabPanNotificationLog>();
-	}
-
-	public int getAlertMeLowLimit() {
-		return alertMeLowLimit;
-	}
-
-	public List<AdCekabPanNotificationLog> getCekabPanNotificationLogs() {
-		return cekabPanNotificationLogs;
-	}
-
-	public Integer getId() {
-		return id;
-	}
-
-	public AdPaymentCard getPaymentCard() {
-		return paymentCard;
-	}
-
-	public String getStatus() {
-		return status;
-	}
-}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLog.java src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLog.java
deleted file mode 100644
index adb0c57..0000000
--- src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLog.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-public class AdCekabPanNotificationLog implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private String amount;
-	private String city;
-	private Date created;
-	private String currency;
-	private String functionCode;
-	private Integer id;
-	private transient String last4PaymentCardDigits;
-	private String location;
-	private List<AdCekabPanNotificationLogMedia> medias;
-	private String pan;
-	private String purchaseDate;
-	private String purchaseTime;
-	private String replyCode;
-	private String result;
-	private String shop;
-
-	public AdCekabPanNotificationLog() {
-		this.medias = new ArrayList<AdCekabPanNotificationLogMedia>();
-		this.last4PaymentCardDigits = "";
-	}
-
-	public String getAmount() {
-		return amount;
-	}
-
-	public String getCity() {
-		return city;
-	}
-
-	public Date getCreated() {
-		return created;
-	}
-
-	public String getCurrency() {
-		return currency;
-	}
-
-	public String getFunctionCode() {
-		return functionCode;
-	}
-
-	public Integer getId() {
-		return id;
-	}
-
-	public String getLast4PaymentCardDigits() {
-		return last4PaymentCardDigits;
-	}
-
-	public String getLocation() {
-		return location;
-	}
-
-	public List<AdCekabPanNotificationLogMedia> getMedias() {
-		return medias;
-	}
-
-	public String getPan() {
-		return pan;
-	}
-
-	public String getPurchaseDate() {
-		return purchaseDate;
-	}
-
-	public String getPurchaseTime() {
-		return purchaseTime;
-	}
-
-	public String getReplyCode() {
-		return replyCode;
-	}
-
-	public String getResult() {
-		return result;
-	}
-
-	public String getShop() {
-		return shop;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLogMedia.java src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLogMedia.java
deleted file mode 100644
index 4ce0d44..0000000
--- src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLogMedia.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-
-public class AdCekabPanNotificationLogMedia implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private String caption;
-	private int cekabPanNotificationLogId;
-	private int id;
-	private byte[] media;
-	private String mediaType;
-
-	public String getCaption() {
-		return caption;
-	}
-
-	public int getCekabPanNotificationLogId() {
-		return cekabPanNotificationLogId;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public byte[] getMedia() {
-		return media;
-	}
-
-	public String getMediaType() {
-		return mediaType;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdLoginRequest.java src/se/smartrefill/ad/bank/domain/AdLoginRequest.java
deleted file mode 100644
index 2adb55d..0000000
--- src/se/smartrefill/ad/bank/domain/AdLoginRequest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-
-public class AdLoginRequest implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private String password;
-	private String username;
-
-	public AdLoginRequest(String username, String password) {
-		this.username = username;
-		this.password = password;
-	}
-
-	public String getPassword() {
-		return password;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public void setUsername(String userName) {
-		this.username = userName;
-	}
-}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdMoneyTransferCard.java src/se/smartrefill/ad/bank/domain/AdMoneyTransferCard.java
deleted file mode 100644
index a90c4cf..0000000
--- src/se/smartrefill/ad/bank/domain/AdMoneyTransferCard.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class AdMoneyTransferCard implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private String alias;
-	private int creditCardId;
-	private int id;
-	private String mobileNumber;
-	private List<AdMoneyTransferOrder> moneyTransferOrders;
-	private AdMoneyTransferService moneyTransferService;
-	private boolean pending;
-
-	public AdMoneyTransferCard() {
-		this.moneyTransferOrders = new ArrayList<AdMoneyTransferOrder>();
-	}
-
-	public String getAlias() {
-		return alias;
-	}
-
-	public int getCreditCardId() {
-		return creditCardId;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public String getMobileNumber() {
-		return mobileNumber;
-	}
-
-	public List<AdMoneyTransferOrder> getMoneyTransferOrders() {
-		return moneyTransferOrders;
-	}
-
-	public AdMoneyTransferService getMoneyTransferService() {
-		return moneyTransferService;
-	}
-
-	public boolean isPending() {
-		return pending;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdMoneyTransferOrder.java src/se/smartrefill/ad/bank/domain/AdMoneyTransferOrder.java
deleted file mode 100644
index 20e51d1..0000000
--- src/se/smartrefill/ad/bank/domain/AdMoneyTransferOrder.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-
-public class AdMoneyTransferOrder implements Serializable {
-	public static final int STATE_COMPLETE = 2;
-	public static final int STATE_FAILED = 3;
-	public static final int STATE_PENDING = 1;
-	public static final int STATE_UNKNOWN = 0;
-	private static final long serialVersionUID = 1L;
-	private String amount;
-	private String created;
-	private int id;
-	private AdMoneyTransferCard moneyTransferCard;
-	private int state = 0;
-
-	public String getAmount() {
-		return amount;
-	}
-
-	public String getCreated() {
-		return created;
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public AdMoneyTransferCard getMoneyTransferCard() {
-		return moneyTransferCard;
-	}
-
-	public int getState() {
-		return state;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdMoneyTransferService.java src/se/smartrefill/ad/bank/domain/AdMoneyTransferService.java
deleted file mode 100644
index 733e77b..0000000
--- src/se/smartrefill/ad/bank/domain/AdMoneyTransferService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.util.ArrayList;
-import java.util.List;
-import se.smartrefill.ad.domain.AdService;
-
-public class AdMoneyTransferService extends AdService {
-	private static final long serialVersionUID = 1L;
-	private List<AdMoneyTransferCard> moneyTransferCards;
-
-	public AdMoneyTransferService() {
-		this.moneyTransferCards = new ArrayList<AdMoneyTransferCard>();
-	}
-
-	public List<AdMoneyTransferCard> getMoneyTransferCards() {
-		return moneyTransferCards;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
deleted file mode 100644
index c55f130..0000000
--- src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-
-public class AdPendingCreditCard
-  implements Serializable
-{
-  private static final long serialVersionUID = 1L;
-  private String alias;
-  private int customerId;
-  private String number;
-  private String partner;
-  private String phoneNumber;
-	private int serviceId;
-
-	public String getAlias() {
-		return alias;
-	}
-	  public int getCustomerId() {
-			return customerId;
-		}
-
-	public String getNumber() {
-		return number;
-	}
-
-	public String getPartner() {
-		return partner;
-	}
-
-	public String getPhoneNumber() {
-		return phoneNumber;
-	}
-
-	public int getServiceId() {
-		return serviceId;
-	}
-}
diff --git src/se/smartrefill/ad/bank/domain/AdTexts.java src/se/smartrefill/ad/bank/domain/AdTexts.java
deleted file mode 100644
index 9a2cda6..0000000
--- src/se/smartrefill/ad/bank/domain/AdTexts.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package se.smartrefill.ad.bank.domain;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-public class AdTexts implements Serializable {
-	private static final long serialVersionUID = 1L;
-	private Map<String, String> texts;
-
-	public AdTexts() {
-		this.texts = new HashMap<String, String>();
-	}
-
-	public Map<String, String> getTexts() {
-		return texts;
-	}
-}
diff --git src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
deleted file mode 100644
index f801bcf..0000000
--- src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package se.smartrefill.ad.bank.remoting.service;
-
-import java.util.List;
-import se.smartrefill.ad.bank.domain.AdAccount;
-
-public abstract interface RemoteBalanceService
-{
-  public abstract AdAccount getAccountTransactions(int customerId, AdAccount account, String scrollDirection);
-  public abstract List<AdAccount> getAccounts(int customerId);
-}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
deleted file mode 100644
index 4a5ac4e..0000000
--- src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package se.smartrefill.ad.bank.remoting.service;
-
-import se.smartrefill.ad.bank.domain.AdLoginRequest;
-import se.smartrefill.ad.domain.AdCustomer;
-
-public abstract interface RemoteCustomerService
-{
-  public abstract AdCustomer login(AdLoginRequest paramAdLoginRequest);
-  
-  public abstract void logout(int customerId);
-}
diff --git src/se/smartrefill/ad/domain/AdAbstractCustomer.java src/se/smartrefill/ad/domain/AdAbstractCustomer.java
deleted file mode 100644
index 6238819..0000000
--- src/se/smartrefill/ad/domain/AdAbstractCustomer.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package se.smartrefill.ad.domain;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class AdAbstractCustomer
-  implements Serializable
-{
-  private static final long serialVersionUID = 1L;
-  protected String countryCode;
-  protected String customerOwner;
-  protected Integer id;
-  protected String maskedCardNumber;
-  protected Boolean mustChangePassword;
-  protected Integer paymentCardId;
-  protected List<AdPaymentCard> paymentCards;
-  protected List<AdService> services;
-  protected String socialSecurityNumber;
-
-  public AdAbstractCustomer()
-  {
-    this.services = new ArrayList<AdService>();
-    this.paymentCards = new ArrayList<AdPaymentCard>();
-  }
-  
-  public int getId(){
-	  return id;
-  }
-}
diff --git src/se/smartrefill/ad/domain/AdCustomer.java src/se/smartrefill/ad/domain/AdCustomer.java
deleted file mode 100644
index 25defd6..0000000
--- src/se/smartrefill/ad/domain/AdCustomer.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package se.smartrefill.ad.domain;
-
-import java.io.Serializable;
-
-import se.smartrefill.ad.bank.domain.AdBalanceService;
-
-public class AdCustomer extends AdAbstractCustomer implements Serializable {
-	private static final long serialVersionUID = 1L;
-
-	public AdBalanceService getBalanceService() {
-		
-		for (AdService service : this.services) {
-			if (service instanceof AdBalanceService)
-				return (AdBalanceService)service;
-		}
-		return null;
-	}
-}
diff --git src/se/smartrefill/ad/domain/AdPaymentCard.java src/se/smartrefill/ad/domain/AdPaymentCard.java
deleted file mode 100644
index 3ced145..0000000
--- src/se/smartrefill/ad/domain/AdPaymentCard.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package se.smartrefill.ad.domain;
-
-import java.io.Serializable;
-
-public class AdPaymentCard
-  implements Serializable
-{
-  private static final long serialVersionUID = 1L;
-  private String description;
-  private int id;
-  private String maskedPaymentCard;
-  private int paymentRef;
-  
-  public String getDescription() {
-		return description;
-	}
-	public int getId() {
-		return id;
-	}
-	public String getMaskedPaymentCard() {
-		return maskedPaymentCard;
-	}
-	public int getPaymentRef() {
-		return paymentRef;
-	}
-}
diff --git src/se/smartrefill/ad/domain/AdService.java src/se/smartrefill/ad/domain/AdService.java
deleted file mode 100644
index 2eeca97..0000000
--- src/se/smartrefill/ad/domain/AdService.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package se.smartrefill.ad.domain;
-
-import java.io.Serializable;
-
-public abstract class AdService
-  implements Serializable
-{
-  private static final long serialVersionUID = 1L;
-  private Integer id;
-  private String imei;
-  private String manufacturer;
-  private String mobileNumber;
-  private String model;
-  private String operator;
-  private String password;
-  private String userName;
-
-  public Integer getId()
-  {
-    return this.id;
-  }
-
-  public String getImei()
-  {
-    return this.imei;
-  }
-
-  public String getManufacturer()
-  {
-    return this.manufacturer;
-  }
-
-  public String getMobileNumber()
-  {
-    return this.mobileNumber;
-  }
-
-  public String getModel()
-  {
-    return this.model;
-  }
-
-  public String getOperator()
-  {
-    return this.operator;
-  }
-
-  public String getPassword()
-  {
-    return this.password;
-  }
-
-  public String getUserName()
-  {
-    return this.userName;
-  }
-}
\ No newline at end of file
diff --git src/se/smartrefill/exception/CustomerBlockedException.java src/se/smartrefill/exception/CustomerBlockedException.java
deleted file mode 100644
index a943ab4..0000000
--- src/se/smartrefill/exception/CustomerBlockedException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package se.smartrefill.exception;
-
-public class CustomerBlockedException extends SmartrefillException {
-	private static final long serialVersionUID = 1L;
-
-	public CustomerBlockedException() {
-	}
-
-	public CustomerBlockedException(String paramString) {
-		super(paramString);
-	}
-}
diff --git src/se/smartrefill/exception/InvalidLoginException.java src/se/smartrefill/exception/InvalidLoginException.java
deleted file mode 100644
index fcddf65..0000000
--- src/se/smartrefill/exception/InvalidLoginException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package se.smartrefill.exception;
-
-public class InvalidLoginException extends SmartrefillException{
-	private static final long serialVersionUID = 1L;
-
-	public InvalidLoginException() {
-	}
-
-	public InvalidLoginException(String paramString) {
-		super(paramString);
-	}
-}
\ No newline at end of file
diff --git src/se/smartrefill/exception/InvalidSecurityCodeException.java src/se/smartrefill/exception/InvalidSecurityCodeException.java
deleted file mode 100644
index c185f34..0000000
--- src/se/smartrefill/exception/InvalidSecurityCodeException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package se.smartrefill.exception;
-
-public class InvalidSecurityCodeException extends ValidationException
-{
-  private static final long serialVersionUID = 1L;
-
-  public InvalidSecurityCodeException()
-  {
-  }
-
-  public InvalidSecurityCodeException(String paramString)
-  {
-    super(paramString);
-  }
-}
\ No newline at end of file
diff --git src/se/smartrefill/exception/SmartrefillException.java src/se/smartrefill/exception/SmartrefillException.java
deleted file mode 100644
index 98a0111..0000000
--- src/se/smartrefill/exception/SmartrefillException.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package se.smartrefill.exception;
-
-public class SmartrefillException extends RuntimeException {
-	private static final long serialVersionUID = 1L;
-
-	public SmartrefillException() {
-		this(null);
-	}
-
-	public SmartrefillException(String paramString) {
-		super(paramString);
-	}
-}
diff --git src/se/smartrefill/exception/UnauthenticatedUserException.java src/se/smartrefill/exception/UnauthenticatedUserException.java
deleted file mode 100644
index fdb6dd9..0000000
--- src/se/smartrefill/exception/UnauthenticatedUserException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package se.smartrefill.exception;
-
-public class UnauthenticatedUserException extends SmartrefillException {
-	private static final long serialVersionUID = 1L;
-
-	public UnauthenticatedUserException() {
-	}
-
-	public UnauthenticatedUserException(String paramString) {
-		super(paramString);
-	}
-}
diff --git src/se/smartrefill/exception/ValidationException.java src/se/smartrefill/exception/ValidationException.java
deleted file mode 100644
index e05b245..0000000
--- src/se/smartrefill/exception/ValidationException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package se.smartrefill.exception;
-
-public class ValidationException extends SmartrefillException
-{
-  private static final long serialVersionUID = 1L;
-
-  public ValidationException()
-  {
-  }
-
-  public ValidationException(String paramString)
-  {
-    super(paramString);
-  }
-}
\ No newline at end of file
diff --git src/se/smartrefill/remoting/domain/exception/CustomerBlockedException.java src/se/smartrefill/remoting/domain/exception/CustomerBlockedException.java
deleted file mode 100644
index 32a06b3..0000000
--- src/se/smartrefill/remoting/domain/exception/CustomerBlockedException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class CustomerBlockedException extends SmartrefillException {
-	private static final long serialVersionUID = 1L;
-
-	public CustomerBlockedException() {
-	}
-
-	public CustomerBlockedException(String paramString) {
-		super(paramString);
-	}
-}
diff --git src/se/smartrefill/remoting/domain/exception/InvalidLoginException.java src/se/smartrefill/remoting/domain/exception/InvalidLoginException.java
deleted file mode 100644
index 7fc2bbd..0000000
--- src/se/smartrefill/remoting/domain/exception/InvalidLoginException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class InvalidLoginException extends SmartrefillException{
-	private static final long serialVersionUID = 1L;
-
-	public InvalidLoginException() {
-	}
-
-	public InvalidLoginException(String paramString) {
-		super(paramString);
-	}
-}
\ No newline at end of file
diff --git src/se/smartrefill/remoting/domain/exception/InvalidSecurityCodeException.java src/se/smartrefill/remoting/domain/exception/InvalidSecurityCodeException.java
deleted file mode 100644
index dde2f1b..0000000
--- src/se/smartrefill/remoting/domain/exception/InvalidSecurityCodeException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class InvalidSecurityCodeException extends ValidationException
-{
-  private static final long serialVersionUID = 1L;
-
-  public InvalidSecurityCodeException()
-  {
-  }
-
-  public InvalidSecurityCodeException(String paramString)
-  {
-    super(paramString);
-  }
-}
\ No newline at end of file
diff --git src/se/smartrefill/remoting/domain/exception/NoSessionException.java src/se/smartrefill/remoting/domain/exception/NoSessionException.java
deleted file mode 100644
index 7614fd7..0000000
--- src/se/smartrefill/remoting/domain/exception/NoSessionException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class NoSessionException extends SmartrefillException {
-	private static final long serialVersionUID = 1L;
-
-	public NoSessionException() {
-	}
-}
diff --git src/se/smartrefill/remoting/domain/exception/SmartrefillException.java src/se/smartrefill/remoting/domain/exception/SmartrefillException.java
deleted file mode 100644
index a02d003..0000000
--- src/se/smartrefill/remoting/domain/exception/SmartrefillException.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class SmartrefillException extends RuntimeException {
-	private static final long serialVersionUID = 1L;
-
-	public SmartrefillException() {
-		this(null);
-	}
-
-	public SmartrefillException(String paramString) {
-		super(paramString);
-	}
-}
diff --git src/se/smartrefill/remoting/domain/exception/UnauthenticatedUserException.java src/se/smartrefill/remoting/domain/exception/UnauthenticatedUserException.java
deleted file mode 100644
index a7b77be..0000000
--- src/se/smartrefill/remoting/domain/exception/UnauthenticatedUserException.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class UnauthenticatedUserException extends SmartrefillException {
-	private static final long serialVersionUID = 1L;
-
-	public UnauthenticatedUserException() {
-	}
-
-	public UnauthenticatedUserException(String paramString) {
-		super(paramString);
-	}
-}
diff --git src/se/smartrefill/remoting/domain/exception/ValidationException.java src/se/smartrefill/remoting/domain/exception/ValidationException.java
deleted file mode 100644
index 559efe3..0000000
--- src/se/smartrefill/remoting/domain/exception/ValidationException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package se.smartrefill.remoting.domain.exception;
-
-public class ValidationException extends SmartrefillException
-{
-  private static final long serialVersionUID = 1L;
-
-  public ValidationException()
-  {
-  }
-
-  public ValidationException(String paramString)
-  {
-    super(paramString);
-  }
-}
\ No newline at end of file

commit 8c4f88408c7e595eeba847feb8721ee65f1e8872
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun Mar 18 17:41:58 2012 +0100

    Finalize implementation for Skandiabanken JSON-api

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 0f8acc2..749d216 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -119,10 +119,6 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         for (Account account: accounts) {
             updateTransactions(account, urlopen);
         }
-        if (urlopen != null) {
-            urlopen.close();
-        }
-
     }
 
     public Urllib login() throws LoginException, BankException {
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 3a9bc79..b17e5ba 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -9,6 +9,7 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.HttpResponseException;
 import org.apache.http.message.BasicNameValuePair;
+import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -16,9 +17,11 @@ import android.content.Context;
 import android.provider.Settings.Secure;
 import android.text.InputType;
 
+import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -92,6 +95,7 @@ public class Skandiabanken extends Bank {
 			String loginResponse = urlopen.open(loginUrl, postData);
 			JSONObject obj = new JSONObject(loginResponse);
 			customerId = (int) obj.getLong("id");
+			urlopen.addHeader("x-smartrefill-customer", "" + customerId);
 		} catch (HttpResponseException e) {
 			if (e.getStatusCode() == 401)
 				throw new BankException(
@@ -138,11 +142,27 @@ public class Skandiabanken extends Bank {
 
 		String accountsUrl = getBaseUrlWithCustomerOwner() + "/customer/"
 				+ customerId + "/accounts";
-		String accountsJsonString;
 		try {
-			accountsJsonString = urlopen.open(accountsUrl);
-			JSONObject json = new JSONObject(accountsJsonString);
-			// TODO Handle accounts
+			String accountsJsonString = urlopen.open(accountsUrl);
+			JSONArray json = new JSONArray(accountsJsonString);
+			for (int i = 0; i< json.length(); i++)
+			{
+				JSONObject acountJsonObj = json.getJSONObject(i);
+				
+				String name = acountJsonObj.optString("alias");
+				
+				if (name.length() != 0)
+					name += " - ";
+				
+				name += acountJsonObj.getString("accountNumber");
+
+				// disposableAmount also exists in JSON
+				String balanceString = acountJsonObj.getString("amount");
+				String id = acountJsonObj.getString("id");
+				int type = Account.REGULAR; // accountType exists in JSON
+				Account account = new Account(name, Helpers.parseBalance(balanceString), id, type);
+				accounts.add(account);
+			}
 		} catch (IOException e) {
 			throw new BankException("IOException " + e.getMessage());
 		} catch (JSONException e) {
@@ -155,9 +175,35 @@ public class Skandiabanken extends Bank {
 			throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
 
-		String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
-				+ "/customer/" + customerId + "/account/" + account.getId();
-		// TODO Get transactions
+		if (customerId == 0)
+			login();
+		
+		try {
+	        ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+	        
+			String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
+					+ "/customer/" + customerId + "/account/" + account.getId();
+			
+			String accountJsonString = urlopen.open(accountTransactionsUrl);
+			JSONObject accountJSONObj = new JSONObject(accountJsonString);
+			JSONArray transactionsJSONArray = accountJSONObj.getJSONArray("transactions");
+			for (int i = 0; i< transactionsJSONArray.length(); i++)
+			{
+				JSONObject transactionJsonObj = transactionsJSONArray.getJSONObject(i);
+				String date = transactionJsonObj.getString("date"); // time and timestamp also exists in JSON
+				String ammountString = transactionJsonObj.getString("amount");
+				String description = transactionJsonObj.getString("merchant");
+				Transaction transaction = new Transaction(date, description, Helpers.parseBalance(ammountString));
+				transactions.add(transaction);
+			}
+			
+			account.setTransactions(transactions);
+			
+		} catch (IOException e) {
+			throw new BankException("IOException " + e.getMessage());
+		} catch (JSONException e) {
+			throw new BankException("Oväntat svarsformat " + e.getMessage());
+		}
 	}
 
 	@Override

commit d8758ff4f82397ec52ba3ff695e4ec4be55f140e
Author: Jonas Björk <jonas@vulkanlandet.se>
Date:   Thu Mar 8 22:13:55 2012 +0000

    Added Meniga (www.meniga.is)

diff --git res/drawable/logo_meniga.png res/drawable/logo_meniga.png
new file mode 100644
index 0000000..ef78257
Binary files /dev/null and res/drawable/logo_meniga.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 8a58c48..a353e9e 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -16,10 +16,6 @@
 
 package com.liato.bankdroid.banking;
 
-import java.math.BigDecimal;
-import java.util.ArrayList;
-
-import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.database.Cursor;
@@ -82,10 +78,15 @@ import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
+import com.liato.bankdroid.banking.banks.Meniga;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
 import com.liato.bankdroid.provider.IBankTypes;
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
 
 public class BankFactory {
 
@@ -205,6 +206,8 @@ public class BankFactory {
             return new Vasttrafik(context);
         case IBankTypes.EVERYDAYCARD:
             return new Everydaycard(context);
+        case IBankTypes.MENIGA:
+            return new Meniga(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -269,6 +272,7 @@ public class BankFactory {
         banks.add(new NordeaDK(context));
         banks.add(new Vasttrafik(context));
         banks.add(new Everydaycard(context));
+        banks.add(new Meniga(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Meniga.java src/com/liato/bankdroid/banking/banks/Meniga.java
new file mode 100644
index 0000000..efea9ad
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Meniga.java
@@ -0,0 +1,179 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+import eu.nullbyte.android.urllib.Urllib;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Meniga extends Bank{
+    private static final String TAG = "Meniga";
+    private static final String NAME = "Meniga";
+    private static final String NAME_SHORT = "meniga";
+    private static final String URL = "https://www.meniga.is/";
+    private static final int BANKTYPE_ID = IBankTypes.MENIGA;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+    private static final String INPUT_HINT_USERNAME = "name@company.com";
+
+    private Pattern reAccounts = Pattern.compile("\\?account=([^']+)'[^>]*>\\s*<div\\s*class=\"account-info\">[^<]*<span\\s*class=\"bold\">([^<]+)</span>\\s*(?:</div>\\s*<div\\s*class=\"account-status\">)\\s*<span\\s*class=\"(minus|plus)\">([^k]+)kr");
+    private Pattern reTransactions = Pattern.compile("\"Id\":([^,]*),.*?\"Text\":\"([^\"]*)\".*?\"OriginalDate\":\".?.?Date\\(([^\\)]*)\\).*?\"Amount\":([^,]*),");
+
+    String response;
+
+    public Meniga(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.setCurrency("ISK");
+    }
+
+    public Meniga(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+    @Override
+    protected LoginPackage preLogin() throws BankException, IOException {
+        urlopen = new Urllib();
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        response = urlopen.open("https://www.meniga.is/Mobile");
+        List<NameValuePair> postData = new ArrayList<NameValuePair>();
+        postData.add(new BasicNameValuePair("email", username));
+        postData.add(new BasicNameValuePair("password", password));
+        return new LoginPackage(urlopen, postData, response, "https://www.meniga.is/Mobile");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
+
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+            if (response.contains("<div class=\"login\">")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+
+        try{
+            response = urlopen.open("https://www.meniga.is/mobile/language/?lang=sv-SE");
+        }
+        catch (ClientProtocolException e){
+            //Do nothing
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://www.meniga.is/Mobile/Accounts");
+            matcher = reAccounts.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Type              id
+                 * 2: Name              accont
+                 * 3: ----              plus or minus
+                 * 4: Balance            5 678
+                 *
+                 */
+                Account account = new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim());
+                account.setCurrency("ISK");
+                balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+                accounts.add(account);
+            }
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        finally {
+            super.updateComplete();
+        }
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        if (account.getType() == Account.OTHER) return;
+
+        String response;
+        Matcher matcher;
+        try {
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            response = urlopen.open("https://www.meniga.is/Transactions?account="+account.getId());
+            matcher = reTransactions.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Id                    1231213
+                 * 2: Specification         Pressbyran
+                 * 3: Date in millisec      2142411351235
+                 * 4: Amount                -20
+                 *
+                 *
+                 */
+             Long date = Long.valueOf(matcher.group(3));
+             SimpleDateFormat ft = new SimpleDateFormat ("yy-MM-dd");
+             Transaction transaction = new Transaction(ft.format(date), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4)));
+             transaction.setCurrency("ISK");
+             transactions.add(transaction);
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 9378587..d1ba2cb 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -78,4 +78,5 @@ public interface IBankTypes {
     public final static int VASTTRAFIK = 54;
     public final static int EVERYDAYCARD = 55;
 	public static final int AKELIUSINVEST = 56;
+    public static final int MENIGA = 57;
 }

commit ce615679bf9f9b08f914d0f9e452beb6bccb17b1
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun Feb 12 17:10:26 2012 +0100

    Start reimplementing Skandiabanken to use thier JSON-API

diff --git src/com/caucho/hessian/HessianException.java src/com/caucho/hessian/HessianException.java
deleted file mode 100644
index 3b8f510..0000000
--- src/com/caucho/hessian/HessianException.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-package com.caucho.hessian;
-
-/**
- * Base runtime exception for Hessian exceptions.
- */
-public class HessianException extends RuntimeException {
-	/**
-	 * Zero-arg constructor.
-	 */
-	public HessianException() {
-	}
-
-	/**
-	 * Create the exception.
-	 */
-	public HessianException(String message) {
-		super(message);
-	}
-
-	/**
-	 * Create the exception.
-	 */
-	public HessianException(String message, Throwable rootCause) {
-		super(message, rootCause);
-	}
-
-	/**
-	 * Create the exception.
-	 */
-	public HessianException(Throwable rootCause) {
-		super(rootCause);
-	}
-}
diff --git src/com/caucho/hessian/client/HessianConnectionException.java src/com/caucho/hessian/client/HessianConnectionException.java
deleted file mode 100644
index 7f31eee..0000000
--- src/com/caucho/hessian/client/HessianConnectionException.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.client;
-
-import com.caucho.hessian.HessianException;
-
-/**
- * Exception caused by failure of the client proxy to connect to the server.
- */
-public class HessianConnectionException extends HessianException {
-  /**
-   * Zero-arg constructor.
-   */
-  public HessianConnectionException()
-  {
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianConnectionException(String message)
-  {
-    super(message);
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianConnectionException(String message, Throwable rootCause)
-  {
-    super(message, rootCause);
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianConnectionException(Throwable rootCause)
-  {
-    super(rootCause);
-  }
-}
diff --git src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
deleted file mode 100644
index aae791c..0000000
--- src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.caucho.hessian.client;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Map;
-
-import android.util.Log;
-
-import com.ast.util.CookieParser.Cookie;
-import com.caucho.hessian.client.HessianHttpProxyFactory.HessianHttpProxy;
-import com.caucho.hessian.io.HessianRemoteObject;
-
-// This class is added in the bankdroid project to enable adding some http-headers required by Skandiabanken
-// The class also takes care of a ugly hack for some strange cookie-handling for Skandiabanken (see getCookie)
-public class HessianHttpHeaderProxyFactory extends HessianHttpProxyFactory{
-
-	Map<String, String> mHeaderMap;
-	
-	public HessianHttpHeaderProxyFactory(Map<String, String> headers){
-		mHeaderMap = headers;
-	}
-	
-    @SuppressWarnings({"unchecked"})
-    @Override
-    public <T> T create(Class<T> api, String urlName, ClassLoader loader) throws MalformedURLException {
-        InvocationHandler handler = new HessianHttpHeaderProxy(this, new URL(urlName));
-        return (T) Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
-    }
-    
-    public void addHeader(String key, String value){
-    	mHeaderMap.put(key, value);
-    }
-    
-    public void removeHeader(String key){
-    	mHeaderMap.remove(key);
-    }
-	
-	class HessianHttpHeaderProxy extends HessianHttpProxy{
-
-		HessianHttpHeaderProxy(HessianProxyFactory factory, URL url) {
-			super(factory, url);
-		}
-		
-		@Override
-		protected void addRequestHeaders(URLConnection conn) {
-			super.addRequestHeaders(conn);
-
-			for (Map.Entry<String, String> header : mHeaderMap.entrySet())
-				conn.setRequestProperty(header.getKey(), header.getValue());
-		}
-
-	    @Override
-		protected void putCookie(Cookie cookie) {
-	    	// Ugly hack: for some reason the path in the cookie is not as expected
-            if (cookie.host.contentEquals("smartrefill.se"))
-            {
-            	//Log.d("Skandiabanken cookie", "using path / instead of " + cookie.path);
-            	cookie.path = "/";
-            }
-            super.putCookie(cookie);
-		}
-	}
-}
diff --git src/com/caucho/hessian/client/HessianHttpProxyFactory.java src/com/caucho/hessian/client/HessianHttpProxyFactory.java
deleted file mode 100644
index 3371e3e..0000000
--- src/com/caucho/hessian/client/HessianHttpProxyFactory.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2009 hessdroid@gmail.com
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.caucho.hessian.client;
-
-import android.util.Log;
-
-import com.ast.util.CookieParser;
-import com.ast.util.CookieParser.Cookie;
-import com.caucho.hessian.io.HessianRemoteObject;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * <code>HessianHttpProxyFactory</code> extends the
- * <code>HessianProxyFactory</code>'s capabilities, by adding support for HTTP
- * Cookies. A cookie map is used to map Server/Paths to cookies
- *
- * @author <a href="mailto:wolf@wolfpaulus.com">Wolf Paulus</a>
- * @version 1.0 Date: Nov 17, 2009
- */
-
-public class HessianHttpProxyFactory extends HessianProxyFactory {
-    /*
-      * public Object create2(Class api, String urlName, ClassLoader loader)
-      * throws MalformedURLException { InvocationHandler handler = new
-      * HessianHttpProxy(this, new URL(urlName)); return
-      * Proxy.newProxyInstance(api.getClassLoader(), new Class[]{api,
-      * HessianRemoteObject.class}, handler); }
-      */
-
-    /**
-     * Creates a new proxy with the specified URL. The returned object is a
-     * proxy with the interface specified by api.
-     * <p/>
-     * <p/>
-     * <pre>
-     * String url = "http://localhost:8080/ejb/hello");
-     * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
-     * </pre>
-     *
-     * @param api     the interface the proxy class needs to implement
-     * @param urlName the URL where the client object is located.
-     * @param loader  <code>ClassLoader</code> to be used loading the proxy
-     *                instance's class
-     * @return a proxy to the object with the specified interface.
-     * @throws java.net.MalformedURLException if URL object cannot be created with the provided urlName
-     */
-    @SuppressWarnings({"unchecked"})
-    @Override
-    public <T> T create(Class<T> api, String urlName, ClassLoader loader) throws MalformedURLException {
-        //
-        // todo: since the api is already loaded, maybe the api class' classloader should be tried,
-        // in case the provided classloader fails.
-
-        InvocationHandler handler = new HessianHttpProxy(this, new URL(urlName));
-        return (T) Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
-    }
-
-    /**
-     * Clear the Cookie Cache, should be run on every logout.
-     */
-    public static void clearCookieCache() {
-        HessianHttpProxy.cookieMap.clear();
-    }
-
-    /**
-     * The <code>HessianHttpProxy</code> intercepts request and response, so that
-     * cookies can be read in the incoming response and written before an
-     * outgoing request is sent. Cookie strings are stored in a
-     * <code>Hashtable</code>; and the URL's host+path is used for the key.
-     * <p/>
-     * When the cookie string is retrieved, the path is shortened, all the way
-     * to / until a match is found.
-     * <p/>
-     * Available Header Fields are:
-     * <p/>
-     * Header Field: date (Wed, 18 Nov 2009 21:01:44 GMT)
-     * Header Field: content-type (application/x-hessian)
-     * Header Field: transfer-encoding (chunked)
-     * Header Field: server (Apache-Coyote/1.1)
-     * Header Field: set-cookie (JSESSIONID=5930D0459F0CE1B769ED5D08B031F9D2; Path=/Server)
-     */
-    protected static class HessianHttpProxy extends HessianProxy {
-        private static final HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>();
-
-        private static final String COOKIE_SET = "set-cookie";
-
-        HessianHttpProxy(HessianProxyFactory factory, URL url) {
-            super(url, factory);
-        }
-
-        /**
-         * Read cookies found in a server's response, so we can send them back
-         * with the next request. The response-header field names are the key
-         * values of the map.
-         *
-         * @param conn <code>URLConnection</code>
-         */
-        protected void parseResponseHeaders(URLConnection conn) {
-
-            List<String> cookieStrings = conn.getHeaderFields().get(HessianHttpProxy.COOKIE_SET);
-            if (cookieStrings != null) {
-                String host = conn.getURL().getHost();
-                for (String s : cookieStrings) {
-                    Cookie cookie = CookieParser.parse(host, s);
-                    //Log.d("Skandiabanken cookie", "Cookie string: " + s);
-                    putCookie(cookie);
-                }
-            }
-        }
-
-        /**
-         * Add the cookies we received in a previous response, into the current
-         * request. The getUrl().getPath() might return something like this:
-         * /Server/comm Here we look for a close match in the cookiemap,
-         * starting with the most specific.
-         *
-         * @param conn <code>URLConnection</code>
-         */
-        protected void addRequestHeaders(URLConnection conn) {
-
-            String host = conn.getURL().getHost();
-            String path = conn.getURL().getPath();
-
-            while (path != null && 0 < path.length()) {
-                //Log.d("Skandiabanken cookie", "Host:+" + host +",Path:"+path);
-                Cookie cookie = getCookie(host, path);
-                if (cookie != null) {
-                    conn.setRequestProperty("Cookie", cookie.value);
-                    //Log.d("Skandiabanken cookie", "Cookie set in request:" + cookie.value);
-                    break;
-                }
-                int i = path.lastIndexOf("/");
-				if (0==i && 1<path.length()) {
-                    path = "/";
-                } else {
-                    path = path.substring(0, i);
-                }
-			}
-		}
-
-		protected Cookie getCookie(String host, String path) {
-			return HessianHttpProxy.cookieMap.get(host + path);
-		}
-
-		protected void putCookie(Cookie cookie) {
-            HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
-            //Log.d("Skandiabanken cookie", "Cookie cached: " + cookie.host + cookie.path);
-		}
-	}
-}
diff --git src/com/caucho/hessian/client/HessianMetaInfoAPI.java src/com/caucho/hessian/client/HessianMetaInfoAPI.java
deleted file mode 100644
index 74b528f..0000000
--- src/com/caucho/hessian/client/HessianMetaInfoAPI.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.client;
-
-/**
- * API retrieving hessian meta information.
- */
-public interface HessianMetaInfoAPI {
-  /**
-   * Returns a service attribute.
-   *
-   * <ul>
-   * <li>java.api.class - the Java interface for the object interface.
-   * <li>java.ejb.home.class - the EJB home interface
-   * <li>java.ejb.remote.class - the EJB remote interface
-   * <li>java.primary.key.class - the EJB primary key class
-   * </ul>
-   */
-  public Object _hessian_getAttribute(String name);
-}
diff --git src/com/caucho/hessian/client/HessianProxy.java src/com/caucho/hessian/client/HessianProxy.java
deleted file mode 100644
index 1767a32..0000000
--- src/com/caucho/hessian/client/HessianProxy.java
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.client;
-
-import android.util.Log;
-
-import com.caucho.hessian.io.*;
-import com.caucho.services.server.AbstractSkeleton;
-
-import java.io.*;
-import java.util.logging.*;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.WeakHashMap;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-
-
-/**
- * Proxy implementation for Hessian clients. Applications will generally use
- * HessianProxyFactory to create proxy clients.
- */
-public class HessianProxy implements InvocationHandler {
-	private static final Logger log = Logger.getLogger(HessianProxy.class
-			.getName());
-
-	protected HessianProxyFactory _factory;
-	private WeakHashMap<Method, String> _mangleMap = new WeakHashMap<Method, String>();
-	private URL _url;
-
-	/**
-	 * Package protected constructor for factory
-	 */
-	HessianProxy(HessianProxyFactory factory, URL url) {
-		_factory = factory;
-		_url = url;
-	}
-
-	/**
-	 * Protected constructor for subclassing
-	 */
-	protected HessianProxy(URL url, HessianProxyFactory factory) {
-		_factory = factory;
-		_url = url;
-	}
-
-	/**
-	 * Returns the proxy's URL.
-	 */
-	public URL getURL() {
-		return _url;
-	}
-
-	/**
-	 * Handles the object invocation.
-	 * 
-	 * @param proxy
-	 *            the proxy object to invoke
-	 * @param method
-	 *            the method to call
-	 * @param args
-	 *            the arguments to the proxy object
-	 */
-	public Object invoke(Object proxy, Method method, Object[] args)
-			throws Throwable {
-		String mangleName;
-
-		synchronized (_mangleMap) {
-			mangleName = _mangleMap.get(method);
-		}
-
-		if (mangleName == null) {
-			String methodName = method.getName();
-			Class[] params = method.getParameterTypes();
-
-			// equals and hashCode are special cased
-			if (methodName.equals("equals") && params.length == 1
-					&& params[0].equals(Object.class)) {
-				Object value = args[0];
-				if (value == null || !Proxy.isProxyClass(value.getClass()))
-					return Boolean.FALSE;
-
-				HessianProxy handler = (HessianProxy) Proxy
-						.getInvocationHandler(value);
-
-				return Boolean.valueOf(_url.equals(handler.getURL()));
-			} else if (methodName.equals("hashCode") && params.length == 0)
-				return Integer.valueOf(_url.hashCode());
-			else if (methodName.equals("getHessianType"))
-				return proxy.getClass().getInterfaces()[0].getName();
-			else if (methodName.equals("getHessianURL"))
-				return _url.toString();
-			else if (methodName.equals("toString") && params.length == 0)
-				return "HessianProxy[" + _url + "]";
-
-			if (!_factory.isOverloadEnabled())
-				mangleName = method.getName();
-			else
-				mangleName = mangleName(method);
-
-			synchronized (_mangleMap) {
-				_mangleMap.put(method, mangleName);
-			}
-		}
-
-		InputStream is = null;
-		URLConnection conn = null;
-		HttpURLConnection httpConn = null;
-
-		try {
-			if (log.isLoggable(Level.FINER))
-				log.finer("Hessian[" + _url + "] calling " + mangleName);
-
-			conn = sendRequest(mangleName, args);
-
-			if (conn instanceof HttpURLConnection) {
-				httpConn = (HttpURLConnection) conn;
-				int code = 500;
-
-				try {
-					code = httpConn.getResponseCode();
-				} catch (Exception e) {
-				}
-
-				parseResponseHeaders(conn);
-
-				if (code != 200) {
-					StringBuffer sb = new StringBuffer();
-					int ch;
-
-					try {
-						is = httpConn.getInputStream();
-
-						if (is != null) {
-							while ((ch = is.read()) >= 0)
-								sb.append((char) ch);
-
-							is.close();
-						}
-
-						is = httpConn.getErrorStream();
-						if (is != null) {
-							while ((ch = is.read()) >= 0)
-								sb.append((char) ch);
-						}
-					} catch (FileNotFoundException e) {
-						throw new HessianConnectionException(
-								"HessianProxy cannot connect to '" + _url, e);
-					} catch (IOException e) {
-						if (is == null)
-							throw new HessianConnectionException(code + ": "
-									+ e, e);
-						else
-							throw new HessianConnectionException(code + ": "
-									+ sb, e);
-					}
-
-					if (is != null)
-						is.close();
-
-					throw new HessianConnectionException(code + ": "
-							+ sb.toString());
-				}
-			}
-
-			is = conn.getInputStream();
-
-			if (log.isLoggable(Level.FINEST)) {
-				PrintWriter dbg = new PrintWriter(new LogWriter(log));
-				is = new HessianDebugInputStream(is, dbg);
-			}
-
-//			if (false) {
-//				PrintWriter dbg = new PrintWriter(new LogCatLogWriter());
-//				is = new HessianDebugInputStream(is, dbg);
-//			}
-
-			AbstractHessianInput in = _factory.getHessianInput(is);
-
-			in.startReply();
-
-			Object value = in.readObject(method.getReturnType());
-
-			if (value instanceof InputStream) {
-				value = new ResultInputStream(httpConn, is, in,
-						(InputStream) value);
-				is = null;
-				httpConn = null;
-			} else
-				in.completeReply();
-
-			return value;
-		} catch (HessianProtocolException e) {
-			throw new HessianRuntimeException(e);
-		} finally {
-			try {
-				if (is != null)
-					is.close();
-			} catch (Exception e) {
-				log.log(Level.FINE, e.toString(), e);
-			}
-
-			try {
-				if (httpConn != null)
-					httpConn.disconnect();
-			} catch (Exception e) {
-				log.log(Level.FINE, e.toString(), e);
-			}
-		}
-	}
-
-	protected String mangleName(Method method) {
-		Class[] param = method.getParameterTypes();
-
-		if (param == null || param.length == 0)
-			return method.getName();
-		else
-			return AbstractSkeleton.mangleName(method, false);
-	}
-
-	/**
-	 * Method that allows subclasses to parse response headers such as cookies.
-	 * Default implementation is empty.
-	 * 
-	 * @param conn
-	 */
-	protected void parseResponseHeaders(URLConnection conn) {
-
-	}
-
-	protected URLConnection sendRequest(String methodName, Object[] args)
-			throws IOException {
-		URLConnection conn = null;
-
-		conn = _factory.openConnection(_url);
-		boolean isValid = false;
-
-		try {
-			// Used chunked mode when available, i.e. JDK 1.5.
-			if (_factory.isChunkedPost() && conn instanceof HttpURLConnection) {
-				try {
-					HttpURLConnection httpConn = (HttpURLConnection) conn;
-
-					httpConn.setChunkedStreamingMode(8 * 1024);
-				} catch (Throwable e) {
-				}
-			}
-
-			addRequestHeaders(conn);
-
-			OutputStream os = null;
-
-			try {
-				os = conn.getOutputStream();
-			} catch (Exception e) {
-				throw new HessianRuntimeException(e);
-			}
-
-			if (log.isLoggable(Level.FINEST)) {
-				PrintWriter dbg = new PrintWriter(new LogWriter(log));
-				os = new HessianDebugOutputStream(os, dbg);
-			}
-
-			AbstractHessianOutput out = _factory.getHessianOutput(os);
-
-			out.call(methodName, args);
-			out.flush();
-
-			isValid = true;
-
-			return conn;
-		} finally {
-			if (!isValid && conn instanceof HttpURLConnection)
-				((HttpURLConnection) conn).disconnect();
-		}
-	}
-
-	/**
-	 * Method that allows subclasses to add request headers such as cookies.
-	 * Default implementation is empty.
-	 */
-	protected void addRequestHeaders(URLConnection conn) {
-
-	}
-
-	static class ResultInputStream extends InputStream {
-		private HttpURLConnection _conn;
-		private InputStream _connIs;
-		private AbstractHessianInput _in;
-		private InputStream _hessianIs;
-
-		ResultInputStream(HttpURLConnection conn, InputStream is,
-				AbstractHessianInput in, InputStream hessianIs) {
-			_conn = conn;
-			_connIs = is;
-			_in = in;
-			_hessianIs = hessianIs;
-		}
-
-		public int read() throws IOException {
-			if (_hessianIs != null) {
-				int value = _hessianIs.read();
-
-				if (value < 0)
-					close();
-
-				return value;
-			} else
-				return -1;
-		}
-
-		public int read(byte[] buffer, int offset, int length)
-				throws IOException {
-			if (_hessianIs != null) {
-				int value = _hessianIs.read(buffer, offset, length);
-
-				if (value < 0)
-					close();
-
-				return value;
-			} else
-				return -1;
-		}
-
-		public void close() throws IOException {
-			HttpURLConnection conn = _conn;
-			_conn = null;
-
-			InputStream connIs = _connIs;
-			_connIs = null;
-
-			AbstractHessianInput in = _in;
-			_in = null;
-
-			InputStream hessianIs = _hessianIs;
-			_hessianIs = null;
-
-			try {
-				if (hessianIs != null)
-					hessianIs.close();
-			} catch (Exception e) {
-				log.log(Level.FINE, e.toString(), e);
-			}
-
-			try {
-				if (in != null) {
-					in.completeReply();
-					in.close();
-				}
-			} catch (Exception e) {
-				log.log(Level.FINE, e.toString(), e);
-			}
-
-			try {
-				if (connIs != null) {
-					connIs.close();
-				}
-			} catch (Exception e) {
-				log.log(Level.FINE, e.toString(), e);
-			}
-
-			try {
-				if (conn != null) {
-					conn.disconnect();
-				}
-			} catch (Exception e) {
-				log.log(Level.FINE, e.toString(), e);
-			}
-		}
-	}
-
-	static class LogWriter extends Writer {
-		private Logger _log;
-		private Level _level = Level.FINEST;
-		private StringBuilder _sb = new StringBuilder();
-
-		LogWriter(Logger log) {
-			_log = log;
-		}
-		
-		public void write(char ch) {
-			if (ch == '\n' && _sb.length() > 0) {
-				_log.fine(_sb.toString());
-				_sb.setLength(0);
-			} else
-				_sb.append((char) ch);
-		}
-
-		public void write(char[] buffer, int offset, int length) {
-			for (int i = 0; i < length; i++) {
-				char ch = buffer[offset + i];
-
-				if (ch == '\n' && _sb.length() > 0) {
-					_log.fine(_sb.toString());
-					_sb.setLength(0);
-				} else
-					_sb.append((char) ch);
-			}
-		}
-
-		public void flush() {
-		}
-
-		public void close() {
-			if (_sb.length() > 0)
-				_log.fine(_sb.toString());
-		}
-	}	
-	
-	static class LogCatLogWriter extends Writer {
-		private StringBuilder _sb = new StringBuilder();
-
-		public void write(char ch) {
-			if (ch == '\n' && _sb.length() > 0) {
-				Log.d("HessianLogCatLogWriter", _sb.toString());
-				_sb.setLength(0);
-			} else
-				_sb.append((char) ch);
-		}
-
-		public void write(char[] buffer, int offset, int length) {
-			for (int i = 0; i < length; i++) {
-				char ch = buffer[offset + i];
-
-				if (ch == '\n' && _sb.length() > 0) {
-					Log.d("HessianLogCatLogWriter", _sb.toString());
-					_sb.setLength(0);
-				} else
-					_sb.append((char) ch);
-			}
-		}
-
-		public void flush() {
-		}
-
-		public void close() {
-			if (_sb.length() > 0){
-				Log.d("HessianLogCatLogWriter", _sb.toString());
-			}
-		}
-	}
-}
diff --git src/com/caucho/hessian/client/HessianProxyFactory.java src/com/caucho/hessian/client/HessianProxyFactory.java
deleted file mode 100644
index 39a8887..0000000
--- src/com/caucho/hessian/client/HessianProxyFactory.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.client;
-
-import com.caucho.hessian.io.*;
-import com.caucho.services.client.ServiceProxyFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.logging.Logger;
-
-/**
- * Factory for creating Hessian client stubs.  The returned stub will
- * call the remote object for all methods.
- * <p/>
- * <pre>
- * String url = "http://localhost:8080/ejb/hello";
- * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
- * </pre>
- * <p/>
- * After creation, the stub can be like a regular Java class.  Because
- * it makes remote calls, it can throw more exceptions than a Java class.
- * In particular, it may throw protocol exceptions.
- * <p/>
- * <h3>Authentication</h3>
- * <p/>
- * <p>The proxy can use HTTP basic authentication if the user and the
- * password are set.
- */
-@SuppressWarnings({"UnusedDeclaration"})
-public class HessianProxyFactory implements ServiceProxyFactory {
-    protected static Logger log = Logger.getLogger(HessianProxyFactory.class.getName());
-
-    private SerializerFactory _serializerFactory;
-    private HessianRemoteResolver _resolver;
-
-    private String _user;
-    private String _password;
-    private String _basicAuth;
-
-    private boolean _isOverloadEnabled = false;
-
-    private boolean _isHessian2Reply = true;
-    private boolean _isHessian2Request = false;
-
-    private boolean _isChunkedPost = true;
-    private boolean _isDebug = false;
-
-    private long _readTimeout = -1;
-
-    /**
-     * Creates the new proxy factory.
-     */
-    public HessianProxyFactory() {
-        _resolver = new HessianProxyResolver(this);
-    }
-
-    /**
-     * Sets the user.
-     *
-     * @param user <code>String</code>
-     */
-    public void setUser(String user) {
-        _user = user;
-        _basicAuth = null;
-    }
-
-    /**
-     * Sets the password.
-     *
-     * @param password <code>String</code>
-     */
-    public void setPassword(String password) {
-        _password = password;
-        _basicAuth = null;
-    }
-
-    /**
-     * Sets the debug
-     *
-     * @param isDebug <code>boolean</code>
-     */
-    public void setDebug(boolean isDebug) {
-        _isDebug = isDebug;
-    }
-
-    /**
-     * Gets the debug
-     *
-     * @return <code>boolean</code>
-     */
-    public boolean isDebug() {
-        return _isDebug;
-    }
-
-    /**
-     * Returns true if overloaded methods are allowed (using mangling)
-     *
-     * @return <code>boolean</code>
-     */
-    public boolean isOverloadEnabled() {
-        return _isOverloadEnabled;
-    }
-
-    /**
-     * set true if overloaded methods are allowed (using mangling)
-     *
-     * @param isOverloadEnabled <code>boolean</code>
-     */
-    public void setOverloadEnabled(boolean isOverloadEnabled) {
-        _isOverloadEnabled = isOverloadEnabled;
-    }
-
-    /**
-     * Set true if should use chunked encoding on the request.
-     *
-     * @param isChunked <code>boolean</code>
-     */
-    public void setChunkedPost(boolean isChunked) {
-        _isChunkedPost = isChunked;
-    }
-
-    /**
-     * Set true if should use chunked encoding on the request.
-     *
-     * @return <code>boolean</code>
-     */
-    public boolean isChunkedPost() {
-        return _isChunkedPost;
-    }
-
-    /**
-     * The socket timeout on requests in milliseconds.
-     *
-     * @return <code>long</code>
-     */
-    public long getReadTimeout() {
-        return _readTimeout;
-    }
-
-    /**
-     * The socket timeout on requests in milliseconds.
-     *
-     * @param timeout <code>long</code>
-     */
-    public void setReadTimeout(long timeout) {
-        _readTimeout = timeout;
-    }
-
-    /**
-     * True if the proxy can read Hessian 2 responses.
-     *
-     * @param isHessian2 <code>boolean</code>
-     */
-    public void setHessian2Reply(boolean isHessian2) {
-        _isHessian2Reply = isHessian2;
-    }
-
-    /**
-     * True if the proxy should send Hessian 2 requests.
-     *
-     * @param isHessian2 <code>boolean</code>
-     */
-    public void setHessian2Request(boolean isHessian2) {
-        _isHessian2Request = isHessian2;
-
-        if (isHessian2)
-            _isHessian2Reply = true;
-    }
-
-    /**
-     * @return <code>HessianRemoteResolver</code> the remote resolver.
-     */
-    public HessianRemoteResolver getRemoteResolver() {
-        return _resolver;
-    }
-
-    /**
-     * Sets the serializer factory.
-     *
-     * @param factory <code>SerializerFactory</code>
-     */
-    public void setSerializerFactory(SerializerFactory factory) {
-        _serializerFactory = factory;
-    }
-
-    /**
-     * Gets the serializer factory.
-     *
-     * @return <code>SerializerFactory</code>
-     */
-    public SerializerFactory getSerializerFactory() {
-        if (_serializerFactory == null)
-            _serializerFactory = new SerializerFactory();
-
-        return _serializerFactory;
-    }
-
-    /**
-     * Creates the URL connection.
-     *
-     * @param url <coe>URL</code>
-     * @return <code>URLConnection</code>
-     * @throws IOException if connection cannot be opened
-     */
-    protected URLConnection openConnection(URL url)
-            throws IOException {
-        URLConnection conn = url.openConnection();
-
-        conn.setDoOutput(true);
-
-        if (_readTimeout > 0) {
-            try {
-                conn.setReadTimeout((int) _readTimeout);
-            } catch (Throwable e) { // intentionally empty
-            }
-        }
-
-        conn.setRequestProperty("Content-Type", "x-application/hessian");
-
-        if (_basicAuth != null)
-            conn.setRequestProperty("Authorization", _basicAuth);
-        else if (_user != null && _password != null) {
-            _basicAuth = "Basic " + base64(_user + ":" + _password);
-            conn.setRequestProperty("Authorization", _basicAuth);
-        }
-
-        return conn;
-    }
-
-    /**
-     * Creates a new proxy with the specified URL.  The API class uses
-     * the java.api.class value from _hessian_
-     *
-     * @param urlName the URL where the client object is located.
-     * @return a proxy to the object with the specified interface.
-     * @throws java.net.MalformedURLException if URL object cannot be created with the provided urlName
-     * @throws ClassNotFoundException         if the current Thread's contextClassLoader cannot find the api class
-     */
-    @SuppressWarnings({"unchecked"})
-    public Object create(String urlName) throws MalformedURLException, ClassNotFoundException {
-        HessianMetaInfoAPI metaInfo = create(HessianMetaInfoAPI.class, urlName);
-        String apiClassName = (String) metaInfo._hessian_getAttribute("java.api.class");
-
-        if (apiClassName == null) {
-            throw new HessianRuntimeException(urlName + " has an unknown api.");
-        }
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        Class<Object> apiClass = (Class<Object>) Class.forName(apiClassName, false, loader);
-        return create(apiClass, urlName);
-    }
-
-    /**
-     * Creates a new proxy with the specified URL.  The returned object
-     * is a proxy with the interface specified by api.
-     * <p/>
-     * <pre>
-     * String url = "http://localhost:8080/ejb/hello");
-     * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
-     * </pre>
-     *
-     * @param api     the interface the proxy class needs to implement
-     * @param urlName the URL where the client object is located.
-     * @return a proxy to the object with the specified interface.
-     */
-    public <T>T create(Class<T> api, String urlName) throws MalformedURLException {
-        return create(api, urlName, Thread.currentThread().getContextClassLoader());
-    }
-
-    /**
-     * Creates a new proxy with the specified URL.  The returned object
-     * is a proxy with the interface specified by api.
-     * <p/>
-     * <pre>
-     * String url = "http://localhost:8080/ejb/hello");
-     * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
-     * </pre>
-     *
-     * @param api     the interface the proxy class needs to implement
-     * @param urlName the URL where the client object is located.
-     * @param loader  <code>ClassLoader</code> to be used loading the proxy instance's class
-     * @return a proxy to the object with the specified interface.
-     * @throws java.net.MalformedURLException if URL object cannot be created with the provided urlName
-     */
-    @SuppressWarnings({"unchecked"})
-    public <T>T create(Class<T> api, String urlName, ClassLoader loader) throws MalformedURLException {
-        if (api == null) {
-            throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
-        }
-        InvocationHandler handler;
-        URL url = new URL(urlName);
-        handler = new HessianProxy(this, url);
-        return (T) Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
-    }
-
-    public AbstractHessianInput getHessianInput(InputStream is) {
-        AbstractHessianInput in;
-
-        if (_isDebug)
-            is = new HessianDebugInputStream(is, new PrintWriter(System.out));
-
-        in = new Hessian2Input(is);
-
-        in.setRemoteResolver(getRemoteResolver());
-
-        in.setSerializerFactory(getSerializerFactory());
-
-        return in;
-    }
-
-    public AbstractHessianOutput getHessianOutput(OutputStream os) {
-        AbstractHessianOutput out;
-
-        if (_isHessian2Request)
-            out = new Hessian2Output(os);
-        else {
-            HessianOutput out1 = new HessianOutput(os);
-            out = out1;
-
-            if (_isHessian2Reply)
-                out1.setVersion(2);
-        }
-
-        out.setSerializerFactory(getSerializerFactory());
-
-        return out;
-    }
-
-
-    /**
-     * Creates the Base64 value.
-     *
-     * @param value <code>String</code>
-     * @return <code>String</code> base65 encoded String
-     */
-    private String base64(String value) {
-        StringBuffer cb = new StringBuffer();
-
-        int i;
-        for (i = 0; i + 2 < value.length(); i += 3) {
-            long chunk = (int) value.charAt(i);
-            chunk = (chunk << 8) + (int) value.charAt(i + 1);
-            chunk = (chunk << 8) + (int) value.charAt(i + 2);
-
-            cb.append(encode(chunk >> 18));
-            cb.append(encode(chunk >> 12));
-            cb.append(encode(chunk >> 6));
-            cb.append(encode(chunk));
-        }
-
-        if (i + 1 < value.length()) {
-            long chunk = (int) value.charAt(i);
-            chunk = (chunk << 8) + (int) value.charAt(i + 1);
-            chunk <<= 8;
-
-            cb.append(encode(chunk >> 18));
-            cb.append(encode(chunk >> 12));
-            cb.append(encode(chunk >> 6));
-            cb.append('=');
-        } else if (i < value.length()) {
-            long chunk = (int) value.charAt(i);
-            chunk <<= 16;
-
-            cb.append(encode(chunk >> 18));
-            cb.append(encode(chunk >> 12));
-            cb.append('=');
-            cb.append('=');
-        }
-
-        return cb.toString();
-    }
-
-    public static char encode(long d) {
-        d &= 0x3f;
-        if (d < 26)
-            return (char) (d + 'A');
-        else if (d < 52)
-            return (char) (d + 'a' - 26);
-        else if (d < 62)
-            return (char) (d + '0' - 52);
-        else if (d == 62)
-            return '+';
-        else
-            return '/';
-    }
-}
-
diff --git src/com/caucho/hessian/client/HessianProxyResolver.java src/com/caucho/hessian/client/HessianProxyResolver.java
deleted file mode 100644
index 36a1a7c..0000000
--- src/com/caucho/hessian/client/HessianProxyResolver.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.client;
-
-import com.caucho.hessian.io.HessianRemoteResolver;
-
-import java.io.IOException;
-
-/**
- * Looks up remote objects in the proxy.
- */
-public class HessianProxyResolver implements HessianRemoteResolver {
-  private HessianProxyFactory _factory;
-  
-  /**
-   * Creates an uninitialized Hessian remote resolver.
-   */
-  public HessianProxyResolver(HessianProxyFactory factory)
-  {
-    _factory = factory;
-  }
-
-  /**
-   * Looks up a proxy object.
-   */
-  public Object lookup(String type, String url)
-    throws IOException
-  {
-    ClassLoader loader = Thread.currentThread().getContextClassLoader();
-
-    try {
-      Class api = Class.forName(type, false, loader);
-
-      return _factory.create(api, url);
-    } catch (Exception e) {
-      throw new IOException(String.valueOf(e));
-    }
-  }
-}
diff --git src/com/caucho/hessian/client/HessianRuntimeException.java src/com/caucho/hessian/client/HessianRuntimeException.java
deleted file mode 100644
index 8487a10..0000000
--- src/com/caucho/hessian/client/HessianRuntimeException.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.client;
-
-/**
- * Wrapper for protocol exceptions thrown in the proxy.
- */
-public class HessianRuntimeException extends RuntimeException {
-  private Throwable rootCause;
-
-  /**
-   * Zero-arg constructor.
-   */
-  public HessianRuntimeException()
-  {
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianRuntimeException(String message)
-  {
-    super(message);
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianRuntimeException(String message, Throwable rootCause)
-  {
-    super(message);
-
-    this.rootCause = rootCause;
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianRuntimeException(Throwable rootCause)
-  {
-    super(String.valueOf(rootCause));
-
-    this.rootCause = rootCause;
-  }
-
-  /**
-   * Returns the underlying cause.
-   */
-  public Throwable getRootCause()
-  {
-    return this.rootCause;
-  }
-
-  /**
-   * Returns the underlying cause.
-   */
-  public Throwable getCause()
-  {
-    return getRootCause();
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractDeserializer.java src/com/caucho/hessian/io/AbstractDeserializer.java
deleted file mode 100644
index 75c1a99..0000000
--- src/com/caucho/hessian/io/AbstractDeserializer.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Deserializing an object. 
- */
-abstract public class AbstractDeserializer implements Deserializer {
-  public Class getType()
-  {
-    return Object.class;
-  }
-
-  public Object readObject(AbstractHessianInput in)
-    throws IOException
-  {
-    Object obj = in.readObject();
-
-    String className = getClass().getName();
-
-    if (obj != null)
-      throw error(className + ": unexpected object " + obj.getClass().getName() + " (" + obj + ")");
-    else
-      throw error(className + ": unexpected null value");
-  }
-  
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    throw new UnsupportedOperationException(String.valueOf(this));
-  }
-  
-  public Object readLengthList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    throw new UnsupportedOperationException(String.valueOf(this));
-  }
-  
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    Object obj = in.readObject();
-
-    String className = getClass().getName();
-
-    if (obj != null)
-      throw error(className + ": unexpected object " + obj.getClass().getName() + " (" + obj + ")");
-    else
-      throw error(className + ": unexpected null value");
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    throw new UnsupportedOperationException(String.valueOf(this));
-  }
-
-  protected HessianProtocolException error(String msg)
-  {
-    return new HessianProtocolException(msg);
-  }
-
-  protected String codeName(int ch)
-  {
-    if (ch < 0)
-      return "end of file";
-    else
-      return "0x" + Integer.toHexString(ch & 0xff);
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractHessianInput.java src/com/caucho/hessian/io/AbstractHessianInput.java
deleted file mode 100644
index 5bfa196..0000000
--- src/com/caucho/hessian/io/AbstractHessianInput.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * Abstract base class for Hessian requests.  Hessian users should only
- * need to use the methods in this class.
- *
- * <pre>
- * AbstractHessianInput in = ...; // get input
- * String value;
- *
- * in.startReply();         // read reply header
- * value = in.readString(); // read string value
- * in.completeReply();      // read reply footer
- * </pre>
- */
-abstract public class AbstractHessianInput {
-  private HessianRemoteResolver resolver;
-  
-  /**
-   * Initialize the Hessian stream with the underlying input stream.
-   */
-  public void init(InputStream is)
-  {
-  }
-
-  /**
-   * Returns the call's method
-   */
-  abstract public String getMethod();
-
-  /**
-   * Sets the resolver used to lookup remote objects.
-   */
-  public void setRemoteResolver(HessianRemoteResolver resolver)
-  {
-    this.resolver = resolver;
-  }
-
-  /**
-   * Sets the resolver used to lookup remote objects.
-   */
-  public HessianRemoteResolver getRemoteResolver()
-  {
-    return resolver;
-  }
-
-  /**
-   * Sets the serializer factory.
-   */
-  public void setSerializerFactory(SerializerFactory ser)
-  {
-  }
-
-  /**
-   * Reads the call
-   *
-   * <pre>
-   * c major minor
-   * </pre>
-   */
-  abstract public int readCall()
-    throws IOException;
-
-  /**
-   * For backward compatibility with HessianSkeleton
-   */
-  public void skipOptionalCall()
-    throws IOException
-  {
-  }
-
-  /**
-   * Reads a header, returning null if there are no headers.
-   *
-   * <pre>
-   * H b16 b8 value
-   * </pre>
-   */
-  abstract public String readHeader()
-    throws IOException;
-
-  /**
-   * Starts reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * m b16 b8 method
-   * </pre>
-   */
-  abstract public String readMethod()
-    throws IOException;
-
-  /**
-   * Starts reading the call, including the headers.
-   *
-   * <p>The call expects the following protocol data
-   *
-   * <pre>
-   * c major minor
-   * m b16 b8 method
-   * </pre>
-   */
-  abstract public void startCall()
-    throws IOException;
-
-  /**
-   * Completes reading the call
-   *
-   * <p>The call expects the following protocol data
-   *
-   * <pre>
-   * Z
-   * </pre>
-   */
-  abstract public void completeCall()
-    throws IOException;
-
-  /**
-   * Reads a reply as an object.
-   * If the reply has a fault, throws the exception.
-   */
-  abstract public Object readReply(Class expectedClass)
-    throws Throwable;
-  
-  /**
-   * Starts reading the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * r
-   * v
-   * </pre>
-   */
-  abstract public void startReply()
-    throws Throwable;
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  abstract public void completeReply()
-    throws IOException;
-
-  /**
-   * Reads a boolean
-   *
-   * <pre>
-   * T
-   * F
-   * </pre>
-   */
-  abstract public boolean readBoolean()
-    throws IOException;
-
-  /**
-   * Reads a null
-   *
-   * <pre>
-   * N
-   * </pre>
-   */
-  abstract public void readNull()
-    throws IOException;
-
-  /**
-   * Reads an integer
-   *
-   * <pre>
-   * I b32 b24 b16 b8
-   * </pre>
-   */
-  abstract public int readInt()
-    throws IOException;
-
-  /**
-   * Reads a long
-   *
-   * <pre>
-   * L b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  abstract public long readLong()
-    throws IOException;
-
-  /**
-   * Reads a double.
-   *
-   * <pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  abstract public double readDouble()
-    throws IOException;
-
-  /**
-   * Reads a date.
-   *
-   * <pre>
-   * T b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  abstract public long readUTCDate()
-    throws IOException;
-
-  /**
-   * Reads a string encoded in UTF-8
-   *
-   * <pre>
-   * s b16 b8 non-final string chunk
-   * S b16 b8 final string chunk
-   * </pre>
-   */
-  abstract public String readString()
-    throws IOException;
-
-  /**
-   * Reads an XML node encoded in UTF-8
-   *
-   * <pre>
-   * x b16 b8 non-final xml chunk
-   * X b16 b8 final xml chunk
-   * </pre>
-   */
-  abstract public org.w3c.dom.Node readNode()
-    throws IOException;
-  
-  /**
-   * Starts reading a string.  All the characters must be read before
-   * calling the next method.  The actual characters will be read with
-   * the reader's read() or read(char [], int, int).
-   *
-   * <pre>
-   * s b16 b8 non-final string chunk
-   * S b16 b8 final string chunk
-   * </pre>
-   */
-  abstract public Reader getReader()
-    throws IOException;
-
-  /**
-   * Starts reading a byte array using an input stream.  All the bytes
-   * must be read before calling the following method.
-   *
-   * <pre>
-   * b b16 b8 non-final binary chunk
-   * B b16 b8 final binary chunk
-   * </pre>
-   */
-  abstract public InputStream readInputStream()
-    throws IOException;
-
-  /**
-   * Reads a byte array.
-   *
-   * <pre>
-   * b b16 b8 non-final binary chunk
-   * B b16 b8 final binary chunk
-   * </pre>
-   */
-  abstract public byte []readBytes()
-    throws IOException;
-
-  /**
-   * Reads an arbitrary object from the input stream.
-   *
-   * @param expectedClass the expected class if the protocol doesn't supply it.
-   */
-  abstract public Object readObject(Class expectedClass)
-    throws IOException;
-
-  /**
-   * Reads an arbitrary object from the input stream.
-   */
-  abstract public Object readObject()
-    throws IOException;
-
-  /**
-   * Reads a remote object reference to the stream.  The type is the
-   * type of the remote interface.
-   *
-   * <code><pre>
-   * 'r' 't' b16 b8 type url
-   * </pre></code>
-   */
-  abstract public Object readRemote()
-    throws IOException;
-
-  /**
-   * Reads a reference
-   *
-   * <pre>
-   * R b32 b24 b16 b8
-   * </pre>
-   */
-  abstract public Object readRef()
-    throws IOException;
-
-  /**
-   * Adds an object reference.
-   */
-  abstract public int addRef(Object obj)
-    throws IOException;
-
-  /**
-   * Sets an object reference.
-   */
-  abstract public void setRef(int i, Object obj)
-    throws IOException;
-
-  /**
-   * Resets the references for streaming.
-   */
-  public void resetReferences()
-  {
-  }
-
-  /**
-   * Reads the start of a list
-   */
-  abstract public int readListStart()
-    throws IOException;    
-
-  /**
-   * Reads the length of a list.
-   */
-  abstract public int readLength()
-    throws IOException;    
-
-  /**
-   * Reads the start of a map
-   */
-  abstract public int readMapStart()
-    throws IOException;    
-
-  /**
-   * Reads an object type.
-   */
-  abstract public String readType()
-    throws IOException;    
-
-  /**
-   * Returns true if the data has ended.
-   */
-  abstract public boolean isEnd()
-    throws IOException;
-
-  /**
-   * Read the end byte
-   */
-  abstract public void readEnd()
-    throws IOException;
-
-  /**
-   * Read the end byte
-   */
-  abstract public void readMapEnd()
-    throws IOException;
-
-  /**
-   * Read the end byte
-   */
-  abstract public void readListEnd()
-    throws IOException;
-  
-  public void close()
-    throws IOException
-  {
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractHessianOutput.java src/com/caucho/hessian/io/AbstractHessianOutput.java
deleted file mode 100644
index 9cb209e..0000000
--- src/com/caucho/hessian/io/AbstractHessianOutput.java
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Abstract output stream for Hessian requests.
- *
- * <pre>
- * OutputStream os = ...; // from http connection
- * AbstractOutput out = new HessianSerializerOutput(os);
- * String value;
- *
- * out.startCall("hello");  // start hello call
- * out.writeString("arg1"); // write a string argument
- * out.completeCall();      // complete the call
- * </pre>
- */
-abstract public class AbstractHessianOutput {
-  // serializer factory
-  protected SerializerFactory _serializerFactory;
-
-  /**
-   * Sets the serializer factory.
-   */
-  public void setSerializerFactory(SerializerFactory factory)
-  {
-    _serializerFactory = factory;
-  }
-
-  /**
-   * Gets the serializer factory.
-   */
-  public SerializerFactory getSerializerFactory()
-  {
-    return _serializerFactory;
-  }
-
-  /**
-   * Gets the serializer factory.
-   */
-  public final SerializerFactory findSerializerFactory()
-  {
-    SerializerFactory factory = _serializerFactory;
-
-    if (factory == null)
-      _serializerFactory = factory = new SerializerFactory();
-
-    return factory;
-  }
-  
-  /**
-   * Initialize the output with a new underlying stream.
-   */
-  public void init(OutputStream os)
-  {
-  }
-
-  /**
-   * Writes a complete method call.
-   */
-  public void call(String method, Object []args)
-    throws IOException
-  {
-    startCall(method);
-    
-    if (args != null) {
-      for (int i = 0; i < args.length; i++)
-        writeObject(args[i]);
-    }
-    
-    completeCall();
-  }
-
-  /**
-   * Starts the method call:
-   *
-   * <code><pre>
-   * c major minor
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  abstract public void startCall()
-    throws IOException;
-
-  /**
-   * Starts the method call:
-   *
-   * <code><pre>
-   * c major minor
-   * m b16 b8 method-namek
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  abstract public void startCall(String method)
-    throws IOException;
-
-  /**
-   * Writes a header name.  The header value must immediately follow.
-   *
-   * <code><pre>
-   * H b16 b8 foo <em>value</em>
-   * </pre></code>
-   */
-  abstract public void writeHeader(String name)
-    throws IOException;
-
-  /**
-   * Writes the method tag.
-   *
-   * <code><pre>
-   * m b16 b8 method-name
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  abstract public void writeMethod(String method)
-    throws IOException;
-
-  /**
-   * Completes the method call:
-   *
-   * <code><pre>
-   * z
-   * </pre></code>
-   */
-  abstract public void completeCall()
-    throws IOException;
-
-  /**
-   * Writes a boolean value to the stream.  The boolean will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * T
-   * F
-   * </pre></code>
-   *
-   * @param value the boolean value to write.
-   */
-  abstract public void writeBoolean(boolean value)
-    throws IOException;
-
-  /**
-   * Writes an integer value to the stream.  The integer will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * I b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the integer value to write.
-   */
-  abstract public void writeInt(int value)
-    throws IOException;
-
-  /**
-   * Writes a long value to the stream.  The long will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * L b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the long value to write.
-   */
-  abstract public void writeLong(long value)
-    throws IOException;
-
-  /**
-   * Writes a double value to the stream.  The double will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the double value to write.
-   */
-  abstract public void writeDouble(double value)
-    throws IOException;
-
-  /**
-   * Writes a date to the stream.
-   *
-   * <code><pre>
-   * T  b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param time the date in milliseconds from the epoch in UTC
-   */
-  abstract public void writeUTCDate(long time)
-    throws IOException;
-
-  /**
-   * Writes a null value to the stream.
-   * The null will be written with the following syntax
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeNull()
-    throws IOException;
-
-  /**
-   * Writes a string value to the stream using UTF-8 encoding.
-   * The string will be written with the following syntax:
-   *
-   * <code><pre>
-   * S b16 b8 string-value
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeString(String value)
-    throws IOException;
-
-  /**
-   * Writes a string value to the stream using UTF-8 encoding.
-   * The string will be written with the following syntax:
-   *
-   * <code><pre>
-   * S b16 b8 string-value
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeString(char []buffer, int offset, int length)
-    throws IOException;
-
-  /**
-   * Writes a byte array to the stream.
-   * The array will be written with the following syntax:
-   *
-   * <code><pre>
-   * B b16 b18 bytes
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeBytes(byte []buffer)
-    throws IOException;
-  /**
-   * Writes a byte array to the stream.
-   * The array will be written with the following syntax:
-   *
-   * <code><pre>
-   * B b16 b18 bytes
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeBytes(byte []buffer, int offset, int length)
-    throws IOException;
-  
-  /**
-   * Writes a byte buffer to the stream.
-   */
-  abstract public void writeByteBufferStart()
-    throws IOException;
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * b b16 b18 bytes
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeByteBufferPart(byte []buffer,
-					   int offset,
-					   int length)
-    throws IOException;
-  
-  /**
-   * Writes the last chunk of a byte buffer to the stream.
-   *
-   * <code><pre>
-   * b b16 b18 bytes
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  abstract public void writeByteBufferEnd(byte []buffer,
-					  int offset,
-					  int length)
-    throws IOException;
-
-  /**
-   * Writes a reference.
-   *
-   * <code><pre>
-   * R b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the integer value to write.
-   */
-  abstract public void writeRef(int value)
-    throws IOException;
-
-  /**
-   * Removes a reference.
-   */
-  abstract public boolean removeRef(Object obj)
-    throws IOException;
-
-  /**
-   * Replaces a reference from one object to another.
-   */
-  abstract public boolean replaceRef(Object oldRef, Object newRef)
-    throws IOException;
-
-  /**
-   * Adds an object to the reference list.  If the object already exists,
-   * writes the reference, otherwise, the caller is responsible for
-   * the serialization.
-   *
-   * <code><pre>
-   * R b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param object the object to add as a reference.
-   *
-   * @return true if the object has already been written.
-   */
-  abstract public boolean addRef(Object object)
-    throws IOException;
-
-  /**
-   * Resets the references for streaming.
-   */
-  public void resetReferences()
-  {
-  }
-
-  /**
-   * Writes a generic object to the output stream.
-   */
-  abstract public void writeObject(Object object)
-    throws IOException;
-
-  /**
-   * Writes the list header to the stream.  List writers will call
-   * <code>writeListBegin</code> followed by the list contents and then
-   * call <code>writeListEnd</code>.
-   *
-   * <code><pre>
-   * &lt;list>
-   *   &lt;type>java.util.ArrayList&lt;/type>
-   *   &lt;length>3&lt;/length>
-   *   &lt;int>1&lt;/int>
-   *   &lt;int>2&lt;/int>
-   *   &lt;int>3&lt;/int>
-   * &lt;/list>
-   * </pre></code>
-   */
-  abstract public boolean writeListBegin(int length, String type)
-    throws IOException;
-
-  /**
-   * Writes the tail of the list to the stream.
-   */
-  abstract public void writeListEnd()
-    throws IOException;
-
-  /**
-   * Writes the map header to the stream.  Map writers will call
-   * <code>writeMapBegin</code> followed by the map contents and then
-   * call <code>writeMapEnd</code>.
-   *
-   * <code><pre>
-   * Mt b16 b8 type (<key> <value>)z
-   * </pre></code>
-   */
-  abstract public void writeMapBegin(String type)
-    throws IOException;
-
-  /**
-   * Writes the tail of the map to the stream.
-   */
-  abstract public void writeMapEnd()
-    throws IOException;
-
-  /**
-   * Writes the object header to the stream (for Hessian 2.0), or a
-   * Map for Hessian 1.0.  Object writers will call
-   * <code>writeObjectBegin</code> followed by the map contents and then
-   * call <code>writeObjectEnd</code>.
-   *
-   * <code><pre>
-   * Ot b16 b8 type (<key> <value>)* z
-   * o b32 b24 b16 b8 <value>* z
-   * </pre></code>
-   *
-   * @return true if the object has already been defined.
-   */
-  public int writeObjectBegin(String type)
-    throws IOException
-  {
-    writeMapBegin(type);
-    
-    return -2;
-  }
-
-  /**
-   * Writes the end of the class.
-   */
-  public void writeClassFieldLength(int len)
-    throws IOException
-  {
-  }
-
-  /**
-   * Writes the tail of the object to the stream.
-   */
-  public void writeObjectEnd()
-    throws IOException
-  {
-  }
-
-  /**
-   * Writes a remote object reference to the stream.  The type is the
-   * type of the remote interface.
-   *
-   * <code><pre>
-   * 'r' 't' b16 b8 type url
-   * </pre></code>
-   */
-  abstract public void writeRemote(String type, String url)
-    throws IOException;
-  
-  public void startReply()
-    throws IOException
-  {
-  }
-  
-  public void completeReply()
-    throws IOException
-  {
-  }
-  
-  public void writeFault(String code, String message, Object detail)
-    throws IOException
-  {
-  }
-
-  public void flush()
-    throws IOException
-  {
-  }
-
-  public void close()
-    throws IOException
-  {
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractHessianResolver.java src/com/caucho/hessian/io/AbstractHessianResolver.java
deleted file mode 100644
index 8c86482..0000000
--- src/com/caucho/hessian/io/AbstractHessianResolver.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Looks up remote objects.  The default just returns a HessianRemote object.
- */
-public class AbstractHessianResolver implements HessianRemoteResolver {
-  /**
-   * Looks up a proxy object.
-   */
-  public Object lookup(String type, String url)
-    throws IOException
-  {
-    return new HessianRemote(type, url);
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractListDeserializer.java src/com/caucho/hessian/io/AbstractListDeserializer.java
deleted file mode 100644
index 2fb3fd9..0000000
--- src/com/caucho/hessian/io/AbstractListDeserializer.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Deserializing a JDK 1.2 Collection.
- */
-public class AbstractListDeserializer extends AbstractDeserializer {
-  public Object readObject(AbstractHessianInput in)
-    throws IOException
-  {
-    Object obj = in.readObject();
-
-    if (obj != null)
-      throw error("expected list at " + obj.getClass().getName() + " (" + obj + ")");
-    else
-      throw error("expected list at null");
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractMapDeserializer.java src/com/caucho/hessian/io/AbstractMapDeserializer.java
deleted file mode 100644
index d0203ce..0000000
--- src/com/caucho/hessian/io/AbstractMapDeserializer.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-/**
- * Serializing an object for known object types.
- */
-public class AbstractMapDeserializer extends AbstractDeserializer {
-  
-  public Class getType()
-  {
-    return HashMap.class;
-  }
-  
-  public Object readObject(AbstractHessianInput in)
-    throws IOException
-  {
-    Object obj = in.readObject();
-
-    if (obj != null)
-      throw error("expected map/object at " + obj.getClass().getName() + " (" + obj + ")");
-    else
-      throw error("expected map/object at null");
-  }
-}
diff --git src/com/caucho/hessian/io/AbstractSerializer.java src/com/caucho/hessian/io/AbstractSerializer.java
deleted file mode 100644
index 0939680..0000000
--- src/com/caucho/hessian/io/AbstractSerializer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.logging.*;
-
-/**
- * Serializing an object. 
- */
-abstract public class AbstractSerializer implements Serializer {
-  protected static final Logger log
-    = Logger.getLogger(AbstractSerializer.class.getName());
-  
-  abstract public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException;
-}
diff --git src/com/caucho/hessian/io/AbstractSerializerFactory.java src/com/caucho/hessian/io/AbstractSerializerFactory.java
deleted file mode 100644
index 6fbe292..0000000
--- src/com/caucho/hessian/io/AbstractSerializerFactory.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-/**
- * Factory for returning serialization methods.
- */
-abstract public class AbstractSerializerFactory {
-  /**
-   * Returns the serializer for a class.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  abstract public Serializer getSerializer(Class cl)
-    throws HessianProtocolException;
-
-  /**
-   * Returns the deserializer for a class.
-   *
-   * @param cl the class of the object that needs to be deserialized.
-   *
-   * @return a deserializer object for the serialization.
-   */
-  abstract public Deserializer getDeserializer(Class cl)
-    throws HessianProtocolException;
-}
diff --git src/com/caucho/hessian/io/ArrayDeserializer.java src/com/caucho/hessian/io/ArrayDeserializer.java
deleted file mode 100644
index ed9b53f..0000000
--- src/com/caucho/hessian/io/ArrayDeserializer.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-
-/**
- * Deserializing a Java array
- */
-public class ArrayDeserializer extends AbstractListDeserializer {
-  private Class _componentType;
-  private Class _type;
-  
-  public ArrayDeserializer(Class componentType)
-  {
-    _componentType = componentType;
-    
-    if (_componentType != null) {
-      try {
-        _type = Array.newInstance(_componentType, 0).getClass();
-      } catch (Exception e) {
-      }
-    }
-
-    if (_type == null)
-      _type = Object[].class;
-  }
-
-  public Class getType()
-  {
-    return _type;
-  }
-
-  /**
-   * Reads the array.
-   */
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    if (length >= 0) {
-      Object []data = createArray(length);
-
-      in.addRef(data);
-      
-      if (_componentType != null) {
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readObject(_componentType);
-      }
-      else {
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readObject();
-      }
-
-      in.readListEnd();
-
-      return data;
-    }
-    else {
-      ArrayList list = new ArrayList();
-
-      in.addRef(list);
-
-      if (_componentType != null) {
-        while (! in.isEnd())
-          list.add(in.readObject(_componentType));
-      }
-      else {
-        while (! in.isEnd())
-          list.add(in.readObject());
-      }
-
-      in.readListEnd();
-
-      Object []data = createArray(list.size());
-      for (int i = 0; i < data.length; i++)
-        data[i] = list.get(i);
-
-      return data;
-    }
-  }
-
-  /**
-   * Reads the array.
-   */
-  public Object readLengthList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    Object []data = createArray(length);
-
-    in.addRef(data);
-      
-    if (_componentType != null) {
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readObject(_componentType);
-    }
-    else {
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readObject();
-    }
-
-    return data;
-  }
-
-  protected Object []createArray(int length)
-  {
-    if (_componentType != null)
-      return (Object []) Array.newInstance(_componentType, length);
-    else
-      return new Object[length];
-  }
-
-  public String toString()
-  {
-    return "ArrayDeserializer[" + _componentType + "]";
-  }
-}
diff --git src/com/caucho/hessian/io/ArraySerializer.java src/com/caucho/hessian/io/ArraySerializer.java
deleted file mode 100644
index 85d033e..0000000
--- src/com/caucho/hessian/io/ArraySerializer.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Serializing a Java array.
- */
-public class ArraySerializer extends AbstractSerializer {
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (out.addRef(obj))
-      return;
-
-    Object []array = (Object []) obj;
-
-    boolean hasEnd = out.writeListBegin(array.length,
-					getArrayType(obj.getClass()));
-
-    for (int i = 0; i < array.length; i++)
-      out.writeObject(array[i]);
-
-    if (hasEnd)
-      out.writeListEnd();
-  }
-
-  /**
-   * Returns the &lt;type> name for a &lt;list>.
-   */
-  private String getArrayType(Class cl)
-  {
-    if (cl.isArray())
-      return '[' + getArrayType(cl.getComponentType());
-
-    String name = cl.getName();
-
-    if (name.equals("java.lang.String"))
-      return "string";
-    else if (name.equals("java.lang.Object"))
-      return "object";
-    else if (name.equals("java.util.Date"))
-      return "date";
-    else
-      return name;
-  }
-}
diff --git src/com/caucho/hessian/io/BasicDeserializer.java src/com/caucho/hessian/io/BasicDeserializer.java
deleted file mode 100644
index 807abc0..0000000
--- src/com/caucho/hessian/io/BasicDeserializer.java
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-
-/**
- * Serializing an object for known object types.
- */
-public class BasicDeserializer extends AbstractDeserializer {
-  public static final int NULL = BasicSerializer.NULL;
-  public static final int BOOLEAN = BasicSerializer.BOOLEAN;
-  public static final int BYTE = BasicSerializer.BYTE;
-  public static final int SHORT = BasicSerializer.SHORT;
-  public static final int INTEGER = BasicSerializer.INTEGER;
-  public static final int LONG = BasicSerializer.LONG;
-  public static final int FLOAT = BasicSerializer.FLOAT;
-  public static final int DOUBLE = BasicSerializer.DOUBLE;
-  public static final int CHARACTER = BasicSerializer.CHARACTER;
-  public static final int CHARACTER_OBJECT = BasicSerializer.CHARACTER_OBJECT;
-  public static final int STRING = BasicSerializer.STRING;
-  public static final int DATE = BasicSerializer.DATE;
-  public static final int NUMBER = BasicSerializer.NUMBER;
-  public static final int OBJECT = BasicSerializer.OBJECT;
-  
-  public static final int BOOLEAN_ARRAY = BasicSerializer.BOOLEAN_ARRAY;
-  public static final int BYTE_ARRAY = BasicSerializer.BYTE_ARRAY;
-  public static final int SHORT_ARRAY = BasicSerializer.SHORT_ARRAY;
-  public static final int INTEGER_ARRAY = BasicSerializer.INTEGER_ARRAY;
-  public static final int LONG_ARRAY = BasicSerializer.LONG_ARRAY;
-  public static final int FLOAT_ARRAY = BasicSerializer.FLOAT_ARRAY;
-  public static final int DOUBLE_ARRAY = BasicSerializer.DOUBLE_ARRAY;
-  public static final int CHARACTER_ARRAY = BasicSerializer.CHARACTER_ARRAY;
-  public static final int STRING_ARRAY = BasicSerializer.STRING_ARRAY;
-  public static final int OBJECT_ARRAY = BasicSerializer.OBJECT_ARRAY;
-
-  private int _code;
-
-  public BasicDeserializer(int code)
-  {
-    _code = code;
-  }
-
-  public Class getType()
-  {
-    switch (_code) {
-    case NULL:
-      return void.class;
-    case BOOLEAN:
-      return Boolean.class;
-    case BYTE:
-      return Byte.class;
-    case SHORT:
-      return Short.class;
-    case INTEGER:
-      return Integer.class;
-    case LONG:
-      return Long.class;
-    case FLOAT:
-      return Float.class;
-    case DOUBLE:
-      return Double.class;
-    case CHARACTER:
-      return Character.class;
-    case CHARACTER_OBJECT:
-      return Character.class;
-    case STRING:
-      return String.class;
-    case DATE:
-      return Date.class;
-    case NUMBER:
-      return Number.class;
-    case OBJECT:
-      return Object.class;
-
-    case BOOLEAN_ARRAY:
-      return boolean[].class;
-    case BYTE_ARRAY:
-      return byte[].class;
-    case SHORT_ARRAY:
-      return short[].class;
-    case INTEGER_ARRAY:
-      return int[].class;
-    case LONG_ARRAY:
-      return long[].class;
-    case FLOAT_ARRAY:
-      return float[].class;
-    case DOUBLE_ARRAY:
-      return double[].class;
-    case CHARACTER_ARRAY:
-      return char[].class;
-    case STRING_ARRAY:
-      return String[].class;
-    case OBJECT_ARRAY:
-      return Object[].class;
-    default:
-      throw new UnsupportedOperationException();
-    }
-  }
-  
-  public Object readObject(AbstractHessianInput in)
-    throws IOException
-  {
-    switch (_code) {
-    case NULL:
-      // hessian/3490
-      in.readObject();
-      
-      return null;
-      
-    case BOOLEAN:
-      return Boolean.valueOf(in.readBoolean());
-      
-    case BYTE:
-      return Byte.valueOf((byte) in.readInt());
-      
-    case SHORT:
-      return Short.valueOf((short) in.readInt());
-      
-    case INTEGER:
-      return Integer.valueOf(in.readInt());
-
-    case LONG:
-      return Long.valueOf(in.readLong());
-
-    case FLOAT:
-      return Float.valueOf((float) in.readDouble());
-
-    case DOUBLE:
-      return Double.valueOf(in.readDouble());
-      
-    case STRING:
-      return in.readString();
-      
-    case OBJECT:
-      return in.readObject();
-      
-    case CHARACTER:
-      {
-	String s = in.readString();
-	if (s == null || s.equals(""))
-	  return Character.valueOf((char) 0);
-	else
-	  return Character.valueOf(s.charAt(0));
-      }
-      
-    case CHARACTER_OBJECT:
-      {
-	String s = in.readString();
-	if (s == null || s.equals(""))
-	  return null;
-	else
-	  return Character.valueOf(s.charAt(0));
-      }
-      
-    case DATE:
-      return new Date(in.readUTCDate());
-      
-    case NUMBER:
-      return in.readObject();
-
-    case BYTE_ARRAY:
-      return in.readBytes();
-
-    case CHARACTER_ARRAY:
-    {
-      String s = in.readString();
-
-      if (s == null)
-        return null;
-      else {
-        int len = s.length();
-        char []chars = new char[len];
-        s.getChars(0, len, chars, 0);
-        return chars;
-      }
-    }
-
-    case BOOLEAN_ARRAY:
-    case SHORT_ARRAY:
-    case INTEGER_ARRAY:
-    case LONG_ARRAY:
-    case FLOAT_ARRAY:
-    case DOUBLE_ARRAY:
-    case STRING_ARRAY:
-    {
-      int code = in.readListStart();
-
-      switch (code) {
-      case 'N':
-	return null;
-
-      case 0x10: case 0x11: case 0x12: case 0x13:
-      case 0x14: case 0x15: case 0x16: case 0x17:
-      case 0x18: case 0x19: case 0x1a: case 0x1b:
-      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-	int length = code - 0x10;
-	in.readInt();
-
-	return readLengthList(in, length);
-
-      default:
-	String type = in.readType();
-	length = in.readLength();
-
-	return readList(in, length);
-      }
-    }
-
-    default:
-      throw new UnsupportedOperationException();
-    }
-  }
-  
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    switch (_code) {
-    case BOOLEAN_ARRAY: {
-      if (length >= 0) {
-        boolean []data = new boolean[length];
-
-        in.addRef(data);
-
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readBoolean();
-	
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(Boolean.valueOf(in.readBoolean()));
-	
-        in.readEnd();
-
-        boolean []data = new boolean[list.size()];
-        
-        in.addRef(data);
-        
-        for (int i = 0; i < data.length; i++)
-          data[i] = ((Boolean) list.get(i)).booleanValue();
-
-        return data;
-      }
-    }
-    
-    case SHORT_ARRAY: {
-      if (length >= 0) {
-        short []data = new short[length];
-
-        in.addRef(data);
-        
-        for (int i = 0; i < data.length; i++)
-          data[i] = (short) in.readInt();
-	
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(Short.valueOf((short) in.readInt()));
-
-        in.readEnd();
-
-        short []data = new short[list.size()];
-        for (int i = 0; i < data.length; i++)
-          data[i] = ((Short) list.get(i)).shortValue();
-
-        in.addRef(data);
-        
-        return data;
-      }
-    }
-    
-    case INTEGER_ARRAY: {
-      if (length >= 0) {
-        int []data = new int[length];
-
-        in.addRef(data);
-        
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readInt();
-
-        in.readEnd();
-	
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(Integer.valueOf(in.readInt()));
-
-
-        in.readEnd();
-	
-        int []data = new int[list.size()];
-        for (int i = 0; i < data.length; i++)
-          data[i] = ((Integer) list.get(i)).intValue();
-        
-        in.addRef(data);
-
-        return data;
-      }
-    }
-    
-    case LONG_ARRAY: {
-      if (length >= 0) {
-        long []data = new long[length];
-
-        in.addRef(data);
-
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readLong();
-
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(Long.valueOf(in.readLong()));
-
-        in.readEnd();
-        
-        long []data = new long[list.size()];
-        for (int i = 0; i < data.length; i++)
-          data[i] = ((Long) list.get(i)).longValue();
-        
-        in.addRef(data);
-
-        return data;
-      }
-    }
-    
-    case FLOAT_ARRAY: {
-      if (length >= 0) {
-        float []data = new float[length];
-        in.addRef(data);
-
-        for (int i = 0; i < data.length; i++)
-          data[i] = (float) in.readDouble();
-
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(new Float(in.readDouble()));
-
-        in.readEnd();
-        
-        float []data = new float[list.size()];
-        for (int i = 0; i < data.length; i++)
-          data[i] = ((Float) list.get(i)).floatValue();
-        
-        in.addRef(data);
-
-        return data;
-      }
-    }
-    
-    case DOUBLE_ARRAY: {
-      if (length >= 0) {
-        double []data = new double[length];
-        in.addRef(data);
-
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readDouble();
-
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(new Double(in.readDouble()));
-
-        in.readEnd();
-        
-        double []data = new double[list.size()];
-        in.addRef(data);
-        for (int i = 0; i < data.length; i++)
-          data[i] = ((Double) list.get(i)).intValue();
-
-        in.readEnd();
-
-        return data;
-      }
-    }
-    
-    case STRING_ARRAY: {
-      if (length >= 0) {
-        String []data = new String[length];
-        in.addRef(data);
-
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readString();
-
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-
-        while (! in.isEnd())
-          list.add(in.readString());
-
-        in.readEnd();
-        
-        String []data = new String[list.size()];
-        in.addRef(data);
-        for (int i = 0; i < data.length; i++)
-          data[i] = (String) list.get(i);
-
-        in.readEnd();
-
-        return data;
-      }
-    }
-    
-    case OBJECT_ARRAY: {
-      if (length >= 0) {
-        Object []data = new Object[length];
-        in.addRef(data);
-
-        for (int i = 0; i < data.length; i++)
-          data[i] = in.readObject();
-
-        in.readEnd();
-
-        return data;
-      }
-      else {
-        ArrayList list = new ArrayList();
-        
-        in.addRef(list); // XXX: potential issues here
-
-        while (! in.isEnd())
-          list.add(in.readObject());
-
-        in.readEnd();
-        
-        Object []data = new Object[list.size()];
-        for (int i = 0; i < data.length; i++)
-          data[i] = (Object) list.get(i);
-
-        return data;
-      }
-    }
-    
-    default:
-      throw new UnsupportedOperationException(String.valueOf(this));
-    }
-  }
-  
-  public Object readLengthList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    switch (_code) {
-    case BOOLEAN_ARRAY: {
-      boolean []data = new boolean[length];
-
-      in.addRef(data);
-
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readBoolean();
-
-      return data;
-    }
-    
-    case SHORT_ARRAY: {
-      short []data = new short[length];
-
-      in.addRef(data);
-        
-      for (int i = 0; i < data.length; i++)
-	data[i] = (short) in.readInt();
-
-      return data;
-    }
-    
-    case INTEGER_ARRAY: {
-      int []data = new int[length];
-
-      in.addRef(data);
-        
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readInt();
-
-      return data;
-    }
-    
-    case FLOAT_ARRAY: {
-      float []data = new float[length];
-      in.addRef(data);
-
-      for (int i = 0; i < data.length; i++)
-	data[i] = (float) in.readDouble();
-
-      return data;
-    }
-    
-    case DOUBLE_ARRAY: {
-      double []data = new double[length];
-      in.addRef(data);
-
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readDouble();
-
-      return data;
-    }
-    
-    case STRING_ARRAY: {
-      String []data = new String[length];
-      in.addRef(data);
-
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readString();
-
-      return data;
-    }
-    
-    case OBJECT_ARRAY: {
-      Object []data = new Object[length];
-      in.addRef(data);
-
-      for (int i = 0; i < data.length; i++)
-	data[i] = in.readObject();
-
-      return data;
-    }
-    
-    default:
-      throw new UnsupportedOperationException(String.valueOf(this));
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/BasicSerializer.java src/com/caucho/hessian/io/BasicSerializer.java
deleted file mode 100644
index 7940548..0000000
--- src/com/caucho/hessian/io/BasicSerializer.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Date;
-
-/**
- * Serializing an object for known object types.
- */
-public class BasicSerializer extends AbstractSerializer {
-  public static final int NULL = 0;
-  public static final int BOOLEAN = NULL + 1;
-  public static final int BYTE = BOOLEAN + 1;
-  public static final int SHORT = BYTE + 1;
-  public static final int INTEGER = SHORT + 1;
-  public static final int LONG = INTEGER + 1;
-  public static final int FLOAT = LONG + 1;
-  public static final int DOUBLE = FLOAT + 1;
-  public static final int CHARACTER = DOUBLE + 1;
-  public static final int CHARACTER_OBJECT = CHARACTER + 1;
-  public static final int STRING = CHARACTER_OBJECT + 1;
-  public static final int DATE = STRING + 1;
-  public static final int NUMBER = DATE + 1;
-  public static final int OBJECT = NUMBER + 1;
-  
-  public static final int BOOLEAN_ARRAY = OBJECT + 1;
-  public static final int BYTE_ARRAY = BOOLEAN_ARRAY + 1;
-  public static final int SHORT_ARRAY = BYTE_ARRAY + 1;
-  public static final int INTEGER_ARRAY = SHORT_ARRAY + 1;
-  public static final int LONG_ARRAY = INTEGER_ARRAY + 1;
-  public static final int FLOAT_ARRAY = LONG_ARRAY + 1;
-  public static final int DOUBLE_ARRAY = FLOAT_ARRAY + 1;
-  public static final int CHARACTER_ARRAY = DOUBLE_ARRAY + 1;
-  public static final int STRING_ARRAY = CHARACTER_ARRAY + 1;
-  public static final int OBJECT_ARRAY = STRING_ARRAY + 1;
-
-  private int code;
-
-  public BasicSerializer(int code)
-  {
-    this.code = code;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    switch (code) {
-    case BOOLEAN:
-      out.writeBoolean(((Boolean) obj).booleanValue());
-      break;
-      
-    case BYTE:
-    case SHORT:
-    case INTEGER:
-      out.writeInt(((Number) obj).intValue());
-      break;
-
-    case LONG:
-      out.writeLong(((Number) obj).longValue());
-      break;
-
-    case FLOAT:
-    case DOUBLE:
-      out.writeDouble(((Number) obj).doubleValue());
-      break;
-      
-    case CHARACTER:
-    case CHARACTER_OBJECT:
-      out.writeString(String.valueOf(obj));
-      break;
-      
-    case STRING:
-      out.writeString((String) obj);
-      break;
-      
-    case DATE:
-      out.writeUTCDate(((Date) obj).getTime());
-      break;
-      
-    case BOOLEAN_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      boolean []data = (boolean []) obj;
-      boolean hasEnd = out.writeListBegin(data.length, "[boolean");
-      for (int i = 0; i < data.length; i++)
-        out.writeBoolean(data[i]);
-
-      if (hasEnd)
-	out.writeListEnd();
-      
-      break;
-    }
-
-    case BYTE_ARRAY:
-    {
-      byte []data = (byte []) obj;
-      out.writeBytes(data, 0, data.length);
-      break;
-    }
-
-    case SHORT_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      short []data = (short []) obj;
-      boolean hasEnd = out.writeListBegin(data.length, "[short");
-      
-      for (int i = 0; i < data.length; i++)
-        out.writeInt(data[i]);
-
-      if (hasEnd)
-	out.writeListEnd();
-      break;
-    }
-
-    case INTEGER_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      int []data = (int []) obj;
-      
-      boolean hasEnd = out.writeListBegin(data.length, "[int");
-      
-      for (int i = 0; i < data.length; i++)
-        out.writeInt(data[i]);
-
-      if (hasEnd)
-	out.writeListEnd();
-      
-      break;
-    }
-
-    case LONG_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      long []data = (long []) obj;
-      
-      boolean hasEnd = out.writeListBegin(data.length, "[long");
-      
-      for (int i = 0; i < data.length; i++)
-        out.writeLong(data[i]);
-
-      if (hasEnd)
-	out.writeListEnd();
-      break;
-    }
-
-    case FLOAT_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      float []data = (float []) obj;
-      
-      boolean hasEnd = out.writeListBegin(data.length, "[float");
-      
-      for (int i = 0; i < data.length; i++)
-        out.writeDouble(data[i]);
-
-      if (hasEnd)
-	out.writeListEnd();
-      break;
-    }
-
-    case DOUBLE_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      double []data = (double []) obj;
-      boolean hasEnd = out.writeListBegin(data.length, "[double");
-      
-      for (int i = 0; i < data.length; i++)
-        out.writeDouble(data[i]);
-
-      if (hasEnd)
-	out.writeListEnd();
-      break;
-    }
-
-    case STRING_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      String []data = (String []) obj;
-      
-      boolean hasEnd = out.writeListBegin(data.length, "[string");
-      
-      for (int i = 0; i < data.length; i++) {
-        out.writeString(data[i]);
-      }
-
-      if (hasEnd)
-	out.writeListEnd();
-      break;
-    }
-
-    case CHARACTER_ARRAY:
-    {
-      char []data = (char []) obj;
-      out.writeString(data, 0, data.length);
-      break;
-    }
-
-    case OBJECT_ARRAY:
-    {
-      if (out.addRef(obj))
-        return;
-      
-      Object []data = (Object []) obj;
-      
-      boolean hasEnd = out.writeListBegin(data.length, "[object");
-      
-      for (int i = 0; i < data.length; i++) {
-        out.writeObject(data[i]);
-      }
-
-      if (hasEnd)
-	out.writeListEnd();
-      break;
-    }
-    
-    case NULL:
-      out.writeNull();
-      break;
-
-    default:
-      throw new RuntimeException(code + " " + String.valueOf(obj.getClass()));
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/BeanDeserializer.java src/com/caucho/hessian/io/BeanDeserializer.java
deleted file mode 100644
index a2fb242..0000000
--- src/com/caucho/hessian/io/BeanDeserializer.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-
-/**
- * Serializing an object for known object types.
- */
-public class BeanDeserializer extends AbstractMapDeserializer {
-  private Class _type;
-  private HashMap _methodMap;
-  private Method _readResolve;
-  private Constructor _constructor;
-  private Object []_constructorArgs;
-  
-  public BeanDeserializer(Class cl)
-  {
-    _type = cl;
-    _methodMap = getMethodMap(cl);
-
-    _readResolve = getReadResolve(cl);
-
-    Constructor []constructors = cl.getConstructors();
-    int bestLength = Integer.MAX_VALUE;
-    
-    for (int i = 0; i < constructors.length; i++) {
-      if (constructors[i].getParameterTypes().length < bestLength) {
-        _constructor = constructors[i];
-        bestLength = _constructor.getParameterTypes().length;
-      }
-    }
-
-    if (_constructor != null) {
-      _constructor.setAccessible(true);
-      Class []params = _constructor.getParameterTypes();
-      _constructorArgs = new Object[params.length];
-      for (int i = 0; i < params.length; i++) {
-        _constructorArgs[i] = getParamArg(params[i]);
-      }
-    }
-  }
-
-  public Class getType()
-  {
-    return _type;
-  }
-    
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    try {
-      Object obj = instantiate();
-
-      return readMap(in, obj);
-    } catch (IOException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-    
-  public Object readMap(AbstractHessianInput in, Object obj)
-    throws IOException
-  {
-    try {
-      int ref = in.addRef(obj);
-
-      while (! in.isEnd()) {
-        Object key = in.readObject();
-        
-        Method method = (Method) _methodMap.get(key);
-
-        if (method != null) {
-          Object value = in.readObject(method.getParameterTypes()[0]);
-	  
-          method.invoke(obj, new Object[] {value });
-        }
-        else {
-          Object value = in.readObject();
-        }
-      }
-      
-      in.readMapEnd();
-
-      Object resolve = resolve(obj);
-
-      if (obj != resolve)
-	in.setRef(ref, resolve);
-
-      return resolve;
-    } catch (IOException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-
-  private Object resolve(Object obj)
-  {
-    // if there's a readResolve method, call it
-    try {
-      if (_readResolve != null)
-        return _readResolve.invoke(obj, new Object[0]);
-    } catch (Exception e) {
-    }
-
-    return obj;
-  }
-
-  protected Object instantiate()
-    throws Exception
-  {
-    return _constructor.newInstance(_constructorArgs);
-  }
-
-  /**
-   * Returns the readResolve method
-   */
-  protected Method getReadResolve(Class cl)
-  {
-    for (; cl != null; cl = cl.getSuperclass()) {
-      Method []methods = cl.getDeclaredMethods();
-      
-      for (int i = 0; i < methods.length; i++) {
-	Method method = methods[i];
-
-	if (method.getName().equals("readResolve") &&
-	    method.getParameterTypes().length == 0)
-	  return method;
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * Creates a map of the classes fields.
-   */
-  protected HashMap getMethodMap(Class cl)
-  {
-    HashMap methodMap = new HashMap();
-    
-    for (; cl != null; cl = cl.getSuperclass()) {
-      Method []methods = cl.getDeclaredMethods();
-      
-      for (int i = 0; i < methods.length; i++) {
-	Method method = methods[i];
-
-	if (Modifier.isStatic(method.getModifiers()))
-	  continue;
-
-	String name = method.getName();
-
-	if (! name.startsWith("set"))
-	  continue;
-
-	Class []paramTypes = method.getParameterTypes();
-	if (paramTypes.length != 1)
-	  continue;
-
-	if (! method.getReturnType().equals(void.class))
-	  continue;
-
-	if (findGetter(methods, name, paramTypes[0]) == null)
-	  continue;
-
-	// XXX: could parameterize the handler to only deal with public
-	try {
-	  method.setAccessible(true);
-	} catch (Throwable e) {
-	  e.printStackTrace();
-	}
-    
-	name = name.substring(3);
-
-	int j = 0;
-	for (; j < name.length() && Character.isUpperCase(name.charAt(j)); j++) {
-	}
-
-	if (j == 1)
-	  name = name.substring(0, j).toLowerCase() + name.substring(j);
-	else if (j > 1)
-	  name = name.substring(0, j - 1).toLowerCase() + name.substring(j - 1);
-
-
-	methodMap.put(name, method);
-      }
-    }
-
-    return methodMap;
-  }
-
-  /**
-   * Finds any matching setter.
-   */
-  private Method findGetter(Method []methods, String setterName, Class arg)
-  {
-    String getterName = "get" + setterName.substring(3);
-    
-    for (int i = 0; i < methods.length; i++) {
-      Method method = methods[i];
-
-      if (! method.getName().equals(getterName))
-	continue;
-      
-      if (! method.getReturnType().equals(arg))
-	continue;
-
-      Class []params = method.getParameterTypes();
-
-      if (params.length == 0)
-	return method;
-    }
-
-    return null;
-  }
-
-  /**
-   * Creates a map of the classes fields.
-   */
-  protected static Object getParamArg(Class cl)
-  {
-    if (! cl.isPrimitive())
-      return null;
-    else if (boolean.class.equals(cl))
-      return Boolean.FALSE;
-    else if (byte.class.equals(cl))
-      return Byte.valueOf((byte) 0);
-    else if (short.class.equals(cl))
-      return Short.valueOf((short) 0);
-    else if (char.class.equals(cl))
-      return Character.valueOf((char) 0);
-    else if (int.class.equals(cl))
-      return Integer.valueOf(0);
-    else if (long.class.equals(cl))
-      return Long.valueOf(0);
-    else if (float.class.equals(cl))
-      return Double.valueOf(0);
-    else if (double.class.equals(cl))
-      return Double.valueOf(0);
-    else
-      throw new UnsupportedOperationException();
-  }
-}
diff --git src/com/caucho/hessian/io/BeanSerializer.java src/com/caucho/hessian/io/BeanSerializer.java
deleted file mode 100644
index b994fb6..0000000
--- src/com/caucho/hessian/io/BeanSerializer.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.logging.*;
-
-/**
- * Serializing an object for known object types.
- */
-public class BeanSerializer extends AbstractSerializer {
-  private static final Logger log
-    = Logger.getLogger(BeanSerializer.class.getName());
-  
-  private static final Object []NULL_ARGS = new Object[0];
-  private Method []_methods;
-  private String []_names;
-
-  private Object _writeReplaceFactory;
-  private Method _writeReplace;
-  
-  public BeanSerializer(Class cl)
-  {
-    introspectWriteReplace(cl);
-
-    ArrayList primitiveMethods = new ArrayList();
-    ArrayList compoundMethods = new ArrayList();
-    
-    for (; cl != null; cl = cl.getSuperclass()) {
-      Method []methods = cl.getDeclaredMethods();
-      
-      for (int i = 0; i < methods.length; i++) {
-	Method method = methods[i];
-
-	if (Modifier.isStatic(method.getModifiers()))
-	  continue;
-
-	if (method.getParameterTypes().length != 0)
-	  continue;
-
-	String name = method.getName();
-
-	if (! name.startsWith("get"))
-	  continue;
-
-	Class type = method.getReturnType();
-
-	if (type.equals(void.class))
-	  continue;
-
-	if (findSetter(methods, name, type) == null)
-	  continue;
-
-	// XXX: could parameterize the handler to only deal with public
-	method.setAccessible(true);
-
-	if (type.isPrimitive() ||
-	    type.getName().startsWith("java.lang.") &&
-	    ! type.equals(Object.class))
-	  primitiveMethods.add(method);
-	else
-	  compoundMethods.add(method);
-      }
-    }
-
-    ArrayList methodList = new ArrayList();
-    methodList.addAll(primitiveMethods);
-    methodList.addAll(compoundMethods);
-
-    _methods = new Method[methodList.size()];
-    methodList.toArray(_methods);
-
-    _names = new String[_methods.length];
-    
-    for (int i = 0; i < _methods.length; i++) {
-      String name = _methods[i].getName();
-
-      name = name.substring(3);
-
-      int j = 0;
-      for (; j < name.length() && Character.isUpperCase(name.charAt(j)); j++) {
-      }
-
-      if (j == 1)
-	name = name.substring(0, j).toLowerCase() + name.substring(j);
-      else if (j > 1)
-	name = name.substring(0, j - 1).toLowerCase() + name.substring(j - 1);
-
-      _names[i] = name;
-    }
-  }
-
-  private void introspectWriteReplace(Class cl)
-  {
-    try {
-      ClassLoader loader = Thread.currentThread().getContextClassLoader();
-
-      String className = cl.getName() + "HessianSerializer";
-
-      Class serializerClass = Class.forName(className, false, loader);
-
-      Object serializerObject = serializerClass.newInstance();
-
-      Method writeReplace = getWriteReplace(serializerClass, cl);
-
-      if (writeReplace != null) {
-	_writeReplaceFactory = serializerObject;
-	_writeReplace = writeReplace;
-
-	return;
-      }
-    } catch (ClassNotFoundException e) {
-    } catch (Exception e) {
-      log.log(Level.FINER, e.toString(), e);
-    }
-      
-    _writeReplace = getWriteReplace(cl);
-  }
-
-  /**
-   * Returns the writeReplace method
-   */
-  protected Method getWriteReplace(Class cl)
-  {
-    for (; cl != null; cl = cl.getSuperclass()) {
-      Method []methods = cl.getDeclaredMethods();
-      
-      for (int i = 0; i < methods.length; i++) {
-	Method method = methods[i];
-
-	if (method.getName().equals("writeReplace") &&
-	    method.getParameterTypes().length == 0)
-	  return method;
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * Returns the writeReplace method
-   */
-  protected Method getWriteReplace(Class cl, Class param)
-  {
-    for (; cl != null; cl = cl.getSuperclass()) {
-      for (Method method : cl.getDeclaredMethods()) {
-	if (method.getName().equals("writeReplace")
-	    && method.getParameterTypes().length == 1
-	    && param.equals(method.getParameterTypes()[0]))
-	  return method;
-      }
-    }
-
-    return null;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (out.addRef(obj))
-      return;
-    
-    Class cl = obj.getClass();
-    
-    try {
-      if (_writeReplace != null) {
-	Object repl;
-
-	if (_writeReplaceFactory != null)
-	  repl = _writeReplace.invoke(_writeReplaceFactory, obj);
-	else
-	  repl = _writeReplace.invoke(obj);
-
-	out.removeRef(obj);
-
-	out.writeObject(repl);
-
-	out.replaceRef(repl, obj);
-
-	return;
-      }
-    } catch (Exception e) {
-      log.log(Level.FINER, e.toString(), e);
-    }
-
-    int ref = out.writeObjectBegin(cl.getName());
-
-    if (ref < -1) {
-      // Hessian 1.1 uses a map
-      
-      for (int i = 0; i < _methods.length; i++) {
-	Method method = _methods[i];
-	Object value = null;
-
-	try {
-	  value = _methods[i].invoke(obj, (Object []) null);
-	} catch (Exception e) {
-	  log.log(Level.FINE, e.toString(), e);
-	}
-
-	out.writeString(_names[i]);
-	
-	out.writeObject(value);
-      }
-      
-      out.writeMapEnd();
-    }
-    else {
-      if (ref == -1) {
-	out.writeInt(_names.length);
-	
-	for (int i = 0; i < _names.length; i++)
-	  out.writeString(_names[i]);
-	
-	out.writeObjectBegin(cl.getName());
-      }
-
-      for (int i = 0; i < _methods.length; i++) {
-	Method method = _methods[i];
-	Object value = null;
-
-	try {
-	  value = _methods[i].invoke(obj, (Object []) null);
-	} catch (Exception e) {
-	  log.log(Level.FINER, e.toString(), e);
-	}
-	
-	out.writeObject(value);
-      }
-    }
-  }
-
-  /**
-   * Finds any matching setter.
-   */
-  private Method findSetter(Method []methods, String getterName, Class arg)
-  {
-    String setterName = "set" + getterName.substring(3);
-    
-    for (int i = 0; i < methods.length; i++) {
-      Method method = methods[i];
-
-      if (! method.getName().equals(setterName))
-	continue;
-      
-      if (! method.getReturnType().equals(void.class))
-	continue;
-
-      Class []params = method.getParameterTypes();
-
-      if (params.length == 1 && params[0].equals(arg))
-	return method;
-    }
-
-    return null;
-  }
-}
diff --git src/com/caucho/hessian/io/BeanSerializerFactory.java src/com/caucho/hessian/io/BeanSerializerFactory.java
deleted file mode 100644
index 591a45a..0000000
--- src/com/caucho/hessian/io/BeanSerializerFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-/**
- * Factory for returning serialization methods.
- */
-public class BeanSerializerFactory extends SerializerFactory {
-  /**
-   * Returns the default serializer for a class that isn't matched
-   * directly.  Application can override this method to produce
-   * bean-style serialization instead of field serialization.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  protected Serializer getDefaultSerializer(Class cl)
-  {
-    return new BeanSerializer(cl);
-  }
-  
-  /**
-   * Returns the default deserializer for a class that isn't matched
-   * directly.  Application can override this method to produce
-   * bean-style serialization instead of field serialization.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  protected Deserializer getDefaultDeserializer(Class cl)
-  {
-    return new BeanDeserializer(cl);
-  }
-}
diff --git src/com/caucho/hessian/io/CalendarHandle.java src/com/caucho/hessian/io/CalendarHandle.java
deleted file mode 100644
index 9056110..0000000
--- src/com/caucho/hessian/io/CalendarHandle.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-/**
- * Handle for a calendar object.
- */
-public class CalendarHandle implements java.io.Serializable, HessianHandle {
-  private Class type;
-  private Date date;
-
-  public CalendarHandle()
-  {
-  }
-  
-  public CalendarHandle(Class type, long time)
-  {
-    if (! GregorianCalendar.class.equals(type))
-      this.type = type;
-    
-    this.date = new Date(time);
-  }
-
-  private Object readResolve()
-  {
-    try {
-      Calendar cal;
-      
-      if (this.type != null)
-	cal = (Calendar) this.type.newInstance();
-      else
-	cal = new GregorianCalendar();
-      
-      cal.setTimeInMillis(this.date.getTime());
-
-      return cal;
-    } catch (RuntimeException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/CalendarSerializer.java src/com/caucho/hessian/io/CalendarSerializer.java
deleted file mode 100644
index cc688e5..0000000
--- src/com/caucho/hessian/io/CalendarSerializer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Calendar;
-
-/**
- * Serializing a calendar.
- */
-public class CalendarSerializer extends AbstractSerializer {
-  private static CalendarSerializer SERIALIZER = new CalendarSerializer();
-
-  public static CalendarSerializer create()
-  {
-    return SERIALIZER;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (obj == null)
-      out.writeNull();
-    else {
-      Calendar cal = (Calendar) obj;
-
-      out.writeObject(new CalendarHandle(cal.getClass(),
-					 cal.getTimeInMillis()));
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/ClassDeserializer.java src/com/caucho/hessian/io/ClassDeserializer.java
deleted file mode 100644
index d8cb0d6..0000000
--- src/com/caucho/hessian/io/ClassDeserializer.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-/**
- * Deserializing a JDK 1.2 Class.
- */
-public class ClassDeserializer extends AbstractMapDeserializer {
-  private static final HashMap<String,Class> _primClasses
-    = new HashMap<String,Class>();
-  
-  public ClassDeserializer()
-  {
-  }
-  
-  public Class getType()
-  {
-    return Class.class;
-  }
-  
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    int ref = in.addRef(null);
-    
-    String name = null;
-    
-    while (! in.isEnd()) {
-      String key = in.readString();
-
-      if (key.equals("name"))
-	name = in.readString();
-      else
-	in.readObject();
-    }
-      
-    in.readMapEnd();
-
-    Object value = create(name);
-
-    in.setRef(ref, value);
-
-    return value;
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    int ref = in.addRef(null);
-    
-    String name = null;
-    
-    for (int i = 0; i < fieldNames.length; i++) {
-      if ("name".equals(fieldNames[i]))
-        name = in.readString();
-      else
-	in.readObject();
-    }
-
-    Object value = create(name);
-
-    in.setRef(ref, value);
-
-    return value;
-  }
-
-  Object create(String name)
-    throws IOException
-  {
-    if (name == null)
-      throw new IOException("Serialized Class expects name.");
-
-    Class cl = _primClasses.get(name);
-
-    if (cl != null)
-      return cl;
-
-    ClassLoader loader = Thread.currentThread().getContextClassLoader();
-
-    try {
-      if (loader != null)
-        return Class.forName(name, false, loader);
-      else
-        return Class.forName(name);
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-
-  static {
-    _primClasses.put("void", void.class);
-    _primClasses.put("boolean", boolean.class);
-    _primClasses.put("java.lang.Boolean", Boolean.class);
-    _primClasses.put("byte", byte.class);
-    _primClasses.put("java.lang.Byte", Byte.class);
-    _primClasses.put("char", char.class);
-    _primClasses.put("java.lang.Character", Character.class);
-    _primClasses.put("short", short.class);
-    _primClasses.put("java.lang.Short", Short.class);
-    _primClasses.put("int", int.class);
-    _primClasses.put("java.lang.Integer", Integer.class);
-    _primClasses.put("long", long.class);
-    _primClasses.put("java.lang.Long", Long.class);
-    _primClasses.put("float", float.class);
-    _primClasses.put("java.lang.Float", Float.class);
-    _primClasses.put("double", double.class);
-    _primClasses.put("java.lang.Double", Double.class);
-    _primClasses.put("java.lang.String", String.class);
-  }
-}
diff --git src/com/caucho/hessian/io/ClassSerializer.java src/com/caucho/hessian/io/ClassSerializer.java
deleted file mode 100644
index 0a25797..0000000
--- src/com/caucho/hessian/io/ClassSerializer.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Serializing a remote object.
- */
-public class ClassSerializer extends AbstractSerializer {
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    Class cl = (Class) obj;
-
-    if (cl == null) {
-      out.writeNull();
-    }
-    else if (out.addRef(obj)) {
-      return;
-    }
-    else {
-      int ref = out.writeObjectBegin("java.lang.Class");
-
-      if (ref < -1) {
-	out.writeString("name");
-	out.writeString(cl.getName());
-	out.writeMapEnd();
-      }
-      else {
-	if (ref == -1) {
-	  out.writeInt(1);
-	  out.writeString("name");
-	  out.writeObjectBegin("java.lang.Class");
-	}
-
-	out.writeString(cl.getName());
-      }
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/CollectionDeserializer.java src/com/caucho/hessian/io/CollectionDeserializer.java
deleted file mode 100644
index 93d24b2..0000000
--- src/com/caucho/hessian/io/CollectionDeserializer.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Deserializing a JDK 1.2 Collection.
- */
-public class CollectionDeserializer extends AbstractListDeserializer {
-  private Class _type;
-  
-  public CollectionDeserializer(Class type)
-  {
-    _type = type;
-  }
-  
-  public Class getType()
-  {
-    return _type;
-  }
-  
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    Collection list = createList();
-
-    in.addRef(list);
-
-    while (! in.isEnd())
-      list.add(in.readObject());
-
-    in.readEnd();
-
-    return list;
-  }
-  
-  public Object readLengthList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    Collection list = createList();
-
-    in.addRef(list);
-
-    for (; length > 0; length--)
-      list.add(in.readObject());
-
-    return list;
-  }
-
-  private Collection createList()
-    throws IOException
-  {
-    Collection list = null;
-    
-    if (_type == null)
-      list = new ArrayList();
-    else if (! _type.isInterface()) {
-      try {
-        list = (Collection) _type.newInstance();
-      } catch (Exception e) {
-      }
-    }
-
-    if (list != null) {
-    }
-    else if (SortedSet.class.isAssignableFrom(_type))
-      list = new TreeSet();
-    else if (Set.class.isAssignableFrom(_type))
-      list = new HashSet();
-    else if (List.class.isAssignableFrom(_type))
-      list = new ArrayList();
-    else if (Collection.class.isAssignableFrom(_type))
-      list = new ArrayList();
-    else {
-      try {
-        list = (Collection) _type.newInstance();
-      } catch (Exception e) {
-        throw new IOExceptionWrapper(e);
-      }
-    }
-
-    return list;
-  }
-}
-
-
diff --git src/com/caucho/hessian/io/CollectionSerializer.java src/com/caucho/hessian/io/CollectionSerializer.java
deleted file mode 100644
index 5af824c..0000000
--- src/com/caucho/hessian/io/CollectionSerializer.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * Serializing a JDK 1.2 Collection.
- */
-public class CollectionSerializer extends AbstractSerializer
-{
-  private boolean _sendJavaType = true;
-
-  /**
-   * Set true if the java type of the collection should be sent.
-   */
-  public void setSendJavaType(boolean sendJavaType)
-  {
-    _sendJavaType = sendJavaType;
-  }
-
-  /**
-   * Return true if the java type of the collection should be sent.
-   */
-  public boolean getSendJavaType()
-  {
-    return _sendJavaType;
-  }
-    
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (out.addRef(obj))
-      return;
-
-    Collection list = (Collection) obj;
-
-    Class cl = obj.getClass();
-    boolean hasEnd;
-    
-    if (cl.equals(ArrayList.class)
-	|| ! _sendJavaType
-	|| ! Serializable.class.isAssignableFrom(cl))
-      hasEnd = out.writeListBegin(list.size(), null);
-    else
-      hasEnd = out.writeListBegin(list.size(), obj.getClass().getName());
-
-    Iterator iter = list.iterator();
-    while (iter.hasNext()) {
-      Object value = iter.next();
-
-      out.writeObject(value);
-    }
-
-    if (hasEnd)
-      out.writeListEnd();
-  }
-}
diff --git src/com/caucho/hessian/io/Deflation.java src/com/caucho/hessian/io/Deflation.java
deleted file mode 100644
index 0e3ae50..0000000
--- src/com/caucho/hessian/io/Deflation.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.util.*;
-import java.util.zip.*;
-
-import java.io.*;
-
-import com.caucho.hessian.io.*;
-
-public class Deflation extends HessianEnvelope {
-  public Deflation()
-  {
-  }
-
-  public Hessian2Output wrap(Hessian2Output out)
-    throws IOException
-  {
-    OutputStream os = new DeflateOutputStream(out);
-    
-    Hessian2Output filterOut = new Hessian2Output(os);
-
-    filterOut.setCloseStreamOnClose(true);
-    
-    return filterOut;
-  }
-
-  public Hessian2Input unwrap(Hessian2Input in)
-    throws IOException
-  {
-    int version = in.readEnvelope();
-
-    String method = in.readMethod();
-
-    if (! method.equals(getClass().getName()))
-      throw new IOException("expected hessian Envelope method '" +
-			    getClass().getName() + "' at '" + method + "'");
-
-    return unwrapHeaders(in);
-  }
-
-  public Hessian2Input unwrapHeaders(Hessian2Input in)
-    throws IOException
-  {
-    InputStream is = new DeflateInputStream(in);
-
-    Hessian2Input filter = new Hessian2Input(is);
-    
-    filter.setCloseStreamOnClose(true);
-    
-    return filter;
-  }
-  
-  static class DeflateOutputStream extends OutputStream {
-    private Hessian2Output _out;
-    private OutputStream _bodyOut;
-    private DeflaterOutputStream _deflateOut;
-    
-    DeflateOutputStream(Hessian2Output out)
-      throws IOException
-    {
-      _out = out;
-
-      _out.startEnvelope(Deflation.class.getName());
-    
-      _out.writeInt(0);
-
-      _bodyOut = _out.getBytesOutputStream();
-    
-      _deflateOut = new DeflaterOutputStream(_bodyOut);
-    }
-    
-    public void write(int ch)
-      throws IOException
-    {
-      _deflateOut.write(ch);
-    }
-    
-    public void write(byte []buffer, int offset, int length)
-      throws IOException
-    {
-      _deflateOut.write(buffer, offset, length);
-    }
-
-    public void close()
-      throws IOException
-    {
-      Hessian2Output out = _out;
-      _out = null;
-
-      if (out != null) {
-	_deflateOut.close();
-	_bodyOut.close();
-
-	out.writeInt(0);
-
-        out.completeEnvelope();
-          
-	out.close();
-      }
-    }
-  }
-  
-  static class DeflateInputStream extends InputStream {
-    private Hessian2Input _in;
-    
-    private InputStream _bodyIn;
-    private InflaterInputStream _inflateIn;
-    
-    DeflateInputStream(Hessian2Input in)
-      throws IOException
-    {
-      _in = in;
-
-      int len = in.readInt();
-
-      if (len != 0)
-        throw new IOException("expected no headers");
-      
-      _bodyIn = _in.readInputStream();
-
-      _inflateIn = new InflaterInputStream(_bodyIn);
-    }
-    
-    public int read()
-      throws IOException
-    {
-      return _inflateIn.read();
-    }
-    
-    public int read(byte []buffer, int offset, int length)
-      throws IOException
-    {
-      return _inflateIn.read(buffer, offset, length);
-    }
-
-    public void close()
-      throws IOException
-    {
-      Hessian2Input in = _in;
-      _in = null;
-
-      if (in != null) {
-	_inflateIn.close();
-	_bodyIn.close();
-
-	int len = in.readInt();
-
-	if (len != 0)
-	  throw new IOException("Unexpected footer");
-
-        in.completeEnvelope();
-
-	in.close();
-      }
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/Deserializer.java src/com/caucho/hessian/io/Deserializer.java
deleted file mode 100644
index 82ff422..0000000
--- src/com/caucho/hessian/io/Deserializer.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Deserializing an object. 
- */
-public interface Deserializer {
-  public Class getType();
-
-  public Object readObject(AbstractHessianInput in)
-    throws IOException;
-  
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException;
-  
-  public Object readLengthList(AbstractHessianInput in, int length)
-    throws IOException;
-  
-  public Object readMap(AbstractHessianInput in)
-    throws IOException;
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException;
-}
diff --git src/com/caucho/hessian/io/EnumDeserializer.java src/com/caucho/hessian/io/EnumDeserializer.java
deleted file mode 100644
index aa60b30..0000000
--- src/com/caucho/hessian/io/EnumDeserializer.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-
-/**
- * Deserializing an enum valued object
- */
-public class EnumDeserializer extends AbstractDeserializer {
-  private Class _enumType;
-  private Method _valueOf;
-  
-  public EnumDeserializer(Class cl)
-  {
-    // hessian/33b[34], hessian/3bb[78]
-    if (cl.isEnum())
-      _enumType = cl;
-    else if (cl.getSuperclass().isEnum())
-      _enumType = cl.getSuperclass();
-    else
-      throw new RuntimeException("Class " + cl.getName() + " is not an enum");
-
-    try {
-      _valueOf = _enumType.getMethod("valueOf",
-			     new Class[] { Class.class, String.class });
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-  
-  public Class getType()
-  {
-    return _enumType;
-  }
-  
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    String name = null;
-    
-    while (! in.isEnd()) {
-      String key = in.readString();
-
-      if (key.equals("name"))
-        name = in.readString();
-      else
-	in.readObject();
-    }
-
-    in.readMapEnd();
-
-    Object obj = create(name);
-    
-    in.addRef(obj);
-
-    return obj;
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    String name = null;
-
-    for (int i = 0; i < fieldNames.length; i++) {
-      if ("name".equals(fieldNames[i]))
-        name = in.readString();
-      else
-	in.readObject();
-    }
-
-    Object obj = create(name);
-
-    in.addRef(obj);
-
-    return obj;
-  }
-
-  private Object create(String name)
-    throws IOException
-  {
-    if (name == null)
-      throw new IOException(_enumType.getName() + " expects name.");
-
-    try {
-      return _valueOf.invoke(null, _enumType, name);
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/EnumSerializer.java src/com/caucho/hessian/io/EnumSerializer.java
deleted file mode 100644
index 1edad87..0000000
--- src/com/caucho/hessian/io/EnumSerializer.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-
-/**
- * Serializing an object for known object types.
- */
-public class EnumSerializer extends AbstractSerializer {
-  private Method _name;
-  
-  public EnumSerializer(Class cl)
-  {
-    // hessian/32b[12], hessian/3ab[23]
-    if (! cl.isEnum() && cl.getSuperclass().isEnum())
-      cl = cl.getSuperclass();
-
-    try {
-      _name = cl.getMethod("name", new Class[0]);
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (out.addRef(obj))
-      return;
-
-    Class cl = obj.getClass();
-
-    if (! cl.isEnum() && cl.getSuperclass().isEnum())
-      cl = cl.getSuperclass();
-
-    String name = null;
-    try {
-      name = (String) _name.invoke(obj, (Object[]) null);
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-
-    int ref = out.writeObjectBegin(cl.getName());
-
-    if (ref < -1) {
-      out.writeString("name");
-      out.writeString(name);
-      out.writeMapEnd();
-    }
-    else {
-      if (ref == -1) {
-	out.writeClassFieldLength(1);
-	out.writeString("name");
-	out.writeObjectBegin(cl.getName());
-      }
-
-      out.writeString(name);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/EnumerationDeserializer.java src/com/caucho/hessian/io/EnumerationDeserializer.java
deleted file mode 100644
index 875759b..0000000
--- src/com/caucho/hessian/io/EnumerationDeserializer.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Vector;
-
-/**
- * Deserializing a JDK 1.2 Collection.
- */
-public class EnumerationDeserializer extends AbstractListDeserializer {
-  private static EnumerationDeserializer _deserializer;
-
-  public static EnumerationDeserializer create()
-  {
-    if (_deserializer == null)
-      _deserializer = new EnumerationDeserializer();
-
-    return _deserializer;
-  }
-  
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    Vector list = new Vector();
-
-    in.addRef(list);
-
-    while (! in.isEnd())
-      list.add(in.readObject());
-
-    in.readEnd();
-
-    return list.elements();
-  }
-}
-
-
diff --git src/com/caucho/hessian/io/EnumerationSerializer.java src/com/caucho/hessian/io/EnumerationSerializer.java
deleted file mode 100644
index f539dcd..0000000
--- src/com/caucho/hessian/io/EnumerationSerializer.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Enumeration;
-
-/**
- * Serializing a JDK 1.2 Enumeration.
- */
-public class EnumerationSerializer extends AbstractSerializer {
-  private static EnumerationSerializer _serializer;
-
-  public static EnumerationSerializer create()
-  {
-    if (_serializer == null)
-      _serializer = new EnumerationSerializer();
-
-    return _serializer;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    Enumeration iter = (Enumeration) obj;
-
-    boolean hasEnd = out.writeListBegin(-1, null);
-
-    while (iter.hasMoreElements()) {
-      Object value = iter.nextElement();
-
-      out.writeObject(value);
-    }
-
-    if (hasEnd)
-      out.writeListEnd();
-  }
-}
diff --git src/com/caucho/hessian/io/EnvelopeFactory.java src/com/caucho/hessian/io/EnvelopeFactory.java
deleted file mode 100644
index 0a83608..0000000
--- src/com/caucho/hessian/io/EnvelopeFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.util.logging.*;
-
-public class EnvelopeFactory
-{
-  private static final Logger log
-    = Logger.getLogger(EnvelopeFactory.class.getName());
-}
diff --git src/com/caucho/hessian/io/ExtSerializerFactory.java src/com/caucho/hessian/io/ExtSerializerFactory.java
deleted file mode 100644
index 4802fb7..0000000
--- src/com/caucho/hessian/io/ExtSerializerFactory.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.util.HashMap;
-
-/**
- * Factory for returning serialization methods.
- */
-public class ExtSerializerFactory extends AbstractSerializerFactory {
-  private HashMap _serializerMap = new HashMap();
-  private HashMap _deserializerMap = new HashMap();
-
-  /**
-   * Adds a serializer.
-   *
-   * @param cl the class of the serializer
-   * @param serializer the serializer
-   */
-  public void addSerializer(Class cl, Serializer serializer)
-  {
-    _serializerMap.put(cl, serializer);
-  }
-
-  /**
-   * Adds a deserializer.
-   *
-   * @param cl the class of the deserializer
-   * @param deserializer the deserializer
-   */
-  public void addDeserializer(Class cl, Deserializer deserializer)
-  {
-    _deserializerMap.put(cl, deserializer);
-  }
-  
-  /**
-   * Returns the serializer for a class.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  public Serializer getSerializer(Class cl)
-    throws HessianProtocolException
-  {
-    return (Serializer) _serializerMap.get(cl);
-  }
-  
-  /**
-   * Returns the deserializer for a class.
-   *
-   * @param cl the class of the object that needs to be deserialized.
-   *
-   * @return a deserializer object for the serialization.
-   */
-  public Deserializer getDeserializer(Class cl)
-    throws HessianProtocolException
-  {
-    return (Deserializer) _deserializerMap.get(cl);
-  }
-}
diff --git src/com/caucho/hessian/io/Hessian2Constants.java src/com/caucho/hessian/io/Hessian2Constants.java
deleted file mode 100644
index d568924..0000000
--- src/com/caucho/hessian/io/Hessian2Constants.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-public interface Hessian2Constants
-{
-  public static final int INT_DIRECT_MIN = -0x10;
-  public static final int INT_DIRECT_MAX = 0x2f;
-  public static final int INT_ZERO = 0x90;
-
-  public static final int INT_BYTE_MIN = -0x800;
-  public static final int INT_BYTE_MAX = 0x7ff;
-  public static final int INT_BYTE_ZERO = 0xc8;
-
-  public static final int INT_SHORT_MIN = -0x40000;
-  public static final int INT_SHORT_MAX = 0x3ffff;
-  public static final int INT_SHORT_ZERO = 0xd4;
-
-  public static final long LONG_DIRECT_MIN = -0x08;
-  public static final long LONG_DIRECT_MAX =  0x0f;
-  public static final int LONG_ZERO = 0xe0;
-
-  public static final long LONG_BYTE_MIN = -0x800;
-  public static final long LONG_BYTE_MAX =  0x7ff;
-  public static final int LONG_BYTE_ZERO = 0xf8;
-
-  public static final int LONG_SHORT_MIN = -0x40000;
-  public static final int LONG_SHORT_MAX = 0x3ffff;
-  public static final int LONG_SHORT_ZERO = 0x3c;
-
-  public static final int STRING_DIRECT_MAX = 0x1f;
-  public static final int STRING_DIRECT = 0x00;
-
-  public static final int BYTES_DIRECT_MAX = 0x0f;
-  public static final int BYTES_DIRECT = 0x20;
-  // 0x30-0x37 is reserved
-
-  public static final int LONG_INT = 0x77;
-
-  public static final int DOUBLE_ZERO = 0x67;
-  public static final int DOUBLE_ONE = 0x68;
-  public static final int DOUBLE_BYTE = 0x69;
-  public static final int DOUBLE_SHORT = 0x6a;
-  public static final int DOUBLE_FLOAT = 0x6b;
-  
-  public static final int LENGTH_BYTE = 0x6e;
-  public static final int LIST_FIXED = 0x76; // 'v'
-
-  public static final int REF_BYTE = 0x4a;
-  public static final int REF_SHORT = 0x4b;
-
-  public static final int TYPE_REF = 0x75;
-}
diff --git src/com/caucho/hessian/io/Hessian2Input.java src/com/caucho/hessian/io/Hessian2Input.java
deleted file mode 100644
index 9fd9257..0000000
--- src/com/caucho/hessian/io/Hessian2Input.java
+++ /dev/null
@@ -1,2783 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.*;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.logging.*;
-
-/**
- * Input stream for Hessian requests.
- *
- * <p>HessianInput is unbuffered, so any client needs to provide
- * its own buffering.
- *
- * <pre>
- * InputStream is = ...; // from http connection
- * HessianInput in = new HessianInput(is);
- * String value;
- *
- * in.startReply();         // read reply header
- * value = in.readString(); // read string value
- * in.completeReply();      // read reply footer
- * </pre>
- */
-public class Hessian2Input
-  extends AbstractHessianInput
-  implements Hessian2Constants
-{
-  private static final Logger log
-    = Logger.getLogger(Hessian2Input.class.getName());
-  
-  private static final double D_256 = 1.0 / 256.0;
-  private static final int END_OF_DATA = -2;
-
-  private static Field _detailMessageField;
-
-  private static final int SIZE = 256;
-  private static final int GAP = 16;
-  
-  // factory for deserializing objects in the input stream
-  protected SerializerFactory _serializerFactory;
-
-  private static boolean _isCloseStreamOnClose;
-  
-  protected ArrayList _refs;
-  protected ArrayList _classDefs;
-  protected ArrayList _types;
-  
-  // the underlying input stream
-  private InputStream _is;
-  private final byte []_buffer = new byte[SIZE];
-  
-  // a peek character
-  private int _offset;
-  private int _length;
-
-  // true for streaming data
-  private boolean _isStreaming;
-  
-  // the method for a call
-  private String _method;
-
-  private Reader _chunkReader;
-  private InputStream _chunkInputStream;
-
-  private Throwable _replyFault;
-
-  private StringBuffer _sbuf = new StringBuffer();
-  
-  // true if this is the last chunk
-  private boolean _isLastChunk;
-  // the chunk length
-  private int _chunkLength;
-  
-  /**
-   * Creates a new Hessian input stream, initialized with an
-   * underlying input stream.
-   *
-   * @param is the underlying input stream.
-   */
-  public Hessian2Input(InputStream is)
-  {
-    _is = is;
-  }
-
-  /**
-   * Sets the serializer factory.
-   */
-  public void setSerializerFactory(SerializerFactory factory)
-  {
-    _serializerFactory = factory;
-  }
-
-  /**
-   * Gets the serializer factory.
-   */
-  public SerializerFactory getSerializerFactory()
-  {
-    return _serializerFactory;
-  }
-
-  /**
-   * Gets the serializer factory, creating a default if necessary.
-   */
-  public final SerializerFactory findSerializerFactory()
-  {
-    SerializerFactory factory = _serializerFactory;
-
-    if (factory == null)
-      _serializerFactory = factory = new SerializerFactory();
-    
-    return factory;
-  }
-
-  public void setCloseStreamOnClose(boolean isClose)
-  {
-    _isCloseStreamOnClose = isClose;
-  }
-
-  public boolean isCloseStreamOnClose()
-  {
-    return _isCloseStreamOnClose;
-  }
-
-  /**
-   * Returns the calls method
-   */
-  public String getMethod()
-  {
-    return _method;
-  }
-
-  /**
-   * Returns any reply fault.
-   */
-  public Throwable getReplyFault()
-  {
-    return _replyFault;
-  }
-
-  /**
-   * Starts reading the call
-   *
-   * <pre>
-   * c major minor
-   * </pre>
-   */
-  public int readCall()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'c')
-      throw error("expected hessian call ('c') at " + codeName(tag));
-
-    int major = read();
-    int minor = read();
-
-    return (major << 16) + minor;
-  }
-
-  /**
-   * Starts reading the envelope
-   *
-   * <pre>
-   * E major minor
-   * </pre>
-   */
-  public int readEnvelope()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'E')
-      throw error("expected hessian Envelope ('E') at " + codeName(tag));
-
-    int major = read();
-    int minor = read();
-
-    return (major << 16) + minor;
-  }
-
-  /**
-   * Completes reading the envelope
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeEnvelope()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'z')
-      error("expected end of envelope at " + codeName(tag));
-  }
-
-  /**
-   * Starts reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * m b16 b8 method
-   * </pre>
-   */
-  public String readMethod()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'm')
-      throw error("expected hessian method ('m') at " + codeName(tag));
-    
-    int d1 = read();
-    int d2 = read();
-
-    _isLastChunk = true;
-    _chunkLength = d1 * 256 + d2;
-    _sbuf.setLength(0);
-    int ch;
-    while ((ch = parseChar()) >= 0)
-      _sbuf.append((char) ch);
-    
-    _method = _sbuf.toString();
-
-    return _method;
-  }
-
-  /**
-   * Starts reading the call, including the headers.
-   *
-   * <p>The call expects the following protocol data
-   *
-   * <pre>
-   * c major minor
-   * m b16 b8 method
-   * </pre>
-   */
-  public void startCall()
-    throws IOException
-  {
-    readCall();
-
-    while (readHeader() != null) {
-      readObject();
-    }
-
-    readMethod();
-  }
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeCall()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag == 'z') {
-    }
-    else if (tag < 0)
-      throw error("expected end of call ('z') at end of stream.");
-    else
-      throw error("expected end of call ('z') at " + codeName(tag) + ".  Check method arguments and ensure method overloading is enabled if necessary");
-  }
-
-  /**
-   * Reads a reply as an object.
-   * If the reply has a fault, throws the exception.
-   */
-  @Override
-  public Object readReply(Class expectedClass)
-    throws Throwable
-  {
-    int tag = read();
-    
-    if (tag != 'r') {
-      StringBuilder sb = new StringBuilder();
-      sb.append((char) tag);
-      
-      try {
-	int ch;
-
-	while ((ch = read()) >= 0) {
-	  sb.append((char) ch);
-	}
-      } catch (IOException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-      
-      throw error("expected hessian reply at " + codeName(tag) + "\n"
-		  + sb);
-    }
-
-    int major = read();
-    int minor = read();
-
-    if (major > 2 || major == 2 && minor > 0)
-      throw error("Cannot understand Hessian " + major + "." + minor + " response");
-    tag = read();
-    if (tag == 'f')
-      throw prepareFault();
-    else {
-      if (tag >= 0)
-	_offset--;
-    
-      Object value = readObject(expectedClass);
-      
-      completeValueReply();
-      
-      return value;
-    }
-  }
-
-  /**
-   * Starts reading the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * r
-   * </pre>
-   */
-  public void startReply()
-    throws Throwable
-  {
-    int tag = read();
-    
-    if (tag != 'r') {
-      StringBuilder sb = new StringBuilder();
-      sb.append((char) tag);
-      
-      try {
-	int ch;
-
-	while ((ch = read()) >= 0) {
-	  sb.append((char) ch);
-	}
-      } catch (IOException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-      
-      throw error("expected hessian reply at " + codeName(tag) + "\n"
-		  + sb);
-    }
-
-    int major = read();
-    int minor = read();
-
-    if (major > 2 || major == 2 && minor > 0)
-      throw error("Cannot understand Hessian " + major + "." + minor + " response");
-    
-    tag = read();
-    if (tag == 'f')
-      throw prepareFault();
-    else if (tag >= 0)
-      _offset--;
-  }
-
-  /**
-   * Prepares the fault.
-   */
-  private Throwable prepareFault()
-    throws IOException
-  {
-    HashMap fault = readFault();
-
-    Object detail = fault.get("detail");
-    String message = (String) fault.get("message");
-
-    if (detail instanceof Throwable) {
-      _replyFault = (Throwable) detail;
-      
-      if (message != null && _detailMessageField != null) {
-	try {
-	  _detailMessageField.set(_replyFault, message);
-	} catch (Throwable e) {
-	}
-      }
-	
-      return _replyFault;
-    }
-
-    else {
-      String code = (String) fault.get("code");
-        
-      _replyFault = new HessianServiceException(message, code, detail);
-
-      return _replyFault;
-    }
-  }
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeReply()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'z')
-      error("expected end of reply at " + codeName(tag));
-  }
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeValueReply()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'z')
-      error("expected end of reply at " + codeName(tag));
-  }
-
-  /**
-   * Reads a header, returning null if there are no headers.
-   *
-   * <pre>
-   * H b16 b8 value
-   * </pre>
-   */
-  public String readHeader()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag == 'H') {
-      _isLastChunk = true;
-      _chunkLength = (read() << 8) + read();
-
-      _sbuf.setLength(0);
-      int ch;
-      while ((ch = parseChar()) >= 0)
-        _sbuf.append((char) ch);
-
-      return _sbuf.toString();
-    }
-
-    if (tag >= 0)
-      _offset--;
-
-    return null;
-  }
-
-  /**
-   * Starts reading the message
-   *
-   * <pre>
-   * p major minor
-   * </pre>
-   */
-  public int startMessage()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag == 'p')
-      _isStreaming = false;
-    else if (tag == 'P')
-      _isStreaming = true;
-    else
-      throw error("expected Hessian message ('p') at " + codeName(tag));
-
-    int major = read();
-    int minor = read();
-
-    return (major << 16) + minor;
-  }
-
-  /**
-   * Completes reading the message
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeMessage()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'z')
-      error("expected end of message at " + codeName(tag));
-  }
-
-  /**
-   * Reads a null
-   *
-   * <pre>
-   * N
-   * </pre>
-   */
-  public void readNull()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N': return;
-      
-    default:
-      throw expect("null", tag);
-    }
-  }
-
-  /**
-   * Reads a boolean
-   *
-   * <pre>
-   * T
-   * F
-   * </pre>
-   */
-  public boolean readBoolean()
-    throws IOException
-  {
-    int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    switch (tag) {
-    case 'T': return true;
-    case 'F': return false;
-
-      // direct integer
-    case 0x80: case 0x81: case 0x82: case 0x83:
-    case 0x84: case 0x85: case 0x86: case 0x87:
-    case 0x88: case 0x89: case 0x8a: case 0x8b:
-    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
-      
-    case 0x90: case 0x91: case 0x92: case 0x93:
-    case 0x94: case 0x95: case 0x96: case 0x97:
-    case 0x98: case 0x99: case 0x9a: case 0x9b:
-    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
-      
-    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
-    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
-    case 0xa8: case 0xa9: case 0xaa: case 0xab:
-    case 0xac: case 0xad: case 0xae: case 0xaf:
-
-    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
-    case 0xb8: case 0xb9: case 0xba: case 0xbb:
-    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-      return tag != INT_ZERO;
-
-      // INT_BYTE = 0
-    case 0xc8: 
-      return read() != 0;
-      
-      // INT_BYTE != 0
-    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
-    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
-    case 0xc9: case 0xca: case 0xcb:
-    case 0xcc: case 0xcd: case 0xce: case 0xcf:
-      read();
-      return true;
-
-      // INT_SHORT = 0
-    case 0xd4: 
-      return (256 * read() + read()) != 0;
-      
-      // INT_SHORT != 0
-    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
-    case 0xd5: case 0xd6: case 0xd7:
-      read();
-      read();
-      return true;
-      
-    case 'I': return
-	parseInt() != 0;
-      
-    case 0xd8: case 0xd9: case 0xda: case 0xdb:
-    case 0xdc: case 0xdd: case 0xde: case 0xdf:
-      
-    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
-    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
-    case 0xe8: case 0xe9: case 0xea: case 0xeb:
-    case 0xec: case 0xed: case 0xee: case 0xef:
-      return tag != LONG_ZERO;
-
-      // LONG_BYTE = 0
-    case 0xf8: 
-      return read() != 0;
-      
-      // LONG_BYTE != 0
-    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
-    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
-    case 0xf9: case 0xfa: case 0xfb:
-    case 0xfc: case 0xfd: case 0xfe: case 0xff:
-      read();
-      return true;
-
-      // INT_SHORT = 0
-    case 0x3c: 
-      return (256 * read() + read()) != 0;
-      
-      // INT_SHORT != 0
-    case 0x38: case 0x39: case 0x3a: case 0x3b:
-    case 0x3d: case 0x3e: case 0x3f:
-      read();
-      read();
-      return true;
-
-    case LONG_INT:
-      return (0x1000000L * read()
-	      + 0x10000L * read()
-	      + 0x100 * read()
-	      + read()) != 0;
-      
-    case 'L':
-      return parseLong() != 0;
-
-    case DOUBLE_ZERO:
-      return false;
-      
-    case DOUBLE_ONE:
-      return true;
-      
-    case DOUBLE_BYTE:
-      return read() != 0;
-      
-    case DOUBLE_SHORT:
-      return (0x100 * read() + read()) != 0;
-      
-    case DOUBLE_FLOAT:
-      {
-	int f = parseInt();
-
-	return Float.intBitsToFloat(f) != 0;
-      }
-      
-    case 'D':
-      return parseDouble() != 0.0;
-      
-    case 'N':
-      return false;
-      
-    default:
-      throw expect("boolean", tag);
-    }
-  }
-
-  /**
-   * Reads a short
-   *
-   * <pre>
-   * I b32 b24 b16 b8
-   * </pre>
-   */
-  public short readShort()
-    throws IOException
-  {
-    return (short) readInt();
-  }
-
-  /**
-   * Reads an integer
-   *
-   * <pre>
-   * I b32 b24 b16 b8
-   * </pre>
-   */
-  public final int readInt()
-    throws IOException
-  {
-    //int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return 0;
-      
-    case 'F':
-      return 0;
-      
-    case 'T':
-      return 1;
-
-      // direct integer
-    case 0x80: case 0x81: case 0x82: case 0x83:
-    case 0x84: case 0x85: case 0x86: case 0x87:
-    case 0x88: case 0x89: case 0x8a: case 0x8b:
-    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
-      
-    case 0x90: case 0x91: case 0x92: case 0x93:
-    case 0x94: case 0x95: case 0x96: case 0x97:
-    case 0x98: case 0x99: case 0x9a: case 0x9b:
-    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
-      
-    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
-    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
-    case 0xa8: case 0xa9: case 0xaa: case 0xab:
-    case 0xac: case 0xad: case 0xae: case 0xaf:
-      
-    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
-    case 0xb8: case 0xb9: case 0xba: case 0xbb:
-    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-      return tag - INT_ZERO;
-
-      /* byte int */
-    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
-    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
-    case 0xc8: case 0xc9: case 0xca: case 0xcb:
-    case 0xcc: case 0xcd: case 0xce: case 0xcf:
-      return ((tag - INT_BYTE_ZERO) << 8) + read();
-      
-      /* short int */
-    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
-    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
-      return ((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read();
-
-    case 'I':
-    case LONG_INT:
-      return ((read() << 24)
-	      + (read() << 16)
-	      + (read() << 8)
-	      + read());
-
-      // direct long
-    case 0xd8: case 0xd9: case 0xda: case 0xdb:
-    case 0xdc: case 0xdd: case 0xde: case 0xdf:
-      
-    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
-    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
-    case 0xe8: case 0xe9: case 0xea: case 0xeb:
-    case 0xec: case 0xed: case 0xee: case 0xef:
-      return tag - LONG_ZERO;
-
-      /* byte long */
-    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
-    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
-    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
-    case 0xfc: case 0xfd: case 0xfe: case 0xff:
-      return ((tag - LONG_BYTE_ZERO) << 8) + read();
-      
-      /* short long */
-    case 0x38: case 0x39: case 0x3a: case 0x3b:
-    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-      return ((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read();
-
-    case 'L':
-      return (int) parseLong();
-
-    case DOUBLE_ZERO:
-      return 0;
-
-    case DOUBLE_ONE:
-      return 1;
-
-      //case LONG_BYTE:
-    case DOUBLE_BYTE:
-      return (byte) (_offset < _length ? _buffer[_offset++] : read());
-
-      //case INT_SHORT:
-      //case LONG_SHORT:
-    case DOUBLE_SHORT:
-      return (short) (256 * read() + read());
-
-    case DOUBLE_FLOAT:
-      {
-	int f = parseInt();
-
-	return (int) Float.intBitsToFloat(f);
-      }
-
-    case 'D':
-      return (int) parseDouble();
-      
-    default:
-      throw expect("integer", tag);
-    }
-  }
-
-  /**
-   * Reads a long
-   *
-   * <pre>
-   * L b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public long readLong()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return 0;
-      
-    case 'F':
-      return 0;
-      
-    case 'T':
-      return 1;
-
-      // direct integer
-    case 0x80: case 0x81: case 0x82: case 0x83:
-    case 0x84: case 0x85: case 0x86: case 0x87:
-    case 0x88: case 0x89: case 0x8a: case 0x8b:
-    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
-      
-    case 0x90: case 0x91: case 0x92: case 0x93:
-    case 0x94: case 0x95: case 0x96: case 0x97:
-    case 0x98: case 0x99: case 0x9a: case 0x9b:
-    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
-      
-    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
-    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
-    case 0xa8: case 0xa9: case 0xaa: case 0xab:
-    case 0xac: case 0xad: case 0xae: case 0xaf:
-      
-    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
-    case 0xb8: case 0xb9: case 0xba: case 0xbb:
-    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-      return tag - INT_ZERO;
-
-      /* byte int */
-    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
-    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
-    case 0xc8: case 0xc9: case 0xca: case 0xcb:
-    case 0xcc: case 0xcd: case 0xce: case 0xcf:
-      return ((tag - INT_BYTE_ZERO) << 8) + read();
-      
-      /* short int */
-    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
-    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
-      return ((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read();
-
-      //case LONG_BYTE:
-    case DOUBLE_BYTE:
-      return (byte) (_offset < _length ? _buffer[_offset++] : read());
-
-      //case INT_SHORT:
-      //case LONG_SHORT:
-    case DOUBLE_SHORT:
-      return (short) (256 * read() + read());
-
-    case 'I':
-    case LONG_INT:
-      return parseInt();
-
-      // direct long
-    case 0xd8: case 0xd9: case 0xda: case 0xdb:
-    case 0xdc: case 0xdd: case 0xde: case 0xdf:
-      
-    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
-    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
-    case 0xe8: case 0xe9: case 0xea: case 0xeb:
-    case 0xec: case 0xed: case 0xee: case 0xef:
-      return tag - LONG_ZERO;
-
-      /* byte long */
-    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
-    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
-    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
-    case 0xfc: case 0xfd: case 0xfe: case 0xff:
-      return ((tag - LONG_BYTE_ZERO) << 8) + read();
-      
-      /* short long */
-    case 0x38: case 0x39: case 0x3a: case 0x3b:
-    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-      return ((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read();
-
-    case 'L':
-      return parseLong();
-
-    case DOUBLE_ZERO:
-      return 0;
-
-    case DOUBLE_ONE:
-      return 1;
-
-    case DOUBLE_FLOAT:
-      {
-	int f = parseInt();
-
-	return (long) Float.intBitsToFloat(f);
-      }
-
-    case 'D':
-      return (long) parseDouble();
-      
-    default:
-      throw expect("long", tag);
-    }
-  }
-
-  /**
-   * Reads a float
-   *
-   * <pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public float readFloat()
-    throws IOException
-  {
-    return (float) readDouble();
-  }
-
-  /**
-   * Reads a double
-   *
-   * <pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public double readDouble()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return 0;
-      
-    case 'F':
-      return 0;
-      
-    case 'T':
-      return 1;
-
-      // direct integer
-    case 0x80: case 0x81: case 0x82: case 0x83:
-    case 0x84: case 0x85: case 0x86: case 0x87:
-    case 0x88: case 0x89: case 0x8a: case 0x8b:
-    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
-      
-    case 0x90: case 0x91: case 0x92: case 0x93:
-    case 0x94: case 0x95: case 0x96: case 0x97:
-    case 0x98: case 0x99: case 0x9a: case 0x9b:
-    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
-      
-    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
-    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
-    case 0xa8: case 0xa9: case 0xaa: case 0xab:
-    case 0xac: case 0xad: case 0xae: case 0xaf:
-      
-    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
-    case 0xb8: case 0xb9: case 0xba: case 0xbb:
-    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-      return tag - 0x90;
-
-      /* byte int */
-    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
-    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
-    case 0xc8: case 0xc9: case 0xca: case 0xcb:
-    case 0xcc: case 0xcd: case 0xce: case 0xcf:
-      return ((tag - INT_BYTE_ZERO) << 8) + read();
-      
-      /* short int */
-    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
-    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
-      return ((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read();
-
-    case 'I':
-    case LONG_INT:
-      return parseInt();
-
-      // direct long
-    case 0xd8: case 0xd9: case 0xda: case 0xdb:
-    case 0xdc: case 0xdd: case 0xde: case 0xdf:
-      
-    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
-    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
-    case 0xe8: case 0xe9: case 0xea: case 0xeb:
-    case 0xec: case 0xed: case 0xee: case 0xef:
-      return tag - LONG_ZERO;
-
-      /* byte long */
-    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
-    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
-    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
-    case 0xfc: case 0xfd: case 0xfe: case 0xff:
-      return ((tag - LONG_BYTE_ZERO) << 8) + read();
-      
-      /* short long */
-    case 0x38: case 0x39: case 0x3a: case 0x3b:
-    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-      return ((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read();
-
-    case 'L':
-      return (double) parseLong();
-
-    case DOUBLE_ZERO:
-      return 0;
-
-    case DOUBLE_ONE:
-      return 1;
-
-    case DOUBLE_BYTE:
-      return (byte) (_offset < _length ? _buffer[_offset++] : read());
-
-    case DOUBLE_SHORT:
-      return (short) (256 * read() + read());
-
-    case DOUBLE_FLOAT:
-      {
-	int f = parseInt();
-
-	return Float.intBitsToFloat(f);
-      }
-      
-    case 'D':
-      return parseDouble();
-      
-    default:
-      throw expect("double", tag);
-    }
-  }
-
-  /**
-   * Reads a date.
-   *
-   * <pre>
-   * T b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public long readUTCDate()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag != 'd')
-      throw expect("date", tag);
-
-    long b64 = read();
-    long b56 = read();
-    long b48 = read();
-    long b40 = read();
-    long b32 = read();
-    long b24 = read();
-    long b16 = read();
-    long b8 = read();
-
-    return ((b64 << 56)
-	    + (b56 << 48)
-	    + (b48 << 40)
-	    + (b40 << 32)
-	    + (b32 << 24)
-	    + (b24 << 16)
-	    + (b16 << 8)
-	    + b8);
-  }
-
-  /**
-   * Reads a byte from the stream.
-   */
-  public int readChar()
-    throws IOException
-  {
-    if (_chunkLength > 0) {
-      _chunkLength--;
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      int ch = parseUTF8Char();
-      return ch;
-    }
-    else if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return -1;
-
-    case 'S':
-    case 's':
-    case 'X':
-    case 'x':
-      _isLastChunk = tag == 'S' || tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      _chunkLength--;
-      int value = parseUTF8Char();
-
-      // special code so successive read byte won't
-      // be read as a single object.
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      return value;
-      
-    default:
-      throw expect("char", tag);
-    }
-  }
-
-  /**
-   * Reads a byte array from the stream.
-   */
-  public int readString(char []buffer, int offset, int length)
-    throws IOException
-  {
-    int readLength = 0;
-
-    if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    else if (_chunkLength == 0) {
-      int tag = read();
-
-      switch (tag) {
-      case 'N':
-        return -1;
-      
-      case 'S':
-      case 's':
-      case 'X':
-      case 'x':
-        _isLastChunk = tag == 'S' || tag == 'X';
-        _chunkLength = (read() << 8) + read();
-        break;
-
-      case 0x00: case 0x01: case 0x02: case 0x03:
-      case 0x04: case 0x05: case 0x06: case 0x07:
-      case 0x08: case 0x09: case 0x0a: case 0x0b:
-      case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-
-      case 0x10: case 0x11: case 0x12: case 0x13:
-      case 0x14: case 0x15: case 0x16: case 0x17:
-      case 0x18: case 0x19: case 0x1a: case 0x1b:
-      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-	_isLastChunk = true;
-	_chunkLength = tag - 0x00;
-	break;
-
-      default:
-        throw expect("string", tag);
-      }
-    }
-
-    while (length > 0) {
-      if (_chunkLength > 0) {
-        buffer[offset++] = (char) parseUTF8Char();
-        _chunkLength--;
-        length--;
-        readLength++;
-      }
-      else if (_isLastChunk) {
-        if (readLength == 0)
-          return -1;
-        else {
-          _chunkLength = END_OF_DATA;
-          return readLength;
-        }
-      }
-      else {
-        int tag = read();
-
-        switch (tag) {
-        case 'S':
-        case 's':
-        case 'X':
-        case 'x':
-          _isLastChunk = tag == 'S' || tag == 'X';
-          _chunkLength = (read() << 8) + read();
-          break;
-      
-        default:
-          throw expect("string", tag);
-        }
-      }
-    }
-    
-    if (readLength == 0)
-      return -1;
-    else if (_chunkLength > 0 || ! _isLastChunk)
-      return readLength;
-    else {
-      _chunkLength = END_OF_DATA;
-      return readLength;
-    }
-  }
-
-  /**
-   * Reads a string
-   *
-   * <pre>
-   * S b16 b8 string value
-   * </pre>
-   */
-  public String readString()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-    case 'T':
-      return "true";
-    case 'F':
-      return "false";
-
-      // direct integer
-    case 0x80: case 0x81: case 0x82: case 0x83:
-    case 0x84: case 0x85: case 0x86: case 0x87:
-    case 0x88: case 0x89: case 0x8a: case 0x8b:
-    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
-      
-    case 0x90: case 0x91: case 0x92: case 0x93:
-    case 0x94: case 0x95: case 0x96: case 0x97:
-    case 0x98: case 0x99: case 0x9a: case 0x9b:
-    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
-      
-    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
-    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
-    case 0xa8: case 0xa9: case 0xaa: case 0xab:
-    case 0xac: case 0xad: case 0xae: case 0xaf:
-      
-    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
-    case 0xb8: case 0xb9: case 0xba: case 0xbb:
-    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-      return String.valueOf((tag - 0x90));
-
-      /* byte int */
-    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
-    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
-    case 0xc8: case 0xc9: case 0xca: case 0xcb:
-    case 0xcc: case 0xcd: case 0xce: case 0xcf:
-      return String.valueOf(((tag - INT_BYTE_ZERO) << 8) + read());
-      
-      /* short int */
-    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
-    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
-      return String.valueOf(((tag - INT_SHORT_ZERO) << 16)
-			    + 256 * read() + read());
-
-    case 'I':
-    case LONG_INT:
-      return String.valueOf(parseInt());
-
-      // direct long
-    case 0xd8: case 0xd9: case 0xda: case 0xdb:
-    case 0xdc: case 0xdd: case 0xde: case 0xdf:
-      
-    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
-    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
-    case 0xe8: case 0xe9: case 0xea: case 0xeb:
-    case 0xec: case 0xed: case 0xee: case 0xef:
-      return String.valueOf(tag - LONG_ZERO);
-
-      /* byte long */
-    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
-    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
-    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
-    case 0xfc: case 0xfd: case 0xfe: case 0xff:
-      return String.valueOf(((tag - LONG_BYTE_ZERO) << 8) + read());
-      
-      /* short long */
-    case 0x38: case 0x39: case 0x3a: case 0x3b:
-    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-      return String.valueOf(((tag - LONG_SHORT_ZERO) << 16)
-			    + 256 * read() + read());
-
-    case 'L':
-      return String.valueOf(parseLong());
-
-    case DOUBLE_ZERO:
-      return "0.0";
-
-    case DOUBLE_ONE:
-      return "1.0";
-
-    case DOUBLE_BYTE:
-      return String.valueOf((byte) (_offset < _length
-				    ? _buffer[_offset++]
-				    : read()));
-
-    case DOUBLE_SHORT:
-      return String.valueOf(((short) (256 * read() + read())));
-
-    case DOUBLE_FLOAT:
-      {
-	int f = parseInt();
-
-	return String.valueOf(Float.intBitsToFloat(f));
-      }
-      
-    case 'D':
-      return String.valueOf(parseDouble());
-
-    case 'S':
-    case 's':
-    case 'X':
-    case 'x':
-      _isLastChunk = tag == 'S' || tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      _sbuf.setLength(0);
-      int ch;
-
-      while ((ch = parseChar()) >= 0)
-        _sbuf.append((char) ch);
-
-      return _sbuf.toString();
-
-      // 0-byte string
-    case 0x00: case 0x01: case 0x02: case 0x03:
-    case 0x04: case 0x05: case 0x06: case 0x07:
-    case 0x08: case 0x09: case 0x0a: case 0x0b:
-    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-
-    case 0x10: case 0x11: case 0x12: case 0x13:
-    case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x18: case 0x19: case 0x1a: case 0x1b:
-    case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-      _isLastChunk = true;
-      _chunkLength = tag - 0x00;
-
-      _sbuf.setLength(0);
-
-      while ((ch = parseChar()) >= 0)
-        _sbuf.append((char) ch);
-
-      return _sbuf.toString();
-
-    default:
-      throw expect("string", tag);
-    }
-  }
-
-  /**
-   * Reads an XML node.
-   *
-   * <pre>
-   * S b16 b8 string value
-   * </pre>
-   */
-  public org.w3c.dom.Node readNode()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'S':
-    case 's':
-    case 'X':
-    case 'x':
-      _isLastChunk = tag == 'S' || tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      throw error("XML is not supported");
-
-    case 0x00: case 0x01: case 0x02: case 0x03:
-    case 0x04: case 0x05: case 0x06: case 0x07:
-    case 0x08: case 0x09: case 0x0a: case 0x0b:
-    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-
-    case 0x10: case 0x11: case 0x12: case 0x13:
-    case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x18: case 0x19: case 0x1a: case 0x1b:
-    case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-      _isLastChunk = true;
-      _chunkLength = tag - 0x00;
-
-      throw error("XML is not supported");
-
-    default:
-      throw expect("string", tag);
-    }
-  }
-
-  /**
-   * Reads a byte array
-   *
-   * <pre>
-   * B b16 b8 data value
-   * </pre>
-   */
-  public byte []readBytes()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'B':
-    case 'b':
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-
-      ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
-      int data;
-      while ((data = parseByte()) >= 0)
-        bos.write(data);
-
-      return bos.toByteArray();
-
-    case 0x20: case 0x21: case 0x22: case 0x23:
-    case 0x24: case 0x25: case 0x26: case 0x27:
-    case 0x28: case 0x29: case 0x2a: case 0x2b:
-    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-      _isLastChunk = true;
-      _chunkLength = tag - 0x20;
-
-      bos = new ByteArrayOutputStream();
-
-      while ((data = parseByte()) >= 0)
-        bos.write(data);
-
-      return bos.toByteArray();
-      
-    default:
-      throw expect("bytes", tag);
-    }
-  }
-
-  /**
-   * Reads a byte from the stream.
-   */
-  public int readByte()
-    throws IOException
-  {
-    if (_chunkLength > 0) {
-      _chunkLength--;
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      return read();
-    }
-    else if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return -1;
-
-    case 'B':
-    case 'b':
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-
-      int value = parseByte();
-
-      // special code so successive read byte won't
-      // be read as a single object.
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      return value;
-      
-    default:
-      throw expect("binary", tag);
-    }
-  }
-
-  /**
-   * Reads a byte array from the stream.
-   */
-  public int readBytes(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    int readLength = 0;
-
-    if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    else if (_chunkLength == 0) {
-      int tag = read();
-
-      switch (tag) {
-      case 'N':
-        return -1;
-      
-      case 'B':
-      case 'b':
-        _isLastChunk = tag == 'B';
-        _chunkLength = (read() << 8) + read();
-        break;
-      
-      default:
-        throw expect("binary", tag);
-      }
-    }
-
-    while (length > 0) {
-      if (_chunkLength > 0) {
-        buffer[offset++] = (byte) read();
-        _chunkLength--;
-        length--;
-        readLength++;
-      }
-      else if (_isLastChunk) {
-        if (readLength == 0)
-          return -1;
-        else {
-          _chunkLength = END_OF_DATA;
-          return readLength;
-        }
-      }
-      else {
-        int tag = read();
-
-        switch (tag) {
-        case 'B':
-        case 'b':
-          _isLastChunk = tag == 'B';
-          _chunkLength = (read() << 8) + read();
-          break;
-      
-        default:
-          throw expect("binary", tag);
-        }
-      }
-    }
-    
-    if (readLength == 0)
-      return -1;
-    else if (_chunkLength > 0 || ! _isLastChunk)
-      return readLength;
-    else {
-      _chunkLength = END_OF_DATA;
-      return readLength;
-    }
-  }
-
-  /**
-   * Reads a fault.
-   */
-  private HashMap readFault()
-    throws IOException
-  {
-    HashMap map = new HashMap();
-
-    int code = read();
-    for (; code > 0 && code != 'z'; code = read()) {
-      _offset--;
-      
-      Object key = readObject();
-      Object value = readObject();
-
-      if (key != null && value != null)
-        map.put(key, value);
-    }
-
-    if (code != 'z')
-      throw expect("fault", code);
-
-    return map;
-  }
-
-  /**
-   * Reads an object from the input stream with an expected type.
-   */
-  public Object readObject(Class cl)
-    throws IOException
-  {
-    if (cl == null || cl == Object.class)
-      return readObject();
-    
-    int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'M':
-    {
-      String type = readType();
-
-      // hessian/3bb3
-      if ("".equals(type)) {
-	Deserializer reader;
-	reader = findSerializerFactory().getDeserializer(cl);
-
-	return reader.readMap(this);
-      }
-      else {
-	Deserializer reader;
-	reader = findSerializerFactory().getObjectDeserializer(type, cl);
-
-	return reader.readMap(this);
-      }
-    }
-
-    case 'O':
-    {
-      readObjectDefinition(cl);
-
-      return readObject(cl);
-    }
-
-    case 'o':
-    {
-      int ref = readInt();
-      int size = _classDefs.size();
-
-      if (ref < 0 || size <= ref)
-	throw new HessianProtocolException("'" + ref + "' is an unknown class definition");
-
-      ObjectDefinition def = (ObjectDefinition) _classDefs.get(ref);
-
-      return readObjectInstance(cl, def);
-    }
-
-    case 'V':
-    {
-      String type = readType();
-      int length = readLength();
-      
-      Deserializer reader;
-      reader = findSerializerFactory().getListDeserializer(type, cl);
-
-      Object v = reader.readList(this, length);
-
-      return v;
-    }
-
-    case 'v':
-    {
-      int ref = readInt();
-      String type = (String) _types.get(ref);
-      int length = readInt();
-      
-      Deserializer reader;
-      reader = findSerializerFactory().getListDeserializer(type, cl);
-
-      Object v = reader.readLengthList(this, length);
-
-      return v;
-    }
-
-    case 'R':
-    {
-      int ref = parseInt();
-
-      return _refs.get(ref);
-    }
-
-    case 'r':
-    {
-      String type = readType();
-      String url = readString();
-
-      return resolveRemote(type, url);
-    }
-
-    case REF_BYTE: {
-      int ref = read();
-
-      return _refs.get(ref);
-    }
-
-    case REF_SHORT: {
-      int ref = 256 * read() + read();
-
-      return _refs.get(ref);
-    }
-    }
-
-    if (tag >= 0)
-      _offset--;
-
-    // hessian/3b2i vs hessian/3406
-    // return readObject();
-
-    Object value = findSerializerFactory().getDeserializer(cl).readObject(this);
-    return value;
-  }
-  
-  /**
-   * Reads an arbitrary object from the input stream when the type
-   * is unknown.
-   */
-  public Object readObject()
-    throws IOException
-  {
-    int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-      
-    case 'T':
-      return Boolean.valueOf(true);
-      
-    case 'F':
-      return Boolean.valueOf(false);
-
-      // direct integer
-    case 0x80: case 0x81: case 0x82: case 0x83:
-    case 0x84: case 0x85: case 0x86: case 0x87:
-    case 0x88: case 0x89: case 0x8a: case 0x8b:
-    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
-      
-    case 0x90: case 0x91: case 0x92: case 0x93:
-    case 0x94: case 0x95: case 0x96: case 0x97:
-    case 0x98: case 0x99: case 0x9a: case 0x9b:
-    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
-      
-    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
-    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
-    case 0xa8: case 0xa9: case 0xaa: case 0xab:
-    case 0xac: case 0xad: case 0xae: case 0xaf:
-      
-    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
-    case 0xb8: case 0xb9: case 0xba: case 0xbb:
-    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-      return Integer.valueOf(tag - INT_ZERO);
-
-      /* byte int */
-    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
-    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
-    case 0xc8: case 0xc9: case 0xca: case 0xcb:
-    case 0xcc: case 0xcd: case 0xce: case 0xcf:
-      return Integer.valueOf(((tag - INT_BYTE_ZERO) << 8) + read());
-      
-      /* short int */
-    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
-    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
-      return Integer.valueOf(((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read());
-      
-    case 'I':
-      return Integer.valueOf(parseInt());
-
-      // direct long
-    case 0xd8: case 0xd9: case 0xda: case 0xdb:
-    case 0xdc: case 0xdd: case 0xde: case 0xdf:
-      
-    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
-    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
-    case 0xe8: case 0xe9: case 0xea: case 0xeb:
-    case 0xec: case 0xed: case 0xee: case 0xef:
-      return Long.valueOf(tag - LONG_ZERO);
-
-      /* byte long */
-    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
-    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
-    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
-    case 0xfc: case 0xfd: case 0xfe: case 0xff:
-      return Long.valueOf(((tag - LONG_BYTE_ZERO) << 8) + read());
-      
-      /* short long */
-    case 0x38: case 0x39: case 0x3a: case 0x3b:
-    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-      return Long.valueOf(((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read());
-      
-    case LONG_INT:
-      return Long.valueOf(parseInt());
-    
-    case 'L':
-      return Long.valueOf(parseLong());
-
-    case DOUBLE_ZERO:
-      return Double.valueOf(0);
-
-    case DOUBLE_ONE:
-      return Double.valueOf(1);
-
-    case DOUBLE_BYTE:
-      return Double.valueOf((byte) read());
-
-    case DOUBLE_SHORT:
-      return Double.valueOf((short) (256 * read() + read()));
-      
-    case DOUBLE_FLOAT:
-      {
-	int f = parseInt();
-
-	return Double.valueOf(Float.intBitsToFloat(f));
-      }
-
-    case 'D':
-      return Double.valueOf(parseDouble());
-    
-    case 'd':
-      return new Date(parseLong());
-    
-    case 'x':
-    case 'X': {
-      _isLastChunk = tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      return parseXML();
-    }
-
-    case 's':
-    case 'S': {
-      _isLastChunk = tag == 'S';
-      _chunkLength = (read() << 8) + read();
-
-      int data;
-      _sbuf.setLength(0);
-      
-      while ((data = parseChar()) >= 0)
-        _sbuf.append((char) data);
-
-      return _sbuf.toString();
-    }
-
-    case 0x00: case 0x01: case 0x02: case 0x03:
-    case 0x04: case 0x05: case 0x06: case 0x07:
-    case 0x08: case 0x09: case 0x0a: case 0x0b:
-    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-
-    case 0x10: case 0x11: case 0x12: case 0x13:
-    case 0x14: case 0x15: case 0x16: case 0x17:
-    case 0x18: case 0x19: case 0x1a: case 0x1b:
-    case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-      {
-	_isLastChunk = true;
-	_chunkLength = tag - 0x00;
-
-	int data;
-	_sbuf.setLength(0);
-      
-	while ((data = parseChar()) >= 0)
-	  _sbuf.append((char) data);
-
-	return _sbuf.toString();
-      }
-
-    case 'b':
-    case 'B': {
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-
-      int data;
-      ByteArrayOutputStream bos = new ByteArrayOutputStream();
-      
-      while ((data = parseByte()) >= 0)
-        bos.write(data);
-
-      return bos.toByteArray();
-    }
-
-    case 0x20: case 0x21: case 0x22: case 0x23:
-    case 0x24: case 0x25: case 0x26: case 0x27:
-    case 0x28: case 0x29: case 0x2a: case 0x2b:
-    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-      {
-	_isLastChunk = true;
-	int len = tag - 0x20;
-	_chunkLength = 0;
-
-	byte []data = new byte[len];
-
-	for (int i = 0; i < len; i++)
-	  data[i] = (byte) read();
-
-	return data;
-      }
-
-    case 'V': {
-      String type = readType();
-      int length = readLength();
-
-      return findSerializerFactory().readList(this, length, type);
-    }
-
-      // direct lists
-    case 'v': {
-      int ref = readInt();
-      String type = (String) _types.get(ref);
-      int length = readInt();
-      
-      Deserializer reader;
-      reader = findSerializerFactory().getObjectDeserializer(type, null);
-      
-      return reader.readLengthList(this, length);
-    }
-
-    case 'M': {
-      String type = readType();
-
-      return findSerializerFactory().readMap(this, type);
-    }
-
-    case 'O': {
-      readObjectDefinition(null);
-
-      return readObject();
-    }
-
-    case 'o': {
-      int ref = readInt();
-
-      ObjectDefinition def = (ObjectDefinition) _classDefs.get(ref);
-
-      return readObjectInstance(null, def);
-    }
-
-    case 'R': {
-      int ref = parseInt();
-
-      return _refs.get(ref);
-    }
-
-    case REF_BYTE: {
-      int ref = read();
-
-      return _refs.get(ref);
-    }
-
-    case REF_SHORT: {
-      int ref = 256 * read() + read();
-
-      return _refs.get(ref);
-    }
-      
-    case 'r': {
-      String type = readType();
-      String url = readString();
-
-      return resolveRemote(type, url);
-    }
-
-    default:
-      if (tag < 0)
-	throw new EOFException("readObject: unexpected end of file");
-      else
-	throw error("readObject: unknown code " + codeName(tag));
-    }
-  }
-
-  /**
-   * Reads an object definition:
-   *
-   * <pre>
-   * O string <int> (string)* <value>*
-   * </pre>
-   */
-  private void readObjectDefinition(Class cl)
-    throws IOException
-  {
-    String type = readString();
-    int len = readInt();
-
-    String []fieldNames = new String[len];
-    for (int i = 0; i < len; i++)
-      fieldNames[i] = readString();
-
-    ObjectDefinition def = new ObjectDefinition(type, fieldNames);
-
-    if (_classDefs == null)
-      _classDefs = new ArrayList();
-
-    _classDefs.add(def);
-  }
-
-  private Object readObjectInstance(Class cl, ObjectDefinition def)
-    throws IOException
-  {
-    String type = def.getType();
-    String []fieldNames = def.getFieldNames();
-    
-    if (cl != null) {
-      Deserializer reader;
-      reader = findSerializerFactory().getObjectDeserializer(type, cl);
-
-      return reader.readObject(this, fieldNames);
-    }
-    else {
-      return findSerializerFactory().readObject(this, type, fieldNames);
-    }
-  }
-
-  private String readLenString()
-    throws IOException
-  {
-    int len = readInt();
-    
-    _isLastChunk = true;
-    _chunkLength = len;
-
-    _sbuf.setLength(0);
-    int ch;
-    while ((ch = parseChar()) >= 0)
-      _sbuf.append((char) ch);
-
-    return _sbuf.toString();
-  }
-
-  private String readLenString(int len)
-    throws IOException
-  {
-    _isLastChunk = true;
-    _chunkLength = len;
-
-    _sbuf.setLength(0);
-    int ch;
-    while ((ch = parseChar()) >= 0)
-      _sbuf.append((char) ch);
-
-    return _sbuf.toString();
-  }
-  
-  /**
-   * Reads a remote object.
-   */
-  public Object readRemote()
-    throws IOException
-  {
-    String type = readType();
-    String url = readString();
-
-    return resolveRemote(type, url);
-  }
-
-  /**
-   * Reads a reference.
-   */
-  public Object readRef()
-    throws IOException
-  {
-    return _refs.get(parseInt());
-  }
-
-  /**
-   * Reads the start of a list.
-   */
-  public int readListStart()
-    throws IOException
-  {
-    return read();
-  }
-
-  /**
-   * Reads the start of a list.
-   */
-  public int readMapStart()
-    throws IOException
-  {
-    return read();
-  }
-
-  /**
-   * Returns true if this is the end of a list or a map.
-   */
-  public boolean isEnd()
-    throws IOException
-  {
-    int code;
-
-    if (_offset < _length)
-      code = (_buffer[_offset] & 0xff);
-    else {
-      code = read();
-
-      if (code >= 0)
-	_offset--;
-    }
-
-    return (code < 0 || code == 'z');
-  }
-
-  /**
-   * Reads the end byte.
-   */
-  public void readEnd()
-    throws IOException
-  {
-    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    if (code == 'z')
-      return;
-    else if (code < 0)
-      throw error("unexpected end of file");
-    else
-      throw error("unknown code:" + codeName(code));
-  }
-
-  /**
-   * Reads the end byte.
-   */
-  public void readMapEnd()
-    throws IOException
-  {
-    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    if (code != 'z')
-      throw error("expected end of map ('z') at '" + codeName(code) + "'");
-  }
-
-  /**
-   * Reads the end byte.
-   */
-  public void readListEnd()
-    throws IOException
-  {
-    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    if (code != 'z')
-      throw error("expected end of list ('z') at '" + codeName(code) + "'");
-  }
-
-  /**
-   * Adds a list/map reference.
-   */
-  public int addRef(Object ref)
-  {
-    if (_refs == null)
-      _refs = new ArrayList();
-    
-    _refs.add(ref);
-
-    return _refs.size() - 1;
-  }
-
-  /**
-   * Adds a list/map reference.
-   */
-  public void setRef(int i, Object ref)
-  {
-    _refs.set(i, ref);
-  }
-  
-  /**
-   * Resets the references for streaming.
-   */
-  public void resetReferences()
-  {
-    if (_refs != null)
-      _refs.clear();
-  }
-
-  public Object readStreamingObject()
-    throws IOException
-  {
-    if (_refs != null)
-      _refs.clear();
-
-    return readObject();
-  }
-
-  /**
-   * Resolves a remote object.
-   */
-  public Object resolveRemote(String type, String url)
-    throws IOException
-  {
-    HessianRemoteResolver resolver = getRemoteResolver();
-
-    if (resolver != null)
-      return resolver.lookup(type, url);
-    else
-      return new HessianRemote(type, url);
-  }
-
-  /**
-   * Parses a type from the stream.
-   *
-   * <pre>
-   * t b16 b8
-   * </pre>
-   */
-  public String readType()
-    throws IOException
-  {
-    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    switch (code) {
-    case 't':
-      {
-        int len = 256 * read() + read();
-        String type = readLenString(len);
-
-        if (_types == null)
-          _types = new ArrayList();
-
-        _types.add(type);
-
-        return type;
-      }
-
-    case 'T':
-      {
-        int ref = readInt();
-
-        return (String) _types.get(ref);
-      }
-
-    case TYPE_REF:
-      {
-        int ref = readInt();
-
-        return (String) _types.get(ref);
-      }
-      
-    default:
-      {
-        if (code >= 0)
-          _offset--;
-      
-        return "";
-      }
-    }
-  }
-
-  /**
-   * Parses the length for an array
-   *
-   * <pre>
-   * l b32 b24 b16 b8
-   * </pre>
-   */
-  public int readLength()
-    throws IOException
-  {
-    int code = read();
-
-    if (code == LENGTH_BYTE)
-      return read();
-	
-    else if (code == 'l')
-      return parseInt();
-
-    else {
-      if (code >= 0)
-	_offset--;
-      
-      return -1;
-    }
-  }
-
-  /**
-   * Parses a 32-bit integer value from the stream.
-   *
-   * <pre>
-   * b32 b24 b16 b8
-   * </pre>
-   */
-  private int parseInt()
-    throws IOException
-  {
-    int offset = _offset;
-    
-    if (offset + 3 < _length) {
-      byte []buffer = _buffer;
-      
-      int b32 = buffer[offset + 0] & 0xff;
-      int b24 = buffer[offset + 1] & 0xff;
-      int b16 = buffer[offset + 2] & 0xff;
-      int b8 = buffer[offset + 3] & 0xff;
-
-      _offset = offset + 4;
-
-      return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
-    }
-    else {
-      int b32 = read();
-      int b24 = read();
-      int b16 = read();
-      int b8 = read();
-
-      return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
-    }
-  }
-
-  /**
-   * Parses a 64-bit long value from the stream.
-   *
-   * <pre>
-   * b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  private long parseLong()
-    throws IOException
-  {
-    long b64 = read();
-    long b56 = read();
-    long b48 = read();
-    long b40 = read();
-    long b32 = read();
-    long b24 = read();
-    long b16 = read();
-    long b8 = read();
-
-    return ((b64 << 56) +
-            (b56 << 48) +
-            (b48 << 40) +
-            (b40 << 32) +
-            (b32 << 24) +
-            (b24 << 16) +
-            (b16 << 8) +
-            b8);
-  }
-  
-  /**
-   * Parses a 64-bit double value from the stream.
-   *
-   * <pre>
-   * b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  private double parseDouble()
-    throws IOException
-  {
-    long bits = parseLong();
-  
-    return Double.longBitsToDouble(bits);
-  }
-
-  org.w3c.dom.Node parseXML()
-    throws IOException
-  {
-    throw new UnsupportedOperationException();
-  }
-  
-  /**
-   * Reads a character from the underlying stream.
-   */
-  private int parseChar()
-    throws IOException
-  {
-    while (_chunkLength <= 0) {
-      if (_isLastChunk)
-        return -1;
-
-      int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-      switch (code) {
-      case 's':
-      case 'x':
-        _isLastChunk = false;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-        
-      case 'S':
-      case 'X':
-        _isLastChunk = true;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-	
-      case 0x00: case 0x01: case 0x02: case 0x03:
-      case 0x04: case 0x05: case 0x06: case 0x07:
-      case 0x08: case 0x09: case 0x0a: case 0x0b:
-      case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-
-      case 0x10: case 0x11: case 0x12: case 0x13:
-      case 0x14: case 0x15: case 0x16: case 0x17:
-      case 0x18: case 0x19: case 0x1a: case 0x1b:
-      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-	_isLastChunk = true;
-	_chunkLength = code - 0x00;
-	break;
-
-      default:
-        throw expect("string", code);
-      }
-
-    }
-
-    _chunkLength--;
-
-    return parseUTF8Char();
-  }
-
-  /**
-   * Parses a single UTF8 character.
-   */
-  private int parseUTF8Char()
-    throws IOException
-  {
-    int ch = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
-
-    if (ch < 0x80)
-      return ch;
-    else if ((ch & 0xe0) == 0xc0) {
-      int ch1 = read();
-      int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);
-
-      return v;
-    }
-    else if ((ch & 0xf0) == 0xe0) {
-      int ch1 = read();
-      int ch2 = read();
-      int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f);
-
-      return v;
-    }
-    else
-      throw error("bad utf-8 encoding at " + codeName(ch));
-  }
-  
-  /**
-   * Reads a byte from the underlying stream.
-   */
-  private int parseByte()
-    throws IOException
-  {
-    while (_chunkLength <= 0) {
-      if (_isLastChunk) {
-        return -1;
-      }
-
-      int code = read();
-
-      switch (code) {
-      case 'b':
-        _isLastChunk = false;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-        
-      case 'B':
-        _isLastChunk = true;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-
-      case 0x20: case 0x21: case 0x22: case 0x23:
-      case 0x24: case 0x25: case 0x26: case 0x27:
-      case 0x28: case 0x29: case 0x2a: case 0x2b:
-      case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-        _isLastChunk = true;
-
-        _chunkLength = code - 0x20;
-        break;
-
-      default:
-        throw expect("byte[]", code);
-      }
-    }
-
-    _chunkLength--;
-
-    return read();
-  }
-
-  /**
-   * Reads bytes based on an input stream.
-   */
-  public InputStream readInputStream()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'B':
-    case 'b':
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-      break;
-
-    case 0x20: case 0x21: case 0x22: case 0x23:
-    case 0x24: case 0x25: case 0x26: case 0x27:
-    case 0x28: case 0x29: case 0x2a: case 0x2b:
-    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-      _isLastChunk = true;
-      _chunkLength = tag - 0x20;
-      break;
-      
-    default:
-      throw expect("binary", tag);
-    }
-    
-    return new ReadInputStream();
-  }
-  
-  /**
-   * Reads bytes from the underlying stream.
-   */
-  int read(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    int readLength = 0;
-
-    while (length > 0) {
-      while (_chunkLength <= 0) {
-        if (_isLastChunk)
-          return readLength == 0 ? -1 : readLength;
-
-        int code = read();
-
-        switch (code) {
-        case 'b':
-          _isLastChunk = false;
-
-          _chunkLength = (read() << 8) + read();
-          break;
-        
-        case 'B':
-          _isLastChunk = true;
-
-          _chunkLength = (read() << 8) + read();
-          break;
-
-	case 0x20: case 0x21: case 0x22: case 0x23:
-	case 0x24: case 0x25: case 0x26: case 0x27:
-	case 0x28: case 0x29: case 0x2a: case 0x2b:
-	case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-	  _isLastChunk = true;
-	  _chunkLength = code - 0x20;
-	  break;
-
-        default:
-          throw expect("byte[]", code);
-        }
-      }
-
-      int sublen = _chunkLength;
-      if (length < sublen)
-        sublen = length;
-
-      if (_length <= _offset && ! readBuffer())
-	return -1;
-      
-      if (_length - _offset < sublen)
-	sublen = _length - _offset;
-
-      System.arraycopy(_buffer, _offset, buffer, offset, sublen);
-
-      _offset += sublen;
-      
-      offset += sublen;
-      readLength += sublen;
-      length -= sublen;
-      _chunkLength -= sublen;
-    }
-
-    return readLength;
-  }
-
-  /**
-   * Normally, shouldn't be called externally, but needed for QA, e.g.
-   * ejb/3b01.
-   */
-  public final int read()
-    throws IOException
-  {
-    if (_length <= _offset && ! readBuffer())
-      return -1;
-
-    return _buffer[_offset++] & 0xff;
-  }
-
-  private final boolean readBuffer()
-    throws IOException
-  {
-    byte []buffer = _buffer;
-    int offset = _offset;
-    int length = _length;
-    
-    if (offset < length) {
-      System.arraycopy(buffer, offset, buffer, 0, length - offset);
-      offset = length - offset;
-    }
-    else
-      offset = 0;
-    
-    int len = _is.read(buffer, offset, SIZE - offset);
-
-    if (len <= 0) {
-      _length = offset;
-      _offset = 0;
-      
-      return offset > 0;
-    }
-
-    _length = offset + len;
-    _offset = 0;
-
-    return true;
-  }
-
-  public Reader getReader()
-  {
-    return null;
-  }
-
-  protected IOException expect(String expect, int ch)
-    throws IOException
-  {
-    if (ch < 0)
-      return error("expected " + expect + " at end of file");
-    else {
-      _offset--;
-
-      try {
-	Object obj = readObject();
-
-	if (obj != null) {
-	  return error("expected " + expect
-		       + " at 0x" + Integer.toHexString(ch & 0xff)
-		       + " " + obj.getClass().getName() + " (" + obj + ")");
-	}
-	else
-	  return error("expected " + expect
-		       + " at 0x" + Integer.toHexString(ch & 0xff) + " null");
-      } catch (IOException e) {
-	log.log(Level.FINE, e.toString(), e);
-	
-	return error("expected " + expect
-		     + " at 0x" + Integer.toHexString(ch & 0xff));
-      }
-    }
-  }
-
-  protected String codeName(int ch)
-  {
-    if (ch < 0)
-      return "end of file";
-    else
-      return "0x" + Integer.toHexString(ch & 0xff) + " (" + (char) + ch + ")";
-  }
-  
-  protected IOException error(String message)
-  {
-    if (_method != null)
-      return new HessianProtocolException(_method + ": " + message);
-    else
-      return new HessianProtocolException(message);
-  }
-
-  public void close()
-    throws IOException
-  {
-    InputStream is = _is;
-    _is = null;
-
-    if (_isCloseStreamOnClose && is != null)
-      is.close();
-  }
-  
-  class ReadInputStream extends InputStream {
-    boolean _isClosed = false;
-	
-    public int read()
-      throws IOException
-    {
-      if (_isClosed)
-	return -1;
-
-      int ch = parseByte();
-      if (ch < 0)
-	_isClosed = true;
-
-      return ch;
-    }
-	
-    public int read(byte []buffer, int offset, int length)
-      throws IOException
-    {
-      if (_isClosed)
-	return -1;
-
-      int len = Hessian2Input.this.read(buffer, offset, length);
-      if (len < 0)
-	_isClosed = true;
-
-      return len;
-    }
-
-    public void close()
-      throws IOException
-    {
-      while (read() >= 0) {
-      }
-    }
-  };
-
-  final static class ObjectDefinition {
-    private final String _type;
-    private final String []_fields;
-
-    ObjectDefinition(String type, String []fields)
-    {
-      _type = type;
-      _fields = fields;
-    }
-
-    String getType()
-    {
-      return _type;
-    }
-
-    String []getFieldNames()
-    {
-      return _fields;
-    }
-  }
-
-  static {
-    try {
-      _detailMessageField = Throwable.class.getDeclaredField("detailMessage");
-      _detailMessageField.setAccessible(true);
-    } catch (Throwable e) {
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/Hessian2Output.java src/com/caucho/hessian/io/Hessian2Output.java
deleted file mode 100644
index d410dea..0000000
--- src/com/caucho/hessian/io/Hessian2Output.java
+++ /dev/null
@@ -1,1661 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import com.caucho.hessian.util.IdentityIntMap;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.HashMap;
-
-/**
- * Output stream for Hessian 2 requests.
- *
- * <p>Since HessianOutput does not depend on any classes other than
- * in the JDK, it can be extracted independently into a smaller package.
- *
- * <p>HessianOutput is unbuffered, so any client needs to provide
- * its own buffering.
- *
- * <pre>
- * OutputStream os = ...; // from http connection
- * Hessian2Output out = new Hessian11Output(os);
- * String value;
- *
- * out.startCall("hello");  // start hello call
- * out.writeString("arg1"); // write a string argument
- * out.completeCall();      // complete the call
- * </pre>
- */
-public class Hessian2Output
-  extends AbstractHessianOutput
-  implements Hessian2Constants
-{
-  // the output stream/
-  protected OutputStream _os;
-  
-  // map of references
-  private IdentityIntMap _refs = new IdentityIntMap();
-
-  private boolean _isCloseStreamOnClose;
-  
-  // map of classes
-  private HashMap _classRefs;
-  
-  // map of types
-  private HashMap _typeRefs;
-
-  private final static int SIZE = 1024;
-  
-  private final byte []_buffer = new byte[SIZE];
-  private int _offset;
-
-  private boolean _isStreaming;
-  
-  /**
-   * Creates a new Hessian output stream, initialized with an
-   * underlying output stream.
-   *
-   * @param os the underlying output stream.
-   */
-  public Hessian2Output(OutputStream os)
-  {
-    _os = os;
-  }
-  
-  public void setCloseStreamOnClose(boolean isClose)
-  {
-    _isCloseStreamOnClose = isClose;
-  }
-  
-  public boolean isCloseStreamOnClose()
-  {
-    return _isCloseStreamOnClose;
-  }
-  
-
-  /**
-   * Writes a complete method call.
-   */
-  public void call(String method, Object []args)
-    throws IOException
-  {
-    startCall(method);
-    
-    if (args != null) {
-      for (int i = 0; i < args.length; i++)
-        writeObject(args[i]);
-    }
-    
-    completeCall();
-  }
-  
-  /**
-   * Starts the method call.  Clients would use <code>startCall</code>
-   * instead of <code>call</code> if they wanted finer control over
-   * writing the arguments, or needed to write headers.
-   *
-   * <code><pre>
-   * c major minor
-   * m b16 b8 method-name
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void startCall(String method)
-    throws IOException
-  {
-    int offset = _offset;
-
-    if (SIZE < offset + 32) {
-      flush();
-      offset = 0;
-    }
-
-    byte []buffer = _buffer;
-    
-    buffer[offset++] = (byte) 'c';
-    buffer[offset++] = (byte) 2;
-    buffer[offset++] = (byte) 0;
-
-    buffer[offset++] = (byte) 'm';
-    int len = method.length();
-    buffer[offset++] = (byte) (len >> 8);
-    buffer[offset++] = (byte) len;
-
-    _offset = offset;
-    
-    printString(method, 0, len);
-  }
-
-  /**
-   * Writes the call tag.  This would be followed by the
-   * headers and the method tag.
-   *
-   * <code><pre>
-   * c major minor
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void startCall()
-    throws IOException
-  {
-    flushIfFull();
-    
-    int offset = _offset;
-    byte []buffer = _buffer;
-    
-    buffer[offset++] = (byte) 'c';
-    buffer[offset++] = (byte) 2;
-    buffer[offset++] = (byte) 0;
-  }
-
-  /**
-   * Writes the streaming call tag.  This would be followed by the
-   * headers and the method tag.
-   *
-   * <code><pre>
-   * C major minor
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void startStreamingCall()
-    throws IOException
-  {
-    flushIfFull();
-    
-    int offset = _offset;
-    byte []buffer = _buffer;
-    
-    buffer[offset++] = (byte) 'C';
-    buffer[offset++] = (byte) 2;
-    buffer[offset++] = (byte) 0;
-  }
-  
-  /**
-   * Starts an envelope.
-   *
-   * <code><pre>
-   * E major minor
-   * m b16 b8 method-name
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void startEnvelope(String method)
-    throws IOException
-  {
-    int offset = _offset;
-
-    if (SIZE < offset + 32) {
-      flush();
-      offset = 0;
-    }
-
-    byte []buffer = _buffer;
-    
-    buffer[offset++] = (byte) 'E';
-    buffer[offset++] = (byte) 2;
-    buffer[offset++] = (byte) 0;
-
-    buffer[offset++] = (byte) 'm';
-    int len = method.length();
-    buffer[offset++] = (byte) (len >> 8);
-    buffer[offset++] = (byte) len;
-
-    _offset = offset;
-    
-    printString(method, 0, len);
-  }
-
-  /**
-   * Completes an envelope.
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeEnvelope()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'z';
-  }
-
-  /**
-   * Writes the method tag.
-   *
-   * <code><pre>
-   * m b16 b8 method-name
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void writeMethod(String method)
-    throws IOException
-  {
-    flushIfFull();
-
-    byte []buffer = _buffer;
-    int offset = _offset;
-    
-    buffer[offset++] = (byte) 'm';
-    int len = method.length();
-    buffer[offset++] = (byte) (len >> 8);
-    buffer[offset++] = (byte) len;
-
-    _offset = offset;
-    
-    printString(method, 0, len);
-  }
-
-  /**
-   * Completes.
-   *
-   * <code><pre>
-   * z
-   * </pre></code>
-   */
-  public void completeCall()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'z';
-  }
-
-  /**
-   * Starts the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * r
-   * </pre>
-   */
-  public void startReply()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'r';
-    _buffer[_offset++] = (byte) 2;
-    _buffer[_offset++] = (byte) 0;
-  }
-
-  /**
-   * Starts the streaming reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * r
-   * </pre>
-   */
-  public void startStreamingReply()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'R';
-    _buffer[_offset++] = (byte) 2;
-    _buffer[_offset++] = (byte) 0;
-  }
-
-  /**
-   * Completes reading the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeReply()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'z';
-  }
-
-  /**
-   * Starts the message
-   *
-   * <p>A message contains several objects followed by a 'z'</p>
-   *
-   * <pre>
-   * p x02 x00
-   * </pre>
-   */
-  public void startMessage()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'p';
-    _buffer[_offset++] = (byte) 2;
-    _buffer[_offset++] = (byte) 0;
-  }
-
-  /**
-   * Completes reading the message
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeMessage()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'z';
-  }
-
-  /**
-   * Writes a header name.  The header value must immediately follow.
-   *
-   * <code><pre>
-   * H b16 b8 foo <em>value</em>
-   * </pre></code>
-   */
-  public void writeHeader(String name)
-    throws IOException
-  {
-    int len = name.length();
-
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'H';
-    _buffer[_offset++] = (byte) (len >> 8);
-    _buffer[_offset++] = (byte) (len);
-
-    printString(name);
-  }
-
-  /**
-   * Writes a fault.  The fault will be written
-   * as a descriptive string followed by an object:
-   *
-   * <code><pre>
-   * f
-   * &lt;string>code
-   * &lt;string>the fault code
-   *
-   * &lt;string>message
-   * &lt;string>the fault mesage
-   *
-   * &lt;string>detail
-   * mt\x00\xnnjavax.ejb.FinderException
-   *     ...
-   * z
-   * z
-   * </pre></code>
-   *
-   * @param code the fault code, a three digit
-   */
-  public void writeFault(String code, String message, Object detail)
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'f'
-      ;
-    writeString("code");
-    writeString(code);
-
-    writeString("message");
-    writeString(message);
-
-    if (detail != null) {
-      writeString("detail");
-      writeObject(detail);
-    }
-
-    flushIfFull();
-    _buffer[_offset++] = (byte) ('z');
-  }
-
-  /**
-   * Writes any object to the output stream.
-   */
-  public void writeObject(Object object)
-    throws IOException
-  {
-    if (object == null) {
-      writeNull();
-      return;
-    }
-
-    Serializer serializer;
-
-    serializer = findSerializerFactory().getSerializer(object.getClass());
-
-    serializer.writeObject(object, this);
-  }
-
-  /**
-   * Writes the list header to the stream.  List writers will call
-   * <code>writeListBegin</code> followed by the list contents and then
-   * call <code>writeListEnd</code>.
-   *
-   * <code><pre>
-   * V
-   * t b16 b8 type
-   * l b32 b24 b16 b8
-   * </pre></code>
-   */
-  public boolean writeListBegin(int length, String type)
-    throws IOException
-  {
-    flushIfFull();
-
-    if (_typeRefs != null) {
-      Integer refV = (Integer) _typeRefs.get(type);
-
-      if (refV != null) {
-	_buffer[_offset++] = (byte) (LIST_FIXED);
-	writeInt(refV.intValue());
-	writeInt(length);
-
-	return false;
-      }
-    }
-    
-    _buffer[_offset++] = (byte) 'V';
-
-    writeType(type);
-
-    flushIfFull();
-
-    if (length < 0) {
-    }
-    else if (length < 0x100) {
-      _buffer[_offset++] = (byte) (LENGTH_BYTE);
-      _buffer[_offset++] = (byte) (length);
-    }
-    else {
-      _buffer[_offset++] = (byte) ('l');
-      _buffer[_offset++] = (byte) (length >> 24);
-      _buffer[_offset++] = (byte) (length >> 16);
-      _buffer[_offset++] = (byte) (length >> 8);
-      _buffer[_offset++] = (byte) (length);
-    }
-
-    return true;
-  }
-
-  /**
-   * Writes the tail of the list to the stream.
-   */
-  public void writeListEnd()
-    throws IOException
-  {
-    flushIfFull();
-    
-    _buffer[_offset++] = (byte) 'z';
-  }
-
-  /**
-   * Writes the map header to the stream.  Map writers will call
-   * <code>writeMapBegin</code> followed by the map contents and then
-   * call <code>writeMapEnd</code>.
-   *
-   * <code><pre>
-   * Mt b16 b8 (<key> <value>)z
-   * </pre></code>
-   */
-  public void writeMapBegin(String type)
-    throws IOException
-  {
-    if (SIZE < _offset + 32)
-      flush();
-    
-    _buffer[_offset++] = 'M';
-
-    writeType(type);
-  }
-
-  /**
-   * Writes the tail of the map to the stream.
-   */
-  public void writeMapEnd()
-    throws IOException
-  {
-    if (SIZE < _offset + 32)
-      flush();
-    
-    _buffer[_offset++] = (byte) 'z';
-  }
-
-  /**
-   * Writes the object definition
-   *
-   * <code><pre>
-   * O t b16 b8 <string>*
-   * </pre></code>
-   */
-  public int writeObjectBegin(String type)
-    throws IOException
-  {
-    if (_classRefs == null)
-      _classRefs = new HashMap();
-
-    Integer refV = (Integer) _classRefs.get(type);
-
-    if (refV != null) {
-      int ref = refV.intValue();
-      
-      if (SIZE < _offset + 32)
-	flush();
-
-      _buffer[_offset++] = (byte) 'o';
-      writeInt(ref);
-
-      return ref;
-    }
-    else {
-      int ref = _classRefs.size();
-      
-      _classRefs.put(type, Integer.valueOf(ref));
-      
-      if (SIZE < _offset + 32)
-	flush();
-
-      _buffer[_offset++] = (byte) 'O';
-
-      writeString(type);
-
-      return -1;
-    }
-  }
-
-  /**
-   * Writes the tail of the class definition to the stream.
-   */
-  public void writeClassFieldLength(int len)
-    throws IOException
-  {
-    writeInt(len);
-  }
-
-  /**
-   * Writes the tail of the object definition to the stream.
-   */
-  public void writeObjectEnd()
-    throws IOException
-  {
-  }
-
-  /**
-   * Writes a remote object reference to the stream.  The type is the
-   * type of the remote interface.
-   *
-   * <code><pre>
-   * 'r' 't' b16 b8 type url
-   * </pre></code>
-   */
-  public void writeRemote(String type, String url)
-    throws IOException
-  {
-    if (SIZE < _offset + 32)
-      flush();
-
-    _buffer[_offset++] = (byte) 'r';
-
-    writeType(type);
-
-    if (SIZE < _offset + 32)
-      flush();
-
-    _buffer[_offset++] = (byte) 'S';
-    
-    printLenString(url);
-  }
-
-  private void writeType(String type)
-    throws IOException
-  {
-    if (type == null)
-      return;
-
-    int len = type.length();
-    if (len == 0)
-      return;
-
-    if (_typeRefs == null)
-      _typeRefs = new HashMap();
-
-    Integer typeRefV = (Integer) _typeRefs.get(type);
-    
-    if (typeRefV != null) {
-      int typeRef = typeRefV.intValue();
-      
-      flushIfFull();
-      
-      _buffer[_offset++] = (byte) TYPE_REF;
-      
-      writeInt(typeRef);
-    }
-    else {
-      _typeRefs.put(type, Integer.valueOf(_typeRefs.size()));
-
-      if (SIZE < _offset + 32)
-	flush();
-      
-      _buffer[_offset++] = (byte) 't';
-      
-      printLenString(type);
-    }
-  }
-
-  /**
-   * Writes a boolean value to the stream.  The boolean will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * T
-   * F
-   * </pre></code>
-   *
-   * @param value the boolean value to write.
-   */
-  public void writeBoolean(boolean value)
-    throws IOException
-  {
-    if (SIZE < _offset + 16)
-      flush();
-
-    if (value)
-      _buffer[_offset++] = (byte) 'T';
-    else
-      _buffer[_offset++] = (byte) 'F';
-  }
-
-  /**
-   * Writes an integer value to the stream.  The integer will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * I b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the integer value to write.
-   */
-  public void writeInt(int value)
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-
-    if (SIZE <= offset + 16) {
-      flush();
-      offset = 0;
-    }
-    
-    if (INT_DIRECT_MIN <= value && value <= INT_DIRECT_MAX)
-      buffer[offset++] = (byte) (value + INT_ZERO);
-    else if (INT_BYTE_MIN <= value && value <= INT_BYTE_MAX) {
-      buffer[offset++] = (byte) (INT_BYTE_ZERO + (value >> 8));
-      buffer[offset++] = (byte) (value);
-    }
-    else if (INT_SHORT_MIN <= value && value <= INT_SHORT_MAX) {
-      buffer[offset++] = (byte) (INT_SHORT_ZERO + (value >> 16));
-      buffer[offset++] = (byte) (value >> 8);
-      buffer[offset++] = (byte) (value);
-    }
-    else {
-      buffer[offset++] = (byte) ('I');
-      buffer[offset++] = (byte) (value >> 24);
-      buffer[offset++] = (byte) (value >> 16);
-      buffer[offset++] = (byte) (value >> 8);
-      buffer[offset++] = (byte) (value);
-    }
-
-    _offset = offset;
-  }
-
-  /**
-   * Writes a long value to the stream.  The long will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * L b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the long value to write.
-   */
-  public void writeLong(long value)
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-
-    if (SIZE <= offset + 16) {
-      flush();
-      offset = 0;
-    }
-
-    if (LONG_DIRECT_MIN <= value && value <= LONG_DIRECT_MAX) {
-      buffer[offset++] = (byte) (value + LONG_ZERO);
-    }
-    else if (LONG_BYTE_MIN <= value && value <= LONG_BYTE_MAX) {
-      buffer[offset++] = (byte) (LONG_BYTE_ZERO + (value >> 8));
-      buffer[offset++] = (byte) (value);
-    }
-    else if (LONG_SHORT_MIN <= value && value <= LONG_SHORT_MAX) {
-      buffer[offset++] = (byte) (LONG_SHORT_ZERO + (value >> 16));
-      buffer[offset++] = (byte) (value >> 8);
-      buffer[offset++] = (byte) (value);
-    }
-    else if (-0x80000000L <= value && value <= 0x7fffffffL) {
-      buffer[offset + 0] = (byte) LONG_INT;
-      buffer[offset + 1] = (byte) (value >> 24);
-      buffer[offset + 2] = (byte) (value >> 16);
-      buffer[offset + 3] = (byte) (value >> 8);
-      buffer[offset + 4] = (byte) (value);
-
-      offset += 5;
-    }
-    else {
-      buffer[offset + 0] = (byte) 'L';
-      buffer[offset + 1] = (byte) (value >> 56);
-      buffer[offset + 2] = (byte) (value >> 48);
-      buffer[offset + 3] = (byte) (value >> 40);
-      buffer[offset + 4] = (byte) (value >> 32);
-      buffer[offset + 5] = (byte) (value >> 24);
-      buffer[offset + 6] = (byte) (value >> 16);
-      buffer[offset + 7] = (byte) (value >> 8);
-      buffer[offset + 8] = (byte) (value);
-
-      offset += 9;
-    }
-
-    _offset = offset;
-  }
-
-  /**
-   * Writes a double value to the stream.  The double will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the double value to write.
-   */
-  public void writeDouble(double value)
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-
-    if (SIZE <= offset + 16) {
-      flush();
-      offset = 0;
-    }
-    
-    int intValue = (int) value;
-    
-    if (intValue == value) {
-      if (intValue == 0) {
-	buffer[offset++] = (byte) DOUBLE_ZERO;
-
-        _offset = offset;
-
-        return;
-      }
-      else if (intValue == 1) {
-	buffer[offset++] = (byte) DOUBLE_ONE;
-
-        _offset = offset;
-
-        return;
-      }
-      else if (-0x80 <= intValue && intValue < 0x80) {
-	buffer[offset++] = (byte) DOUBLE_BYTE;
-	buffer[offset++] = (byte) intValue;
-
-        _offset = offset;
-
-        return;
-      }
-      else if (-0x8000 <= intValue && intValue < 0x8000) {
-	buffer[offset + 0] = (byte) DOUBLE_SHORT;
-	buffer[offset + 1] = (byte) (intValue >> 8);
-	buffer[offset + 2] = (byte) intValue;
-
-	_offset = offset + 3;
-        
-        return;
-      }
-    }
-
-    float f = (float) value;
-
-    if (f == value) {
-      int bits = Float.floatToIntBits(f);
-      
-      buffer[offset + 0] = (byte) (DOUBLE_FLOAT);
-      buffer[offset + 1] = (byte) (bits >> 24);
-      buffer[offset + 2] = (byte) (bits >> 16);
-      buffer[offset + 3] = (byte) (bits >> 8);
-      buffer[offset + 4] = (byte) (bits);
-
-      _offset = offset + 5;
-
-      return;
-    }
-    
-    long bits = Double.doubleToLongBits(value);
-    
-    buffer[offset + 0] = (byte) 'D';
-    buffer[offset + 1] = (byte) (bits >> 56);
-    buffer[offset + 2] = (byte) (bits >> 48);
-    buffer[offset + 3] = (byte) (bits >> 40);
-    buffer[offset + 4] = (byte) (bits >> 32);
-    buffer[offset + 5] = (byte) (bits >> 24);
-    buffer[offset + 6] = (byte) (bits >> 16);
-    buffer[offset + 7] = (byte) (bits >> 8);
-    buffer[offset + 8] = (byte) (bits);
-
-    _offset = offset + 9;
-  }
-
-  /**
-   * Writes a date to the stream.
-   *
-   * <code><pre>
-   * T  b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param time the date in milliseconds from the epoch in UTC
-   */
-  public void writeUTCDate(long time)
-    throws IOException
-  {
-    if (SIZE < _offset + 32)
-      flush();
-
-    int offset = _offset;
-    byte []buffer = _buffer;
-    
-    buffer[offset++] = (byte) ('d');
-    buffer[offset++] = ((byte) (time >> 56));
-    buffer[offset++] = ((byte) (time >> 48));
-    buffer[offset++] = ((byte) (time >> 40));
-    buffer[offset++] = ((byte) (time >> 32));
-    buffer[offset++] = ((byte) (time >> 24));
-    buffer[offset++] = ((byte) (time >> 16));
-    buffer[offset++] = ((byte) (time >> 8));
-    buffer[offset++] = ((byte) (time));
-
-    _offset = offset;
-  }
-
-  /**
-   * Writes a null value to the stream.
-   * The null will be written with the following syntax
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeNull()
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-
-    if (SIZE <= offset + 16) {
-      flush();
-      offset = 0;
-    }
-
-    buffer[offset++] = 'N';
-
-    _offset = offset;
-  }
-
-  /**
-   * Writes a string value to the stream using UTF-8 encoding.
-   * The string will be written with the following syntax:
-   *
-   * <code><pre>
-   * S b16 b8 string-value
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeString(String value)
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-
-    if (SIZE <= offset + 16) {
-      flush();
-      offset = 0;
-    }
-    
-    if (value == null) {
-      buffer[offset++] = (byte) 'N';
-
-      _offset = offset;
-    }
-    else {
-      int length = value.length();
-      int strOffset = 0;
-      
-      while (length > 0x8000) {
-        int sublen = 0x8000;
-
-	offset = _offset;
-
-	if (SIZE <= offset + 16) {
-	  flush();
-	  offset = 0;
-	}
-
-	// chunk can't end in high surrogate
-	char tail = value.charAt(strOffset + sublen - 1);
-
-	if (0xd800 <= tail && tail <= 0xdbff)
-	  sublen--;
-
-	buffer[offset + 0] = (byte) 's';
-        buffer[offset + 1] = (byte) (sublen >> 8);
-        buffer[offset + 2] = (byte) (sublen);
-
-	_offset = offset + 3;
-
-        printString(value, strOffset, sublen);
-
-        length -= sublen;
-        strOffset += sublen;
-      }
-
-      offset = _offset;
-
-      if (SIZE <= offset + 16) {
-	flush();
-	offset = 0;
-      }
-
-      if (length <= STRING_DIRECT_MAX) {
-	buffer[offset++] = (byte) (STRING_DIRECT + length);
-      }
-      else {
-	buffer[offset++] = (byte) ('S');
-	buffer[offset++] = (byte) (length >> 8);
-	buffer[offset++] = (byte) (length);
-      }
-
-      _offset = offset;
-
-      printString(value, strOffset, length);
-    }
-  }
-
-  /**
-   * Writes a string value to the stream using UTF-8 encoding.
-   * The string will be written with the following syntax:
-   *
-   * <code><pre>
-   * S b16 b8 string-value
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeString(char []buffer, int offset, int length)
-    throws IOException
-  {
-    if (buffer == null) {
-      if (SIZE < _offset + 16)
-	flush();
-      
-      _buffer[_offset++] = (byte) ('N');
-    }
-    else {
-      while (length > 0x8000) {
-        int sublen = 0x8000;
-
-	if (SIZE < _offset + 16)
-	  flush();
-
-	// chunk can't end in high surrogate
-	char tail = buffer[offset + sublen - 1];
-
-	if (0xd800 <= tail && tail <= 0xdbff)
-	  sublen--;
-	
-        _buffer[_offset++] = (byte) 's';
-        _buffer[_offset++] = (byte) (sublen >> 8);
-        _buffer[_offset++] = (byte) (sublen);
-
-        printString(buffer, offset, sublen);
-
-        length -= sublen;
-        offset += sublen;
-      }
-
-      if (SIZE < _offset + 16)
-	flush();
-	
-      if (length <= STRING_DIRECT_MAX) {
-	_buffer[_offset++] = (byte) (STRING_DIRECT + length);
-      }
-      else {
-	_buffer[_offset++] = (byte) ('S');
-	_buffer[_offset++] = (byte) (length >> 8);
-	_buffer[_offset++] = (byte) (length);
-      }
-
-      printString(buffer, offset, length);
-    }
-  }
-
-  /**
-   * Writes a byte array to the stream.
-   * The array will be written with the following syntax:
-   *
-   * <code><pre>
-   * B b16 b18 bytes
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeBytes(byte []buffer)
-    throws IOException
-  {
-    if (buffer == null) {
-      if (SIZE < _offset + 16)
-	flush();
-
-      _buffer[_offset++] = 'N';
-    }
-    else
-      writeBytes(buffer, 0, buffer.length);
-  }
-  
-  /**
-   * Writes a byte array to the stream.
-   * The array will be written with the following syntax:
-   *
-   * <code><pre>
-   * B b16 b18 bytes
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeBytes(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    if (buffer == null) {
-      if (SIZE < _offset + 16)
-	flushBuffer();
-      
-      _buffer[_offset++] = (byte) 'N';
-    }
-    else {
-      flush();
-
-      while (length > SIZE - _offset - 3) {
-        int sublen = SIZE - _offset - 3;
-
-        if (sublen < 16) {
-          flushBuffer();
-
-          sublen = SIZE - _offset - 3;
-
-          if (length < sublen)
-            sublen = length;
-        }
-
-        _buffer[_offset++] = (byte) 'b';
-        _buffer[_offset++] = (byte) (sublen >> 8);
-        _buffer[_offset++] = (byte) sublen;
-
-        System.arraycopy(buffer, offset, _buffer, _offset, sublen);
-        _offset += sublen;
-
-        length -= sublen;
-        offset += sublen;
-      }
-
-      if (SIZE < _offset + 16)
-        flushBuffer();
-
-      if (length < 0x10) {
-        _buffer[_offset++] = (byte) (BYTES_DIRECT + length);
-      }
-      else {
-        _buffer[_offset++] = (byte) 'B';
-        _buffer[_offset++] = (byte) (length >> 8);
-        _buffer[_offset++] = (byte) (length);
-      }
-
-      System.arraycopy(buffer, offset, _buffer, _offset, length);
-
-      _offset += length;
-    }
-  }
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * </pre></code>
-   */
-  public void writeByteBufferStart()
-    throws IOException
-  {
-  }
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * b b16 b18 bytes
-   * </pre></code>
-   */
-  public void writeByteBufferPart(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    while (length > 0) {
-      int sublen = length;
-
-      if (0x8000 < sublen)
-	sublen = 0x8000;
-
-      flush(); // bypass buffer
-      
-      _os.write('b');
-      _os.write(sublen >> 8);
-      _os.write(sublen);
-
-      _os.write(buffer, offset, sublen);
-
-      length -= sublen;
-      offset += sublen;
-    }
-  }
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * b b16 b18 bytes
-   * </pre></code>
-   */
-  public void writeByteBufferEnd(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    writeBytes(buffer, offset, length);
-  }
-
-  /**
-   * Returns an output stream to write binary data.
-   */
-  public OutputStream getBytesOutputStream()
-    throws IOException
-  {
-    return new BytesOutputStream();
-  }
-
-  /**
-   * Writes a reference.
-   *
-   * <code><pre>
-   * R b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the integer value to write.
-   */
-  public void writeRef(int value)
-    throws IOException
-  {
-    if (SIZE < _offset + 16)
-      flush();
-    
-    if (value < 0x100) {
-      _buffer[_offset++] = (byte) (REF_BYTE);
-      _buffer[_offset++] = (byte) (value);
-    }
-    else if (value < 0x10000) {
-      _buffer[_offset++] = (byte) (REF_SHORT);
-      _buffer[_offset++] = (byte) (value >> 8);
-      _buffer[_offset++] = (byte) (value);
-    }
-    else {
-      _buffer[_offset++] = (byte) ('R');
-      _buffer[_offset++] = (byte) (value >> 24);
-      _buffer[_offset++] = (byte) (value >> 16);
-      _buffer[_offset++] = (byte) (value >> 8);
-      _buffer[_offset++] = (byte) (value);
-    }
-  }
-
-  /**
-   * If the object has already been written, just write its ref.
-   *
-   * @return true if we're writing a ref.
-   */
-  public boolean addRef(Object object)
-    throws IOException
-  {
-    int ref = _refs.get(object);
-
-    if (ref >= 0) {
-      writeRef(ref);
-      
-      return true;
-    }
-    else {
-      _refs.put(object, _refs.size());
-      
-      return false;
-    }
-  }
-
-  /**
-   * Removes a reference.
-   */
-  public boolean removeRef(Object obj)
-    throws IOException
-  {
-    if (_refs != null) {
-      _refs.remove(obj);
-
-      return true;
-    }
-    else
-      return false;
-  }
-
-  /**
-   * Replaces a reference from one object to another.
-   */
-  public boolean replaceRef(Object oldRef, Object newRef)
-    throws IOException
-  {
-    Integer value = (Integer) _refs.remove(oldRef);
-
-    if (value != null) {
-      _refs.put(newRef, value);
-      return true;
-    }
-    else
-      return false;
-  }
-
-  /**
-   * Resets the references for streaming.
-   */
-  public void resetReferences()
-  {
-    if (_refs != null)
-      _refs.clear();
-  }
-
-  /**
-   * Starts the streaming message
-   *
-   * <p>A streaming message starts with 'P'</p>
-   *
-   * <pre>
-   * P x02 x00
-   * </pre>
-   */
-  public void writeStreamingObject(Object obj)
-    throws IOException
-  {
-    if (_refs != null)
-      _refs.clear();
-    
-    flush();
-
-    _isStreaming = true;
-    _offset = 3;
-
-    writeObject(obj);
-
-    int len = _offset - 3;
-    
-    _buffer[0] = (byte) 'P';
-    _buffer[1] = (byte) (len >> 8);
-    _buffer[2] = (byte) len;
-
-    _isStreaming = false;
-
-    flush();
-  }
-
-  /**
-   * Prints a string to the stream, encoded as UTF-8 with preceeding length
-   *
-   * @param v the string to print.
-   */
-  public void printLenString(String v)
-    throws IOException
-  {
-    if (SIZE < _offset + 16)
-      flush();
-    
-    if (v == null) {
-      _buffer[_offset++] = (byte) (0);
-      _buffer[_offset++] = (byte) (0);
-    }
-    else {
-      int len = v.length();
-      _buffer[_offset++] = (byte) (len >> 8);
-      _buffer[_offset++] = (byte) (len);
-
-      printString(v, 0, len);
-    }
-  }
-
-  /**
-   * Prints a string to the stream, encoded as UTF-8
-   *
-   * @param v the string to print.
-   */
-  public void printString(String v)
-    throws IOException
-  {
-    printString(v, 0, v.length());
-  }
-  
-  /**
-   * Prints a string to the stream, encoded as UTF-8
-   *
-   * @param v the string to print.
-   */
-  public void printString(String v, int strOffset, int length)
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-    
-    for (int i = 0; i < length; i++) {
-      if (SIZE <= offset + 16) {
-	_offset = offset;
-	flush();
-	offset = 0;
-      }
-      
-      char ch = v.charAt(i + strOffset);
-
-      if (ch < 0x80)
-        buffer[offset++] = (byte) (ch);
-      else if (ch < 0x800) {
-        buffer[offset++] = (byte) (0xc0 + ((ch >> 6) & 0x1f));
-        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
-      }
-      else {
-        buffer[offset++] = (byte) (0xe0 + ((ch >> 12) & 0xf));
-        buffer[offset++] = (byte) (0x80 + ((ch >> 6) & 0x3f));
-        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
-      }
-    }
-
-    _offset = offset;
-  }
-  
-  /**
-   * Prints a string to the stream, encoded as UTF-8
-   *
-   * @param v the string to print.
-   */
-  public void printString(char []v, int strOffset, int length)
-    throws IOException
-  {
-    int offset = _offset;
-    byte []buffer = _buffer;
-    
-    for (int i = 0; i < length; i++) {
-      if (SIZE <= offset + 16) {
-	_offset = offset;
-	flush();
-	offset = 0;
-      }
-      
-      char ch = v[i + strOffset];
-
-      if (ch < 0x80)
-        buffer[offset++] = (byte) (ch);
-      else if (ch < 0x800) {
-        buffer[offset++] = (byte) (0xc0 + ((ch >> 6) & 0x1f));
-        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
-      }
-      else {
-        buffer[offset++] = (byte) (0xe0 + ((ch >> 12) & 0xf));
-        buffer[offset++] = (byte) (0x80 + ((ch >> 6) & 0x3f));
-        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
-      }
-    }
-
-    _offset = offset;
-  }
-  
-  private final void flushIfFull()
-    throws IOException
-  {
-    int offset = _offset;
-    
-    if (SIZE < offset + 32) {
-      _offset = 0;
-      _os.write(_buffer, 0, offset);
-    }
-  }
-
-  public final void flush()
-    throws IOException
-  {
-    flushBuffer();
-
-    _os.flush();
-  }
-
-  public final void flushBuffer()
-    throws IOException
-  {
-    int offset = _offset;
-
-    if (! _isStreaming && offset > 0) {
-      _offset = 0;
-      
-      _os.write(_buffer, 0, offset);
-    }
-    else if (_isStreaming && offset > 3) {
-      int len = offset - 3;
-      _buffer[0] = 'p';
-      _buffer[1] = (byte) (len >> 8);
-      _buffer[2] = (byte) len;
-      _offset = 3;
-      
-      _os.write(_buffer, 0, offset);
-    }
-  }
-
-  public final void close()
-    throws IOException
-  {
-    flushBuffer();
-    
-    OutputStream os = _os;
-    _os = null;
-
-    if (os != null) {
-      if (_isCloseStreamOnClose)
-	os.close();
-    }
-  }
-
-  class BytesOutputStream extends OutputStream {
-    private int _startOffset;
-    
-    BytesOutputStream()
-      throws IOException
-    {
-      if (SIZE < _offset + 16) {
-        Hessian2Output.this.flush();
-      }
-
-      _startOffset = _offset;
-      _offset += 3; // skip 'b' xNN xNN
-    }
-
-    @Override
-    public void write(int ch)
-      throws IOException
-    {
-      if (SIZE <= _offset) {
-        int length = (_offset - _startOffset) - 3;
-
-        _buffer[_startOffset] = (byte) 'b';
-        _buffer[_startOffset + 1] = (byte) (length >> 8);
-        _buffer[_startOffset + 2] = (byte) (length);
-
-        Hessian2Output.this.flush();
-
-        _startOffset = _offset;
-        _offset += 3;
-      }
-
-      _buffer[_offset++] = (byte) ch;
-    }
-
-    @Override
-    public void write(byte []buffer, int offset, int length)
-      throws IOException
-    {
-      while (length > 0) {
-        int sublen = SIZE - _offset;
-
-        if (length < sublen)
-          sublen = length;
-
-        if (sublen > 0) {
-          System.arraycopy(buffer, offset, _buffer, _offset, sublen);
-          _offset += sublen;
-        }
-
-        length -= sublen;
-        offset += sublen;
-
-        if (SIZE <= _offset) {
-          int chunkLength = (_offset - _startOffset) - 3;
-
-          _buffer[_startOffset] = (byte) 'b';
-          _buffer[_startOffset + 1] = (byte) (chunkLength >> 8);
-          _buffer[_startOffset + 2] = (byte) (chunkLength);
-
-          Hessian2Output.this.flush();
-
-          _startOffset = _offset;
-          _offset += 3;
-        }
-      }
-    }
-
-    @Override
-    public void close()
-      throws IOException
-    {
-      int startOffset = _startOffset;
-      _startOffset = -1;
-
-      if (startOffset < 0)
-        return;
-
-      int length = (_offset - startOffset) - 3;
-
-      _buffer[startOffset] = (byte) 'B';
-      _buffer[startOffset + 1] = (byte) (length >> 8);
-      _buffer[startOffset + 2] = (byte) (length);
-
-      Hessian2Output.this.flush();
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/Hessian2StreamingInput.java src/com/caucho/hessian/io/Hessian2StreamingInput.java
deleted file mode 100644
index ca40553..0000000
--- src/com/caucho/hessian/io/Hessian2StreamingInput.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Output stream for Hessian 2 streaming requests.
- */
-public class Hessian2StreamingInput
-{
-  private Hessian2Input _in;
-  
-  /**
-   * Creates a new Hessian input stream, initialized with an
-   * underlying input stream.
-   *
-   * @param is the underlying output stream.
-   */
-  public Hessian2StreamingInput(InputStream is)
-  {
-    _in = new Hessian2Input(new StreamingInputStream(is));
-  }
-
-  /**
-   * Read the next object
-   */
-  public Object readObject()
-    throws IOException
-  {
-    return _in.readStreamingObject();
-  }
-
-  /**
-   * Close the output.
-   */
-  public void close()
-    throws IOException
-  {
-    _in.close();
-  }
-
-  static class StreamingInputStream extends InputStream {
-    private InputStream _is;
-    private int _length;
-
-    StreamingInputStream(InputStream is)
-    {
-      _is = is;
-    }
-
-    public int read()
-      throws IOException
-    {
-      InputStream is = _is;
-      
-      while (_length == 0) {
-	int code = is.read();
-
-	if (code < 0)
-	  return -1;
-	else if (code != 'p' && code != 'P')
-	  throw new HessianProtocolException("expected streaming packet at 0x"
-					     + Integer.toHexString(code & 0xff));
-
-	int d1 = is.read();
-	int d2 = is.read();
-
-	if (d2 < 0)
-	  return -1;
-	
-	_length = (d1 << 8) + d2;
-      }
-
-      _length--;
-      return is.read();
-    }
-
-    public int read(byte []buffer, int offset, int length)
-      throws IOException
-    {
-      InputStream is = _is;
-      
-      while (_length == 0) {
-	int code = is.read();
-
-	if (code < 0)
-	  return -1;
-	else if (code != 'p' && code != 'P') {
-	  throw new HessianProtocolException("expected streaming packet at 0x"
-					     + Integer.toHexString(code & 0xff)
-					     + " (" + (char) code + ")");
-	}
-
-	int d1 = is.read();
-	int d2 = is.read();
-
-	if (d2 < 0)
-	  return -1;
-	
-	_length = (d1 << 8) + d2;
-      }
-
-      int sublen = _length;
-      if (length < sublen)
-	sublen = length;
-
-      sublen = is.read(buffer, offset, sublen);
-
-      if (sublen < 0)
-	return -1;
-
-      _length -= sublen;
-
-      return sublen;
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/Hessian2StreamingOutput.java src/com/caucho/hessian/io/Hessian2StreamingOutput.java
deleted file mode 100644
index eae58cd..0000000
--- src/com/caucho/hessian/io/Hessian2StreamingOutput.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.HashMap;
-
-/**
- * Output stream for Hessian 2 streaming requests.
- */
-public class Hessian2StreamingOutput
-{
-  private Hessian2Output _out;
-  
-  /**
-   * Creates a new Hessian output stream, initialized with an
-   * underlying output stream.
-   *
-   * @param os the underlying output stream.
-   */
-  public Hessian2StreamingOutput(OutputStream os)
-  {
-    _out = new Hessian2Output(os);
-  }
-  
-  public void setCloseStreamOnClose(boolean isClose)
-  {
-    _out.setCloseStreamOnClose(isClose);
-  }
-  
-  public boolean isCloseStreamOnClose()
-  {
-    return _out.isCloseStreamOnClose();
-  }
-
-  /**
-   * Writes any object to the output stream.
-   */
-  public void writeObject(Object object)
-    throws IOException
-  {
-    _out.writeStreamingObject(object);
-  }
-
-  /**
-   * Flushes the output.
-   */
-  public void flush()
-    throws IOException
-  {
-    _out.flush();
-  }
-
-  /**
-   * Close the output.
-   */
-  public void close()
-    throws IOException
-  {
-    _out.close();
-  }
-}
diff --git src/com/caucho/hessian/io/HessianDebugInputStream.java src/com/caucho/hessian/io/HessianDebugInputStream.java
deleted file mode 100644
index d2504e5..0000000
--- src/com/caucho/hessian/io/HessianDebugInputStream.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * Debugging input stream for Hessian requests.
- */
-public class HessianDebugInputStream extends InputStream
-{
-  private InputStream _is;
-  
-  private HessianDebugState _state;
-  
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianDebugInputStream(InputStream is, PrintWriter dbg)
-  {
-    _is = is;
-
-    if (dbg == null)
-      dbg = new PrintWriter(System.out);
-
-    _state = new HessianDebugState(dbg);
-  }
-  
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianDebugInputStream(InputStream is, Logger log, Level level)
-  {
-    this(is, new PrintWriter(new LogWriter(log, level)));
-  }
-
-  /**
-   * Reads a character.
-   */
-  public int read()
-    throws IOException
-  {
-    int ch;
-
-    InputStream is = _is;
-
-    if (is == null)
-      return -1;
-    else {
-      ch = is.read();
-    }
-
-    //Log.d("Hessian",(int)ch);
-    _state.next(ch);
-
-    return ch;
-  }
-
-  /**
-   * closes the stream.
-   */
-  public void close()
-    throws IOException
-  {
-    InputStream is = _is;
-    _is = null;
-
-    if (is != null)
-      is.close();
-    
-    _state.println();
-  }
-
-  static class LogWriter extends Writer {
-    private Logger _log;
-    private Level _level;
-    private StringBuilder _sb = new StringBuilder();
-
-    LogWriter(Logger log, Level level)
-    {
-      _log = log;
-      _level = level;
-    }
-
-    public void write(char ch)
-    {
-      if (ch == '\n' && _sb.length() > 0) {
-	_log.log(_level, _sb.toString());
-	_sb.setLength(0);
-      }
-      else
-	_sb.append((char) ch);
-    }
-
-    public void write(char []buffer, int offset, int length)
-    {
-      for (int i = 0; i < length; i++) {
-	char ch = buffer[offset + i];
-	
-	if (ch == '\n' && _sb.length() > 0) {
-	  _log.log(_level, _sb.toString());
-	  _sb.setLength(0);
-	}
-	else
-	  _sb.append((char) ch);
-      }
-    }
-
-    public void flush()
-    {
-    }
-
-    public void close()
-    {
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/HessianDebugOutputStream.java src/com/caucho/hessian/io/HessianDebugOutputStream.java
deleted file mode 100644
index 04b9f6d..0000000
--- src/com/caucho/hessian/io/HessianDebugOutputStream.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
-import java.io.PrintWriter;
-
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/**
- * Debugging output stream for Hessian requests.
- */
-public class HessianDebugOutputStream extends OutputStream
-{
-  private OutputStream _os;
-  
-  private HessianDebugState _state;
-  
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianDebugOutputStream(OutputStream os, PrintWriter dbg)
-  {
-    _os = os;
-
-    _state = new HessianDebugState(dbg);
-  }
-  
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianDebugOutputStream(OutputStream os, Logger log, Level level)
-  {
-    this(os, new PrintWriter(new LogWriter(log, level)));
-  }
-
-  /**
-   * Writes a character.
-   */
-  public void write(int ch)
-    throws IOException
-  {
-    ch = ch & 0xff;
-    
-    _os.write(ch);
-
-    _state.next(ch);
-  }
-
-  public void flush()
-    throws IOException
-  {
-    _os.flush();
-  }
-
-  /**
-   * closes the stream.
-   */
-  public void close()
-    throws IOException
-  {
-    OutputStream os = _os;
-    _os = null;
-
-    if (os != null)
-      os.close();
-
-    _state.println();
-  }
-
-  static class LogWriter extends Writer {
-    private Logger _log;
-    private Level _level;
-    private StringBuilder _sb = new StringBuilder();
-
-    LogWriter(Logger log, Level level)
-    {
-      _log = log;
-      _level = level;
-    }
-
-    public void write(char ch)
-    {
-      if (ch == '\n' && _sb.length() > 0) {
-	_log.log(_level, _sb.toString());
-	_sb.setLength(0);
-      }
-      else
-	_sb.append((char) ch);
-    }
-
-    public void write(char []buffer, int offset, int length)
-    {
-      for (int i = 0; i < length; i++) {
-	char ch = buffer[offset + i];
-	
-	if (ch == '\n' && _sb.length() > 0) {
-	  _log.log(_level, _sb.toString());
-	  _sb.setLength(0);
-	}
-	else
-	  _sb.append((char) ch);
-      }
-    }
-
-    public void flush()
-    {
-    }
-
-    public void close()
-    {
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/HessianDebugState.java src/com/caucho/hessian/io/HessianDebugState.java
deleted file mode 100644
index ff6bde8..0000000
--- src/com/caucho/hessian/io/HessianDebugState.java
+++ /dev/null
@@ -1,1771 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * Debugging input stream for Hessian requests.
- */
-public class HessianDebugState implements Hessian2Constants
-{
-  private PrintWriter _dbg;
-
-  private State _state;
-  private ArrayList<State> _stateStack = new ArrayList<State>();
-
-  private ArrayList<ObjectDef> _objectDefList
-    = new ArrayList<ObjectDef>();
-
-  private ArrayList<String> _typeDefList
-    = new ArrayList<String>();
-
-  private int _refId;
-  private boolean _isNewline = true;
-  private boolean _isObject = false;
-  private int _column;
-  
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianDebugState(PrintWriter dbg)
-  {
-    _dbg = dbg;
-
-    _state = new InitialState();
-  }
-
-  /**
-   * Reads a character.
-   */
-  public void next(int ch)
-    throws IOException
-  {
-    _state = _state.next(ch);
-  }
-
-  void pushStack(State state)
-  {
-    _stateStack.add(state);
-  }
-
-  State popStack()
-  {
-    return _stateStack.remove(_stateStack.size() - 1);
-  }
-
-  void println()
-  {
-    if (! _isNewline) {
-      _dbg.println();
-      _dbg.flush();
-    }
-
-    _isNewline = true;
-    _column = 0;
-  }
-
-  abstract class State {
-    State _next;
-
-    State()
-    {
-    }
-
-    State(State next)
-    {
-      _next = next;
-    }
-    
-    abstract State next(int ch);
-
-    boolean isShift(Object value)
-    {
-      return false;
-    }
-
-    State shift(Object value)
-    {
-      return this;
-    }
-
-    int depth()
-    {
-      if (_next != null)
-	return _next.depth();
-      else
-	return 0;
-    }
-
-    void printIndent(int depth)
-    {
-      if (_isNewline) {
-	for (int i = _column; i < depth() + depth; i++) {
-	  _dbg.print(" ");
-	  _column++;
-	}
-      }
-    }
-
-    void print(String string)
-    {
-      print(0, string);
-    }
-
-    void print(int depth, String string)
-    {
-      printIndent(depth);
-      
-      _dbg.print(string);
-      _isNewline = false;
-      _isObject = false;
-
-      int p = string.lastIndexOf('\n');
-      if (p > 0)
-	_column = string.length() - p - 1;
-      else
-	_column += string.length();
-    }
-
-    void println(String string)
-    {
-      println(0, string);
-    }
-
-    void println(int depth, String string)
-    {
-      printIndent(depth);
-
-      _dbg.println(string);
-      _dbg.flush();
-      _isNewline = true;
-      _isObject = false;
-      _column = 0;
-    }
-
-    void println()
-    {
-      if (! _isNewline) {
-	_dbg.println();
-	_dbg.flush();
-      }
-
-      _isNewline = true;
-      _isObject = false;
-      _column = 0;
-    }
-
-    void printObject(String string)
-    {
-      if (_isObject)
-	println();
-      
-      printIndent(0);
-
-      _dbg.print(string);
-      _dbg.flush();
-
-      _column += string.length();
-
-      _isNewline = false;
-      _isObject = true;
-    }
-    
-    protected State nextObject(int ch)
-    {
-      switch (ch) {
-      case -1:
-	println();
-	return this;
-	
-      case 'N':
-	if (isShift(null))
-	  return shift(null);
-	else {
-	  printObject("null");
-	  return this;
-	}
-	
-      case 'T':
-	if (isShift(Boolean.TRUE))
-	  return shift(Boolean.TRUE);
-	else {
-	  printObject("true");
-	  return this;
-	}
-	
-      case 'F':
-	if (isShift(Boolean.FALSE))
-	  return shift(Boolean.FALSE);
-	else {
-	  printObject("false");
-	  return this;
-	}
-
-      case 0x80: case 0x81: case 0x82: case 0x83: 
-      case 0x84: case 0x85: case 0x86: case 0x87: 
-      case 0x88: case 0x89: case 0x8a: case 0x8b: 
-      case 0x8c: case 0x8d: case 0x8e: case 0x8f: 
-
-      case 0x90: case 0x91: case 0x92: case 0x93: 
-      case 0x94: case 0x95: case 0x96: case 0x97: 
-      case 0x98: case 0x99: case 0x9a: case 0x9b: 
-      case 0x9c: case 0x9d: case 0x9e: case 0x9f: 
-
-      case 0xa0: case 0xa1: case 0xa2: case 0xa3: 
-      case 0xa4: case 0xa5: case 0xa6: case 0xa7: 
-      case 0xa8: case 0xa9: case 0xaa: case 0xab: 
-      case 0xac: case 0xad: case 0xae: case 0xaf: 
-
-      case 0xb0: case 0xb1: case 0xb2: case 0xb3: 
-      case 0xb4: case 0xb5: case 0xb6: case 0xb7: 
-      case 0xb8: case 0xb9: case 0xba: case 0xbb: 
-      case 0xbc: case 0xbd: case 0xbe: case 0xbf:
-	{
-	  Integer value = new Integer(ch - 0x90);
-	  
-	  if (isShift(value))
-	    return shift(value);
-	  else {
-	    printObject(value.toString());
-	    return this;
-	  }
-	}
-
-      case 0xc0: case 0xc1: case 0xc2: case 0xc3: 
-      case 0xc4: case 0xc5: case 0xc6: case 0xc7: 
-      case 0xc8: case 0xc9: case 0xca: case 0xcb: 
-      case 0xcc: case 0xcd: case 0xce: case 0xcf:
-	return new IntegerState(this, "int", ch - 0xc8, 3);
-
-      case 0xd0: case 0xd1: case 0xd2: case 0xd3: 
-      case 0xd4: case 0xd5: case 0xd6: case 0xd7: 
-	return new IntegerState(this, "int", ch - 0xd4, 2);
-
-      case 'I':
-	return new IntegerState(this, "int");
-	
-      case 0xd8: case 0xd9: case 0xda: case 0xdb: 
-      case 0xdc: case 0xdd: case 0xde: case 0xdf: 
-      case 0xe0: case 0xe1: case 0xe2: case 0xe3: 
-      case 0xe4: case 0xe5: case 0xe6: case 0xe7: 
-      case 0xe8: case 0xe9: case 0xea: case 0xeb: 
-      case 0xec: case 0xed: case 0xee: case 0xef:
-	{
-	  Long value = new Long(ch - 0xe0);
-	  
-	  if (isShift(value))
-	    return shift(value);
-	  else {
-	    printObject(value.toString() + "L");
-	    return this;
-	  }
-	}
-	
-      case 0xf0: case 0xf1: case 0xf2: case 0xf3: 
-      case 0xf4: case 0xf5: case 0xf6: case 0xf7: 
-      case 0xf8: case 0xf9: case 0xfa: case 0xfb: 
-      case 0xfc: case 0xfd: case 0xfe: case 0xff:
-	return new LongState(this, "long", ch - 0xf8, 7);
-	
-      case 0x38: case 0x39: case 0x3a: case 0x3b: 
-      case 0x3c: case 0x3d: case 0x3e: case 0x3f:
-	return new LongState(this, "long", ch - 0x3c, 6);
-	
-      case 0x77:
-	return new LongState(this, "long", 0, 4);
-
-      case 'L':
-	return new LongState(this, "long");
-
-      case 0x67: case 0x68:
-	{
-	  Double value = new Double(ch - 0x67);
-	  
-	  if (isShift(value))
-	    return shift(value);
-	  else {
-	    printObject(value.toString());
-	    return this;
-	  }
-	}
-
-      case 0x69:
-	return new DoubleIntegerState(this, 3);
-
-      case 0x6a:
-	return new DoubleIntegerState(this, 2);
-
-      case 0x6b:
-	return new FloatState(this);
-	
-      case 'D':
-	return new DoubleState(this);
-
-      case 0x4a:
-	return new RefState(this, "Ref", 0, 3);
-
-      case 0x4b:
-	return new RefState(this, "Ref", 0, 2);
-
-      case 'R':
-	return new RefState(this, "Ref");
-
-      case 'r':
-	return new RemoteState(this);
-
-      case 'd':
-	return new DateState(this);
-
-      case 0x00:
-	{
-	  String value = "\"\"";
-	  
-	  if (isShift(value))
-	    return shift(value);
-	  else {
-	    printObject(value.toString());
-	    return this;
-	  }
-	}
-
-      case 0x01: case 0x02: case 0x03:
-      case 0x04: case 0x05: case 0x06: case 0x07:
-      case 0x08: case 0x09: case 0x0a: case 0x0b:
-      case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-	
-      case 0x10: case 0x11: case 0x12: case 0x13:
-      case 0x14: case 0x15: case 0x16: case 0x17:
-      case 0x18: case 0x19: case 0x1a: case 0x1b:
-      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
-	return new StringState(this, 'S', ch);
-
-      case 'S': case 'X':
-	return new StringState(this, 'S', true);
-
-      case 's': case 'x':
-	return new StringState(this, 'S', false);
-
-      case 0x20:
-	{
-	  String value = "binary(0)";
-	  
-	  if (isShift(value))
-	    return shift(value);
-	  else {
-	    printObject(value.toString());
-	    return this;
-	  }
-	}
-
-      case 0x21: case 0x22: case 0x23:
-      case 0x24: case 0x25: case 0x26: case 0x27:
-      case 0x28: case 0x29: case 0x2a: case 0x2b:
-      case 0x2c: case 0x2d: case 0x2e: case 0x2f:
-	return new BinaryState(this, 'B', ch - 0x20);
-
-      case 'B':
-	return new BinaryState(this, 'B', true);
-
-      case 'b':
-	return new BinaryState(this, 'B', false);
-
-      case 'M':
-	return new MapState(this, _refId++);
-
-      case 'V':
-	return new ListState(this, _refId++);
-
-      case 'v':
-	return new CompactListState(this, _refId++);
-
-      case 'O':
-	return new ObjectDefState(this);
-
-      case 'o':
-	return new ObjectState(this, _refId++);
-
-      case 'P':
-	return new StreamingState(this, true);
-
-      case 'p':
-	return new StreamingState(this, false);
-	
-      default:
-	return this;
-      }
-    }
-  }
-  
-  class InitialState extends State {
-    State next(int ch)
-    {
-      println();
-      
-      if (ch == 'r') {
-	return new ReplyState(this);
-      }
-      else if (ch == 'c') {
-	return new CallState(this);
-      }
-      else
-	return nextObject(ch);
-    }
-  }
-  
-  class IntegerState extends State {
-    String _typeCode;
-    
-    int _length;
-    int _value;
-
-    IntegerState(State next, String typeCode)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-    }
-
-    IntegerState(State next, String typeCode, int value, int length)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-
-      _value = value;
-      _length = length;
-    }
-
-    State next(int ch)
-    {
-      _value = 256 * _value + (ch & 0xff);
-
-      if (++_length == 4) {
-	Integer value = new Integer(_value);
-	
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value.toString());
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class LongState extends State {
-    String _typeCode;
-    
-    int _length;
-    long _value;
-
-    LongState(State next, String typeCode)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-    }
-
-    LongState(State next, String typeCode, long value, int length)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-
-      _value = value;
-      _length = length;
-    }
-
-    State next(int ch)
-    {
-      _value = 256 * _value + (ch & 0xff);
-
-      if (++_length == 8) {
-	Long value = new Long(_value);
-	
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value.toString() + "L");
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class DoubleIntegerState extends State {
-    int _length;
-    int _value;
-    boolean _isFirst = true;
-
-    DoubleIntegerState(State next, int length)
-    {
-      super(next);
-
-      _length = length;
-    }
-
-    State next(int ch)
-    {
-      if (_isFirst)
-	_value = (byte) ch;
-      else
-	_value = 256 * _value + (ch & 0xff);
-
-      _isFirst = false;
-
-      if (++_length == 4) {
-	Double value = new Double(_value);
-	
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value.toString());
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class RefState extends State {
-    String _typeCode;
-    
-    int _length;
-    int _value;
-
-    RefState(State next, String typeCode)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-    }
-
-    RefState(State next, String typeCode, int value, int length)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-
-      _value = value;
-      _length = length;
-    }
-
-    State next(int ch)
-    {
-      _value = 256 * _value + (ch & 0xff);
-
-      if (++_length == 4) {
-	Integer value = new Integer(_value);
-	
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject("ref(#" + value + ")");
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class DateState extends State {
-    int _length;
-    long _value;
-
-    DateState(State next)
-    {
-      super(next);
-    }
-      
-    
-    State next(int ch)
-    {
-      _value = 256 * _value + (ch & 0xff);
-
-      if (++_length == 8) {
-	java.util.Date value = new java.util.Date(_value);
-
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value.toString());
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class DoubleState extends State {
-    int _length;
-    long _value;
-
-    DoubleState(State next)
-    {
-      super(next);
-    }
-    
-    State next(int ch)
-    {
-      _value = 256 * _value + (ch & 0xff);
-
-      if (++_length == 8) {
-	Double value = Double.longBitsToDouble(_value);
-
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value.toString());
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class FloatState extends State {
-    int _length;
-    int _value;
-
-    FloatState(State next)
-    {
-      super(next);
-    }
-    
-    State next(int ch)
-    {
-      _value = 256 * _value + (ch & 0xff);
-
-      if (++_length == 4) {
-	Double value = (double) Float.intBitsToFloat(_value);
-
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value.toString() + "F");
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class StringState extends State {
-    private static final int TOP = 0;
-    private static final int UTF_2_1 = 1;
-    private static final int UTF_3_1 = 2;
-    private static final int UTF_3_2 = 3;
-
-    char _typeCode;
-    
-    StringBuilder _value = new StringBuilder();
-    int _lengthIndex;
-    int _length;
-    boolean _isLastChunk;
-    
-    int _utfState;
-    char _ch;
-
-    StringState(State next, char typeCode, boolean isLastChunk)
-    {
-      super(next);
-      
-      _typeCode = typeCode;
-      _isLastChunk = isLastChunk;
-    }
-
-    StringState(State next, char typeCode, int length)
-    {
-      super(next);
-      
-      _typeCode = typeCode;
-      _isLastChunk = true;
-      _length = length;
-      _lengthIndex = 2;
-    }
-    
-    State next(int ch)
-    {
-      if (_lengthIndex < 2) {
-	_length = 256 * _length + (ch & 0xff);
-	
-	if (++_lengthIndex == 2 && _length == 0 && _isLastChunk) {
-	  if (_next.isShift(_value.toString()))
-	    return _next.shift(_value.toString());
-	  else {
-	    printObject("\"" + _value + "\"");
-	    return _next;
-	  }
-	}
-	else
-	  return this;
-      }
-      else if (_length == 0) {
-	if (ch == 's' || ch == 'x') {
-	  _isLastChunk = false;
-	  _lengthIndex = 0;
-	  return this;
-	}
-	else if (ch == 'S' || ch == 'X') {
-	  _isLastChunk = true;
-	  _lengthIndex = 0;
-	  return this;
-	}
-	else if (ch == 0x00) {
-	  if (_next.isShift(_value.toString()))
-	    return _next.shift(_value.toString());
-	  else {
-	    printObject("\"" + _value + "\"");
-	    return _next;
-	  }
-	}
-	else if (0x00 <= ch && ch < 0x20) {
-	  _isLastChunk = true;
-	  _lengthIndex = 2;
-	  _length = ch & 0xff;
-	  return this;
-	}
-	else {
-	  println(String.valueOf((char) ch) + ": unexpected character");
-	  return _next;
-	}
-      }
-
-      switch (_utfState) {
-      case TOP:
-	if (ch < 0x80) {
-	  _length--;
-
-	  _value.append((char) ch);
-	}
-	else if (ch < 0xe0) {
-	  _ch = (char) ((ch & 0x1f) << 6);
-	  _utfState = UTF_2_1;
-	}
-	else {
-	  _ch = (char) ((ch & 0xf) << 12);
-	  _utfState = UTF_3_1;
-	}
-	break;
-
-      case UTF_2_1:
-      case UTF_3_2:
-	_ch += ch & 0x3f;
-	_value.append(_ch);
-	_length--;
-	_utfState = TOP;
-	break;
-
-      case UTF_3_1:
-	_ch += (char) ((ch & 0x3f) << 6);
-	_utfState = UTF_3_2;
-	break;
-      }
-
-      if (_length == 0 && _isLastChunk) {
-	if (_next.isShift(_value.toString()))
-	  return _next.shift(_value.toString());
-	else {
-	  printObject("\"" + _value + "\"");
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class BinaryState extends State {
-    char _typeCode;
-    
-    int _totalLength;
-    
-    int _lengthIndex;
-    int _length;
-    boolean _isLastChunk;
-    
-    BinaryState(State next, char typeCode, boolean isLastChunk)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-      _isLastChunk = isLastChunk;
-    }
-
-    BinaryState(State next, char typeCode, int length)
-    {
-      super(next);
-
-      _typeCode = typeCode;
-      _isLastChunk = true;
-      _length = length;
-      _lengthIndex = 2;
-    }
-    
-    State next(int ch)
-    {
-      if (_lengthIndex < 2) {
-	_length = 256 * _length + (ch & 0xff);
-	
-	if (++_lengthIndex == 2 && _length == 0 && _isLastChunk) {
-	  String value = "binary(" + _totalLength + ")";
-	  
-	  if (_next.isShift(value))
-	    return _next.shift(value);
-	  else {
-	    printObject(value);
-	    return _next;
-	  }
-	}
-	else
-	  return this;
-      }
-      else if (_length == 0) {
-	if (ch == 'b') {
-	  _isLastChunk = false;
-	  _lengthIndex = 0;
-	  return this;
-	}
-	else if (ch == 'B') {
-	  _isLastChunk = true;
-	  _lengthIndex = 0;
-	  return this;
-	}
-	else if (ch == 0x20) {
-	  String value = "binary(" + _totalLength + ")";
-	  
-	  if (_next.isShift(value))
-	    return _next.shift(value);
-	  else {
-	    printObject(value);
-	    return _next;
-	  }
-	}
-	else if (0x20 <=ch && ch < 0x30) {
-	  _isLastChunk = true;
-	  _lengthIndex = 2;
-	  _length = (ch & 0xff) - 0x20;
-	  return this;
-	}
-	else {
-	  println(String.valueOf((char) ch) + ": unexpected character");
-	  return _next;
-	}
-      }
-      
-      _length--;
-      _totalLength++;
-
-      if (_length == 0 && _isLastChunk) {
-	String value = "binary(" + _totalLength + ")";
-	
-	if (_next.isShift(value))
-	  return _next.shift(value);
-	else {
-	  printObject(value);
-	  
-	  return _next;
-	}
-      }
-      else
-	return this;
-    }
-  }
-  
-  class MapState extends State {
-    private static final int TYPE = 0;
-    private static final int KEY = 1;
-    private static final int VALUE = 2;
-
-    private int _refId;
-
-    private int _state;
-    private int _valueDepth;
-    private boolean _hasData;
-
-    MapState(State next, int refId)
-    {
-      super(next);
-      
-      _refId = refId;
-      _state = TYPE;
-    }
-
-    @Override
-    boolean isShift(Object value)
-    {
-      return _state == TYPE;
-    }
-
-    @Override
-    State shift(Object type)
-    {
-      if (_state == TYPE) {
-	if (type instanceof String) {
-	  _typeDefList.add((String) type);
-	}
-	else if (type instanceof Integer) {
-	  int iValue = (Integer) type;
-
-	  if (iValue >= 0 && iValue < _typeDefList.size())
-	    type = _typeDefList.get(iValue);
-	}
-	
-	printObject("map " + type + "(#" + _refId + ")");
-
-	_state = VALUE;
-      
-	return this;
-      }
-      else
-	throw new IllegalStateException();
-    }
-
-    @Override
-    int depth()
-    {
-      if (_state == TYPE)
-	return _next.depth();
-      else if (_state == KEY)
-	return _next.depth() + 2;
-      else
-	return _valueDepth;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case TYPE:
-	if (ch == 't') {
-	  return new StringState(this, 't', true);
-	}
-	else if (ch == 0x75) {
-	  return new IndirectState(this);
-	}
-	else if (ch == 'z') {
-	  printObject("map (#" + _refId + ")");
-	  return _next;
-	}
-	else {
-	  printObject("map (#" + _refId + ")");
-	  
-	  _state = KEY;
-	  
-	  return nextObject(ch);
-	}
-	
-      case VALUE:
-	if (ch == 'z') {
-	  if (_hasData)
-	    println();
-	  
-	  return _next;
-	}
-	else {
-	  if (_hasData)
-	    println();
-
-	  _hasData = true;
-	  _state = KEY;
-	  
-	  return nextObject(ch);
-	}
-	
-      case KEY:
-	print(" => ");
-	_isObject = false;
-	_valueDepth = _column;
-
-	_state = VALUE;
-	
-	return nextObject(ch);
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class ObjectDefState extends State {
-    private static final int TYPE = 1;
-    private static final int COUNT = 2;
-    private static final int FIELD = 3;
-    private static final int COMPLETE = 4;
-
-    private int _refId;
-
-    private int _state;
-    private boolean _hasData;
-    private int _count;
-
-    private String _type;
-    private ArrayList<String> _fields = new ArrayList<String>();
-
-    ObjectDefState(State next)
-    {
-      super(next);
-      
-      _state = TYPE;
-    }
-
-    @Override
-    boolean isShift(Object value)
-    {
-      return true;
-    }
-
-    @Override
-    State shift(Object object)
-    {
-      if (_state == TYPE) {
-	_type = (String) object;
-
-	print("/* defun " + _type + " [");
-
-	_objectDefList.add(new ObjectDef(_type, _fields));
-
-	_state = COUNT;
-      }
-      else if (_state == COUNT) {
-	_count = (Integer) object;
-
-	_state = FIELD;
-      }
-      else if (_state == FIELD) {
-	String field = (String) object;
-
-	_count--;
-
-	_fields.add(field);
-
-	if (_fields.size() == 1)
-	  print(field);
-	else
-	  print(", " + field);
-      }
-      else {
-	throw new UnsupportedOperationException();
-      }
-
-      return this;
-    }
-
-    @Override
-    int depth()
-    {
-      if (_state <= TYPE)
-	return _next.depth();
-      else
-	return _next.depth() + 2;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case TYPE:
-	return nextObject(ch);
-	
-      case COUNT:
-	return nextObject(ch);
-	
-      case FIELD:
-	if (_count == 0) {
-	  println("] */");
-	  _next.printIndent(0);
-
-	  return _next.nextObject(ch);
-	}
-	else
-	  return nextObject(ch);
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class ObjectState extends State {
-    private static final int TYPE = 0;
-    private static final int FIELD = 1;
-
-    private int _refId;
-
-    private int _state;
-    private ObjectDef _def;
-    private int _count;
-    private int _fieldDepth;
-
-    ObjectState(State next, int refId)
-    {
-      super(next);
-
-      _refId = refId;
-      _state = TYPE;
-    }
-
-    @Override
-    boolean isShift(Object value)
-    {
-      if (_state == TYPE)
-	return true;
-      else
-	return false;
-    }
-
-    @Override
-    State shift(Object object)
-    {
-      if (_state == TYPE) {
-	int def = (Integer) object;
-
-	_def = _objectDefList.get(def);
-
-	println("object " + _def.getType() + " (#" + _refId + ")");
-
-	_state = FIELD;
-
-	if (_def.getFields().size() == 0)
-	  return _next;
-      }
-
-      return this;
-    }
-
-    @Override
-    int depth()
-    {
-      if (_state <= TYPE)
-	return _next.depth();
-      else
-	return _fieldDepth;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case TYPE:
-	return nextObject(ch);
-	
-      case FIELD:
-	if (_def.getFields().size() <= _count)
-	  return _next.next(ch);
-
-	_fieldDepth = _next.depth() + 2;
-	println();
-	print(_def.getFields().get(_count++) + ": ");
-
-	_fieldDepth = _column;
-
-	_isObject = false;
-	return nextObject(ch);
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class ListState extends State {
-    private static final int TYPE = 0;
-    private static final int LENGTH = 1;
-    private static final int VALUE = 2;
-
-    private int _refId;
-
-    private int _state;
-    private boolean _hasData;
-    private int _count;
-    private int _valueDepth;
-
-    ListState(State next, int refId)
-    {
-      super(next);
-      
-      _refId = refId;
-      _state = TYPE;
-    }
-
-    @Override
-    boolean isShift(Object value)
-    {
-      return _state == TYPE || _state == LENGTH;
-    }
-
-    @Override
-    State shift(Object object)
-    {
-      if (_state == TYPE) {
-	Object type = object;
-	
-	if (type instanceof String) {
-	  _typeDefList.add((String) type);
-	}
-	else if (object instanceof Integer) {
-	  int index = (Integer) object;
-
-	  if (index >= 0 && index < _typeDefList.size())
-	    type = _typeDefList.get(index);
-	}
-	
-	printObject("list " + type + "(#" + _refId + ")");
-      
-	_state = LENGTH;
-      
-	return this;
-      }
-      else if (_state == LENGTH) {
-	_state = VALUE;
-
-	return this;
-      }
-      else
-	return this;
-    }
-
-    @Override
-    int depth()
-    {
-      if (_state <= LENGTH)
-	return _next.depth();
-      else if (_state == VALUE)
-	return _valueDepth;
-      else
-	return _next.depth() + 2;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case TYPE:
-	if (ch == 't') {
-	  return new StringState(this, 't', true);
-	}
-	else if (ch == TYPE_REF) {
-	  return new IndirectState(this);
-	}
-	else if (ch == 'l') {
-	  printObject("list (#" + _refId + ")");
-	  _state = LENGTH;
-	  
-	  return new IntegerState(this, "length");
-	}
-	else if (ch == LENGTH_BYTE) {
-	  printObject("list (#" + _refId + ")");
-	  _state = LENGTH;
-	  
-	  return new IntegerState(this, "length", 0, 3);
-	}
-	else if (ch == 'z') {
-	  printObject("list (#" + _refId + ")");
-	  return _next;
-	}
-	else {
-	  printObject("list (#" + _refId + ")");
-	  
-	  _state = VALUE;
-
-	  _valueDepth = _next.depth() + 2;
-	  println();
-	  printObject(_count++ + ": ");
-	  _valueDepth = _column;
-	  _isObject = false;
-	  
-	  return nextObject(ch);
-	}
-	
-      case LENGTH:
-	if (ch == 'z') {
-	  return _next;
-	}
-	else if (ch == 'l') {
-	  return new IntegerState(this, "length");
-	}
-	else if (ch == LENGTH_BYTE) {
-	  return new IntegerState(this, "length", 0, 3);
-	}
-	else {
-	  _state = VALUE;
-	  
-	  _valueDepth = _next.depth() + 2;
-	  println();
-	  printObject(_count++ + ": ");
-	  _valueDepth = _column;
-	  _isObject = false;
-	  
-	  return nextObject(ch);
-	}
-	
-      case VALUE:
-	if (ch == 'z') {
-	  if (_count > 0)
-	    println();
-	  
-	  return _next;
-	}
-	else {
-	  _valueDepth = _next.depth() + 2;
-	  println();
-	  printObject(_count++ + ": ");
-	  _valueDepth = _column;
-	  _isObject = false;
-	  
-	  return nextObject(ch);
-	}
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class CompactListState extends State {
-    private static final int TYPE = 0;
-    private static final int LENGTH = 1;
-    private static final int VALUE = 2;
-
-    private int _refId;
-
-    private int _state;
-    private boolean _hasData;
-    private int _length;
-    private int _count;
-    private int _valueDepth;
-
-    CompactListState(State next, int refId)
-    {
-      super(next);
-      
-      _refId = refId;
-      _state = TYPE;
-    }
-
-    @Override
-    boolean isShift(Object value)
-    {
-      return _state == TYPE || _state == LENGTH;
-    }
-
-    @Override
-    State shift(Object object)
-    {
-      if (_state == TYPE) {
-	Object type = object;
-	
-	if (object instanceof Integer) {
-	  int index = (Integer) object;
-
-	  if (index >= 0 && index < _typeDefList.size())
-	    type = _typeDefList.get(index);
-	}
-	
-	printObject("list " + type + "(#" + _refId + ")");
-      
-	_state = LENGTH;
-      
-	return this;
-      }
-      else if (_state == LENGTH) {
-	_length = (Integer) object;
-	
-	_state = VALUE;
-
-	if (_length == 0)
-	  return _next;
-	else
-	  return this;
-      }
-      else
-	return this;
-    }
-
-    @Override
-    int depth()
-    {
-      if (_state <= LENGTH)
-	return _next.depth();
-      else if (_state == VALUE)
-	return _valueDepth;
-      else
-	return _next.depth() + 2;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case TYPE:
-	return nextObject(ch);
-	
-      case LENGTH:
-	return nextObject(ch);
-	
-      case VALUE:
-	if (_length <= _count)
-	  return _next.next(ch);
-	else {
-	  _valueDepth = _next.depth() + 2;
-	  println();
-	  printObject(_count++ + ": ");
-	  _valueDepth = _column;
-	  _isObject = false;
-	  
-	  return nextObject(ch);
-	}
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class CallState extends State {
-    private static final int MAJOR = 0;
-    private static final int MINOR = 1;
-    private static final int HEADER = 2;
-    private static final int METHOD = 3;
-    private static final int VALUE = 4;
-    private static final int ARG = 5;
-
-    private int _state;
-    private int _major;
-    private int _minor;
-
-    CallState(State next)
-    {
-      super(next);
-    }
-
-    int depth()
-    {
-      return _next.depth() + 2;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case MAJOR:
-	_major = ch;
-	_state = MINOR;
-	return this;
-	
-      case MINOR:
-	_minor = ch;
-	_state = HEADER;
-	println(-2, "call " + _major + "." + _minor);
-	return this;
-	
-      case HEADER:
-	if (ch == 'H') {
-	  println();
-	  print("header ");
-	  _isObject = false;
-	  _state = VALUE;
-	  return new StringState(this, 'H', true);
-	}
- 	else if (ch == 'm') {
-	  println();
-	  print("method ");
-	  _isObject = false;
-	  _state = ARG;
-	  return new StringState(this, 'm', true);
-	}
-	else {
-	  println((char) ch + ": unexpected char");
-	  return popStack();
-	}
-	
-      case VALUE:
-	print(" => ");
-	_isObject = false;
-	_state = HEADER;
-	return nextObject(ch);
-	
-      case ARG:
-	if (ch == 'z')
-	  return _next;
-	else
-	  return nextObject(ch);
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class ReplyState extends State {
-    private static final int MAJOR = 0;
-    private static final int MINOR = 1;
-    private static final int HEADER = 2;
-    private static final int VALUE = 3;
-    private static final int END = 4;
-
-    private int _state;
-    private int _major;
-    private int _minor;
-
-    ReplyState(State next)
-    {
-      _next = next;
-    }
-
-    int depth()
-    {
-      return _next.depth() + 2;
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case MAJOR:
-	if (ch == 't' || ch == 'S')
-	  return new RemoteState(this).next(ch);
-	
-	_major = ch;
-	_state = MINOR;
-	return this;
-	
-      case MINOR:
-	_minor = ch;
-	_state = HEADER;
-	println(-2, "reply " + _major + "." + _minor);
-	return this;
-	
-      case HEADER:
-	if (ch == 'H') {
-	  _state = VALUE;
-	  return new StringState(this, 'H', true);
-	}
-	else if (ch == 'f') {
-	  print("fault ");
-	  _isObject = false;
-	  _state = END;
-	  return new MapState(this, 0);
-	}
- 	else {
-	  _state = END;
-	  return nextObject(ch);
-	}
-	
-      case VALUE:
-	_state = HEADER;
-	return nextObject(ch);
-	
-      case END:
-	println();
-	if (ch == 'z') {
-	  return _next;
-	}
-	else
-	  return _next.next(ch);
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class IndirectState extends State {
-    IndirectState(State next)
-    {
-      super(next);
-    }
-
-    boolean isShift(Object object)
-    {
-      return _next.isShift(object);
-    }
-
-    State shift(Object object)
-    {
-      return _next.shift(object);
-    }
-    
-    State next(int ch)
-    {
-      return nextObject(ch);
-    }
-  }
-  
-  class RemoteState extends State {
-    private static final int TYPE = 0;
-    private static final int VALUE = 1;
-    private static final int END = 2;
-
-    private int _state;
-    private int _major;
-    private int _minor;
-
-    RemoteState(State next)
-    {
-      super(next);
-    }
-    
-    State next(int ch)
-    {
-      switch (_state) {
-      case TYPE:
-	println(-1, "remote");
-	if (ch == 't') {
-	  _state = VALUE;
-	  return new StringState(this, 't', false);
-	}
-	else {
-	  _state = END;
-	  return nextObject(ch);
-	}
-
-      case VALUE:
-	_state = END;
-	return _next.nextObject(ch);
-
-      case END:
-	return _next.next(ch);
-
-      default:
-	throw new IllegalStateException();
-      }
-    }
-  }
-  
-  class StreamingState extends State {
-    private int _digit;
-    private int _length;
-    private boolean _isLast;
-    private boolean _isFirst = true;
-
-    private State _childState;
-
-    StreamingState(State next, boolean isLast)
-    {
-      super(next);
-
-      _isLast = isLast;
-      _childState = new InitialState();
-    }
-    
-    State next(int ch)
-    {
-      if (_digit < 2) {
-	_length = 256 * _length + ch;
-	_digit++;
-
-	if (_digit == 2 && _length == 0 && _isLast) {
-	  _refId = 0;
-	  return _next;
-	}
-	else {
-	  if (_digit == 2)
-	    println(-1, "packet-start(" + _length + ")");
-	  
-	  return this;
-	}
-      }
-      else if (_length == 0) {
-	_isLast = (ch == 'P');
-	_digit = 0;
-	
-	return this;
-      }
-
-      _childState = _childState.next(ch);
-
-      _length--;
-
-      if (_length == 0 && _isLast) {
-	println(-1, "");
-	println(-1, "packet-end");
-	_refId = 0;
-	return _next;
-      }
-      else
-	return this;
-    }
-  }
-
-  static class ObjectDef {
-    private String _type;
-    private ArrayList<String> _fields;
-
-    ObjectDef(String type, ArrayList<String> fields)
-    {
-      _type = type;
-      _fields = fields;
-    }
-
-    String getType()
-    {
-      return _type;
-    }
-
-    ArrayList<String> getFields()
-    {
-      return _fields;
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/HessianEnvelope.java src/com/caucho/hessian/io/HessianEnvelope.java
deleted file mode 100644
index dfee9e7..0000000
--- src/com/caucho/hessian/io/HessianEnvelope.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.*;
-
-/**
- * Factory class for wrapping and unwrapping hessian streams.
- */
-abstract public class HessianEnvelope {
-  /**
-   * Wrap the Hessian output stream in an envelope.
-   */
-  abstract public Hessian2Output wrap(Hessian2Output out)
-    throws IOException;
-
-  /**
-   * Unwrap the Hessian input stream with this envelope.  It is an
-   * error if the actual envelope does not match the expected envelope
-   * class.
-   */
-  abstract public Hessian2Input unwrap(Hessian2Input in)
-    throws IOException;
-
-  /**
-   * Unwrap the envelope after having read the envelope code ('E') and
-   * the envelope method.  Called by the EnvelopeFactory for dynamic
-   * reading of the envelopes.
-   */
-  abstract public Hessian2Input unwrapHeaders(Hessian2Input in)
-    throws IOException;
-}
diff --git src/com/caucho/hessian/io/HessianFieldException.java src/com/caucho/hessian/io/HessianFieldException.java
deleted file mode 100644
index db513d0..0000000
--- src/com/caucho/hessian/io/HessianFieldException.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Exception during field reading.
- */
-public class HessianFieldException extends HessianProtocolException {
-  /**
-   * Zero-arg constructor.
-   */
-  public HessianFieldException()
-  {
-  }
-  
-  /**
-   * Create the exception.
-   */
-  public HessianFieldException(String message)
-  {
-    super(message);
-  }
-  
-  /**
-   * Create the exception.
-   */
-  public HessianFieldException(String message, Throwable cause)
-  {
-    super(message, cause);
-  }
-  
-  /**
-   * Create the exception.
-   */
-  public HessianFieldException(Throwable cause)
-  {
-    super(cause);
-  }
-}
diff --git src/com/caucho/hessian/io/HessianHandle.java src/com/caucho/hessian/io/HessianHandle.java
deleted file mode 100644
index 7e50420..0000000
--- src/com/caucho/hessian/io/HessianHandle.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-/**
- * Marks a type as a handle
- */
-public interface HessianHandle {
-}
diff --git src/com/caucho/hessian/io/HessianInput.java src/com/caucho/hessian/io/HessianInput.java
deleted file mode 100644
index a449622..0000000
--- src/com/caucho/hessian/io/HessianInput.java
+++ /dev/null
@@ -1,1700 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-
-/**
- * Input stream for Hessian requests.
- *
- * <p>HessianInput is unbuffered, so any client needs to provide
- * its own buffering.
- *
- * <pre>
- * InputStream is = ...; // from http connection
- * HessianInput in = new HessianInput(is);
- * String value;
- *
- * in.startReply();         // read reply header
- * value = in.readString(); // read string value
- * in.completeReply();      // read reply footer
- * </pre>
- */
-public class HessianInput extends AbstractHessianInput {
-  private static int END_OF_DATA = -2;
-
-  private static Field _detailMessageField;
-  
-  // factory for deserializing objects in the input stream
-  protected SerializerFactory _serializerFactory;
-  
-  protected ArrayList _refs;
-  
-  // the underlying input stream
-  private InputStream _is;
-  // a peek character
-  protected int _peek = -1;
-  
-  // the method for a call
-  private String _method;
-
-  private Reader _chunkReader;
-  private InputStream _chunkInputStream;
-
-  private Throwable _replyFault;
-
-  private StringBuffer _sbuf = new StringBuffer();
-  
-  // true if this is the last chunk
-  private boolean _isLastChunk;
-  // the chunk length
-  private int _chunkLength;
-
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianInput()
-  {
-  }
-  
-  /**
-   * Creates a new Hessian input stream, initialized with an
-   * underlying input stream.
-   *
-   * @param is the underlying input stream.
-   */
-  public HessianInput(InputStream is)
-  {
-    init(is);
-  }
-
-  /**
-   * Sets the serializer factory.
-   */
-  public void setSerializerFactory(SerializerFactory factory)
-  {
-    _serializerFactory = factory;
-  }
-
-  /**
-   * Gets the serializer factory.
-   */
-  public SerializerFactory getSerializerFactory()
-  {
-    return _serializerFactory;
-  }
-
-  /**
-   * Initialize the hessian stream with the underlying input stream.
-   */
-  public void init(InputStream is)
-  {
-    _is = is;
-    _method = null;
-    _isLastChunk = true;
-    _chunkLength = 0;
-    _peek = -1;
-    _refs = null;
-    _replyFault = null;
-
-    if (_serializerFactory == null)
-      _serializerFactory = new SerializerFactory();
-  }
-
-  /**
-   * Returns the calls method
-   */
-  public String getMethod()
-  {
-    return _method;
-  }
-
-  /**
-   * Returns any reply fault.
-   */
-  public Throwable getReplyFault()
-  {
-    return _replyFault;
-  }
-
-  /**
-   * Starts reading the call
-   *
-   * <pre>
-   * c major minor
-   * </pre>
-   */
-  public int readCall()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'c')
-      throw error("expected hessian call ('c') at " + codeName(tag));
-
-    int major = read();
-    int minor = read();
-
-    return (major << 16) + minor;
-  }
-
-  /**
-   * For backward compatibility with HessianSkeleton
-   */
-  public void skipOptionalCall()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag == 'c') {
-      read();
-      read();
-    }
-    else
-      _peek = tag;
-  }
-
-  /**
-   * Starts reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * m b16 b8 method
-   * </pre>
-   */
-  public String readMethod()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'm')
-      throw error("expected hessian method ('m') at " + codeName(tag));
-    int d1 = read();
-    int d2 = read();
-
-    _isLastChunk = true;
-    _chunkLength = d1 * 256 + d2;
-    _sbuf.setLength(0);
-    int ch;
-    while ((ch = parseChar()) >= 0)
-      _sbuf.append((char) ch);
-    
-    _method = _sbuf.toString();
-
-    return _method;
-  }
-
-  /**
-   * Starts reading the call, including the headers.
-   *
-   * <p>The call expects the following protocol data
-   *
-   * <pre>
-   * c major minor
-   * m b16 b8 method
-   * </pre>
-   */
-  public void startCall()
-    throws IOException
-  {
-    readCall();
-
-    while (readHeader() != null) {
-      readObject();
-    }
-
-    readMethod();
-  }
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeCall()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag == 'z') {
-    }
-    else
-      throw error("expected end of call ('z') at " + codeName(tag) + ".  Check method arguments and ensure method overloading is enabled if necessary");
-  }
-
-  /**
-   * Reads a reply as an object.
-   * If the reply has a fault, throws the exception.
-   */
-  public Object readReply(Class expectedClass)
-    throws Throwable
-  {
-    int tag = read();
-    
-    if (tag != 'r')
-      error("expected hessian reply at " + codeName(tag));
-
-    int major = read();
-    int minor = read();
-
-    tag = read();
-    if (tag == 'f')
-      throw prepareFault();
-    else {
-      _peek = tag;
-    
-      Object value = readObject(expectedClass);
-
-      completeValueReply();
-
-      return value;
-    }
-  }
-
-  /**
-   * Starts reading the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * r
-   * </pre>
-   */
-  public void startReply()
-    throws Throwable
-  {
-    int tag = read();
-    
-    if (tag != 'r')
-      error("expected hessian reply at " + codeName(tag));
-
-    int major = read();
-    int minor = read();
-    
-    tag = read();
-    if (tag == 'f')
-      throw prepareFault();
-    else
-      _peek = tag;
-  }
-
-  /**
-   * Prepares the fault.
-   */
-  private Throwable prepareFault()
-    throws IOException
-  {
-    HashMap fault = readFault();
-
-    Object detail = fault.get("detail");
-    String message = (String) fault.get("message");
-
-    if (detail instanceof Throwable) {
-      _replyFault = (Throwable) detail;
-      
-      if (message != null && _detailMessageField != null) {
-	try {
-	  _detailMessageField.set(_replyFault, message);
-	} catch (Throwable e) {
-	}
-      }
-	
-      return _replyFault;
-    }
-
-    else {
-      String code = (String) fault.get("code");
-        
-      _replyFault = new HessianServiceException(message, code, detail);
-
-      return _replyFault;
-    }
-  }
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeReply()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'z')
-      error("expected end of reply at " + codeName(tag));
-  }
-
-  /**
-   * Completes reading the call
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeValueReply()
-    throws IOException
-  {
-    int tag = read();
-    
-    if (tag != 'z')
-      error("expected end of reply at " + codeName(tag));
-  }
-
-  /**
-   * Reads a header, returning null if there are no headers.
-   *
-   * <pre>
-   * H b16 b8 value
-   * </pre>
-   */
-  public String readHeader()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag == 'H') {
-      _isLastChunk = true;
-      _chunkLength = (read() << 8) + read();
-
-      _sbuf.setLength(0);
-      int ch;
-      while ((ch = parseChar()) >= 0)
-        _sbuf.append((char) ch);
-
-      return _sbuf.toString();
-    }
-
-    _peek = tag;
-
-    return null;
-  }
-
-  /**
-   * Reads a null
-   *
-   * <pre>
-   * N
-   * </pre>
-   */
-  public void readNull()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N': return;
-      
-    default:
-      throw expect("null", tag);
-    }
-  }
-
-  /**
-   * Reads a boolean
-   *
-   * <pre>
-   * T
-   * F
-   * </pre>
-   */
-  public boolean readBoolean()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'T': return true;
-    case 'F': return false;
-    case 'I': return parseInt() == 0;
-    case 'L': return parseLong() == 0;
-    case 'D': return parseDouble() == 0.0;
-    case 'N': return false;
-      
-    default:
-      throw expect("boolean", tag);
-    }
-  }
-
-  /**
-   * Reads a byte
-   *
-   * <pre>
-   * I b32 b24 b16 b8
-   * </pre>
-   */
-  /*
-  public byte readByte()
-    throws IOException
-  {
-    return (byte) readInt();
-  }
-  */
-
-  /**
-   * Reads a short
-   *
-   * <pre>
-   * I b32 b24 b16 b8
-   * </pre>
-   */
-  public short readShort()
-    throws IOException
-  {
-    return (short) readInt();
-  }
-
-  /**
-   * Reads an integer
-   *
-   * <pre>
-   * I b32 b24 b16 b8
-   * </pre>
-   */
-  public int readInt()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'T': return 1;
-    case 'F': return 0;
-    case 'I': return parseInt();
-    case 'L': return (int) parseLong();
-    case 'D': return (int) parseDouble();
-      
-    default:
-      throw expect("int", tag);
-    }
-  }
-
-  /**
-   * Reads a long
-   *
-   * <pre>
-   * L b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public long readLong()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'T': return 1;
-    case 'F': return 0;
-    case 'I': return parseInt();
-    case 'L': return parseLong();
-    case 'D': return (long) parseDouble();
-      
-    default:
-      throw expect("long", tag);
-    }
-  }
-
-  /**
-   * Reads a float
-   *
-   * <pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public float readFloat()
-    throws IOException
-  {
-    return (float) readDouble();
-  }
-
-  /**
-   * Reads a double
-   *
-   * <pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public double readDouble()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'T': return 1;
-    case 'F': return 0;
-    case 'I': return parseInt();
-    case 'L': return (double) parseLong();
-    case 'D': return parseDouble();
-      
-    default:
-      throw expect("long", tag);
-    }
-  }
-
-  /**
-   * Reads a date.
-   *
-   * <pre>
-   * T b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  public long readUTCDate()
-    throws IOException
-  {
-    int tag = read();
-
-    if (tag != 'd')
-      throw error("expected date at " + codeName(tag));
-
-    long b64 = read();
-    long b56 = read();
-    long b48 = read();
-    long b40 = read();
-    long b32 = read();
-    long b24 = read();
-    long b16 = read();
-    long b8 = read();
-
-    return ((b64 << 56) +
-            (b56 << 48) +
-            (b48 << 40) +
-            (b40 << 32) +
-            (b32 << 24) +
-            (b24 << 16) +
-            (b16 << 8) +
-            b8);
-  }
-
-  /**
-   * Reads a byte from the stream.
-   */
-  public int readChar()
-    throws IOException
-  {
-    if (_chunkLength > 0) {
-      _chunkLength--;
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      int ch = parseUTF8Char();
-      return ch;
-    }
-    else if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return -1;
-
-    case 'S':
-    case 's':
-    case 'X':
-    case 'x':
-      _isLastChunk = tag == 'S' || tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      _chunkLength--;
-      int value = parseUTF8Char();
-
-      // special code so successive read byte won't
-      // be read as a single object.
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      return value;
-      
-    default:
-      throw new IOException("expected 'S' at " + (char) tag);
-    }
-  }
-
-  /**
-   * Reads a byte array from the stream.
-   */
-  public int readString(char []buffer, int offset, int length)
-    throws IOException
-  {
-    int readLength = 0;
-
-    if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    else if (_chunkLength == 0) {
-      int tag = read();
-
-      switch (tag) {
-      case 'N':
-        return -1;
-      
-      case 'S':
-      case 's':
-      case 'X':
-      case 'x':
-        _isLastChunk = tag == 'S' || tag == 'X';
-        _chunkLength = (read() << 8) + read();
-        break;
-
-      default:
-        throw new IOException("expected 'S' at " + (char) tag);
-      }
-    }
-
-    while (length > 0) {
-      if (_chunkLength > 0) {
-        buffer[offset++] = (char) parseUTF8Char();
-        _chunkLength--;
-        length--;
-        readLength++;
-      }
-      else if (_isLastChunk) {
-        if (readLength == 0)
-          return -1;
-        else {
-          _chunkLength = END_OF_DATA;
-          return readLength;
-        }
-      }
-      else {
-        int tag = read();
-
-        switch (tag) {
-        case 'S':
-        case 's':
-        case 'X':
-        case 'x':
-          _isLastChunk = tag == 'S' || tag == 'X';
-          _chunkLength = (read() << 8) + read();
-          break;
-      
-        default:
-          throw new IOException("expected 'S' at " + (char) tag);
-        }
-      }
-    }
-    
-    if (readLength == 0)
-      return -1;
-    else if (_chunkLength > 0 || ! _isLastChunk)
-      return readLength;
-    else {
-      _chunkLength = END_OF_DATA;
-      return readLength;
-    }
-  }
-
-  /**
-   * Reads a string
-   *
-   * <pre>
-   * S b16 b8 string value
-   * </pre>
-   */
-  public String readString()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'I':
-      return String.valueOf(parseInt());
-    case 'L':
-      return String.valueOf(parseLong());
-    case 'D':
-      return String.valueOf(parseDouble());
-
-    case 'S':
-    case 's':
-    case 'X':
-    case 'x':
-      _isLastChunk = tag == 'S' || tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      _sbuf.setLength(0);
-      int ch;
-
-      while ((ch = parseChar()) >= 0)
-        _sbuf.append((char) ch);
-
-      return _sbuf.toString();
-
-    default:
-      throw expect("string", tag);
-    }
-  }
-
-  /**
-   * Reads an XML node.
-   *
-   * <pre>
-   * S b16 b8 string value
-   * </pre>
-   */
-  public org.w3c.dom.Node readNode()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'S':
-    case 's':
-    case 'X':
-    case 'x':
-      _isLastChunk = tag == 'S' || tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      throw error("Can't handle string in this context");
-
-    default:
-      throw expect("string", tag);
-    }
-  }
-
-  /**
-   * Reads a byte array
-   *
-   * <pre>
-   * B b16 b8 data value
-   * </pre>
-   */
-  public byte []readBytes()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'B':
-    case 'b':
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-
-      ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
-      int data;
-      while ((data = parseByte()) >= 0)
-        bos.write(data);
-
-      return bos.toByteArray();
-      
-    default:
-      throw expect("bytes", tag);
-    }
-  }
-
-  /**
-   * Reads a byte from the stream.
-   */
-  public int readByte()
-    throws IOException
-  {
-    if (_chunkLength > 0) {
-      _chunkLength--;
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      return read();
-    }
-    else if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return -1;
-
-    case 'B':
-    case 'b':
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-
-      int value = parseByte();
-
-      // special code so successive read byte won't
-      // be read as a single object.
-      if (_chunkLength == 0 && _isLastChunk)
-        _chunkLength = END_OF_DATA;
-
-      return value;
-      
-    default:
-      throw new IOException("expected 'B' at " + (char) tag);
-    }
-  }
-
-  /**
-   * Reads a byte array from the stream.
-   */
-  public int readBytes(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    int readLength = 0;
-
-    if (_chunkLength == END_OF_DATA) {
-      _chunkLength = 0;
-      return -1;
-    }
-    else if (_chunkLength == 0) {
-      int tag = read();
-
-      switch (tag) {
-      case 'N':
-        return -1;
-      
-      case 'B':
-      case 'b':
-        _isLastChunk = tag == 'B';
-        _chunkLength = (read() << 8) + read();
-        break;
-      
-      default:
-        throw new IOException("expected 'B' at " + (char) tag);
-      }
-    }
-
-    while (length > 0) {
-      if (_chunkLength > 0) {
-        buffer[offset++] = (byte) read();
-        _chunkLength--;
-        length--;
-        readLength++;
-      }
-      else if (_isLastChunk) {
-        if (readLength == 0)
-          return -1;
-        else {
-          _chunkLength = END_OF_DATA;
-          return readLength;
-        }
-      }
-      else {
-        int tag = read();
-
-        switch (tag) {
-        case 'B':
-        case 'b':
-          _isLastChunk = tag == 'B';
-          _chunkLength = (read() << 8) + read();
-          break;
-      
-        default:
-          throw new IOException("expected 'B' at " + (char) tag);
-        }
-      }
-    }
-    
-    if (readLength == 0)
-      return -1;
-    else if (_chunkLength > 0 || ! _isLastChunk)
-      return readLength;
-    else {
-      _chunkLength = END_OF_DATA;
-      return readLength;
-    }
-  }
-
-  /**
-   * Reads a fault.
-   */
-  private HashMap readFault()
-    throws IOException
-  {
-    HashMap map = new HashMap();
-
-    int code = read();
-    for (; code > 0 && code != 'z'; code = read()) {
-      _peek = code;
-      
-      Object key = readObject();
-      Object value = readObject();
-
-      if (key != null && value != null)
-        map.put(key, value);
-    }
-
-    if (code != 'z')
-      throw expect("fault", code);
-
-    return map;
-  }
-
-  /**
-   * Reads an object from the input stream with an expected type.
-   */
-  public Object readObject(Class cl)
-    throws IOException
-  {
-    if (cl == null || cl == Object.class)
-      return readObject();
-    
-    int tag = read();
-    
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'M':
-    {
-      String type = readType();
-
-      // hessian/3386
-      if ("".equals(type)) {
-	Deserializer reader;
-	reader = _serializerFactory.getDeserializer(cl);
-
-	return reader.readMap(this);
-      }
-      else {
-	Deserializer reader;
-	reader = _serializerFactory.getObjectDeserializer(type);
-
-        return reader.readMap(this);
-      }
-    }
-
-    case 'V':
-    {
-      String type = readType();
-      int length = readLength();
-      
-      Deserializer reader;
-      reader = _serializerFactory.getObjectDeserializer(type);
-      
-      if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))
-        return reader.readList(this, length);
-
-      reader = _serializerFactory.getDeserializer(cl);
-
-      Object v = reader.readList(this, length);
-
-      return v;
-    }
-
-    case 'R':
-    {
-      int ref = parseInt();
-
-      return _refs.get(ref);
-    }
-
-    case 'r':
-    {
-      String type = readType();
-      String url = readString();
-
-      return resolveRemote(type, url);
-    }
-    }
-
-    _peek = tag;
-
-    // hessian/332i vs hessian/3406
-    //return readObject();
-    
-    Object value = _serializerFactory.getDeserializer(cl).readObject(this);
-
-    return value;
-  }
-  
-  /**
-   * Reads an arbitrary object from the input stream when the type
-   * is unknown.
-   */
-  public Object readObject()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-      
-    case 'T':
-      return Boolean.valueOf(true);
-      
-    case 'F':
-      return Boolean.valueOf(false);
-      
-    case 'I':
-      return Integer.valueOf(parseInt());
-    
-    case 'L':
-      return Long.valueOf(parseLong());
-    
-    case 'D':
-      return Double.valueOf(parseDouble());
-    
-    case 'd':
-      return new Date(parseLong());
-    
-    case 'x':
-    case 'X': {
-      _isLastChunk = tag == 'X';
-      _chunkLength = (read() << 8) + read();
-
-      return parseXML();
-    }
-
-    case 's':
-    case 'S': {
-      _isLastChunk = tag == 'S';
-      _chunkLength = (read() << 8) + read();
-
-      int data;
-      _sbuf.setLength(0);
-      
-      while ((data = parseChar()) >= 0)
-        _sbuf.append((char) data);
-
-      return _sbuf.toString();
-    }
-
-    case 'b':
-    case 'B': {
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-
-      int data;
-      ByteArrayOutputStream bos = new ByteArrayOutputStream();
-      
-      while ((data = parseByte()) >= 0)
-        bos.write(data);
-
-      return bos.toByteArray();
-    }
-
-    case 'V': {
-      String type = readType();
-      int length = readLength();
-
-      return _serializerFactory.readList(this, length, type);
-    }
-
-    case 'M': {
-      String type = readType();
-
-      return _serializerFactory.readMap(this, type);
-    }
-
-    case 'R': {
-      int ref = parseInt();
-
-      return _refs.get(ref);
-    }
-
-    case 'r': {
-      String type = readType();
-      String url = readString();
-
-      return resolveRemote(type, url);
-    }
-
-    default:
-      throw error("unknown code for readObject at " + codeName(tag));
-    }
-  }
-
-  /**
-   * Reads a remote object.
-   */
-  public Object readRemote()
-    throws IOException
-  {
-    String type = readType();
-    String url = readString();
-
-    return resolveRemote(type, url);
-  }
-
-  /**
-   * Reads a reference.
-   */
-  public Object readRef()
-    throws IOException
-  {
-    return _refs.get(parseInt());
-  }
-
-  /**
-   * Reads the start of a list.
-   */
-  public int readListStart()
-    throws IOException
-  {
-    return read();
-  }
-
-  /**
-   * Reads the start of a list.
-   */
-  public int readMapStart()
-    throws IOException
-  {
-    return read();
-  }
-
-  /**
-   * Returns true if this is the end of a list or a map.
-   */
-  public boolean isEnd()
-    throws IOException
-  {
-    int code = read();
-
-    _peek = code;
-
-    return (code < 0 || code == 'z');
-  }
-
-  /**
-   * Reads the end byte.
-   */
-  public void readEnd()
-    throws IOException
-  {
-    int code = read();
-
-    if (code != 'z')
-      throw error("unknown code at " + codeName(code));
-  }
-
-  /**
-   * Reads the end byte.
-   */
-  public void readMapEnd()
-    throws IOException
-  {
-    int code = read();
-
-    if (code != 'z')
-      throw error("expected end of map ('z') at " + codeName(code));
-  }
-
-  /**
-   * Reads the end byte.
-   */
-  public void readListEnd()
-    throws IOException
-  {
-    int code = read();
-
-    if (code != 'z')
-      throw error("expected end of list ('z') at " + codeName(code));
-  }
-
-  /**
-   * Adds a list/map reference.
-   */
-  public int addRef(Object ref)
-  {
-    if (_refs == null)
-      _refs = new ArrayList();
-    
-    _refs.add(ref);
-
-    return _refs.size() - 1;
-  }
-
-  /**
-   * Adds a list/map reference.
-   */
-  public void setRef(int i, Object ref)
-  {
-    _refs.set(i, ref);
-  }
-
-  /**
-   * Resets the references for streaming.
-   */
-  public void resetReferences()
-  {
-    if (_refs != null)
-      _refs.clear();
-  }
-
-  /**
-   * Resolves a remote object.
-   */
-  public Object resolveRemote(String type, String url)
-    throws IOException
-  {
-    HessianRemoteResolver resolver = getRemoteResolver();
-
-    if (resolver != null)
-      return resolver.lookup(type, url);
-    else
-      return new HessianRemote(type, url);
-  }
-
-  /**
-   * Parses a type from the stream.
-   *
-   * <pre>
-   * t b16 b8
-   * </pre>
-   */
-  public String readType()
-    throws IOException
-  {
-    int code = read();
-
-    if (code != 't') {
-      _peek = code;
-      return "";
-    }
-
-    _isLastChunk = true;
-    _chunkLength = (read() << 8) + read();
-
-    _sbuf.setLength(0);
-    int ch;
-    while ((ch = parseChar()) >= 0)
-      _sbuf.append((char) ch);
-
-    return _sbuf.toString();
-  }
-
-  /**
-   * Parses the length for an array
-   *
-   * <pre>
-   * l b32 b24 b16 b8
-   * </pre>
-   */
-  public int readLength()
-    throws IOException
-  {
-    int code = read();
-
-    if (code != 'l') {
-      _peek = code;
-      return -1;
-    }
-
-    return parseInt();
-  }
-
-  /**
-   * Parses a 32-bit integer value from the stream.
-   *
-   * <pre>
-   * b32 b24 b16 b8
-   * </pre>
-   */
-  private int parseInt()
-    throws IOException
-  {
-    int b32 = read();
-    int b24 = read();
-    int b16 = read();
-    int b8 = read();
-
-    return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
-  }
-
-  /**
-   * Parses a 64-bit long value from the stream.
-   *
-   * <pre>
-   * b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  private long parseLong()
-    throws IOException
-  {
-    long b64 = read();
-    long b56 = read();
-    long b48 = read();
-    long b40 = read();
-    long b32 = read();
-    long b24 = read();
-    long b16 = read();
-    long b8 = read();
-
-    return ((b64 << 56) +
-            (b56 << 48) +
-            (b48 << 40) +
-            (b40 << 32) +
-            (b32 << 24) +
-            (b24 << 16) +
-            (b16 << 8) +
-            b8);
-  }
-  
-  /**
-   * Parses a 64-bit double value from the stream.
-   *
-   * <pre>
-   * b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre>
-   */
-  private double parseDouble()
-    throws IOException
-  {
-    long b64 = read();
-    long b56 = read();
-    long b48 = read();
-    long b40 = read();
-    long b32 = read();
-    long b24 = read();
-    long b16 = read();
-    long b8 = read();
-
-    long bits = ((b64 << 56) +
-                 (b56 << 48) +
-                 (b48 << 40) +
-                 (b40 << 32) +
-                 (b32 << 24) +
-                 (b24 << 16) +
-                 (b16 << 8) +
-                 b8);
-  
-    return Double.longBitsToDouble(bits);
-  }
-
-  org.w3c.dom.Node parseXML()
-    throws IOException
-  {
-    throw new UnsupportedOperationException();
-  }
-  
-  /**
-   * Reads a character from the underlying stream.
-   */
-  private int parseChar()
-    throws IOException
-  {
-    while (_chunkLength <= 0) {
-      if (_isLastChunk)
-        return -1;
-
-      int code = read();
-
-      switch (code) {
-      case 's':
-      case 'x':
-        _isLastChunk = false;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-        
-      case 'S':
-      case 'X':
-        _isLastChunk = true;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-
-      default:
-        throw expect("string", code);
-      }
-
-    }
-
-    _chunkLength--;
-
-    return parseUTF8Char();
-  }
-
-  /**
-   * Parses a single UTF8 character.
-   */
-  private int parseUTF8Char()
-    throws IOException
-  {
-    int ch = read();
-
-    if (ch < 0x80)
-      return ch;
-    else if ((ch & 0xe0) == 0xc0) {
-      int ch1 = read();
-      int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);
-
-      return v;
-    }
-    else if ((ch & 0xf0) == 0xe0) {
-      int ch1 = read();
-      int ch2 = read();
-      int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f);
-
-      return v;
-    }
-    else
-      throw error("bad utf-8 encoding at " + codeName(ch));
-  }
-  
-  /**
-   * Reads a byte from the underlying stream.
-   */
-  private int parseByte()
-    throws IOException
-  {
-    while (_chunkLength <= 0) {
-      if (_isLastChunk) {
-        return -1;
-      }
-
-      int code = read();
-
-      switch (code) {
-      case 'b':
-        _isLastChunk = false;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-        
-      case 'B':
-        _isLastChunk = true;
-
-        _chunkLength = (read() << 8) + read();
-        break;
-
-      default:
-        throw expect("byte[]", code);
-      }
-    }
-
-    _chunkLength--;
-
-    return read();
-  }
-
-  /**
-   * Reads bytes based on an input stream.
-   */
-  public InputStream readInputStream()
-    throws IOException
-  {
-    int tag = read();
-
-    switch (tag) {
-    case 'N':
-      return null;
-
-    case 'B':
-    case 'b':
-      _isLastChunk = tag == 'B';
-      _chunkLength = (read() << 8) + read();
-      break;
-      
-    default:
-      throw expect("inputStream", tag);
-    }
-    
-    return new InputStream() {
-	boolean _isClosed = false;
-	
-	public int read()
-	  throws IOException
-	{
-	  if (_isClosed || _is == null)
-	    return -1;
-
-	  int ch = parseByte();
-	  if (ch < 0)
-	    _isClosed = true;
-
-	  return ch;
-	}
-	
-	public int read(byte []buffer, int offset, int length)
-	  throws IOException
-	{
-	  if (_isClosed || _is == null)
-	    return -1;
-
-	  int len = HessianInput.this.read(buffer, offset, length);
-	  if (len < 0)
-	    _isClosed = true;
-
-	  return len;
-	}
-
-	public void close()
-	  throws IOException
-	{
-	  while (read() >= 0) {
-	  }
-
-	  _isClosed = true;
-	}
-      };
-  }
-  
-  /**
-   * Reads bytes from the underlying stream.
-   */
-  int read(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    int readLength = 0;
-    
-    while (length > 0) {
-      while (_chunkLength <= 0) {
-        if (_isLastChunk)
-          return readLength == 0 ? -1 : readLength;
-
-        int code = read();
-
-        switch (code) {
-        case 'b':
-          _isLastChunk = false;
-
-          _chunkLength = (read() << 8) + read();
-          break;
-        
-        case 'B':
-          _isLastChunk = true;
-
-          _chunkLength = (read() << 8) + read();
-          break;
-
-        default:
-          throw expect("byte[]", code);
-        }
-      }
-
-      int sublen = _chunkLength;
-      if (length < sublen)
-        sublen = length;
-
-      sublen = _is.read(buffer, offset, sublen);
-      offset += sublen;
-      readLength += sublen;
-      length -= sublen;
-      _chunkLength -= sublen;
-    }
-
-    return readLength;
-  }
-
-  final int read()
-    throws IOException
-  {
-    if (_peek >= 0) {
-      int value = _peek;
-      _peek = -1;
-      return value;
-    }
-
-    int ch = _is.read();
-      
-    return ch;
-  }
-
-  public void close()
-  {
-    _is = null;
-  }
-
-  public Reader getReader()
-  {
-    return null;
-  }
-
-  protected IOException expect(String expect, int ch)
-  {
-    return error("expected " + expect + " at " + codeName(ch));
-  }
-
-  protected String codeName(int ch)
-  {
-    if (ch < 0)
-      return "end of file";
-    else
-      return "0x" + Integer.toHexString(ch & 0xff) + " (" + (char) + ch + ")";
-  }
-  
-  protected IOException error(String message)
-  {
-    if (_method != null)
-      return new HessianProtocolException(_method + ": " + message);
-    else
-      return new HessianProtocolException(message);
-  }
-
-  static {
-    try {
-      _detailMessageField = Throwable.class.getDeclaredField("detailMessage");
-      _detailMessageField.setAccessible(true);
-    } catch (Throwable e) {
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/HessianInputFactory.java src/com/caucho/hessian/io/HessianInputFactory.java
deleted file mode 100644
index e09ecbd..0000000
--- src/com/caucho/hessian/io/HessianInputFactory.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.util.logging.*;
-import java.io.*;
-
-public class HessianInputFactory
-{
-  public static final Logger log
-    = Logger.getLogger(HessianInputFactory.class.getName());
-
-  private SerializerFactory _serializerFactory;
-
-  public void setSerializerFactory(SerializerFactory factory)
-  {
-    _serializerFactory = factory;
-  }
-
-  public SerializerFactory getSerializerFactory()
-  {
-    return _serializerFactory;
-  }
-
-  public AbstractHessianInput open(InputStream is)
-    throws IOException
-  {
-    int code = is.read();
-
-    int major = is.read();
-    int minor = is.read();
-
-    switch (code) {
-    case 'c':
-    case 'C':
-    case 'r':
-    case 'R':
-      if (major >= 2) {
-	AbstractHessianInput in = new Hessian2Input(is);
-	in.setSerializerFactory(_serializerFactory);
-	return in;
-      }
-      else {
-	AbstractHessianInput in = new HessianInput(is);
-	in.setSerializerFactory(_serializerFactory);
-	return in;
-      }
-
-    default:
-      throw new IOException((char) code + " is an unknown Hessian message code.");
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/HessianOutput.java src/com/caucho/hessian/io/HessianOutput.java
deleted file mode 100644
index 63d6377..0000000
--- src/com/caucho/hessian/io/HessianOutput.java
+++ /dev/null
@@ -1,949 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.IdentityHashMap;
-
-/**
- * Output stream for Hessian requests, compatible with microedition
- * Java.  It only uses classes and types available in JDK.
- *
- * <p>Since HessianOutput does not depend on any classes other than
- * in the JDK, it can be extracted independently into a smaller package.
- *
- * <p>HessianOutput is unbuffered, so any client needs to provide
- * its own buffering.
- *
- * <pre>
- * OutputStream os = ...; // from http connection
- * HessianOutput out = new HessianOutput(os);
- * String value;
- *
- * out.startCall("hello");  // start hello call
- * out.writeString("arg1"); // write a string argument
- * out.completeCall();      // complete the call
- * </pre>
- */
-public class HessianOutput extends AbstractHessianOutput {
-  // the output stream/
-  protected OutputStream os;
-  // map of references
-  private IdentityHashMap _refs;
-  private int _version = 1;
-  
-  /**
-   * Creates a new Hessian output stream, initialized with an
-   * underlying output stream.
-   *
-   * @param os the underlying output stream.
-   */
-  public HessianOutput(OutputStream os)
-  {
-    init(os);
-  }
-
-  /**
-   * Creates an uninitialized Hessian output stream.
-   */
-  public HessianOutput()
-  {
-  }
-
-  /**
-   * Initializes the output
-   */
-  public void init(OutputStream os)
-  {
-    this.os = os;
-
-    _refs = null;
-
-    if (_serializerFactory == null)
-      _serializerFactory = new SerializerFactory();
-  }
-
-  /**
-   * Sets the client's version.
-   */
-  public void setVersion(int version)
-  {
-    _version = version;
-  }
-
-  /**
-   * Writes a complete method call.
-   */
-  public void call(String method, Object []args)
-    throws IOException
-  {
-    startCall(method);
-    
-    if (args != null) {
-      for (int i = 0; i < args.length; i++)
-        writeObject(args[i]);
-    }
-    
-    completeCall();
-  }
-
-  /**
-   * Starts the method call.  Clients would use <code>startCall</code>
-   * instead of <code>call</code> if they wanted finer control over
-   * writing the arguments, or needed to write headers.
-   *
-   * <code><pre>
-   * c major minor
-   * m b16 b8 method-name
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void startCall(String method)
-    throws IOException
-  {
-    os.write('c');
-    os.write(_version);
-    os.write(0);
-
-    os.write('m');
-    int len = method.length();
-    os.write(len >> 8);
-    os.write(len);
-    printString(method, 0, len);
-  }
-
-  /**
-   * Writes the call tag.  This would be followed by the
-   * headers and the method tag.
-   *
-   * <code><pre>
-   * c major minor
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void startCall()
-    throws IOException
-  {
-    os.write('c');
-    os.write(0);
-    os.write(1);
-  }
-
-  /**
-   * Writes the method tag.
-   *
-   * <code><pre>
-   * m b16 b8 method-name
-   * </pre></code>
-   *
-   * @param method the method name to call.
-   */
-  public void writeMethod(String method)
-    throws IOException
-  {
-    os.write('m');
-    int len = method.length();
-    os.write(len >> 8);
-    os.write(len);
-    printString(method, 0, len);
-  }
-
-  /**
-   * Completes.
-   *
-   * <code><pre>
-   * z
-   * </pre></code>
-   */
-  public void completeCall()
-    throws IOException
-  {
-    os.write('z');
-  }
-
-  /**
-   * Starts the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * r
-   * </pre>
-   */
-  public void startReply()
-    throws IOException
-  {
-    os.write('r');
-    os.write(1);
-    os.write(0);
-  }
-
-  /**
-   * Completes reading the reply
-   *
-   * <p>A successful completion will have a single value:
-   *
-   * <pre>
-   * z
-   * </pre>
-   */
-  public void completeReply()
-    throws IOException
-  {
-    os.write('z');
-  }
-
-  /**
-   * Writes a header name.  The header value must immediately follow.
-   *
-   * <code><pre>
-   * H b16 b8 foo <em>value</em>
-   * </pre></code>
-   */
-  public void writeHeader(String name)
-    throws IOException
-  {
-    int len = name.length();
-    
-    os.write('H');
-    os.write(len >> 8);
-    os.write(len);
-
-    printString(name);
-  }
-
-  /**
-   * Writes a fault.  The fault will be written
-   * as a descriptive string followed by an object:
-   *
-   * <code><pre>
-   * f
-   * &lt;string>code
-   * &lt;string>the fault code
-   *
-   * &lt;string>message
-   * &lt;string>the fault mesage
-   *
-   * &lt;string>detail
-   * mt\x00\xnnjavax.ejb.FinderException
-   *     ...
-   * z
-   * z
-   * </pre></code>
-   *
-   * @param code the fault code, a three digit
-   */
-  public void writeFault(String code, String message, Object detail)
-    throws IOException
-  {
-    os.write('f');
-    writeString("code");
-    writeString(code);
-
-    writeString("message");
-    writeString(message);
-
-    if (detail != null) {
-      writeString("detail");
-      writeObject(detail);
-    }
-    os.write('z');
-  }
-
-  /**
-   * Writes any object to the output stream.
-   */
-  public void writeObject(Object object)
-    throws IOException
-  {
-    if (object == null) {
-      writeNull();
-      return;
-    }
-
-    Serializer serializer;
-
-    serializer = _serializerFactory.getSerializer(object.getClass());
-
-    serializer.writeObject(object, this);
-  }
-
-  /**
-   * Writes the list header to the stream.  List writers will call
-   * <code>writeListBegin</code> followed by the list contents and then
-   * call <code>writeListEnd</code>.
-   *
-   * <code><pre>
-   * V
-   * t b16 b8 type
-   * l b32 b24 b16 b8
-   * </pre></code>
-   */
-  public boolean writeListBegin(int length, String type)
-    throws IOException
-  {
-    os.write('V');
-
-    if (type != null) {
-      os.write('t');
-      printLenString(type);
-    }
-
-    if (length >= 0) {
-      os.write('l');
-      os.write(length >> 24);
-      os.write(length >> 16);
-      os.write(length >> 8);
-      os.write(length);
-    }
-
-    return true;
-  }
-
-  /**
-   * Writes the tail of the list to the stream.
-   */
-  public void writeListEnd()
-    throws IOException
-  {
-    os.write('z');
-  }
-
-  /**
-   * Writes the map header to the stream.  Map writers will call
-   * <code>writeMapBegin</code> followed by the map contents and then
-   * call <code>writeMapEnd</code>.
-   *
-   * <code><pre>
-   * Mt b16 b8 (<key> <value>)z
-   * </pre></code>
-   */
-  public void writeMapBegin(String type)
-    throws IOException
-  {
-    os.write('M');
-    os.write('t');
-    printLenString(type);
-  }
-
-  /**
-   * Writes the tail of the map to the stream.
-   */
-  public void writeMapEnd()
-    throws IOException
-  {
-    os.write('z');
-  }
-
-  /**
-   * Writes a remote object reference to the stream.  The type is the
-   * type of the remote interface.
-   *
-   * <code><pre>
-   * 'r' 't' b16 b8 type url
-   * </pre></code>
-   */
-  public void writeRemote(String type, String url)
-    throws IOException
-  {
-    os.write('r');
-    os.write('t');
-    printLenString(type);
-    os.write('S');
-    printLenString(url);
-  }
-
-  /**
-   * Writes a boolean value to the stream.  The boolean will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * T
-   * F
-   * </pre></code>
-   *
-   * @param value the boolean value to write.
-   */
-  public void writeBoolean(boolean value)
-    throws IOException
-  {
-    if (value)
-      os.write('T');
-    else
-      os.write('F');
-  }
-
-  /**
-   * Writes an integer value to the stream.  The integer will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * I b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the integer value to write.
-   */
-  public void writeInt(int value)
-    throws IOException
-  {
-    os.write('I');
-    os.write(value >> 24);
-    os.write(value >> 16);
-    os.write(value >> 8);
-    os.write(value);
-  }
-
-  /**
-   * Writes a long value to the stream.  The long will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * L b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the long value to write.
-   */
-  public void writeLong(long value)
-    throws IOException
-  {
-    os.write('L');
-    os.write((byte) (value >> 56));
-    os.write((byte) (value >> 48));
-    os.write((byte) (value >> 40));
-    os.write((byte) (value >> 32));
-    os.write((byte) (value >> 24));
-    os.write((byte) (value >> 16));
-    os.write((byte) (value >> 8));
-    os.write((byte) (value));
-  }
-
-  /**
-   * Writes a double value to the stream.  The double will be written
-   * with the following syntax:
-   *
-   * <code><pre>
-   * D b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the double value to write.
-   */
-  public void writeDouble(double value)
-    throws IOException
-  {
-    long bits = Double.doubleToLongBits(value);
-    
-    os.write('D');
-    os.write((byte) (bits >> 56));
-    os.write((byte) (bits >> 48));
-    os.write((byte) (bits >> 40));
-    os.write((byte) (bits >> 32));
-    os.write((byte) (bits >> 24));
-    os.write((byte) (bits >> 16));
-    os.write((byte) (bits >> 8));
-    os.write((byte) (bits));
-  }
-
-  /**
-   * Writes a date to the stream.
-   *
-   * <code><pre>
-   * T  b64 b56 b48 b40 b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param time the date in milliseconds from the epoch in UTC
-   */
-  public void writeUTCDate(long time)
-    throws IOException
-  {
-    os.write('d');
-    os.write((byte) (time >> 56));
-    os.write((byte) (time >> 48));
-    os.write((byte) (time >> 40));
-    os.write((byte) (time >> 32));
-    os.write((byte) (time >> 24));
-    os.write((byte) (time >> 16));
-    os.write((byte) (time >> 8));
-    os.write((byte) (time));
-  }
-
-  /**
-   * Writes a null value to the stream.
-   * The null will be written with the following syntax
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeNull()
-    throws IOException
-  {
-    os.write('N');
-  }
-
-  /**
-   * Writes a string value to the stream using UTF-8 encoding.
-   * The string will be written with the following syntax:
-   *
-   * <code><pre>
-   * S b16 b8 string-value
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeString(String value)
-    throws IOException
-  {
-    if (value == null) {
-      os.write('N');
-    }
-    else {
-      int length = value.length();
-      int offset = 0;
-      
-      while (length > 0x8000) {
-        int sublen = 0x8000;
-
-	// chunk can't end in high surrogate
-	char tail = value.charAt(offset + sublen - 1);
-
-	if (0xd800 <= tail && tail <= 0xdbff)
-	  sublen--;
-        
-        os.write('s');
-        os.write(sublen >> 8);
-        os.write(sublen);
-
-        printString(value, offset, sublen);
-
-        length -= sublen;
-        offset += sublen;
-      }
-
-      os.write('S');
-      os.write(length >> 8);
-      os.write(length);
-
-      printString(value, offset, length);
-    }
-  }
-
-  /**
-   * Writes a string value to the stream using UTF-8 encoding.
-   * The string will be written with the following syntax:
-   *
-   * <code><pre>
-   * S b16 b8 string-value
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeString(char []buffer, int offset, int length)
-    throws IOException
-  {
-    if (buffer == null) {
-      os.write('N');
-    }
-    else {
-      while (length > 0x8000) {
-        int sublen = 0x8000;
-
-	// chunk can't end in high surrogate
-	char tail = buffer[offset + sublen - 1];
-
-	if (0xd800 <= tail && tail <= 0xdbff)
-	  sublen--;
-        
-        os.write('s');
-        os.write(sublen >> 8);
-        os.write(sublen);
-
-        printString(buffer, offset, sublen);
-
-        length -= sublen;
-        offset += sublen;
-      }
-
-      os.write('S');
-      os.write(length >> 8);
-      os.write(length);
-
-      printString(buffer, offset, length);
-    }
-  }
-
-  /**
-   * Writes a byte array to the stream.
-   * The array will be written with the following syntax:
-   *
-   * <code><pre>
-   * B b16 b18 bytes
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeBytes(byte []buffer)
-    throws IOException
-  {
-    if (buffer == null)
-      os.write('N');
-    else
-      writeBytes(buffer, 0, buffer.length);
-  }
-  
-  /**
-   * Writes a byte array to the stream.
-   * The array will be written with the following syntax:
-   *
-   * <code><pre>
-   * B b16 b18 bytes
-   * </pre></code>
-   *
-   * If the value is null, it will be written as
-   *
-   * <code><pre>
-   * N
-   * </pre></code>
-   *
-   * @param value the string value to write.
-   */
-  public void writeBytes(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    if (buffer == null) {
-      os.write('N');
-    }
-    else {
-      while (length > 0x8000) {
-        int sublen = 0x8000;
-        
-        os.write('b');
-        os.write(sublen >> 8);
-        os.write(sublen);
-
-        os.write(buffer, offset, sublen);
-
-        length -= sublen;
-        offset += sublen;
-      }
-
-      os.write('B');
-      os.write(length >> 8);
-      os.write(length);
-      os.write(buffer, offset, length);
-    }
-  }
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * </pre></code>
-   */
-  public void writeByteBufferStart()
-    throws IOException
-  {
-  }
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * b b16 b18 bytes
-   * </pre></code>
-   */
-  public void writeByteBufferPart(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    while (length > 0) {
-      int sublen = length;
-
-      if (0x8000 < sublen)
-	sublen = 0x8000;
-
-      os.write('b');
-      os.write(sublen >> 8);
-      os.write(sublen);
-
-      os.write(buffer, offset, sublen);
-
-      length -= sublen;
-      offset += sublen;
-    }
-  }
-  
-  /**
-   * Writes a byte buffer to the stream.
-   *
-   * <code><pre>
-   * b b16 b18 bytes
-   * </pre></code>
-   */
-  public void writeByteBufferEnd(byte []buffer, int offset, int length)
-    throws IOException
-  {
-    writeBytes(buffer, offset, length);
-  }
-
-  /**
-   * Writes a reference.
-   *
-   * <code><pre>
-   * R b32 b24 b16 b8
-   * </pre></code>
-   *
-   * @param value the integer value to write.
-   */
-  public void writeRef(int value)
-    throws IOException
-  {
-    os.write('R');
-    os.write(value >> 24);
-    os.write(value >> 16);
-    os.write(value >> 8);
-    os.write(value);
-  }
-
-  /**
-   * Writes a placeholder.
-   *
-   * <code><pre>
-   * P
-   * </pre></code>
-   */
-  public void writePlaceholder()
-    throws IOException
-  {
-    os.write('P');
-  }
-
-  /**
-   * If the object has already been written, just write its ref.
-   *
-   * @return true if we're writing a ref.
-   */
-  public boolean addRef(Object object)
-    throws IOException
-  {
-    if (_refs == null)
-      _refs = new IdentityHashMap();
-
-    Integer ref = (Integer) _refs.get(object);
-
-    if (ref != null) {
-      int value = ref.intValue();
-      
-      writeRef(value);
-      return true;
-    }
-    else {
-      _refs.put(object, new Integer(_refs.size()));
-      
-      return false;
-    }
-  }
-
-  /**
-   * Resets the references for streaming.
-   */
-  public void resetReferences()
-  {
-    if (_refs != null)
-      _refs.clear();
-  }
-
-  /**
-   * Removes a reference.
-   */
-  public boolean removeRef(Object obj)
-    throws IOException
-  {
-    if (_refs != null) {
-      _refs.remove(obj);
-
-      return true;
-    }
-    else
-      return false;
-  }
-
-  /**
-   * Replaces a reference from one object to another.
-   */
-  public boolean replaceRef(Object oldRef, Object newRef)
-    throws IOException
-  {
-    Integer value = (Integer) _refs.remove(oldRef);
-
-    if (value != null) {
-      _refs.put(newRef, value);
-      return true;
-    }
-    else
-      return false;
-  }
-
-  /**
-   * Prints a string to the stream, encoded as UTF-8 with preceeding length
-   *
-   * @param v the string to print.
-   */
-  public void printLenString(String v)
-    throws IOException
-  {
-    if (v == null) {
-      os.write(0);
-      os.write(0);
-    }
-    else {
-      int len = v.length();
-      os.write(len >> 8);
-      os.write(len);
-
-      printString(v, 0, len);
-    }
-  }
-
-  /**
-   * Prints a string to the stream, encoded as UTF-8
-   *
-   * @param v the string to print.
-   */
-  public void printString(String v)
-    throws IOException
-  {
-    printString(v, 0, v.length());
-  }
-  
-  /**
-   * Prints a string to the stream, encoded as UTF-8
-   *
-   * @param v the string to print.
-   */
-  public void printString(String v, int offset, int length)
-    throws IOException
-  {
-    for (int i = 0; i < length; i++) {
-      char ch = v.charAt(i + offset);
-
-      if (ch < 0x80)
-        os.write(ch);
-      else if (ch < 0x800) {
-        os.write(0xc0 + ((ch >> 6) & 0x1f));
-        os.write(0x80 + (ch & 0x3f));
-      }
-      else {
-        os.write(0xe0 + ((ch >> 12) & 0xf));
-        os.write(0x80 + ((ch >> 6) & 0x3f));
-        os.write(0x80 + (ch & 0x3f));
-      }
-    }
-  }
-  
-  /**
-   * Prints a string to the stream, encoded as UTF-8
-   *
-   * @param v the string to print.
-   */
-  public void printString(char []v, int offset, int length)
-    throws IOException
-  {
-    for (int i = 0; i < length; i++) {
-      char ch = v[i + offset];
-
-      if (ch < 0x80)
-        os.write(ch);
-      else if (ch < 0x800) {
-        os.write(0xc0 + ((ch >> 6) & 0x1f));
-        os.write(0x80 + (ch & 0x3f));
-      }
-      else {
-        os.write(0xe0 + ((ch >> 12) & 0xf));
-        os.write(0x80 + ((ch >> 6) & 0x3f));
-        os.write(0x80 + (ch & 0x3f));
-      }
-    }
-  }
-
-  public void flush()
-    throws IOException
-  {
-    if (this.os != null)
-      this.os.flush();
-  }
-
-  public void close()
-    throws IOException
-  {
-    if (this.os != null)
-      this.os.flush();
-  }
-}
diff --git src/com/caucho/hessian/io/HessianProtocolException.java src/com/caucho/hessian/io/HessianProtocolException.java
deleted file mode 100644
index 94810a1..0000000
--- src/com/caucho/hessian/io/HessianProtocolException.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Exception for faults when the fault doesn't return a java exception.
- * This exception is required for MicroHessianInput.
- */
-public class HessianProtocolException extends IOException {
-  private Throwable rootCause;
-  
-  /**
-   * Zero-arg constructor.
-   */
-  public HessianProtocolException()
-  {
-  }
-  
-  /**
-   * Create the exception.
-   */
-  public HessianProtocolException(String message)
-  {
-    super(message);
-  }
-  
-  /**
-   * Create the exception.
-   */
-  public HessianProtocolException(String message, Throwable rootCause)
-  {
-    super(message);
-
-    this.rootCause = rootCause;
-  }
-  
-  /**
-   * Create the exception.
-   */
-  public HessianProtocolException(Throwable rootCause)
-  {
-    super(String.valueOf(rootCause));
-
-    this.rootCause = rootCause;
-  }
-
-  /**
-   * Returns the underlying cause.
-   */
-  public Throwable getRootCause()
-  {
-    return rootCause;
-  }
-
-  /**
-   * Returns the underlying cause.
-   */
-  public Throwable getCause()
-  {
-    return getRootCause();
-  }
-}
diff --git src/com/caucho/hessian/io/HessianRemote.java src/com/caucho/hessian/io/HessianRemote.java
deleted file mode 100644
index 915c365..0000000
--- src/com/caucho/hessian/io/HessianRemote.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-/**
- * Encapsulates a remote address when no stub is available, e.g. for
- * Java MicroEdition.
- */
-public class HessianRemote {
-  private String type;
-  private String url;
-
-  /**
-   * Creates a new Hessian remote object.
-   *
-   * @param type the remote stub interface
-   * @param url the remote url
-   */
-  public HessianRemote(String type, String url)
-  {
-    this.type = type;
-    this.url = url;
-  }
-
-  /**
-   * Creates an uninitialized Hessian remote.
-   */
-  public HessianRemote()
-  {
-  }
-
-  /**
-   * Returns the remote api class name.
-   */
-  public String getType()
-  {
-    return type;
-  }
-
-  /**
-   * Returns the remote URL.
-   */
-  public String getURL()
-  {
-    return url;
-  }
-
-  /**
-   * Sets the remote URL.
-   */
-  public void setURL(String url)
-  {
-    this.url = url;
-  }
-
-  /**
-   * Defines the hashcode.
-   */
-  public int hashCode()
-  {
-    return url.hashCode();
-  }
-
-  /**
-   * Defines equality
-   */
-  public boolean equals(Object obj)
-  {
-    if (! (obj instanceof HessianRemote))
-      return false;
-
-    HessianRemote remote = (HessianRemote) obj;
-
-    return url.equals(remote.url);
-  }
-
-  /**
-   * Readable version of the remote.
-   */
-  public String toString()
-  {
-    return "[HessianRemote " + url + "]";
-  }
-}
diff --git src/com/caucho/hessian/io/HessianRemoteObject.java src/com/caucho/hessian/io/HessianRemoteObject.java
deleted file mode 100644
index 26deb08..0000000
--- src/com/caucho/hessian/io/HessianRemoteObject.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-/**
- * Interface for any hessian remote object.
- */
-public interface HessianRemoteObject {
-  public String getHessianType();
-  public String getHessianURL();
-}
diff --git src/com/caucho/hessian/io/HessianRemoteResolver.java src/com/caucho/hessian/io/HessianRemoteResolver.java
deleted file mode 100644
index 222ee9e..0000000
--- src/com/caucho/hessian/io/HessianRemoteResolver.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Looks up remote objects.  The default just returns a HessianRemote object.
- */
-public interface HessianRemoteResolver {
-  /**
-   * Looks up a proxy object.
-   */
-  public Object lookup(String type, String url)
-    throws IOException;
-}
diff --git src/com/caucho/hessian/io/HessianSerializerInput.java src/com/caucho/hessian/io/HessianSerializerInput.java
deleted file mode 100644
index 5b23880..0000000
--- src/com/caucho/hessian/io/HessianSerializerInput.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Input stream for Hessian requests, deserializing objects using the
- * java.io.Serialization protocol.
- *
- * <p>HessianSerializerInput is unbuffered, so any client needs to provide
- * its own buffering.
- *
- * <h3>Serialization</h3>
- *
- * <pre>
- * InputStream is = new FileInputStream("test.xml");
- * HessianOutput in = new HessianSerializerOutput(is);
- *
- * Object obj = in.readObject();
- * is.close();
- * </pre>
- *
- * <h3>Parsing a Hessian reply</h3>
- *
- * <pre>
- * InputStream is = ...; // from http connection
- * HessianInput in = new HessianSerializerInput(is);
- * String value;
- *
- * in.startReply();         // read reply header
- * value = in.readString(); // read string value
- * in.completeReply();      // read reply footer
- * </pre>
- */
-public class HessianSerializerInput extends HessianInput {
-  /**
-   * Creates a new Hessian input stream, initialized with an
-   * underlying input stream.
-   *
-   * @param is the underlying input stream.
-   */
-  public HessianSerializerInput(InputStream is)
-  {
-    super(is);
-  }
-
-  /**
-   * Creates an uninitialized Hessian input stream.
-   */
-  public HessianSerializerInput()
-  {
-  }
-
-  /**
-   * Reads an object from the input stream.  cl is known not to be
-   * a Map.
-   */
-  protected Object readObjectImpl(Class cl)
-    throws IOException
-  {
-    try {
-      Object obj = cl.newInstance();
-
-      if (_refs == null)
-        _refs = new ArrayList();
-      _refs.add(obj);
-
-      HashMap fieldMap = getFieldMap(cl);
-
-      int code = read();
-      for (; code >= 0 && code != 'z'; code = read()) {
-        _peek = code;
-        
-        Object key = readObject();
-        
-        Field field = (Field) fieldMap.get(key);
-
-        if (field != null) {
-          Object value = readObject(field.getType());
-          field.set(obj, value);
-        }
-        else {
-          Object value = readObject();
-        }
-      }
-      
-      if (code != 'z')
-        throw expect("map", code);
-
-      // if there's a readResolve method, call it
-      try {
-        Method method = cl.getMethod("readResolve", new Class[0]);
-        return method.invoke(obj, new Object[0]);
-      } catch (Exception e) {
-      }
-
-      return obj;
-    } catch (IOException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-
-  /**
-   * Creates a map of the classes fields.
-   */
-  protected HashMap getFieldMap(Class cl)
-  {
-    HashMap fieldMap = new HashMap();
-    
-    for (; cl != null; cl = cl.getSuperclass()) {
-      Field []fields = cl.getDeclaredFields();
-      for (int i = 0; i < fields.length; i++) {
-        Field field = fields[i];
-
-        if (Modifier.isTransient(field.getModifiers()) ||
-            Modifier.isStatic(field.getModifiers()))
-          continue;
-
-        // XXX: could parameterize the handler to only deal with public
-        field.setAccessible(true);
-
-        fieldMap.put(field.getName(), field);
-      }
-    }
-
-    return fieldMap;
-  }
-}
diff --git src/com/caucho/hessian/io/HessianSerializerOutput.java src/com/caucho/hessian/io/HessianSerializerOutput.java
deleted file mode 100644
index 2f18e6f..0000000
--- src/com/caucho/hessian/io/HessianSerializerOutput.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-/**
- * Output stream for Hessian requests.
- *
- * <p>HessianOutput is unbuffered, so any client needs to provide
- * its own buffering.
- *
- * <h3>Serialization</h3>
- *
- * <pre>
- * OutputStream os = new FileOutputStream("test.xml");
- * HessianOutput out = new HessianSerializerOutput(os);
- *
- * out.writeObject(obj);
- * os.close();
- * </pre>
- *
- * <h3>Writing an RPC Call</h3>
- *
- * <pre>
- * OutputStream os = ...; // from http connection
- * HessianOutput out = new HessianSerializerOutput(os);
- * String value;
- *
- * out.startCall("hello");  // start hello call
- * out.writeString("arg1"); // write a string argument
- * out.completeCall();      // complete the call
- * </pre>
- */
-public class HessianSerializerOutput extends HessianOutput {
-  /**
-   * Creates a new Hessian output stream, initialized with an
-   * underlying output stream.
-   *
-   * @param os the underlying output stream.
-   */
-  public HessianSerializerOutput(OutputStream os)
-  {
-    super(os);
-  }
-
-  /**
-   * Creates an uninitialized Hessian output stream.
-   */
-  public HessianSerializerOutput()
-  {
-  }
-
-  /**
-   * Applications which override this can do custom serialization.
-   *
-   * @param object the object to write.
-   */
-  public void writeObjectImpl(Object obj)
-    throws IOException
-  {
-    Class cl = obj.getClass();
-    
-    try {
-      Method method = cl.getMethod("writeReplace", new Class[0]);
-      Object repl = method.invoke(obj, new Object[0]);
-
-      writeObject(repl);
-      return;
-    } catch (Exception e) {
-    }
-
-    try {
-      writeMapBegin(cl.getName());
-      for (; cl != null; cl = cl.getSuperclass()) {
-        Field []fields = cl.getDeclaredFields();
-        for (int i = 0; i < fields.length; i++) {
-          Field field = fields[i];
-
-          if (Modifier.isTransient(field.getModifiers()) ||
-              Modifier.isStatic(field.getModifiers()))
-            continue;
-
-          // XXX: could parameterize the handler to only deal with public
-          field.setAccessible(true);
-      
-          writeString(field.getName());
-          writeObject(field.get(obj));
-        }
-      }
-      writeMapEnd();
-    } catch (IllegalAccessException e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/HessianServiceException.java src/com/caucho/hessian/io/HessianServiceException.java
deleted file mode 100644
index 38249c6..0000000
--- src/com/caucho/hessian/io/HessianServiceException.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-/**
- * Exception for faults when the fault doesn't return a java exception.
- * This exception is required for MicroHessianInput.
- */
-public class HessianServiceException extends Exception {
-  private String code;
-  private Object detail;
-
-  /**
-   * Zero-arg constructor.
-   */
-  public HessianServiceException()
-  {
-  }
-
-  /**
-   * Create the exception.
-   */
-  public HessianServiceException(String message, String code, Object detail)
-  {
-    super(message);
-    this.code = code;
-    this.detail = detail;
-  }
-
-  /**
-   * Returns the code.
-   */
-  public String getCode()
-  {
-    return code;
-  }
-
-  /**
-   * Returns the detail.
-   */
-  public Object getDetail()
-  {
-    return detail;
-  }
-}
diff --git src/com/caucho/hessian/io/IOExceptionWrapper.java src/com/caucho/hessian/io/IOExceptionWrapper.java
deleted file mode 100644
index df0073e..0000000
--- src/com/caucho/hessian/io/IOExceptionWrapper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Exception wrapper for IO.
- */
-public class IOExceptionWrapper extends IOException {
-  private Throwable _cause;
-  
-  public IOExceptionWrapper(Throwable cause)
-  {
-    super(cause.toString());
-
-    _cause = cause;
-  }
-  
-  public IOExceptionWrapper(String msg, Throwable cause)
-  {
-    super(msg);
-
-    _cause = cause;
-  }
-
-  public Throwable getCause()
-  {
-    return _cause;
-  }
-}
diff --git src/com/caucho/hessian/io/InputStreamDeserializer.java src/com/caucho/hessian/io/InputStreamDeserializer.java
deleted file mode 100644
index 8655885..0000000
--- src/com/caucho/hessian/io/InputStreamDeserializer.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Serializing a stream object.
- */
-public class InputStreamDeserializer extends AbstractDeserializer {
-  public InputStreamDeserializer()
-  {
-  }
-  
-  public Object readObject(AbstractHessianInput in)
-    throws IOException
-  {
-    return in.readInputStream();
-  }
-}
diff --git src/com/caucho/hessian/io/InputStreamSerializer.java src/com/caucho/hessian/io/InputStreamSerializer.java
deleted file mode 100644
index 9540e96..0000000
--- src/com/caucho/hessian/io/InputStreamSerializer.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Serializing a stream object.
- */
-public class InputStreamSerializer extends AbstractSerializer {
-  public InputStreamSerializer()
-  {
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    InputStream is = (InputStream) obj;
-
-    if (is == null)
-      out.writeNull();
-    else {
-      byte []buf = new byte[1024];
-      int len;
-
-      while ((len = is.read(buf, 0, buf.length)) > 0) {
-	out.writeByteBufferPart(buf, 0, len);
-      }
-      
-      out.writeByteBufferEnd(buf, 0, 0);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/IteratorSerializer.java src/com/caucho/hessian/io/IteratorSerializer.java
deleted file mode 100644
index 95ce4d7..0000000
--- src/com/caucho/hessian/io/IteratorSerializer.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-/**
- * Serializing a JDK 1.2 Iterator.
- */
-public class IteratorSerializer extends AbstractSerializer {
-  private static IteratorSerializer _serializer;
-
-  public static IteratorSerializer create()
-  {
-    if (_serializer == null)
-      _serializer = new IteratorSerializer();
-
-    return _serializer;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    Iterator iter = (Iterator) obj;
-
-    boolean hasEnd = out.writeListBegin(-1, null);
-
-    while (iter.hasNext()) {
-      Object value = iter.next();
-
-      out.writeObject(value);
-    }
-
-    if (hasEnd)
-      out.writeListEnd();
-  }
-}
diff --git src/com/caucho/hessian/io/JavaDeserializer.java src/com/caucho/hessian/io/JavaDeserializer.java
deleted file mode 100644
index 2d0743a..0000000
--- src/com/caucho/hessian/io/JavaDeserializer.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-
-/**
- * Serializing an object for known object types.
- */
-public class JavaDeserializer extends AbstractMapDeserializer {
-  private static final Logger log = Logger.getLogger(JavaDeserializer.class.getName());
-  
-  private final static Map<Class<?>, FieldDeserializer> deserializerCache = new HashMap<Class<?>, FieldDeserializer>();
-  
-  private final Class<?> _type;
-  private Map<String, FieldDeserializer> _fieldMap;
-  private Map<String, Field> _keyFieldMap;
-  private Method _readResolve;
-  
-  private Constructor _constructor;
-  private Object []_constructorArgs;
-  
-  public JavaDeserializer(Class<?> type)
-  {
-    _type = type;
-    _keyFieldMap = new HashMap<String, Field>();
-    
-    initFieldMap(type);
-
-    _readResolve = getReadResolve(type);
-
-    if (_readResolve != null) {
-      _readResolve.setAccessible(true);
-    }
-
-    Constructor []constructors = type.getDeclaredConstructors();
-    long bestCost = Long.MAX_VALUE;
-
-    for (int i = 0; i < constructors.length; i++) {
-      Class []param = constructors[i].getParameterTypes();
-      long cost = 0;
-
-      for (int j = 0; j < param.length; j++) {
-	cost = 4 * cost;
-
-	if (Object.class.equals(param[j]))
-	  cost += 1;
-	else if (String.class.equals(param[j]))
-	  cost += 2;
-	else if (int.class.equals(param[j]))
-	  cost += 3;
-	else if (long.class.equals(param[j]))
-	  cost += 4;
-	else if (param[j].isPrimitive())
-	  cost += 5;
-	else
-	  cost += 6;
-      }
-
-      if (cost < 0 || cost > (1 << 48))
-	cost = 1 << 48;
-
-      cost += (long) param.length << 48;
-
-      if (cost < bestCost) {
-        _constructor = constructors[i];
-        bestCost = cost;
-      }
-    }
-
-    if (_constructor != null) {
-      _constructor.setAccessible(true);
-      Class []params = _constructor.getParameterTypes();
-      _constructorArgs = new Object[params.length];
-      for (int i = 0; i < params.length; i++) {
-        _constructorArgs[i] = getParamArg(params[i]);
-      }
-    }
-  }
-
-  public Class<?> getType()
-  {
-    return _type;
-  }
-    
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    try {
-      Object obj = instantiate();
-      return readMap(in, obj);
-    } catch (IOException e) {
-      throw e;
-    } catch (RuntimeException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e);
-    }
-  }
-    
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    try {
-      Object obj = instantiate();
-
-      return readObject(in, obj, fieldNames);
-    } catch (IOException e) {
-      throw e;
-    } catch (RuntimeException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e);
-    }
-  }
-
-  private static Method getReadResolve(Class<?> cl)
-  {
-    try {
-		return cl.getMethod("readResolve", new Class[0]);
-	} catch (Exception e) {}
-	return null;
-  }
-    
-  public Object readMap(AbstractHessianInput in, Object obj)
-    throws IOException
-  {
-    try {
-      int ref = in.addRef(obj);
-
-      while (! in.isEnd()) {
-        Object key = in.readObject();
-        
-        final Field field = _keyFieldMap.get(key);
-		final FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(key);
-
-        if (deser != null)
-          deser.deserialize(in, field, obj);
-        else
-          in.readObject();
-      }
-      
-      in.readMapEnd();
-
-      Object resolve = resolve(obj);
-
-      if (obj != resolve)
-	in.setRef(ref, resolve);
-
-      return resolve;
-    } catch (IOException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-    
-  public Object readObject(AbstractHessianInput in,
-			   Object obj,
-			   String []fieldNames)
-    throws IOException
-  {
-    try {
-      int ref = in.addRef(obj);
-
-      for (int i = 0; i < fieldNames.length; i++) {
-        String name = fieldNames[i];
-        
-        final Field field = _keyFieldMap.get(name);
-		final FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(name);
-
-        if (deser != null)
-        	deser.deserialize(in, _keyFieldMap.get(name), obj);
-        else
-          in.readObject();
-      }
-
-      Object resolve = resolve(obj);
-
-      if (obj != resolve)
-	in.setRef(ref, resolve);
-
-      return resolve;
-    } catch (IOException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e);
-    }
-  }
-
-  private Object resolve(Object obj)
-    throws Exception
-  {
-    // if there's a readResolve method, call it
-    try {
-      if (_readResolve != null)
-        return _readResolve.invoke(obj, new Object[0]);
-    } catch (InvocationTargetException e) {
-      if (e.getTargetException() != null)
-	throw e;
-    }
-
-    return obj;
-  }
-
-  protected <T> T instantiate()
-    throws Exception
-  {
-    try {
-      if (_constructor != null)
-	return (T) _constructor.newInstance(_constructorArgs);
-      else
-	return (T) _type.newInstance();
-    } catch (Exception e) {
-      throw new HessianProtocolException("'" + _type.getName() + "' could not be instantiated", e);
-    }
-  }
-
-  /**
-   * Creates a map of the classes fields.
-   */
-  private void initFieldMap(Class<?> cl)
-  {
-    _fieldMap = new HashMap<String, FieldDeserializer>();
-    
-    while (cl != null) {
-      Field []fields = cl.getDeclaredFields();
-      for (int i = 0; i < fields.length; i++) {
-        final Field field = fields[i];
-
-        if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers()))
-          continue;
-        else if (_fieldMap.get(field.getName()) != null)
-          continue;
-
-        try {
-          field.setAccessible(true);
-        } catch (Throwable e) {}
-
-		final Class<?> type = field.getType();
-		FieldDeserializer deser = null;
-	
-		if (!deserializerCache.containsKey(type))  {
-			if (String.class.equals(type))
-				deser = new StringFieldDeserializer();
-			else if (byte.class.equals(type)) {
-				deser = new ByteFieldDeserializer();
-			}
-			else if (short.class.equals(type)) {
-				deser = new ShortFieldDeserializer();
-			}
-			else if (int.class.equals(type)) {
-				deser = new IntFieldDeserializer();
-			}
-			else if (long.class.equals(type)) {
-				deser = new LongFieldDeserializer();
-			}
-			else if (float.class.equals(type)) {
-				deser = new FloatFieldDeserializer();
-			}
-			else if (double.class.equals(type)) {
-				deser = new DoubleFieldDeserializer();
-			}
-			else if (boolean.class.equals(type)) {
-				deser = new BooleanFieldDeserializer();
-			}
-			else if (java.sql.Date.class.equals(type)) {
-				deser = new SqlDateFieldDeserializer();
-			}
-			else if (java.sql.Timestamp.class.equals(type)) {
-				deser = new SqlTimestampFieldDeserializer();
-			}
-			else if (java.sql.Time.class.equals(type)) {
-				deser = new SqlTimeFieldDeserializer();
-			}
-			else {
-				deser = new ObjectFieldDeserializer();
-			}	
-			
-			deserializerCache.put(type, deser);
-		}
-	
-		_fieldMap.put(field.getName(), deserializerCache.get(type));
-		_keyFieldMap.put(field.getName(), field);
-	  }
-      cl = cl.getSuperclass();
-    }
-  }
-
-  /**
-   * Creates a map of the classes fields.
-   */
-  protected static Object getParamArg(Class cl)
-  {
-    if (! cl.isPrimitive())
-      return null;
-    else if (boolean.class.equals(cl))
-      return Boolean.FALSE;
-    else if (byte.class.equals(cl))
-      return new Byte((byte) 0);
-    else if (short.class.equals(cl))
-      return new Short((short) 0);
-    else if (char.class.equals(cl))
-      return new Character((char) 0);
-    else if (int.class.equals(cl))
-      return Integer.valueOf(0);
-    else if (long.class.equals(cl))
-      return Long.valueOf(0);
-    else if (float.class.equals(cl))
-      return Float.valueOf(0);
-    else if (double.class.equals(cl))
-      return Double.valueOf(0);
-    else
-      throw new UnsupportedOperationException();
-  }
-
-  abstract static class FieldDeserializer {
-    abstract void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException;
-  }
-
-  static class ObjectFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      Object value = null;
-      
-      try {
-	value = in.readObject(field.getType());
-	
-	field.set(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class BooleanFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      boolean value = false;
-      
-      try {
-	value = in.readBoolean();
-	
-	field.setBoolean(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class ByteFieldDeserializer extends FieldDeserializer {
-     void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      int value = 0;
-      
-      try {
-	value = in.readInt();
-	
-	field.setByte(obj, (byte) value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class ShortFieldDeserializer extends FieldDeserializer {
-     void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      int value = 0;
-      
-      try {
-	value = in.readInt();
-	
-	field.setShort(obj, (short) value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class IntFieldDeserializer extends FieldDeserializer {
-     void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      int value = 0;
-      
-      try {
-	value = in.readInt();
-	
-	field.setInt(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class LongFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      long value = 0;
-      
-      try {
-	value = in.readLong();
-	
-	field.setLong(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class FloatFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      double value = 0;
-      
-      try {
-	value = in.readDouble();
-	
-	field.setFloat(obj, (float) value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class DoubleFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      double value = 0;
-      
-      try {
-	value = in.readDouble();
-	
-	field.setDouble(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class StringFieldDeserializer extends FieldDeserializer {
-     void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      String value = null;
-      
-      try {
-	value = in.readString();
-	
-	field.set(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class SqlDateFieldDeserializer extends FieldDeserializer {
-     void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      java.sql.Date value = null;
-
-      try {
-        java.util.Date date = (java.util.Date) in.readObject();
-        value = new java.sql.Date(date.getTime());
-
-        field.set(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class SqlTimestampFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      java.sql.Timestamp value = null;
-
-      try {
-        java.util.Date date = (java.util.Date) in.readObject();
-        value = new java.sql.Timestamp(date.getTime());
-
-        field.set(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static class SqlTimeFieldDeserializer extends FieldDeserializer {
-    void deserialize(AbstractHessianInput in, Field field, Object obj)
-      throws IOException
-    {
-      java.sql.Time value = null;
-
-      try {
-        java.util.Date date = (java.util.Date) in.readObject();
-        value = new java.sql.Time(date.getTime());
-
-        field.set(obj, value);
-      } catch (Exception e) {
-        logDeserializeError(field, obj, value, e);
-      }
-    }
-  }
-
-  static void logDeserializeError(Field field, Object obj, Object value,
-                                  Throwable e)
-    throws IOException
-  {
-    String fieldName = (field.getDeclaringClass().getName()
-                        + "." + field.getName());
-
-    if (e instanceof HessianFieldException)
-      throw (HessianFieldException) e;
-    else if (e instanceof IOException)
-      throw new HessianFieldException(fieldName + ": " + e.getMessage(), e);
-    
-    if (value != null)
-      throw new HessianFieldException(fieldName + ": " + value.getClass().getName() + " (" + value + ")"
-					 + " cannot be assigned to '" + field.getType().getName() + "'");
-    else
-       throw new HessianFieldException(fieldName + ": " + field.getType().getName() + " cannot be assigned from null", e);
-  }
-}
diff --git src/com/caucho/hessian/io/JavaSerializer.java src/com/caucho/hessian/io/JavaSerializer.java
deleted file mode 100644
index 22b58f2..0000000
--- src/com/caucho/hessian/io/JavaSerializer.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Serializing an object for known object types.
- */
-public class JavaSerializer extends AbstractSerializer
-{
-  private static final Logger log = Logger.getLogger(JavaSerializer.class.getName());
-
-  private static Map<Class<?>, ArrayList<Field>> fieldsCache = new HashMap<Class<?>, ArrayList<Field>>();
-  private static Map<Class<?>, ArrayList<FieldSerializer>> fieldSerializerCache = new HashMap<Class<?>, ArrayList<FieldSerializer>>();
-  
-  private Object _writeReplaceFactory;
-  private Method _writeReplace;
-  
-  private Class<?> _type;
-  
-  public JavaSerializer(Class<?> cl)
-  {
-	_type = cl;
-	
-	introspectWriteReplace(cl);
-    
-    if (_writeReplace != null)
-      _writeReplace.setAccessible(true);
-
-    if (!fieldsCache.containsKey(cl))  {
-    	final ArrayList<Field> primitiveFields = new ArrayList<Field>();
-    	final ArrayList<Field> compoundFields = new ArrayList<Field>();
-    	final ArrayList<FieldSerializer> fieldSerializers = new ArrayList<FieldSerializer>();
-	    
-    	
-    	
-	    for (; cl != null; cl = cl.getSuperclass()) {
-	      final Field []fields = cl.getDeclaredFields();
-	      for (int i = 0; i < fields.length; i++) {
-	    	Field field = fields[i];
-	
-			if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers()))
-			  continue;
-	
-			field.setAccessible(true);
-		
-			if (field.getType().isPrimitive() || (field.getType().getName().startsWith("java.lang.") && ! field.getType().equals(Object.class)))
-			  primitiveFields.add(field);
-			else
-			  compoundFields.add(field);
-		  }
-		}
-	    
-	    final ArrayList<Field> result = new ArrayList<Field>();
-	    result.addAll(primitiveFields);
-	    result.addAll(compoundFields);
-	    
-	    fieldsCache.put(_type, result);
-	    fieldSerializerCache.put(_type, fieldSerializers);
-	    
-	    for (int i = 0; i < result.size(); i++) {
-	    	fieldSerializers.add(getFieldSerializer(result.get(i).getType()));
-	    }
-    }
-  }
-
-  private void introspectWriteReplace(Class cl)
-  {
-    try {
-      ClassLoader loader = Thread.currentThread().getContextClassLoader();
-
-      String className = cl.getName() + "HessianSerializer";
-
-      Class serializerClass = Class.forName(className, false, loader);
-
-      Object serializerObject = serializerClass.newInstance();
-
-      Method writeReplace = getWriteReplace(serializerClass, cl);
-
-      if (writeReplace != null) {
-	_writeReplaceFactory = serializerObject;
-	_writeReplace = writeReplace;
-
-	return;
-      }
-    } catch (ClassNotFoundException e) {
-    } catch (Exception e) {
-      log.log(Level.FINER, e.toString(), e);
-    }
-      
-    _writeReplace = getWriteReplace(cl);
-  }
-
-  /**
-   * Returns the writeReplace method
-   */
-  protected static Method getWriteReplace(Class<?> cl)
-  {
-    try {
-		return cl.getMethod("writeReplace", new Class[0]);
-	} catch (Exception e) {}
-	
-	return null;
-  }
-
-  /**
-   * Returns the writeReplace method
-   */
-  protected Method getWriteReplace(Class<?> cl, Class<?> param)
-  {
-    try {
-		return cl.getMethod("writeReplace", new Class[] { param });
-	} catch (Exception e) {}
-	
-	return null;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (out.addRef(obj)) {
-      return;
-    }
-    
-    final Class<?> cl = obj.getClass();
-
-    try {
-      if (_writeReplace != null) {
-	Object repl;
-
-	if (_writeReplaceFactory != null)
-	  repl = _writeReplace.invoke(_writeReplaceFactory, obj);
-	else
-	  repl = _writeReplace.invoke(obj);
-
-	out.removeRef(obj);
-
-	out.writeObject(repl);
-
-	out.replaceRef(repl, obj);
-
-	return;
-      }
-    } catch (RuntimeException e) {
-      throw e;
-    } catch (Exception e) {
-      // log.log(Level.FINE, e.toString(), e);
-      throw new RuntimeException(e);
-    }
-
-    int ref = out.writeObjectBegin(cl.getName());
-
-    if (ref < -1) {
-      writeObject10(obj, out);
-    }
-    else {
-      if (ref == -1) {
-	writeDefinition20(out);
-	out.writeObjectBegin(cl.getName());
-      }
-
-      writeInstance(obj, out);
-    }
-  }
-  
-  private void writeObject10(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-  	final ArrayList<Field> fields = fieldsCache.get(_type);
-  	final ArrayList<FieldSerializer> fieldSerializers = fieldSerializerCache.get(_type);
-    
-  	for (int i = 0; i < fields.size(); i++) {
-      final Field field = fields.get(i);
-
-      out.writeString(field.getName());
-	
-      fieldSerializers.get(i).serialize(out, obj, field);
-    }
-      
-    out.writeMapEnd();
-  }
-  
-  private void writeDefinition20(AbstractHessianOutput out)
-    throws IOException
-  {
-	final ArrayList<Field> fields = fieldsCache.get(_type);
-	  
-    out.writeClassFieldLength(fields.size());
-	
-    for (int i = 0; i < fields.size(); i++) {
-      final Field field = fields.get(i);
-      
-      out.writeString(field.getName());
-    }
-  }
-  
-  public void writeInstance(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-	final ArrayList<Field> fields = fieldsCache.get(_type);
-	final ArrayList<FieldSerializer> fieldSerializers = fieldSerializerCache.get(_type);	  
-	  
-    for (int i = 0; i < fields.size(); i++) {
-      final Field field = fields.get(i);
-
-      fieldSerializers.get(i).serialize(out, obj, field);
-    }
-  }
-
-  private static FieldSerializer getFieldSerializer(Class<?> type)
-  {
-    if (int.class.equals(type)
-        || byte.class.equals(type)
-        || short.class.equals(type)
-        || int.class.equals(type)) {
-      return IntFieldSerializer.SER;
-    }
-    else if (long.class.equals(type)) {
-      return LongFieldSerializer.SER;
-    }
-    else if (double.class.equals(type) ||
-        float.class.equals(type)) {
-      return DoubleFieldSerializer.SER;
-    }
-    else if (boolean.class.equals(type)) {
-      return BooleanFieldSerializer.SER;
-    }
-    else if (String.class.equals(type)) {
-      return StringFieldSerializer.SER;
-    }
-    else if (java.util.Date.class.equals(type)
-             || java.sql.Date.class.equals(type)
-             || java.sql.Timestamp.class.equals(type)
-             || java.sql.Time.class.equals(type)) {
-      return DateFieldSerializer.SER;
-    }
-    else
-      return FieldSerializer.SER;
-  }
-
-  static class FieldSerializer {
-    static final FieldSerializer SER = new FieldSerializer();
-    
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      Object value = null;
-	
-      try {
-	value = field.get(obj);
-      } catch (IllegalAccessException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-
-      try {
-	out.writeObject(value);
-      } catch (RuntimeException e) {
-	throw new RuntimeException(e.getMessage() + "\n Java field: " + field,
-				   e);
-      } catch (IOException e) {
-	throw new IOExceptionWrapper(e.getMessage() + "\n Java field: " + field,
-			      e);
-      }
-    }
-  }
-
-  static class BooleanFieldSerializer extends FieldSerializer {
-    static final FieldSerializer SER = new BooleanFieldSerializer();
-    
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      boolean value = false;
-	
-      try {
-	value = field.getBoolean(obj);
-      } catch (IllegalAccessException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-
-      out.writeBoolean(value);
-    }
-  }
-
-  static class IntFieldSerializer extends FieldSerializer {
-    static final FieldSerializer SER = new IntFieldSerializer();
-    
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      int value = 0;
-	
-      try {
-	value = field.getInt(obj);
-      } catch (IllegalAccessException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-
-      out.writeInt(value);
-    }
-  }
-
-  static class LongFieldSerializer extends FieldSerializer {
-    static final FieldSerializer SER = new LongFieldSerializer();
-    
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      long value = 0;
-	
-      try {
-	value = field.getLong(obj);
-      } catch (IllegalAccessException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-
-      out.writeLong(value);
-    }
-  }
-
-  static class DoubleFieldSerializer extends FieldSerializer {
-    static final FieldSerializer SER = new DoubleFieldSerializer();
-    
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      double value = 0;
-	
-      try {
-	value = field.getDouble(obj);
-      } catch (IllegalAccessException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-
-      out.writeDouble(value);
-    }
-  }
-
-  static class StringFieldSerializer extends FieldSerializer {
-    static final FieldSerializer SER = new StringFieldSerializer();
-    
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      String value = null;
-	
-      try {
-	value = (String) field.get(obj);
-      } catch (IllegalAccessException e) {
-	log.log(Level.FINE, e.toString(), e);
-      }
-
-      out.writeString(value);
-    }
-  }
-
-  static class DateFieldSerializer extends FieldSerializer {
-    static final FieldSerializer SER = new DateFieldSerializer();
-
-    void serialize(AbstractHessianOutput out, Object obj, Field field)
-      throws IOException
-    {
-      java.util.Date value = null;
-
-      try {
-        value = (java.util.Date) field.get(obj);
-      } catch (IllegalAccessException e) {
-        log.log(Level.FINE, e.toString(), e);
-      }
-
-      
-      if (value != null) out.writeUTCDate(value.getTime()); else out.writeNull();
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/LocaleHandle.java src/com/caucho/hessian/io/LocaleHandle.java
deleted file mode 100644
index 68239f8..0000000
--- src/com/caucho/hessian/io/LocaleHandle.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.util.Locale;
-
-/**
- * Handle for a locale object.
- */
-public class LocaleHandle implements java.io.Serializable, HessianHandle {
-  private String value;
-
-  public LocaleHandle(String locale)
-  {
-    this.value = locale;
-  }
-
-  private Object readResolve()
-  {
-    String s = this.value;
-    
-    if (s == null)
-      return null;
-    
-    int len = s.length();
-    char ch = ' ';
-
-    int i = 0;
-    for (;
-	 i < len && ('a' <= (ch = s.charAt(i)) && ch <= 'z'
-		     || 'A' <= ch && ch <= 'Z'
-		     || '0' <= ch && ch <= '9');
-	 i++) {
-    }
-
-    String language = s.substring(0, i);
-    String country = null;
-    String var = null;
-
-    if (ch == '-' || ch == '_') {
-      int head = ++i;
-      
-      for (;
-	   i < len && ('a' <= (ch = s.charAt(i)) && ch <= 'z'
-		       || 'A' <= ch && ch <= 'Z'
-		       || '0' <= ch && ch <= '9');
-	   i++) {
-      }
-      
-      country = s.substring(head, i);
-    }
-
-    if (ch == '-' || ch == '_') {
-      int head = ++i;
-      
-      for (;
-	   i < len && ('a' <= (ch = s.charAt(i)) && ch <= 'z'
-		       || 'A' <= ch && ch <= 'Z'
-		       || '0' <= ch && ch <= '9');
-	   i++) {
-      }
-      
-      var = s.substring(head, i);
-    }
-
-    if (var != null)
-      return new Locale(language, country, var);
-    else if (country != null)
-      return new Locale(language, country);
-    else
-      return new Locale(language);
-  }
-}
diff --git src/com/caucho/hessian/io/LocaleSerializer.java src/com/caucho/hessian/io/LocaleSerializer.java
deleted file mode 100644
index f15f32d..0000000
--- src/com/caucho/hessian/io/LocaleSerializer.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Locale;
-
-/**
- * Serializing a locale.
- */
-public class LocaleSerializer extends AbstractSerializer {
-  private static LocaleSerializer SERIALIZER = new LocaleSerializer();
-
-  public static LocaleSerializer create()
-  {
-    return SERIALIZER;
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (obj == null)
-      out.writeNull();
-    else {
-      Locale locale = (Locale) obj;
-
-      out.writeObject(new LocaleHandle(locale.toString()));
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/MapDeserializer.java src/com/caucho/hessian/io/MapDeserializer.java
deleted file mode 100644
index ed61dbf..0000000
--- src/com/caucho/hessian/io/MapDeserializer.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.*;
-import java.lang.reflect.*;
-
-/**
- * Deserializing a JDK 1.2 Map.
- */
-public class MapDeserializer extends AbstractMapDeserializer {
-  private Class _type;
-  private Constructor _ctor;
-  
-  public MapDeserializer(Class type)
-  {
-    if (type == null)
-      type = HashMap.class;
-    
-    _type = type;
-
-    Constructor []ctors = type.getConstructors();
-    for (int i = 0; i < ctors.length; i++) {
-      if (ctors[i].getParameterTypes().length == 0)
-	_ctor = ctors[i];
-    }
-
-    if (_ctor == null) {
-      try {
-	_ctor = HashMap.class.getConstructor(new Class[0]);
-      } catch (Exception e) {
-	throw new IllegalStateException(e);
-      }
-    }
-  }
-  
-  public Class getType()
-  {
-    if (_type != null)
-      return _type;
-    else
-      return HashMap.class;
-  }
-
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    Map map;
-    
-    if (_type == null)
-      map = new HashMap();
-    else if (_type.equals(Map.class))
-      map = new HashMap();
-    else if (_type.equals(SortedMap.class))
-      map = new TreeMap();
-    else {
-      try {
-        map = (Map) _ctor.newInstance();
-      } catch (Exception e) {
-        throw new IOExceptionWrapper(e);
-      }
-    }
-
-    in.addRef(map);
-
-    while (! in.isEnd()) {
-      map.put(in.readObject(), in.readObject());
-    }
-
-    in.readEnd();
-
-    return map;
-  }
-
-  @Override
-  public Object readObject(AbstractHessianInput in,
-			   String []fieldNames)
-    throws IOException
-  {
-    Map map = createMap();
-      
-    int ref = in.addRef(map);
-
-    for (int i = 0; i < fieldNames.length; i++) {
-      String name = fieldNames[i];
-
-      map.put(name, in.readObject());
-    }
-
-    return map;
-  }
-
-  private Map createMap()
-    throws IOException
-  {
-    
-    if (_type == null)
-      return new HashMap();
-    else if (_type.equals(Map.class))
-      return new HashMap();
-    else if (_type.equals(SortedMap.class))
-      return new TreeMap();
-    else {
-      try {
-        return (Map) _ctor.newInstance();
-      } catch (Exception e) {
-        throw new IOExceptionWrapper(e);
-      }
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/MapSerializer.java src/com/caucho/hessian/io/MapSerializer.java
deleted file mode 100644
index 42d8986..0000000
--- src/com/caucho/hessian/io/MapSerializer.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Serializing a JDK 1.2 java.util.Map.
- */
-public class MapSerializer extends AbstractSerializer {
-  private boolean _isSendJavaType = true;
-
-  /**
-   * Set true if the java type of the collection should be sent.
-   */
-  public void setSendJavaType(boolean sendJavaType)
-  {
-    _isSendJavaType = sendJavaType;
-  }
-
-  /**
-   * Return true if the java type of the collection should be sent.
-   */
-  public boolean getSendJavaType()
-  {
-    return _isSendJavaType;
-  }
-    
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (out.addRef(obj))
-      return;
-
-    Map map = (Map) obj;
-
-    Class cl = obj.getClass();
-    
-    if (cl.equals(HashMap.class)
-	|| ! _isSendJavaType
-	|| ! (obj instanceof java.io.Serializable))
-      out.writeMapBegin(null);
-    else
-      out.writeMapBegin(obj.getClass().getName());
-
-    Iterator iter = map.entrySet().iterator();
-    while (iter.hasNext()) {
-      Map.Entry entry = (Map.Entry) iter.next();
-
-      out.writeObject(entry.getKey());
-      out.writeObject(entry.getValue());
-    }
-    out.writeMapEnd();
-  }
-}
diff --git src/com/caucho/hessian/io/ObjectDeserializer.java src/com/caucho/hessian/io/ObjectDeserializer.java
deleted file mode 100644
index ec2647b..0000000
--- src/com/caucho/hessian/io/ObjectDeserializer.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-
-/**
- * Serializing an object for known object types.
- */
-public class ObjectDeserializer extends AbstractDeserializer {
-  private Class _cl;
-
-  public ObjectDeserializer(Class cl)
-  {
-    _cl = cl;
-  }
-
-  public Class getType()
-  {
-    return _cl;
-  }
-  
-  public Object readObject(AbstractHessianInput in)
-    throws IOException
-  {
-    return in.readObject();
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    throw new UnsupportedOperationException(String.valueOf(this));
-  }
-  
-  public Object readList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    throw new UnsupportedOperationException(String.valueOf(this));
-  }
-  
-  public Object readLengthList(AbstractHessianInput in, int length)
-    throws IOException
-  {
-    throw new UnsupportedOperationException(String.valueOf(this));
-  }
-
-  @Override
-  public String toString()
-  {
-    return getClass().getSimpleName() + "[" + _cl + "]";
-  }
-}
diff --git src/com/caucho/hessian/io/RemoteSerializer.java src/com/caucho/hessian/io/RemoteSerializer.java
deleted file mode 100644
index 889aa31..0000000
--- src/com/caucho/hessian/io/RemoteSerializer.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Serializing a remote object.
- */
-public class RemoteSerializer extends AbstractSerializer {
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (obj instanceof HessianRemoteObject) {
-      HessianRemoteObject remote = (HessianRemoteObject) obj;
-
-      out.writeRemote(remote.getHessianType(), remote.getHessianURL());
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/Serializer.java src/com/caucho/hessian/io/Serializer.java
deleted file mode 100644
index 94b7076..0000000
--- src/com/caucho/hessian/io/Serializer.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Serializing an object. 
- */
-public interface Serializer {
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException;
-}
diff --git src/com/caucho/hessian/io/SerializerFactory.java src/com/caucho/hessian/io/SerializerFactory.java
deleted file mode 100644
index 851d4ae..0000000
--- src/com/caucho/hessian/io/SerializerFactory.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.*;
-import java.math.BigDecimal;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Factory for returning serialization methods.
- */
-public class SerializerFactory extends AbstractSerializerFactory
-{
-  private static final Logger log
-    = Logger.getLogger(SerializerFactory.class.getName());
-
-  private static Deserializer OBJECT_DESERIALIZER
-    = new BasicDeserializer(BasicDeserializer.OBJECT);
-  
-  private static HashMap _staticSerializerMap;
-  private static HashMap _staticDeserializerMap;
-  private static HashMap _staticTypeMap;
-
-  protected Serializer _defaultSerializer;
-
-  // Additional factories
-  protected ArrayList _factories = new ArrayList();
-  
-  protected CollectionSerializer _collectionSerializer;
-  protected MapSerializer _mapSerializer;
-  
-  private Deserializer _hashMapDeserializer;
-  private Deserializer _arrayListDeserializer;
-  private HashMap _cachedSerializerMap;
-  private HashMap _cachedDeserializerMap;
-  private HashMap _cachedTypeDeserializerMap;
-
-  private boolean _isAllowNonSerializable;
-
-  /**
-   * Set true if the collection serializer should send the java type.
-   */
-  public void setSendCollectionType(boolean isSendType)
-  {
-    if (_collectionSerializer == null)
-      _collectionSerializer = new CollectionSerializer();
-
-    _collectionSerializer.setSendJavaType(isSendType);
-    
-    if (_mapSerializer == null)
-      _mapSerializer = new MapSerializer();
-
-    _mapSerializer.setSendJavaType(isSendType);
-  }
-
-  /**
-   * Adds a factory.
-   */
-  public void addFactory(AbstractSerializerFactory factory)
-  {
-    _factories.add(factory);
-  }
-
-  /**
-   * If true, non-serializable objects are allowed.
-   */
-  public void setAllowNonSerializable(boolean allow)
-  {
-    _isAllowNonSerializable = allow;
-  }
-
-  /**
-   * If true, non-serializable objects are allowed.
-   */
-  public boolean isAllowNonSerializable()
-  {
-    return _isAllowNonSerializable;
-  }
-
-  /**
-   * Returns the serializer for a class.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  public Serializer getSerializer(Class cl)
-    throws HessianProtocolException
-  {
-    Serializer serializer;
-
-    serializer = (Serializer) _staticSerializerMap.get(cl);
-    if (serializer != null)
-      return serializer;
-
-    if (_cachedSerializerMap != null) {
-      synchronized (_cachedSerializerMap) {
-	serializer = (Serializer) _cachedSerializerMap.get(cl);
-      }
-      
-      if (serializer != null)
-	return serializer;
-    }
-
-    for (int i = 0;
-	 serializer == null && _factories != null && i < _factories.size();
-	 i++) {
-      AbstractSerializerFactory factory;
-
-      factory = (AbstractSerializerFactory) _factories.get(i);
-
-      serializer = factory.getSerializer(cl);
-    }
-
-    if (serializer != null) {
-    }
-
-    else if (JavaSerializer.getWriteReplace(cl) != null)
-      serializer = new JavaSerializer(cl);
-
-    else if (HessianRemoteObject.class.isAssignableFrom(cl))
-      serializer = new RemoteSerializer();
-//
-//    else if (BurlapRemoteObject.class.isAssignableFrom(cl))
-//      serializer = new RemoteSerializer();
-
-    else if (Map.class.isAssignableFrom(cl)) {
-      if (_mapSerializer == null)
-	_mapSerializer = new MapSerializer();
-      
-      serializer = _mapSerializer;
-    }
-    else if (Collection.class.isAssignableFrom(cl)) {
-      if (_collectionSerializer == null) {
-	_collectionSerializer = new CollectionSerializer();
-      }
-
-      serializer = _collectionSerializer;
-    }
-
-    else if (cl.isArray())
-      serializer = new ArraySerializer();
-
-    else if (Throwable.class.isAssignableFrom(cl))
-      serializer = new ThrowableSerializer(cl);
-
-    else if (InputStream.class.isAssignableFrom(cl))
-      serializer = new InputStreamSerializer();
-
-    else if (Iterator.class.isAssignableFrom(cl))
-      serializer = IteratorSerializer.create();
-
-    else if (Enumeration.class.isAssignableFrom(cl))
-      serializer = EnumerationSerializer.create();
-    
-    else if (Calendar.class.isAssignableFrom(cl))
-      serializer = CalendarSerializer.create();
-    
-    else if (Locale.class.isAssignableFrom(cl))
-      serializer = LocaleSerializer.create();
-    
-    else if (Enum.class.isAssignableFrom(cl))
-      serializer = new EnumSerializer(cl);
-
-    if (serializer == null)
-      serializer = getDefaultSerializer(cl);
-
-    if (_cachedSerializerMap == null)
-      _cachedSerializerMap = new HashMap(8);
-
-    synchronized (_cachedSerializerMap) {
-      _cachedSerializerMap.put(cl, serializer);
-    }
-
-    return serializer;
-  }
-
-  /**
-   * Returns the default serializer for a class that isn't matched
-   * directly.  Application can override this method to produce
-   * bean-style serialization instead of field serialization.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  protected Serializer getDefaultSerializer(Class cl)
-  {
-    if (_defaultSerializer != null)
-      return _defaultSerializer;
-
-    if (! Serializable.class.isAssignableFrom(cl)
-	&& ! _isAllowNonSerializable) {
-      throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable");
-    }
-
-    return new JavaSerializer(cl);
-  }
-  
-  /**
-   * Returns the deserializer for a class.
-   *
-   * @param cl the class of the object that needs to be deserialized.
-   *
-   * @return a deserializer object for the serialization.
-   */
-  public Deserializer getDeserializer(Class cl)
-    throws HessianProtocolException
-  {
-    Deserializer deserializer;
-
-    deserializer = (Deserializer) _staticDeserializerMap.get(cl);
-    if (deserializer != null)
-      return deserializer;
-
-    if (_cachedDeserializerMap != null) {
-      synchronized (_cachedDeserializerMap) {
-	deserializer = (Deserializer) _cachedDeserializerMap.get(cl);
-      }
-      
-      if (deserializer != null)
-	return deserializer;
-    }
-
-
-    for (int i = 0;
-	 deserializer == null && _factories != null && i < _factories.size();
-	 i++) {
-      AbstractSerializerFactory factory;
-      factory = (AbstractSerializerFactory) _factories.get(i);
-
-      deserializer = factory.getDeserializer(cl);
-    }
-
-    if (deserializer != null) {
-    }
-
-    else if (Collection.class.isAssignableFrom(cl))
-      deserializer = new CollectionDeserializer(cl);
-
-    else if (Map.class.isAssignableFrom(cl))
-      deserializer = new MapDeserializer(cl);
-    
-    else if (cl.isInterface())
-      deserializer = new ObjectDeserializer(cl);
-
-    else if (cl.isArray())
-      deserializer = new ArrayDeserializer(cl.getComponentType());
-
-    else if (Enumeration.class.isAssignableFrom(cl))
-      deserializer = EnumerationDeserializer.create();
-
-    else if (Enum.class.isAssignableFrom(cl))
-      deserializer = new EnumDeserializer(cl);
-    
-    else
-      deserializer = getDefaultDeserializer(cl);
-
-    if (_cachedDeserializerMap == null)
-      _cachedDeserializerMap = new HashMap(8);
-
-    synchronized (_cachedDeserializerMap) {
-      _cachedDeserializerMap.put(cl, deserializer);
-    }
-
-    return deserializer;
-  }
-
-  /**
-   * Returns the default serializer for a class that isn't matched
-   * directly.  Application can override this method to produce
-   * bean-style serialization instead of field serialization.
-   *
-   * @param cl the class of the object that needs to be serialized.
-   *
-   * @return a serializer object for the serialization.
-   */
-  protected Deserializer getDefaultDeserializer(Class cl)
-  {
-    return new JavaDeserializer(cl);
-  }
-
-  /**
-   * Reads the object as a list.
-   */
-  public Object readList(AbstractHessianInput in, int length, String type)
-    throws HessianProtocolException, IOException
-  {
-    Deserializer deserializer = getDeserializer(type);
-
-    if (deserializer != null)
-      return deserializer.readList(in, length);
-    else
-      return new CollectionDeserializer(ArrayList.class).readList(in, length);
-  }
-  
-  /**
-   * Reads the object as a map.
-   */
-  public Object readMap(AbstractHessianInput in, String type)
-    throws HessianProtocolException, IOException
-  {
-    Deserializer deserializer = getDeserializer(type);
-
-    if (deserializer != null)
-      return deserializer.readMap(in);
-    else if (_hashMapDeserializer != null)
-      return _hashMapDeserializer.readMap(in);
-    else {
-      _hashMapDeserializer = new MapDeserializer(HashMap.class);
-      
-      return _hashMapDeserializer.readMap(in);
-    }
-  }
-  
-  /**
-   * Reads the object as a map.
-   */
-  public Object readObject(AbstractHessianInput in,
-			   String type,
-			   String []fieldNames)
-    throws HessianProtocolException, IOException
-  {
-    Deserializer deserializer = getDeserializer(type);
-
-    if (deserializer != null)
-      return deserializer.readObject(in, fieldNames);
-    else if (_hashMapDeserializer != null)
-      return _hashMapDeserializer.readObject(in, fieldNames);
-    else {
-      _hashMapDeserializer = new MapDeserializer(HashMap.class);
-      
-      return _hashMapDeserializer.readObject(in, fieldNames);
-    }
-  }
-
-  /**
-   * Reads the object as a map.
-   */
-  public Deserializer getObjectDeserializer(String type, Class cl)
-    throws HessianProtocolException
-  {
-    Deserializer reader = getObjectDeserializer(type);
-    
-    if (cl == null
-	|| cl.equals(reader.getType())
-	|| cl.isAssignableFrom(reader.getType())
-	|| HessianHandle.class.isAssignableFrom(reader.getType())) {
-      return reader;
-    }
-
-    if (log.isLoggable(Level.FINE)) {
-      log.fine("hessian: expected '" + cl.getName() + "' at '" + type + "' ("
-	       + reader.getType().getName() + ")");
-    }
-    
-    return getDeserializer(cl);
-  }
-  
-  /**
-   * Reads the object as a map.
-   */
-  public Deserializer getObjectDeserializer(String type)
-    throws HessianProtocolException
-  {
-    Deserializer deserializer = getDeserializer(type);
-
-    if (deserializer != null)
-      return deserializer;
-    else if (_hashMapDeserializer != null)
-      return _hashMapDeserializer;
-    else {
-      _hashMapDeserializer = new MapDeserializer(HashMap.class);
-      
-      return _hashMapDeserializer;
-    }
-  }
-
-  /**
-   * Reads the object as a map.
-   */
-  public Deserializer getListDeserializer(String type, Class cl)
-    throws HessianProtocolException
-  {
-    Deserializer reader = getListDeserializer(type);
-    
-    if (cl == null
-	|| cl.equals(reader.getType())
-	|| cl.isAssignableFrom(reader.getType())) {
-      return reader;
-    }
-
-    if (log.isLoggable(Level.FINE)) {
-      log.fine("hessian: expected '" + cl.getName() + "' at '" + type + "' ("
-	       + reader.getType().getName() + ")");
-    }
-    
-    return getDeserializer(cl);
-  }
-  
-  /**
-   * Reads the object as a map.
-   */
-  public Deserializer getListDeserializer(String type)
-    throws HessianProtocolException
-  {
-    Deserializer deserializer = getDeserializer(type);
-
-    if (deserializer != null)
-      return deserializer;
-    else if (_arrayListDeserializer != null)
-      return _arrayListDeserializer;
-    else {
-      _arrayListDeserializer = new CollectionDeserializer(ArrayList.class);
-      
-      return _arrayListDeserializer;
-    }
-  }
-
-  /**
-   * Returns a deserializer based on a string type.
-   */
-  public Deserializer getDeserializer(String type)
-    throws HessianProtocolException
-  {
-    if (type == null || type.equals(""))
-      return null;
-
-    Deserializer deserializer;
-    
-    if (_cachedTypeDeserializerMap != null) {
-      synchronized (_cachedTypeDeserializerMap) {
-	deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type);
-      }
-
-      if (deserializer != null)
-	return deserializer;
-    }
-
-
-    deserializer = (Deserializer) _staticTypeMap.get(type);
-    if (deserializer != null)
-      return deserializer;
-
-    if (type.startsWith("[")) {
-      Deserializer subDeserializer = getDeserializer(type.substring(1));
-
-      if (subDeserializer != null)
-        deserializer = new ArrayDeserializer(subDeserializer.getType());
-      else
-        deserializer = new ArrayDeserializer(Object.class);
-    }
-    else {
-      try {
-	Class cl = Class.forName(type, false, getClass().getClassLoader());
-	deserializer = getDeserializer(cl);
-      } catch (Exception e) {
-	log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + getClass().getClassLoader() + ":\n" + e);
-	
-	log.log(Level.FINER, e.toString(), e);
-      }
-    }
-
-    if (deserializer != null) {
-      if (_cachedTypeDeserializerMap == null)
-	_cachedTypeDeserializerMap = new HashMap(8);
-
-      synchronized (_cachedTypeDeserializerMap) {
-	_cachedTypeDeserializerMap.put(type, deserializer);
-      }
-    }
-
-    return deserializer;
-  }
-
-  private static void addBasic(Class cl, String typeName, int type)
-  {
-    _staticSerializerMap.put(cl, new BasicSerializer(type));
-
-    Deserializer deserializer = new BasicDeserializer(type);
-    _staticDeserializerMap.put(cl, deserializer);
-    _staticTypeMap.put(typeName, deserializer);
-  }
-
-  static {
-    _staticSerializerMap = new HashMap();
-    _staticDeserializerMap = new HashMap();
-    _staticTypeMap = new HashMap();
-
-    addBasic(void.class, "void", BasicSerializer.NULL);
-    
-    addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN);
-    addBasic(Byte.class, "byte", BasicSerializer.BYTE);
-    addBasic(Short.class, "short", BasicSerializer.SHORT);
-    addBasic(Integer.class, "int", BasicSerializer.INTEGER);
-    addBasic(Long.class, "long", BasicSerializer.LONG);
-    addBasic(Float.class, "float", BasicSerializer.FLOAT);
-    addBasic(Double.class, "double", BasicSerializer.DOUBLE);
-    addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT);
-    addBasic(String.class, "string", BasicSerializer.STRING);
-    addBasic(Object.class, "object", BasicSerializer.OBJECT);
-    addBasic(java.util.Date.class, "date", BasicSerializer.DATE);
-
-    addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN);
-    addBasic(byte.class, "byte", BasicSerializer.BYTE);
-    addBasic(short.class, "short", BasicSerializer.SHORT);
-    addBasic(int.class, "int", BasicSerializer.INTEGER);
-    addBasic(long.class, "long", BasicSerializer.LONG);
-    addBasic(float.class, "float", BasicSerializer.FLOAT);
-    addBasic(double.class, "double", BasicSerializer.DOUBLE);
-    addBasic(char.class, "char", BasicSerializer.CHARACTER);
-    
-    addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY);
-    addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY);
-    addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY);
-    addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY);
-    addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY);
-    addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY);
-    addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY);
-    addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY);
-    addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY);
-    addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY);
-
-    _staticSerializerMap.put(Class.class, new ClassSerializer());
-    _staticDeserializerMap.put(Class.class, new ClassDeserializer());
-
-    _staticDeserializerMap.put(Number.class, new BasicDeserializer(BasicSerializer.NUMBER));
-    
-    _staticSerializerMap.put(BigDecimal.class, new StringValueSerializer());
-    try {
-      _staticDeserializerMap.put(BigDecimal.class,
-			   new StringValueDeserializer(BigDecimal.class));
-    } catch (Throwable e) {
-    }
-    
-    _staticSerializerMap.put(File.class, new StringValueSerializer());
-    try {
-      _staticDeserializerMap.put(File.class,
-			   new StringValueDeserializer(File.class));
-    } catch (Throwable e) {
-    }
-    
-//    _staticSerializerMap.put(ObjectName.class, new StringValueSerializer());
-//    try {
-//      _staticDeserializerMap.put(ObjectName.class,
-//			   new StringValueDeserializer(ObjectName.class));
-//    } catch (Throwable e) {
-//    }
-    
-    _staticSerializerMap.put(java.sql.Date.class, new SqlDateSerializer());
-    _staticSerializerMap.put(java.sql.Time.class, new SqlDateSerializer());
-    _staticSerializerMap.put(java.sql.Timestamp.class, new SqlDateSerializer());
-    
-    _staticSerializerMap.put(java.io.InputStream.class,
-			     new InputStreamSerializer());
-    _staticDeserializerMap.put(java.io.InputStream.class,
-			       new InputStreamDeserializer());
-
-    try {
-      _staticDeserializerMap.put(java.sql.Date.class,
-			  new SqlDateDeserializer(java.sql.Date.class));
-      _staticDeserializerMap.put(java.sql.Time.class,
-			  new SqlDateDeserializer(java.sql.Time.class));
-      _staticDeserializerMap.put(java.sql.Timestamp.class,
-			  new SqlDateDeserializer(java.sql.Timestamp.class));
-    } catch (Throwable e) {
-      e.printStackTrace();
-    }
-
-    // hessian/3bb5
-    try {
-      Class stackTrace = Class.forName("java.lang.StackTraceElement");
-      
-      _staticDeserializerMap.put(stackTrace, new StackTraceElementDeserializer());
-    } catch (Throwable e) {
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/SqlDateDeserializer.java src/com/caucho/hessian/io/SqlDateDeserializer.java
deleted file mode 100644
index 73dff3a..0000000
--- src/com/caucho/hessian/io/SqlDateDeserializer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-
-/**
- * Deserializing a string valued object
- */
-public class SqlDateDeserializer extends AbstractDeserializer {
-  private Class _cl;
-  private Constructor _constructor;
-  
-  public SqlDateDeserializer(Class cl)
-    throws NoSuchMethodException
-  {
-    _cl = cl;
-    _constructor = cl.getConstructor(new Class[] { long.class });
-  }
-  
-  public Class getType()
-  {
-    return _cl;
-  }
-  
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    int ref = in.addRef(null);
-    
-    long initValue = Long.MIN_VALUE;
-    
-    while (! in.isEnd()) {
-      String key = in.readString();
-
-      if (key.equals("value"))
-	initValue = in.readUTCDate();
-      else
-	in.readString();
-    }
-
-    in.readMapEnd();
-
-    Object value = create(initValue);
-
-    in.setRef(ref, value);
-
-    return value;
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    int ref = in.addRef(null);
-    
-    long initValue = Long.MIN_VALUE;
-
-    for (int i = 0; i < fieldNames.length; i++) {
-      String key = fieldNames[i];
-
-      if (key.equals("value"))
-	initValue = in.readUTCDate();
-      else
-	in.readObject();
-    }
-
-    Object value = create(initValue);
-
-    in.setRef(ref, value);
-
-    return value;
-  }
-
-  private Object create(long initValue)
-    throws IOException
-  {
-    if (initValue == Long.MIN_VALUE)
-      throw new IOException(_cl.getName() + " expects name.");
-
-    try {
-      return _constructor.newInstance(new Object[] { new Long(initValue) });
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/SqlDateSerializer.java src/com/caucho/hessian/io/SqlDateSerializer.java
deleted file mode 100644
index 2c12884..0000000
--- src/com/caucho/hessian/io/SqlDateSerializer.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.util.Date;
-
-/**
- * Serializing a sql date object.
- */
-public class SqlDateSerializer extends AbstractSerializer
-{
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (obj == null)
-      out.writeNull();
-    else {
-      Class cl = obj.getClass();
-
-      if (out.addRef(obj))
-	return;
-      
-      int ref = out.writeObjectBegin(cl.getName());
-
-      if (ref < -1) {
-	out.writeString("value");
-	out.writeUTCDate(((Date) obj).getTime());
-	out.writeMapEnd();
-      }
-      else {
-	if (ref == -1) {
-	  out.writeInt(1);
-	  out.writeString("value");
-	  out.writeObjectBegin(cl.getName());
-	}
-
-	out.writeUTCDate(((Date) obj).getTime());
-      }
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/StackTraceElementDeserializer.java src/com/caucho/hessian/io/StackTraceElementDeserializer.java
deleted file mode 100644
index 93c6c50..0000000
--- src/com/caucho/hessian/io/StackTraceElementDeserializer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.*;
-import java.util.HashMap;
-
-/**
- * Deserializing a JDK 1.4 StackTraceElement
- */
-public class StackTraceElementDeserializer extends JavaDeserializer {
-  public StackTraceElementDeserializer()
-  {
-    super(StackTraceElement.class);
-  }
-
-  @Override
-  protected Object instantiate()
-    throws Exception
-  {
-    return new StackTraceElement("", "", "", 0);
-  }
-}
diff --git src/com/caucho/hessian/io/StringValueDeserializer.java src/com/caucho/hessian/io/StringValueDeserializer.java
deleted file mode 100644
index 0cef102..0000000
--- src/com/caucho/hessian/io/StringValueDeserializer.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-
-/**
- * Deserializing a string valued object
- */
-public class StringValueDeserializer extends AbstractDeserializer {
-  private Class _cl;
-  private Constructor _constructor;
-  
-  public StringValueDeserializer(Class cl)
-  {
-    try {
-      _cl = cl;
-      _constructor = cl.getConstructor(new Class[] { String.class });
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-  
-  public Class getType()
-  {
-    return _cl;
-  }
-  
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    String value = null;
-    
-    while (! in.isEnd()) {
-      String key = in.readString();
-
-      if (key.equals("value"))
-        value = in.readString();
-      else
-	in.readObject();
-    }
-
-    in.readMapEnd();
-
-    Object object = create(value);
-
-    in.addRef(object);
-
-    return object;
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    String value = null;
-
-    for (int i = 0; i < fieldNames.length; i++) {
-      if ("value".equals(fieldNames[i]))
-        value = in.readString();
-      else
-	in.readObject();
-    }
-
-    Object object = create(value);
-    
-    in.addRef(object);
-
-    return object;
-  }
-
-  private Object create(String value)
-    throws IOException
-  {
-    if (value == null)
-      throw new IOException(_cl.getName() + " expects name.");
-
-    try {
-      return _constructor.newInstance(new Object[] { value });
-    } catch (Exception e) {
-      throw new IOExceptionWrapper(e);
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/StringValueSerializer.java src/com/caucho/hessian/io/StringValueSerializer.java
deleted file mode 100644
index 0da24c8..0000000
--- src/com/caucho/hessian/io/StringValueSerializer.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Serializing a remote object.
- */
-public class StringValueSerializer extends AbstractSerializer {
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    if (obj == null)
-      out.writeNull();
-    else {
-      if (out.addRef(obj))
-	return;
-      
-      Class cl = obj.getClass();
-
-      int ref = out.writeObjectBegin(cl.getName());
-
-      if (ref < -1) {
-	out.writeString("value");
-	out.writeString(obj.toString());
-	out.writeMapEnd();
-      }
-      else {
-	if (ref == -1) {
-	  out.writeInt(1);
-	  out.writeString("value");
-	  out.writeObjectBegin(cl.getName());
-	}
-
-	out.writeString(obj.toString());
-      }
-    }
-  }
-}
diff --git src/com/caucho/hessian/io/ThrowableSerializer.java src/com/caucho/hessian/io/ThrowableSerializer.java
deleted file mode 100644
index 1c2bfd4..0000000
--- src/com/caucho/hessian/io/ThrowableSerializer.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Serializing an object for known object types.
- */
-public class ThrowableSerializer extends JavaSerializer {
-  public ThrowableSerializer(Class cl)
-  {
-    super(cl);
-  }
-  
-  public void writeObject(Object obj, AbstractHessianOutput out)
-    throws IOException
-  {
-    Throwable e = (Throwable) obj;
-
-    e.getStackTrace();
-
-    super.writeObject(obj, out);
-  }
-}
diff --git src/com/caucho/hessian/io/ValueDeserializer.java src/com/caucho/hessian/io/ValueDeserializer.java
deleted file mode 100644
index d4d7ac0..0000000
--- src/com/caucho/hessian/io/ValueDeserializer.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.io;
-
-import java.io.IOException;
-
-/**
- * Deserializing a string valued object
- */
-abstract public class ValueDeserializer extends AbstractDeserializer {
-  public Object readMap(AbstractHessianInput in)
-    throws IOException
-  {
-    String initValue = null;
-    
-    while (! in.isEnd()) {
-      String key = in.readString();
-
-      if (key.equals("value"))
-        initValue = in.readString();
-      else
-	in.readObject();
-    }
-
-    in.readMapEnd();
-
-    return create(initValue);
-  }
-  
-  public Object readObject(AbstractHessianInput in, String []fieldNames)
-    throws IOException
-  {
-    String initValue = null;
-
-    for (int i = 0; i < fieldNames.length; i++) {
-      if ("value".equals(fieldNames[i]))
-        initValue = in.readString();
-      else
-	in.readObject();
-    }
-
-    return create(initValue);
-  }
-
-  abstract Object create(String value)
-    throws IOException;
-}
diff --git src/com/caucho/hessian/util/IdentityIntMap.java src/com/caucho/hessian/util/IdentityIntMap.java
deleted file mode 100644
index 1f84e06..0000000
--- src/com/caucho/hessian/util/IdentityIntMap.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.hessian.util;
-
-/**
- * The IntMap provides a simple hashmap from keys to integers.  The API is
- * an abbreviation of the HashMap collection API.
- *
- * <p>The convenience of IntMap is avoiding all the silly wrapping of
- * integers.
- */
-public class IdentityIntMap {
-  /**
-   * Encoding of a null entry.  Since NULL is equal to Integer.MIN_VALUE, 
-   * it's impossible to distinguish between the two.
-   */
-  public final static int NULL = 0xdeadbeef; // Integer.MIN_VALUE + 1;
-
-  private static final Object DELETED = new Object();
-
-  private Object []_keys;
-  private int []_values;
-
-  private int _size;
-  private int _mask;
-
-  /**
-   * Create a new IntMap.  Default size is 16.
-   */
-  public IdentityIntMap()
-  {
-    _keys = new Object[256];
-    _values = new int[256];
-
-    _mask = _keys.length - 1;
-    _size = 0;
-  }
-
-  /**
-   * Clear the hashmap.
-   */
-  public void clear()
-  {
-    Object []keys = _keys;
-    int []values = _values;
-
-    for (int i = keys.length - 1; i >= 0; i--) {
-      keys[i] = null;
-      values[i] = 0;
-    }
-
-    _size = 0;
-  }
-  /**
-   * Returns the current number of entries in the map.
-   */
-  public int size()
-  {
-    return _size;
-  }
-
-  /**
-   * Puts a new value in the property table with the appropriate flags
-   */
-  public int get(Object key)
-  {
-    int mask = _mask;
-    int hash = System.identityHashCode(key) % mask & mask;
-
-    Object []keys = _keys;
-
-    while (true) {
-      Object mapKey = keys[hash];
-
-      if (mapKey == null)
-        return NULL;
-      else if (mapKey == key)
-        return _values[hash];
-
-      hash = (hash + 1) % mask;
-    }
-  }
-
-  /**
-   * Expands the property table
-   */
-  private void resize(int newSize)
-  {
-    Object []newKeys = new Object[newSize];
-    int []newValues = new int[newSize];
-
-    int mask = _mask = newKeys.length - 1;
-
-    Object []keys = _keys;
-    int values[] = _values;
-
-    for (int i = keys.length - 1; i >= 0; i--) {
-      Object key = keys[i];
-
-      if (key == null || key == DELETED)
-        continue;
-
-      int hash = System.identityHashCode(key) % mask & mask;
-
-      while (true) {
-        if (newKeys[hash] == null) {
-          newKeys[hash] = key;
-          newValues[hash] = values[i];
-          break;
-        }
-
-        hash = (hash + 1) % mask;
-      }
-    }
-
-    _keys = newKeys;
-    _values = newValues;
-  }
-
-  /**
-   * Puts a new value in the property table with the appropriate flags
-   */
-  public int put(Object key, int value)
-  {
-    int mask = _mask;
-    int hash = System.identityHashCode(key) % mask & mask;
-
-    Object []keys = _keys;
-
-    while (true) {
-      Object testKey = keys[hash];
-
-      if (testKey == null || testKey == DELETED) {
-        keys[hash] = key;
-        _values[hash] = value;
-
-        _size++;
-
-        if (keys.length <= 4 * _size)
-          resize(4 * keys.length);
-
-        return NULL;
-      }
-      else if (key != testKey) {
-        hash = (hash + 1) % mask;
-
-        continue;
-      }
-      else {
-        int old = _values[hash];
-
-        _values[hash] = value;
-
-        return old;
-      }
-    }
-  }
-
-  /**
-   * Deletes the entry.  Returns true if successful.
-   */
-  public int remove(Object key)
-  {
-    int mask = _mask;
-    int hash = System.identityHashCode(key) % mask & mask;
-
-    while (true) {
-      Object mapKey = _keys[hash];
-
-      if (mapKey == null)
-        return NULL;
-      else if (mapKey == key) {
-        _keys[hash] = DELETED;
-
-        _size--;
-
-        return _values[hash];
-      }
-
-      hash = (hash + 1) % mask;
-    }
-  }
-
-  public String toString()
-  {
-    StringBuffer sbuf = new StringBuffer();
-
-    sbuf.append("IntMap[");
-    boolean isFirst = true;
-
-    for (int i = 0; i <= _mask; i++) {
-      if (_keys[i] != null && _keys[i] != DELETED) {
-        if (! isFirst)
-          sbuf.append(", ");
-
-        isFirst = false;
-        sbuf.append(_keys[i]);
-        sbuf.append(":");
-        sbuf.append(_values[i]);
-      }
-    }
-    sbuf.append("]");
-
-    return sbuf.toString();
-  }
-}
diff --git src/com/caucho/services/client/ServiceProxyFactory.java src/com/caucho/services/client/ServiceProxyFactory.java
deleted file mode 100644
index 7d4552a..0000000
--- src/com/caucho/services/client/ServiceProxyFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.services.client;
-
-/**
- * Factory for creating client stubs.  The returned stub will
- * call the remote object for all methods.
- *
- * <pre>
- * URL url = new URL("http://localhost:8080/ejb/hello");
- * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
- * </pre>
- *
- * After creation, the stub can be like a regular Java class.  Because
- * it makes remote calls, it can throw more exceptions than a Java class.
- * In particular, it may throw protocol exceptions.
- */
-public interface ServiceProxyFactory {
-  /**
-   * Creates a new proxy with the specified URL.  The returned object
-   * is a proxy with the interface specified by api.
-   *
-   * <pre>
-   * String url = "http://localhost:8080/ejb/hello");
-   * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
-   * </pre>
-   *
-   * @param api the interface the proxy class needs to implement
-   * @param url the URL where the client object is located.
-   *
-   * @return a proxy to the object with the specified interface.
-   * @throws java.net.MalformedURLException in case url to remote interface is invalid
-   */
-  public <T>T create(Class<T> api, String url)
-    throws java.net.MalformedURLException;
-}
diff --git src/com/caucho/services/server/AbstractSkeleton.java src/com/caucho/services/server/AbstractSkeleton.java
deleted file mode 100644
index 47dc67e..0000000
--- src/com/caucho/services/server/AbstractSkeleton.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
- *
- * The Apache Software License, Version 1.1
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Caucho Technology (http://www.caucho.com/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
- *    endorse or promote products derived from this software without prior
- *    written permission. For written permission, please contact
- *    info@caucho.com.
- *
- * 5. Products derived from this software may not be called "Resin"
- *    nor may "Resin" appear in their names without prior written
- *    permission of Caucho Technology.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @author Scott Ferguson
- */
-
-package com.caucho.services.server;
-
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-
-/**
- * Proxy class for Hessian services.
- */
-abstract public class AbstractSkeleton {
-  private Class _apiClass;
-  private Class _homeClass;
-  private Class _objectClass;
-  
-  private HashMap _methodMap = new HashMap();
-
-  /**
-   * Create a new hessian skeleton.
-   *
-   * @param apiClass the API interface
-   */
-  protected AbstractSkeleton(Class apiClass)
-  {
-    _apiClass = apiClass;
-    
-    Method []methodList = apiClass.getMethods();
-
-    for (int i = 0; i < methodList.length; i++) {
-      Method method = methodList[i];
-
-      if (_methodMap.get(method.getName()) == null)
-        _methodMap.put(method.getName(), methodList[i]);
-
-      Class []param = method.getParameterTypes();
-      String mangledName = method.getName() + "__" + param.length;
-      _methodMap.put(mangledName, methodList[i]);
-      
-      _methodMap.put(mangleName(method, false), methodList[i]);
-    }
-  }
-
-  /**
-   * Returns the API class of the current object.
-   */
-  public String getAPIClassName()
-  {
-    return _apiClass.getName();
-  }
-
-  /**
-   * Returns the API class of the factory/home.
-   */
-  public String getHomeClassName()
-  {
-    if (_homeClass != null)
-      return _homeClass.getName();
-    else
-      return getAPIClassName();
-  }
-
-  /**
-   * Sets the home API class.
-   */
-  public void setHomeClass(Class homeAPI)
-  {
-    _homeClass = homeAPI;
-  }
-
-  /**
-   * Returns the API class of the object URLs
-   */
-  public String getObjectClassName()
-  {
-    if (_objectClass != null)
-      return _objectClass.getName();
-    else
-      return getAPIClassName();
-  }
-
-  /**
-   * Sets the object API class.
-   */
-  public void setObjectClass(Class objectAPI)
-  {
-    _objectClass = objectAPI;
-  }
-
-  /**
-   * Returns the method by the mangled name.
-   *
-   * @param mangledName the name passed by the protocol
-   */
-  protected Method getMethod(String mangledName)
-  {
-    return (Method) _methodMap.get(mangledName);
-  }
-
-  /**
-   * Creates a unique mangled method name based on the method name and
-   * the method parameters.
-   *
-   * @param method the method to mangle
-   * @param isFull if true, mangle the full classname
-   *
-   * @return a mangled string.
-   */
-  public static String mangleName(Method method, boolean isFull)
-  {
-    StringBuffer sb = new StringBuffer();
-    
-    sb.append(method.getName());
-    
-    Class []params = method.getParameterTypes();
-    for (int i = 0; i < params.length; i++) {
-      sb.append('_');
-      sb.append(mangleClass(params[i], isFull));
-    }
-
-    return sb.toString();
-  }
-
-  /**
-   * Mangles a classname.
-   */
-  public static String mangleClass(Class cl, boolean isFull)
-  {
-    String name = cl.getName();
-
-    if (name.equals("boolean") || name.equals("java.lang.Boolean"))
-      return "boolean";
-    else if (name.equals("int") || name.equals("java.lang.Integer")
-	     || name.equals("short") || name.equals("java.lang.Short")
-	     || name.equals("byte") || name.equals("java.lang.Byte"))
-      return "int";
-    else if (name.equals("long") || name.equals("java.lang.Long"))
-      return "long";
-    else if (name.equals("float") || name.equals("java.lang.Float")
-	     || name.equals("double") || name.equals("java.lang.Double"))
-      return "double";
-    else if (name.equals("java.lang.String")
-	     || name.equals("com.caucho.util.CharBuffer")
-	     || name.equals("char") || name.equals("java.lang.Character")
-	     || name.equals("java.io.Reader"))
-      return "string";
-    else if (name.equals("java.util.Date")
-	     || name.equals("com.caucho.util.QDate"))
-      return "date";
-    else if (InputStream.class.isAssignableFrom(cl)
-	     || name.equals("[B"))
-      return "binary";
-    else if (cl.isArray()) {
-      return "[" + mangleClass(cl.getComponentType(), isFull);
-    }
-    else if (name.equals("org.w3c.dom.Node")
-	     || name.equals("org.w3c.dom.Element")
-	     || name.equals("org.w3c.dom.Document"))
-      return "xml";
-    else if (isFull)
-      return name;
-    else {
-      int p = name.lastIndexOf('.');
-      if (p > 0)
-        return name.substring(p + 1);
-      else
-        return name;
-    }
-  }
-
-  public String toString()
-  {
-    return getClass().getSimpleName() + "[" + _apiClass.getName() + "]";
-  }
-}
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index dc7a4c3..6036a4e 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -64,7 +64,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         mWebView.setBackgroundColor(0);
         mWebView.getSettings().setJavaScriptEnabled(true);
         mWebView.getSettings().setBuiltInZoomControls(true); 
-        mWebView.getSettings().setUserAgentString(Urllib.USER_AGENT);
+        mWebView.getSettings().setUserAgentString(Urllib.DEFAULT_USER_AGENT);
         mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
         
         mWebView.setWebChromeClient(new WebChromeClient() {
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 22e92d8..3a9bc79 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -5,27 +5,20 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
-import se.smartrefill.ad.bank.domain.AdAccount;
-import se.smartrefill.ad.bank.domain.AdBalanceInformationTransaction;
-import se.smartrefill.ad.bank.domain.AdLoginRequest;
-import se.smartrefill.ad.bank.remoting.service.RemoteBalanceService;
-import se.smartrefill.ad.bank.remoting.service.RemoteCustomerService;
-import se.smartrefill.ad.domain.AdCustomer;
-import se.smartrefill.remoting.domain.exception.CustomerBlockedException;
-import se.smartrefill.remoting.domain.exception.InvalidLoginException;
-import se.smartrefill.remoting.domain.exception.InvalidSecurityCodeException;
-import se.smartrefill.remoting.domain.exception.UnauthenticatedUserException;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpResponseException;
+import org.apache.http.message.BasicNameValuePair;
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import android.content.Context;
 import android.provider.Settings.Secure;
 import android.text.InputType;
 
-import com.caucho.hessian.client.HessianConnectionException;
-import com.caucho.hessian.client.HessianHttpHeaderProxyFactory;
-import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -34,32 +27,28 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Skandiabanken extends Bank {
-    private static final String TAG = "Skandiabanken";
-    private static final String NAME = "Skandiabanken";
-    private static final String NAME_SHORT = "skandiabanken";
-    private static final int BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
-    private static final String URL = "http://www.skandiabanken.se/hem/";
-    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+	private static final String NAME = "Skandiabanken";
+	private static final String NAME_SHORT = "skandiabanken";
+	private static final int BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
+	private static final String URL = "http://www.skandiabanken.se/hem/";
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
+	private static final String BASE_URL = "https://smartrefill.se/BankServices";
+
+	private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_ID = "x-smartrefill-application";
+	private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION = "x-smartrefill-version";
+	private static final String HTTP_HEADER_SMARTREFILL_COUNTRY_CODE = "x-smartrefill-country-code";
+	private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER = "x-smartrefill-customer-owner";
+	private static final String HTTP_HEADER_SMARTREFILL_DEVICE_ID = "x-smartrefill-device";
+	private static final String HTTP_HEADER_SMARTREFILL_INFLOW = "x-smartrefill-inflow";
+
+	private static final String INFLOW_ANDROID = "Android";
+	private final static String customerOwner = "SKANDIABANKEN";
+	private final static String countryCode = "SE";
+	private final static String SERVICE_NAME = "bank";
 
-    
-    private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android2/";
-	private static final String LOGIN_URL = BASE_URL + "customer.service";
-	private static final String BALANCE_URL = BASE_URL + "balance.service";
-	
-	  private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_ID = "x-smartrefill-application";
-	  private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION = "x-smartrefill-version";
-	  private static final String HTTP_HEADER_SMARTREFILL_COUNTRY_CODE = "x-smartrefill-country-code";
-	  private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_ID = "x-smartrefill-customer";
-	  private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER = "x-smartrefill-customer-owner";
-	  private static final String HTTP_HEADER_SMARTREFILL_DEVICE_ID = "x-smartrefill-device";
-	  private static final String HTTP_HEADER_SMARTREFILL_INFLOW = "x-smartrefill-inflow";
-	  private static final String HTTP_HEADER_SMARTREFILL_SECURITY_CODE = "x-smartrefill-security-code";
-	  private static final String INFLOW_ANDROID = "Android";
-	  private final static String customerOwner = "SKANDIABANKEN";
-	  private final static String countryCode = "SE";
-	
 	private int customerId = 0;
 
 	public Skandiabanken(Context context) {
@@ -73,67 +62,71 @@ public class Skandiabanken extends Bank {
 		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
 	}
 
-	public Skandiabanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+	public Skandiabanken(String username, String password, Context context)
+			throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib();
+
+		HashMap<String, String> headers = urlopen.getHeaders();
+		headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID,
+				"se.skandiabanken.android.wallet");
+		headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION, "9");
+		headers.put(HTTP_HEADER_SMARTREFILL_COUNTRY_CODE, countryCode);
+		headers.put(HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER, customerOwner);
+		headers.put(HTTP_HEADER_SMARTREFILL_DEVICE_ID, getDeviceId());
+		headers.put(HTTP_HEADER_SMARTREFILL_INFLOW, INFLOW_ANDROID);
+		
+		urlopen.setUserAgent(null);
+
+		String loginUrl = getBaseUrlWithCustomerOwner() + "/login";
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		postData.add(new BasicNameValuePair("username", username));
+		postData.add(new BasicNameValuePair("password", password));
 
 		try {
-			HessianHttpHeaderProxyFactory proxyFactory = getHessianProxy();
-			
-			RemoteCustomerService test = (RemoteCustomerService) proxyFactory
-				.create(RemoteCustomerService.class, LOGIN_URL, context.getClassLoader());
-			
-			AdCustomer customer = test.login(new AdLoginRequest(username, password));
-			customerId = customer.getId();
-			proxyFactory.addHeader(HTTP_HEADER_SMARTREFILL_CUSTOMER_ID, String.valueOf(customerId));
-			proxyFactory.addHeader(HTTP_HEADER_SMARTREFILL_SECURITY_CODE, password);
-		} catch (InvalidLoginException e) {
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
-		} catch (InvalidSecurityCodeException e) {
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
-		} catch (UnauthenticatedUserException e) {
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
-		} catch (CustomerBlockedException e) {
-			// TODO hard coded string!
-			throw new LoginException("User has been blocked.");
+			String loginResponse = urlopen.open(loginUrl, postData);
+			JSONObject obj = new JSONObject(loginResponse);
+			customerId = (int) obj.getLong("id");
+		} catch (HttpResponseException e) {
+			if (e.getStatusCode() == 401)
+				throw new BankException(
+						"Inloggning misslyckad fel användarnamn eller lösenord");
+			else
+				throw new BankException("Http fel (" + e.getStatusCode() + ") "
+						+ e.getMessage());
+		} catch (ClientProtocolException e) {
+			throw new BankException("ClientProtocolException " + e.getMessage());
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		} catch (HessianConnectionException e) {
-			throw new BankException(e.getMessage());
-		} 
+			throw new BankException("IOException " + e.getMessage());
+		} catch (JSONException e) {
+			throw new BankException("Oväntat svarsformat " + e.getMessage());
+		}
+
 		return urlopen;
 	}
-	
-	public void logout() throws BankException {
 
+	private String getBaseUrlWithCustomerOwner() {
+		return BASE_URL + "/rest/" + SERVICE_NAME + "/" + countryCode + "/"
+				+ customerOwner;
+	}
+
+	private void logout() {
+		String logoutUrl = getBaseUrlWithCustomerOwner() + "/customer/"
+				+ customerId + "/logout";
 		try {
-			HessianHttpHeaderProxyFactory proxyFactory = getHessianProxy();
-			
-			RemoteCustomerService test = (RemoteCustomerService) proxyFactory
-					.create(RemoteCustomerService.class, LOGIN_URL, context.getClassLoader());
-			
-			test.logout(customerId);
-			customerId = 0;
-			proxyFactory.removeHeader(HTTP_HEADER_SMARTREFILL_CUSTOMER_ID);
-			proxyFactory.removeHeader(HTTP_HEADER_SMARTREFILL_SECURITY_CODE);
+			urlopen.post(logoutUrl);
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		} catch (HessianConnectionException e) {
-			throw new BankException(e.getMessage());
-		} catch (RuntimeException e) {
-			throw new BankException("Unexpected error connecting to Skandiabanken: " + e.getMessage());
 		}
 	}
 
 	@Override
-	public void update() throws BankException, LoginException, BankChoiceException {
+	public void update() throws BankException, LoginException,
+			BankChoiceException {
 		super.update();
 
 		if (username == null || password == null || username.length() == 0
@@ -143,121 +136,62 @@ public class Skandiabanken extends Bank {
 
 		login();
 
+		String accountsUrl = getBaseUrlWithCustomerOwner() + "/customer/"
+				+ customerId + "/accounts";
+		String accountsJsonString;
 		try {
-			RemoteBalanceService balanceService = (RemoteBalanceService) getHessianProxy()
-					.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
-			
-			List<AdAccount> adAccounts = balanceService.getAccounts(customerId);
-			for (AdAccount adAccount : adAccounts) {
-				String amount = adAccount.getAmount();
-				if (amount == null)
-					continue;
-				String typeDescription = adAccount.getAccountTypeDescription();
-				if (typeDescription.contentEquals("Upplagt konto"))
-					continue;
-				
-				int type = Account.OTHER;
-				if (typeDescription.contentEquals("Allt i Ett-konto") || typeDescription.contentEquals("Sparkonto"))
-					type = Account.REGULAR;
-				
-				accounts.add(new Account(
-				        adAccount.getAlias() != null ? adAccount.getAlias() : adAccount.getAccountNumber(),
-				        Helpers.parseBalance(amount), adAccount.getId(), type));
-			}
+			accountsJsonString = urlopen.open(accountsUrl);
+			JSONObject json = new JSONObject(accountsJsonString);
+			// TODO Handle accounts
 		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		} catch (RuntimeException e) {
-			throw new BankException("Unexpected error getting balance from Skandiabanken: " + e.getMessage());
-		} finally {
-			super.updateComplete();
+			throw new BankException("IOException " + e.getMessage());
+		} catch (JSONException e) {
+			throw new BankException("Oväntat svarsformat " + e.getMessage());
 		}
-		
-		logout();
 	}
+
 	@Override
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen)
+			throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
 
-		try {
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			RemoteBalanceService balanceService = (RemoteBalanceService) getHessianProxy()
-				.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
-			AdAccount adAccount = null;
-			List<AdAccount> adAccounts = balanceService.getAccounts(customerId);
-			for (AdAccount adAccounti : adAccounts) {
-				if (adAccounti.getId().contentEquals(account.getId())){
-					adAccount = adAccounti;
-					break;
-				}
-			}
-			// TODO Check null
-			
-			AdAccount accountWithTransactions =  balanceService.getAccountTransactions(customerId, adAccount, "f");
-    		List<AdBalanceInformationTransaction> adTransactions = accountWithTransactions.getTransactions();
-    		for (AdBalanceInformationTransaction transaction : adTransactions) {
-				String transactionAmount = transaction.getAmount();
-				String time = transaction.getTime();
-				String merchant = transaction.getMerchant();
-				transactions.add(new Transaction(time, merchant, Helpers.parseBalance(transactionAmount)));	
-			}
-			account.setTransactions(transactions);
-		} catch (IOException e) {
-			throw new BankException(e.getMessage());
-		} catch (RuntimeException e) {
-			throw new BankException("Unexpected error getting transactions from Skandiabanken: " + e.getMessage());
-		}
+		String accountTransactionsUrl = getBaseUrlWithCustomerOwner()
+				+ "/customer/" + customerId + "/account/" + account.getId();
+		// TODO Get transactions
 	}
-	
-	private HessianHttpHeaderProxyFactory mProxyFactory = null;
 
-	private HessianHttpHeaderProxyFactory getHessianProxy() {
-		if (mProxyFactory == null)
-		{
-			HashMap<String, String> headers = new HashMap<String, String>();
-			headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID, "se.skandiabanken.android.wallet");
-			headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION, "6");
-			headers.put(HTTP_HEADER_SMARTREFILL_COUNTRY_CODE, countryCode);
-			headers.put(HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER, customerOwner);
-			headers.put(HTTP_HEADER_SMARTREFILL_DEVICE_ID, getDeviceId());
-			headers.put(HTTP_HEADER_SMARTREFILL_INFLOW, INFLOW_ANDROID);
-			
-			HessianHttpHeaderProxyFactory localHessianProxyFactory = 
-				new HessianHttpHeaderProxyFactory(headers);
-			
-			localHessianProxyFactory.setHessian2Request(false);
-			localHessianProxyFactory.setHessian2Reply(false);
-			localHessianProxyFactory.setChunkedPost(false);
-			localHessianProxyFactory.setReadTimeout(30000L);
-			localHessianProxyFactory.setOverloadEnabled(false);
-			mProxyFactory = localHessianProxyFactory;
+	@Override
+	public void closeConnection() {
+		logout();
+		super.closeConnection();
+	}
+
+	public String getDeviceId() {
+		// TelephonyManager localTelephonyManager =
+		// (TelephonyManager)context.getSystemService("phone");
+		// if (localTelephonyManager.getDeviceId() != null) // null for emulator
+		// return localTelephonyManager.getDeviceId();
+		// else
+		// return "000000000000000";
+		// We should return the imei of the phone (se code above)
+		// As we would need permission to read imei we use something else that
+		// is unique and constant
+		// Bankdroid should have as less permissions as possible...
+		String test = Secure.getString(context.getContentResolver(),
+				Secure.ANDROID_ID);
+
+		if (test == null) // null for emulator
+			test = "0";
+
+		// convert to decimal string (imei is decimal)
+		try {
+			test = String.valueOf(Integer.parseInt(test, 16));
+		} catch (NumberFormatException e) {
 		}
-		
-		return mProxyFactory;
+
+		while (test.length() < 16)
+			test += "0";
+
+		return test.substring(0, 15);
 	}
-	
-	  public String getDeviceId()
-	  {
-//		    TelephonyManager localTelephonyManager = (TelephonyManager)context.getSystemService("phone");
-//			if (localTelephonyManager.getDeviceId() != null) // null for emulator
-//				return localTelephonyManager.getDeviceId();
-//			else
-//				return "000000000000000"; 
-		  // We should return the imei of the phone (se code above)
-		  // As we would need permission to read imei we use something else that is unique and constant
-		  // Bankdroid should have as less permissions as possible...
-		  String test = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
-		  
-		  if (test == null) // null for emulator
-			  test = "0";
-		  
-		  // convert to decimal string (imei is decimal)
-		  try{
-			  test = String.valueOf(Integer.parseInt(test, 16));
-		  } catch (NumberFormatException e) {}
-		  
-		  while (test.length() < 16)
-			  test += "0";
-		  
-		  return test.substring(0, 15);
-	  }
 }
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index e191627..afc7eff 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -49,8 +49,9 @@ import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 
 public class Urllib {
-    public final static String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
-
+    public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+    
+    private String userAgent = DEFAULT_USER_AGENT;
     private DefaultHttpClient httpclient;
 	private HttpContext context;
 	private String currentURI;
@@ -94,17 +95,28 @@ public class Urllib {
     	return this.open(url, new ArrayList <NameValuePair>());
     }
     
+    public String post(String url) throws ClientProtocolException, IOException {
+    	return this.open(url, new ArrayList <NameValuePair>(), true);
+    }
+    
     public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
-    	this.currentURI = url;
+    	return open(url, postData, false);
+    }
+   
+    public String open(String url, List<NameValuePair> postData, boolean forcePost) throws ClientProtocolException, IOException {
+            	this.currentURI = url;
     	String response;
         String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
         String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
     	ResponseHandler<String> responseHandler = new BasicResponseHandler();
-    	if (postData.isEmpty()) {
+    	if (postData.isEmpty() && !forcePost) {
     		//URL urli = new URL(url); 
     		HttpGet urlConnection = new HttpGet(url);
-    		urlConnection.addHeader("User-Agent", USER_AGENT);
-            for (int i = 0; i < headerKeys.length; i++) {
+
+    		if (userAgent != null)
+    			urlConnection.addHeader("User-Agent", userAgent);
+            
+    		for (int i = 0; i < headerKeys.length; i++) {
                 urlConnection.addHeader(headerKeys[i], headerVals[i]);
             }
     		response = httpclient.execute(urlConnection, responseHandler, context);
@@ -112,8 +124,11 @@ public class Urllib {
     	else {
     		HttpPost urlConnection = new HttpPost(url);
     		urlConnection.setEntity(new UrlEncodedFormEntity(postData, this.charset));
-    		urlConnection.addHeader("User-Agent", USER_AGENT);
-            for (int i = 0; i < headerKeys.length; i++) {
+    		
+    		if (userAgent != null)
+    			urlConnection.addHeader("User-Agent", userAgent);
+            
+    		for (int i = 0; i < headerKeys.length; i++) {
                 urlConnection.addHeader(headerKeys[i], headerVals[i]);
             }
     		response = httpclient.execute(urlConnection, responseHandler, context); 
@@ -122,7 +137,7 @@ public class Urllib {
         HttpUriRequest currentReq = (HttpUriRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
         HttpHost currentHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
         this.currentURI = currentHost.toURI() + currentReq.getURI();
-    	
+        
     	return response;
     }
     
@@ -175,4 +190,9 @@ public class Urllib {
     public boolean acceptsInvalidCertificates() {
     	return acceptInvalidCertificates;
     }
+    
+    public void setUserAgent(String userAgent)
+    {
+    	this.userAgent = userAgent; 
+    }
 }
\ No newline at end of file

commit e6582cc4249e2d6ba6a8630322a5dc26e54d35ff
Author: liato <x@x00.us>
Date:   Sun Jan 29 13:03:52 2012 +0100

    Bump verstion to 1.8.7.

diff --git AndroidManifest.xml AndroidManifest.xml
index 187099d..aad4340 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.7-RC1" android:versionCode="130">
+	android:versionName="1.8.7" android:versionCode="131">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 09271061c74836ea71ad1dec105b42a3b3213cea
Author: liato <x@x00.us>
Date:   Sun Jan 29 12:32:24 2012 +0100

    Fix for SEB. Fix for double pattern lock when opening transactions from widget. Closes #80.

diff --git AndroidManifest.xml AndroidManifest.xml
index 3002dcc..187099d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.6" android:versionCode="129">
+	android:versionName="1.8.7-RC1" android:versionCode="130">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 4f30794..aebe4f2 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -22,6 +22,7 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -44,6 +45,7 @@ public class LockableActivity extends Activity {
 	private Editor mEditor;
 	private LockPatternUtils mLockPatternUtils;
 	private boolean mHasLoaded = false;
+	protected boolean mSkipLockOnce = false;
 	
 	private LinearLayout mTitlebarButtons;
 	private LayoutInflater mInflater;
@@ -175,7 +177,7 @@ public class LockableActivity extends Activity {
 		if (mHasLoaded) {
 		    writeLockTime();
 		} else {
-		    writeLockTime(System.currentTimeMillis()-10000);
+		    writeLockTime(SystemClock.elapsedRealtime()-10000);
 		}
 	}
 
@@ -186,10 +188,14 @@ public class LockableActivity extends Activity {
 		if (!mLockPatternUtils.isLockPatternEnabled()) {
 		    return;
 		}
+		if (mSkipLockOnce) {
+		    mSkipLockOnce = false;
+		    return;
+		}
 		// If a lock pattern is set we need to check the time for when the last
 		// activity was open. If it's been more than two seconds the user
 		// will have to enter the lock pattern to continue.
-		long currentTime = System.currentTimeMillis();
+		long currentTime = SystemClock.elapsedRealtime();
 		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
 		long timedif = currentTime - lockedAt;
 		if (timedif > 2000) {
@@ -209,7 +215,7 @@ public class LockableActivity extends Activity {
 	}
 	
 	private void writeLockTime() {
-        writeLockTime(System.currentTimeMillis());
+        writeLockTime(SystemClock.elapsedRealtime());
 	}
 
     private void writeLockTime(long time) {
@@ -229,4 +235,8 @@ public class LockableActivity extends Activity {
             }
         }
     }   	
+    
+    protected void skipLockOnce() {
+        mSkipLockOnce = true;
+    }
 }
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 453703e..78dd0d9 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -116,11 +116,12 @@ public class MainActivity extends LockableActivity {
 		});
 
 		final Bundle extras = getIntent().getExtras();
-		// Clicking on widgets opens their transaction history through MainActivity so that
+		// Clicking on widgets opens the transactions history through MainActivity so that
 		// the user can back out to the main window.
 		if (AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS.equals(getIntent().getAction())) {
 	        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		    if (prefs.getBoolean("widget_opens_transactions", true)) {
+		        skipLockOnce();
     			final Intent intent = new Intent(this, TransactionsActivity.class);
     			intent.putExtra("account", extras.getString("account"));
     			intent.putExtra("bank", extras.getLong("bank"));
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 09c7699..7cb2c1a 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -86,7 +86,7 @@ public class SEB extends Bank {
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
         postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001m.aspx");
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
     }
 
 	@Override

commit 88e135ceb880678b643461ef78368e06a284f040
Author: liato <x@x00.us>
Date:   Sun Jan 29 04:28:50 2012 +0100

    Remove Steam Wallet. Fix ColorPicker. Fix SEB, closes #128.

diff --git AndroidManifest.xml AndroidManifest.xml
index 7e8d191..3002dcc 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.5" android:versionCode="128">
+	android:versionName="1.8.6" android:versionCode="129">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 37d2522..8a58c48 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -129,8 +129,8 @@ public class BankFactory {
             return new Payson(context);
         case IBankTypes.JOJO:
             return new Jojo(context);
-        case IBankTypes.STEAM:
-            return new Steam(context);
+        //case IBankTypes.STEAM:
+        //    return new Steam(context);
         case IBankTypes.DINERSCLUB:
             return new DinersClub(context);
         case IBankTypes.IKANOBANK:
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 908c16f..09c7699 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -86,7 +86,7 @@ public class SEB extends Bank {
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
         postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx");
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001m.aspx");
     }
 
 	@Override
diff --git src/net/margaritov/preference/colorpicker/ColorPickerView.java src/net/margaritov/preference/colorpicker/ColorPickerView.java
index b935499..e515922 100644
--- src/net/margaritov/preference/colorpicker/ColorPickerView.java
+++ src/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -152,7 +152,9 @@ public class ColorPickerView extends View {
 	}
 
 	private void init(){
-	    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+	    if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 11) {
+	        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+	    }
 		mDensity = getContext().getResources().getDisplayMetrics().density;
 		PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
 		RECTANGLE_TRACKER_OFFSET *= mDensity;

commit 263023cd883da7b12c94cb46b9d3fdd23068446c
Author: liato <x@x00.us>
Date:   Fri Jan 27 02:20:07 2012 +0100

    Fix for ICA.

diff --git AndroidManifest.xml AndroidManifest.xml
index 3332920..7e8d191 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.5-RC1" android:versionCode="126">
+	android:versionName="1.8.5" android:versionCode="128">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index f1caa19..6a772ee 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -87,11 +87,12 @@ public class ICA extends Bank {
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ctl00$fakie", ""));
+        postData.add(new BasicNameValuePair("ctl00$fakie", "0"));
         postData.add(new BasicNameValuePair("q", "Sök"));
         postData.add(new BasicNameValuePair("appendUrlString", ""));
         postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$btnLogin", "Logga in"));
-        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$chbRememberMe", "on"));
+        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$txtCivicRegistrationNumber", ""));
+        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$txtEmail", ""));
         postData.add(new BasicNameValuePair("footer-q", "Sök"));
         postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPersno", username));
         postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPasswd", password));

commit 99b8df1d66d281c507a219b7064e9e51ca6a4e89
Author: liato <x@x00.us>
Date:   Wed Jan 25 01:06:14 2012 +0100

    Revert SEB changes.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index b09888c..908c16f 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -86,7 +86,7 @@ public class SEB extends Bank {
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
         postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx");
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx");
     }
 
 	@Override

commit e5acfa706115190c5d15b7da83469129ec3f30ea
Author: liato <x@x00.us>
Date:   Wed Jan 25 01:06:01 2012 +0100

    Change urls for Hemkop.

diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 0d8dfa8..50a13fd 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -50,7 +50,7 @@ public class Hemkop extends Bank {
     private static final String TAG = "Hemkop";
     private static final String NAME = "Hemköp Kundkort";
     private static final String NAME_SHORT = "hemkop";
-    private static final String URL = "http://www.hemkop.se/showdoc.asp?docid=780&show=minasidor";
+    private static final String URL = "https://kundkort.hemkop.se/showdoc.asp?docid=1209";
     private static final int BANKTYPE_ID = IBankTypes.HEMKOP;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
@@ -91,7 +91,7 @@ public class Hemkop extends Bank {
         postData.add(new BasicNameValuePair("hemkop_personnummer", username));
         postData.add(new BasicNameValuePair("hemkop_password", password));
         postData.add(new BasicNameValuePair("login", "Logga in"));
-        return new LoginPackage(urlopen, postData, response, "https://www.hemkop.se/scripts/cgiip.exe/WService=axfood/axfood/common/loginhemkopkundkort.p");
+        return new LoginPackage(urlopen, postData, response, "https://kundkort.hemkop.se/scripts/cgiip.exe/WService=axfood/axfood/common/loginhemkopkundkort.p");
     }
 
     public Urllib login() throws LoginException, BankException {
@@ -102,7 +102,7 @@ public class Hemkop extends Bank {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
             //Login result contains a meta redirect to this page.
-            response = urlopen.open("https://www.hemkop.se/showdoc.asp?docid=780&show=minasidor");
+            response = urlopen.open("https://kundkort.hemkop.se/showdoc.asp?docid=780&show=minasidor");
         }
         catch (ClientProtocolException e) {
             throw new BankException(e.getMessage());
@@ -153,16 +153,16 @@ public class Hemkop extends Bank {
             if (account.getId().equals("AktuelltSaldo")) {
                 // Get a year's worth of card transactions (VISA only)
                 from.set(Calendar.YEAR, from.get(Calendar.YEAR) - 1);
-                url = String.format("https://www.hemkop.se/showdoc.asp?docid=785&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
+                url = String.format("https://kundkort.hemkop.se/showdoc.asp?docid=785&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
             } else if (account.getId().equals("BonusInfo")) {
                 // Get a year's worth of bonus transactions (shopping within Hemköp) until the current month.
                 from.set(Calendar.YEAR, from.get(Calendar.YEAR) - 1);
                 tom.set(Calendar.DATE, 0);
-                url = String.format("https://www.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
+                url = String.format("https://kundkort.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
             } else if (account.getId().equals("BonusInfoSum")) {
                 // Get a bonus transactions (shopping within Hemköp) during the current month.
                 from.set(Calendar.DATE, 1);
-                url = String.format("https://www.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
+                url = String.format("https://kundkort.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
             }
             
             if (url != null) {

commit c418aefce02c2833aa5916ff319b8d78ad77d29b
Author: liato <x@x00.us>
Date:   Mon Jan 23 01:47:40 2012 +0100

    Fix text overflow on bank headers.

diff --git AndroidManifest.xml AndroidManifest.xml
index 378ac5d..3332920 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.4" android:versionCode="125">
+	android:versionName="1.8.5-RC1" android:versionCode="126">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/drawable/logo_akeliusinvest.png res/drawable/logo_akeliusinvest.png
index 28b9578..00c3999 100644
Binary files res/drawable/logo_akeliusinvest.png and res/drawable/logo_akeliusinvest.png differ
diff --git res/layout/listitem_accounts_group.xml res/layout/listitem_accounts_group.xml
index 46e62c3..62de998 100644
--- res/layout/listitem_accounts_group.xml
+++ res/layout/listitem_accounts_group.xml
@@ -1,72 +1,88 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="62dp"
-	android:paddingBottom="5dp"
-	android:paddingLeft="5dp"
-	android:paddingTop="5dp"
-	android:paddingRight="10dp" android:background="@drawable/group_bg" android:id="@+id/layBankHeader">
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/layBankHeader"
+    android:layout_width="fill_parent"
+    android:layout_height="62dp"
+    android:background="@drawable/group_bg"
+    android:paddingBottom="5dp"
+    android:paddingLeft="5dp"
+    android:paddingRight="10dp"
+    android:paddingTop="5dp" >
 
-	<ImageView
-		android:id="@+id/imgListitemAccountsGroup"
+    <ImageView
+        android:id="@+id/imgListitemAccountsGroup"
+        android:layout_width="48dp"
+        android:layout_height="fill_parent"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginLeft="0dp"
+        android:layout_marginRight="2dp"
+        android:maxHeight="48dp"
+        android:maxWidth="48dp"
+        android:minHeight="48dp"
+        android:minWidth="48dp"
+        android:padding="0dp"
+        android:src="@drawable/icon" />
 
-		android:layout_height="fill_parent"
+    <TextView
+        android:id="@+id/txtListitemAccountsGroupBankname"
+        android:layout_width="wrap_content"
+        android:layout_height="21dip"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="false"
+        android:layout_marginRight="4dp"
+        android:layout_toLeftOf="@+id/txtListitemAccountsGroupTotal"
+        android:layout_toRightOf="@id/imgListitemAccountsGroup"
+        android:ellipsize="marquee"
+        android:gravity="top"
+        android:singleLine="true"
+        android:text="Banknamn"
+        android:textColor="#000" />
 
-		android:layout_alignParentTop="true"
-		android:layout_alignParentBottom="true"
-		android:layout_marginRight="2dp"
+    <TextView
+        android:id="@+id/txtListitemAccountsGroupAccountname"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_above="@id/txtListitemAccountsGroupBankname"
+        android:layout_alignParentRight="false"
+        android:layout_alignParentTop="true"
+        android:layout_alignWithParentIfMissing="true"
+        android:layout_toRightOf="@id/imgListitemAccountsGroup"
+        android:ellipsize="marquee"
+        android:gravity="center_vertical"
+        android:includeFontPadding="true"
+        android:lines="1"
+        android:marqueeRepeatLimit="marquee_forever"
+        android:scrollHorizontally="true"
+        android:shadowColor="#78ffffff"
+        android:shadowDx="0"
+        android:shadowDy="1"
+        android:shadowRadius="2"
+        android:text="Personnummer"
+        android:textColor="#000"
+        android:textSize="23dp" />
 
-		android:src="@drawable/icon"
-		android:layout_alignParentLeft="true"
-		android:padding="0dp"
-		android:layout_marginLeft="0dp"
-		android:layout_width="48dp"
-		android:maxHeight="48dp"
-		android:maxWidth="48dp"
-		android:minHeight="48dp"
-		android:minWidth="48dp" />
+    <ImageView
+        android:id="@+id/imgWarning"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@id/txtListitemAccountsGroupBankname"
+        android:layout_alignParentRight="true"
+        android:src="@drawable/indicator_input_error"
+        android:visibility="invisible" >
+    </ImageView>
 
-	<TextView
-		android:id="@+id/txtListitemAccountsGroupBankname"
-
-		android:layout_toRightOf="@id/imgListitemAccountsGroup"
-		android:singleLine="true"
-		android:ellipsize="marquee"
-		android:text="Banknamn"
-		android:textColor="#000"
-		android:layout_width="wrap_content"
-		android:layout_alignParentRight="false" android:layout_alignParentBottom="true" android:layout_height="21dip" android:gravity="top"/>
-
-	<TextView
-		android:layout_height="wrap_content"
-
-		android:layout_toRightOf="@id/imgListitemAccountsGroup"
-		android:layout_alignParentTop="true"
-		android:layout_above="@id/txtListitemAccountsGroupBankname"
-		android:layout_alignWithParentIfMissing="true"
-
-		android:gravity="center_vertical"
-		android:id="@+id/txtListitemAccountsGroupAccountname"
-		android:textColor="#000"
-		android:layout_alignParentRight="false" android:includeFontPadding="true" android:textSize="23dp" android:text="Personnummer" android:lines="1" android:marqueeRepeatLimit="marquee_forever" android:scrollHorizontally="true" android:layout_width="fill_parent" android:ellipsize="marquee"/>
-	<ImageView
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:id="@+id/imgWarning"
-		android:src="@drawable/indicator_input_error"
-		android:layout_alignParentRight="true"
-		android:layout_above="@id/txtListitemAccountsGroupBankname"
-		android:visibility="invisible"></ImageView>
-	<TextView
-		android:id="@+id/txtListitemAccountsGroupTotal"
-		android:layout_alignParentBottom="true"
-		android:singleLine="true"
-		android:ellipsize="marquee"
-		android:text="00000 SEK"
-		android:layout_width="wrap_content"
-		android:layout_alignParentRight="true"
-		android:textColor="#333" android:layout_height="21dp" android:gravity="top"/>
-        
+    <TextView
+        android:id="@+id/txtListitemAccountsGroupTotal"
+        android:layout_width="wrap_content"
+        android:layout_height="21dp"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:ellipsize="marquee"
+        android:gravity="top"
+        android:singleLine="true"
+        android:text="00000 SEK"
+        android:textColor="#333" />
 
 </RelativeLayout>
\ No newline at end of file

commit 5ba21925d258df72ef5326afebac16d9a2c415b8
Merge: cfa4a60 3198336
Author: liato <x@x00.us>
Date:   Sun Jan 22 15:28:05 2012 -0800

    Merge pull request #127 from Snaah/master
    
    Här är source med Akelius Invest, fixar för Coop, Hemköp, SEB och SevenDay och ändrad logga för ICA-banken

commit 319833655cecdedf5e053f3f6821834d42ad29fa
Author: Snah <retpojke@gmail.com>
Date:   Fri Jan 20 01:33:11 2012 +0100

    Bjarneviks fix för Preem tillagd

diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 167637a..3e2b458 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *  Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -50,9 +50,9 @@ public abstract class IkanoPartnerBase extends Bank {
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reCtl = Pattern.compile("(ctl\\d{1,})_CustomValidationSummary", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Transaktioner</", Pattern.CASE_INSENSITIVE);
+    protected Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Transaktioner</", Pattern.CASE_INSENSITIVE);
     private Pattern reCreditInfoUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Kredit-? ?uppgifter</", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("captionLabel\">([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
+    private Pattern reAccounts = Pattern.compile("captionLabel\">(?:<span></span>)?([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
     private Pattern reTransactions = Pattern.compile("<td\\s*class=\"TransactionDateRow\">([^>]+)</td><td[^>]+>(.+?)</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>");
     private String response = null;
 	protected String structId;
@@ -69,8 +69,8 @@ public abstract class IkanoPartnerBase extends Bank {
 		this(context);
 		this.update(username, password);
 	}
-
-    @Override
+	
+	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
diff --git src/com/liato/bankdroid/banking/banks/Preem.java src/com/liato/bankdroid/banking/banks/Preem.java
index e7b31ff..4ecfe11 100644
--- src/com/liato/bankdroid/banking/banks/Preem.java
+++ src/com/liato/bankdroid/banking/banks/Preem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *  Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,8 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package com.liato.bankdroid.banking.banks;
 
+import java.util.regex.Pattern;
+
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
@@ -29,6 +32,7 @@ public class Preem extends IkanoPartnerBase {
 	private static final String NAME_SHORT = "preem";
 	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
 	private static final int BANKTYPE_ID = Bank.PREEM;
+	private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Mitt konto</", Pattern.CASE_INSENSITIVE);
 
     public Preem(Context context) {
         super(context);
@@ -37,6 +41,7 @@ public class Preem extends IkanoPartnerBase {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
+        super.reTransactionsUrl = reTransactionsUrl;
         this.structId = "1437";
     }
 
@@ -46,4 +51,4 @@ public class Preem extends IkanoPartnerBase {
     }
 
 
-}
+}
\ No newline at end of file

commit 07edb50bacbd61a688406f64bb5e5a9856371557
Author: Snah <retpojke@gmail.com>
Date:   Thu Jan 19 01:24:59 2012 +0100

    Tillagd bank:
    Akelius Invest
    - kvar: loggan behöver fixas
            kontonamn behöver radbrytas i "toppboxen" för transaktionshistorik
            andra valutor än SEK (overkill?)
    
    Fixar för:
    Coop
    Hemköp
    SEB
    SevenDay
    - alla enligt Swedroidtråden omkring 2012-01-17
    
    ICA-banken
    - loggan fixad (nu samma som ICA, kopierade bara den)

diff --git res/drawable/logo_akeliusinvest.png res/drawable/logo_akeliusinvest.png
new file mode 100644
index 0000000..28b9578
Binary files /dev/null and res/drawable/logo_akeliusinvest.png differ
diff --git res/drawable/logo_icabanken.png res/drawable/logo_icabanken.png
index 529263c..798be0c 100644
Binary files res/drawable/logo_icabanken.png and res/drawable/logo_icabanken.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 0fda70f..37d2522 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -25,6 +25,7 @@ import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
 
+import com.liato.bankdroid.banking.banks.AkeliusInvest;
 import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
@@ -92,6 +93,8 @@ public class BankFactory {
 		switch (id) {
         case IBankTypes.TESTBANK:
             return new TestBank(context);
+        case IBankTypes.AKELIUSINVEST:
+            return new AkeliusInvest(context);
         case IBankTypes.SWEDBANK:
             return new Swedbank(context);
 		case IBankTypes.NORDEA:
@@ -210,6 +213,7 @@ public class BankFactory {
 
 	public static ArrayList<Bank> listBanks(Context context) {
 		ArrayList<Bank> banks = new ArrayList<Bank>();
+		banks.add(new AkeliusInvest(context));
 		banks.add(new Swedbank(context));
 		banks.add(new Nordea(context));
 		banks.add(new ICABanken(context));
diff --git src/com/liato/bankdroid/banking/banks/AkeliusInvest.java src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
new file mode 100644
index 0000000..0a33a3d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/AkeliusInvest.java
@@ -0,0 +1,214 @@
+/* Copyright (C) 2012 Nullbyte <http://nullbyte.eu>, first version by Snah@Swedroid 2012-01-06
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AkeliusInvest extends Bank {
+	private static final String TAG = "AkeliusInvest";
+	private static final String NAME = "Akelius Invest";
+	private static final String NAME_SHORT = "akeliusinvest";
+	private static final String URL = "https://online.akeliusinvest.com/";
+	private static final int BANKTYPE_ID = IBankTypes.AKELIUSINVEST;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    private static final String INPUT_HINT_USERNAME = "XXXXXXX";
+    private static final boolean STATIC_BALANCE = true;
+
+	private Pattern reLogintoken = Pattern.compile("logintoken\"\\s+value=\"([^\"]+)\"");
+	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+><a[^?]+\\?selectedaccount=([^\"]+)\">([^<]+)</a></td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	// private Pattern reBalance = Pattern.compile("AccountStatement\\.mws\\?selectedaccount=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("top\">([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	public AkeliusInvest(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public AkeliusInvest(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String response = urlopen.open("https://online.akeliusinvest.com/login.mws");
+        Matcher matcher = reLogintoken.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" logintoken.");
+        }
+        String strLogintoken = matcher.group(1);
+        
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("action", "login"));
+        postData.add(new BasicNameValuePair("logintoken", strLogintoken));
+        postData.add(new BasicNameValuePair("df_username", username));
+        postData.add(new BasicNameValuePair("df_password", password));
+        postData.add(new BasicNameValuePair("Language", "SV"));
+        postData.add(new BasicNameValuePair("IdleTime", "900"));
+   
+        return new LoginPackage(urlopen, postData, response, "https://online.akeliusinvest.com/login.mws");
+    }
+    
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reError.matcher(response);
+			if (matcher.find()) {
+			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+			        throw new LoginException(errormsg);    
+			    }
+			    else {
+	                 throw new BankException(errormsg);    
+			    }
+			}
+		}
+		catch (ClientProtocolException e) {
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.e(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://online.akeliusinvest.com/AccountPortfolio.mws");
+			
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                ICA					AKELIUSINVEST
+                 * 1: ID                0000000000			Kontonamn
+                 * 2: Name              ICA KONTO			KontoID
+                 * 3: Disponibelt       00.000,00			Kontonummer
+                 * 4: Saldo             1.655,71			Valuta
+                 * 5: 										Tillgängligt belopp
+                 * 6: 										Saldo
+                 */			    
+//				Försök att lösa problemet med för långa, icke radbrytande kontonamn:
+//					if (matcher.group(1).length() > 24)  {
+//						matcher.group(1).replaceFirst("(", "(\n");
+//					}
+               
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Tillgängligt belopp)", Helpers.parseBalance(matcher.group(5).trim()), matcher.group(2).trim()));
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(6).trim()), "a:" + matcher.group(2).trim());
+                account.setAliasfor(matcher.group(1).trim());
+                
+                accounts.add(account);      
+	                
+                balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+			}
+						if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://online.akeliusinvest.com/AccountStatement.mws?selectedaccount="+account.getId());
+			matcher = reTransactions.matcher(response);
+			/* 				ICA-banken	Akelius Invest
+			 * Beskrivning	1			2
+			 * Datum		2			1
+			 * Belopp		3			3
+			 */
+			
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        finally {
+            super.updateComplete();
+        }
+	}		
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index ba673d8..2b583b4 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -52,7 +52,7 @@ public class Coop extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.COOP;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+ //   private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
     private String response;
@@ -81,11 +81,11 @@ public class Coop extends Bank {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
         }
         String strViewState = matcher.group(1);
-        matcher = reEventValidation.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
-        }
-        String strEventValidation = matcher.group(1);
+//        matcher = reEventValidation.matcher(response);
+//        if (!matcher.find()) {
+//          throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
+//        }
+//        String strEventValidation = matcher.group(1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
         postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
@@ -93,7 +93,7 @@ public class Coop extends Bank {
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+//        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
         return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Oversikt/");
     }
 
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 1ad93cb..0d8dfa8 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -90,6 +90,7 @@ public class Hemkop extends Bank {
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("hemkop_personnummer", username));
         postData.add(new BasicNameValuePair("hemkop_password", password));
+        postData.add(new BasicNameValuePair("login", "Logga in"));
         return new LoginPackage(urlopen, postData, response, "https://www.hemkop.se/scripts/cgiip.exe/WService=axfood/axfood/common/loginhemkopkundkort.p");
     }
 
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 7cb2c1a..b09888c 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -86,7 +86,7 @@ public class SEB extends Bank {
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
         postData.add(new BasicNameValuePair("A3", "4"));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx");
     }
 
 	@Override
diff --git src/com/liato/bankdroid/banking/banks/SevenDay.java src/com/liato/bankdroid/banking/banks/SevenDay.java
index 7dfba78..17215a3 100644
--- src/com/liato/bankdroid/banking/banks/SevenDay.java
+++ src/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -122,7 +122,7 @@ public class SevenDay extends Bank {
 		try {
 			Matcher matcher;
 			matcher = reAccounts.matcher(response);
-			if (matcher.find()) {
+			while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
diff --git src/com/liato/bankdroid/liveview/LiveViewService.java src/com/liato/bankdroid/liveview/LiveViewService.java
index c47affa..f2b9ab7 100644
--- src/com/liato/bankdroid/liveview/LiveViewService.java
+++ src/com/liato/bankdroid/liveview/LiveViewService.java
@@ -88,12 +88,12 @@ public class LiveViewService extends Service {
     private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
         Handler mCallbackHandler = new Handler();
 
-        @Override
+        
         public String getPluginName() throws RemoteException {
             return mPluginName;
         }
 
-        @Override
+       
         public void openInPhone(final String openInPhoneAction) throws RemoteException {
             mCallbackHandler.post(new Runnable() {
                 public void run() {
@@ -122,7 +122,7 @@ public class LiveViewService extends Service {
         return alreadyRunning;
     }
 
-    @Override
+
     public void onCreate() {
         super.onCreate();
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
@@ -132,7 +132,6 @@ public class LiveViewService extends Service {
         mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
     }
 
-    @Override
     public void onDestroy() {
         super.onDestroy();
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onDestroy.");
@@ -146,7 +145,6 @@ public class LiveViewService extends Service {
         alreadyRunning = false;
     }
 
-	@Override
 	public void onStart(Intent intent, int startId) {
         super.onStart(intent, startId);
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 66352c8..9378587 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -77,4 +77,5 @@ public interface IBankTypes {
     public final static int NORDEA_DK = 53;
     public final static int VASTTRAFIK = 54;
     public final static int EVERYDAYCARD = 55;
+	public static final int AKELIUSINVEST = 56;
 }

commit cfa4a60d46991e08db560661cd374ce9e0ff590e
Author: liato <x@x00.us>
Date:   Sat Dec 31 16:22:47 2011 +0100

    Add option to flash LED with notifications.

diff --git res/layout-land/dialog_color_picker.xml res/layout-land/dialog_color_picker.xml
new file mode 100644
index 0000000..7f63aff
--- /dev/null
+++ res/layout-land/dialog_color_picker.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Daniel Nilsson
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout 
+	xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:paddingLeft="5dp"
+    android:paddingRight="5dp"
+    android:orientation="horizontal">
+		
+	<net.margaritov.preference.colorpicker.ColorPickerView
+		android:id="@+id/color_picker_view"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:tag="landscape"
+	/>
+		
+	<LinearLayout
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:orientation="vertical"
+		android:layout_marginBottom="10dp">
+		
+		<TextView
+			android:layout_width="wrap_content" 
+			android:layout_height="wrap_content"	
+			android:text="@string/press_color_to_apply"
+			android:gravity="center"
+			android:layout_marginTop="6dp"
+			android:layout_marginLeft="6dp"
+			android:layout_marginRight="6dp"
+			android:layout_marginBottom="5dp"
+			android:textAppearance="?android:attr/textAppearanceSmall"
+		/>
+
+		<net.margaritov.preference.colorpicker.ColorPickerPanelView
+			android:id="@+id/old_color_panel"
+			android:layout_width="fill_parent"
+			android:layout_height="40dp"
+			android:layout_weight="0.5"
+		/>
+	
+		<TextView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"	
+			android:text="↓"
+			android:textSize="20sp"
+			android:gravity="center"
+			android:layout_marginTop="10dp"
+			android:layout_marginBottom="10dp"
+		/>
+	
+		<net.margaritov.preference.colorpicker.ColorPickerPanelView
+			android:id="@+id/new_color_panel"
+			android:layout_width="fill_parent"
+			android:layout_height="40dp"
+			android:layout_weight="0.5"
+		/>
+	
+	</LinearLayout>
+	
+</LinearLayout>
\ No newline at end of file
diff --git res/layout/dialog_color_picker.xml res/layout/dialog_color_picker.xml
new file mode 100644
index 0000000..1196da5
--- /dev/null
+++ res/layout/dialog_color_picker.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 Daniel Nilsson
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android" 
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:paddingLeft="5dp"
+    android:paddingRight="5dp"
+    android:orientation="vertical">
+		
+	<net.margaritov.preference.colorpicker.ColorPickerView
+		android:id="@+id/color_picker_view"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_centerHorizontal="true"
+		android:tag="portrait"
+	/>
+	
+	<TextView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"	
+		android:text="@string/press_color_to_apply"
+		android:gravity="left"
+		android:layout_marginLeft="6dp"
+		android:layout_marginRight="6dp"
+		android:layout_marginBottom="5dp"
+		android:textAppearance="?android:attr/textAppearanceSmall"
+	/>
+	
+	<LinearLayout
+		android:layout_width="wrap_content"
+		android:layout_height="40dp"
+		android:orientation="horizontal"
+		android:layout_below="@id/color_picker_view"
+		android:layout_marginBottom="10dp">
+
+		<net.margaritov.preference.colorpicker.ColorPickerPanelView
+			android:id="@+id/old_color_panel"
+			android:layout_width="0px"
+			android:layout_height="fill_parent"
+			android:layout_weight="0.5"
+		/>
+	
+		<TextView
+			android:layout_width="wrap_content"
+			android:layout_height="fill_parent"	
+			android:text="→"
+			android:textSize="20sp"
+			android:gravity="center"
+			android:layout_marginLeft="10dp"
+			android:layout_marginRight="10dp"
+		/>
+	
+		<net.margaritov.preference.colorpicker.ColorPickerPanelView
+			android:id="@+id/new_color_panel"
+			android:layout_width="0px"
+			android:layout_height="wrap_content"
+			android:layout_weight="0.5"
+		/>
+	
+	</LinearLayout>
+	
+</LinearLayout>
\ No newline at end of file
diff --git res/layout/status_bar_latest_event_content.xml res/layout/status_bar_latest_event_content.xml
new file mode 100644
index 0000000..2db0ad1
--- /dev/null
+++ res/layout/status_bar_latest_event_content.xml
@@ -0,0 +1,59 @@
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	android:orientation="vertical"
+	android:paddingTop="7dp"
+	android:paddingLeft="5dp"
+	android:background="#ffffffff">
+
+	<LinearLayout
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:orientation="horizontal"
+		android:paddingTop="3dp">
+		<!--com.android.server.status.AnimatedImageView android:id="@+id/icon" -->
+		<ImageView
+			android:id="@+id/icon"
+			android:layout_width="25dp"
+			android:layout_height="25dp"
+			android:src="@drawable/icon" android:scaleType="fitXY"/>
+		<TextView
+			android:id="@+id/title"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:layout_weight="1"
+			android:singleLine="true"
+			android:ellipsize="marquee"
+			android:fadingEdge="horizontal"
+			android:paddingLeft="4dp"
+			android:textSize="16sp"
+			android:textStyle="bold"
+			android:textColor="#ff000000"
+			android:text="Familjekonto" />
+	</LinearLayout>
+	<LinearLayout
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:orientation="horizontal">
+		<TextView
+			android:id="@+id/text"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_weight="1"
+			android:singleLine="true"
+			android:ellipsize="marquee"
+			android:fadingEdge="horizontal"
+			android:paddingLeft="4dp"
+			android:textColor="#ff6b6b6b" android:text="Personkonto: -143,50 SEK (8 351,00 SEK)"/>
+		<TextView
+			android:id="@+id/time"
+			android:layout_marginLeft="4dp"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:singleLine="true"
+			android:paddingRight="5dp"
+			android:text="1:37 PM"
+			android:textColor="#ff6b6b6b" />
+	</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 5e3a67b..8aa13fa 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -73,7 +73,10 @@
 	<string name="enable_notifications_summary">Notifiera vid kontoförändringar</string>
 	<string name="vibrate_title">Vibrera</string>
 	<string name="vibrate_summary">Vibrera vid kontoförändringar</string>
-	<string name="notification_sound_title">Notifieringsljud</string>
+	<string name="led_title">Blinka LED:en</string>
+	<string name="led_summary">Blinka LED:en vid kontoförändringar. (Fungerar ej på alla enheter.)</string>
+	<string name="led_color_title">LED-färg</string>
+   	<string name="notification_sound_title">Notifieringsljud</string>
 	<string name="notification_sound_summary">Välj ett notifieringsljud</string>
 	<string name="notification_sound_name">Välj ljud</string>
 	<string name="account_types_title">Kontotyper</string>
@@ -241,4 +244,8 @@
 	<string name="pair_message">Applikationen nedan vill ta del av kontotyp och transaktionsdata från BankDroid.</string>
 	<string name="approve">GODKÄNN</string>
 	<string name="pair_app_name">Okänd applikation</string>
+
+    <!-- Color Picker -->
+    <string name="dialog_color_picker">Färgväljare</string>
+    <string name="press_color_to_apply">Tryck på färgen för att välja</string>    
 </resources>
diff --git res/values/config.xml res/values/config.xml
new file mode 100644
index 0000000..afa220a
--- /dev/null
+++ res/values/config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="default_led_color">#ff0000ff</color>
+</resources>
\ No newline at end of file
diff --git res/values/strings.xml res/values/strings.xml
index 7d5de9b..cfc6817 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -75,7 +75,10 @@
 	<string name="enable_notifications_summary">Notify on account changes</string>
 	<string name="vibrate_title">Vibrate</string>
 	<string name="vibrate_summary">Vibrate on account changes</string>
-	<string name="notification_sound_title">Notification sound</string>
+	<string name="led_title">Flash LED</string>
+	<string name="led_summary">Flash the LED on account changes. (Not supported by all devices.)</string>
+	<string name="led_color_title">LED color</string>
+   	<string name="notification_sound_title">Notification sound</string>
 	<string name="notification_sound_summary">Select notification sound</string>
 	<string name="notification_sound_name">Select sound</string>
 	<string name="account_types_title">Account types</string>
@@ -293,4 +296,8 @@
 	<string name="pair_message">The Application below wants to access account types and transaction data from BankDroid.</string>
 	<string name="approve">APPROVE</string>
 	<string name="pair_app_name">Unknown application</string>	
+	
+    <!-- Color Picker -->
+    <string name="dialog_color_picker">Color Picker</string>
+    <string name="press_color_to_apply">Press on Color to apply</string>    
 </resources>
diff --git res/xml/settings.xml res/xml/settings.xml
index b09c4ec..96ab6fa 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -105,6 +105,18 @@
 			android:title="@string/vibrate_title"
 			android:summary="@string/vibrate_summary"
 			android:dependency="notify_on_change" />
+		<CheckBoxPreference
+			android:key="notify_with_led"
+			android:defaultValue="true"
+			android:title="@string/led_title"
+			android:summary="@string/led_summary"
+			android:dependency="notify_on_change" />
+		<net.margaritov.preference.colorpicker.ColorPickerPreference
+		    android:key="notify_with_led_color"
+		    android:title="@string/led_color_title"
+		    android:defaultValue="@color/default_led_color"
+		    android:dependency="notify_with_led"
+		/>
 		<!--  <CheckBoxPreference
 			android:key="notify_delta_only"
 			android:defaultValue="false"
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 4045b4e..16c315d 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -142,6 +142,15 @@ public class AutoRefreshService extends Service {
 			notification.vibrate = vib;
 			// notification.defaults |= Notification.DEFAULT_VIBRATE;
 		}
+
+		Log.d("LED", "true? " + prefs.getBoolean("notify_with_led", true));
+        if (prefs.getBoolean("notify_with_led", true)) {
+            notification.ledARGB = prefs.getInt("notify_with_led_color", context.getResources().getColor(R.color.default_led_color));
+            notification.flags |= Notification.FLAG_SHOW_LIGHTS;
+            notification.ledOnMS = 700; 
+            notification.ledOffMS = 200; 
+        }
+		
 		final PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
 				new Intent(context, MainActivity.class), 0);
 
diff --git src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
new file mode 100644
index 0000000..ff9c3c8
--- /dev/null
+++ src/net/margaritov/preference/colorpicker/AlphaPatternDrawable.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010 Daniel Nilsson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.margaritov.preference.colorpicker;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+/**
+ * This drawable that draws a simple white and gray chessboard pattern.
+ * It's pattern you will often see as a background behind a
+ * partly transparent image in many applications.
+ * @author Daniel Nilsson
+ */
+public class AlphaPatternDrawable extends Drawable {
+
+	private int mRectangleSize = 10;
+
+	private Paint mPaint = new Paint();
+	private Paint mPaintWhite = new Paint();
+	private Paint mPaintGray = new Paint();
+
+	private int numRectanglesHorizontal;
+	private int numRectanglesVertical;
+
+	/**
+	 * Bitmap in which the pattern will be cahched.
+	 */
+	private Bitmap		mBitmap;
+
+	public AlphaPatternDrawable(int rectangleSize) {
+		mRectangleSize = rectangleSize;
+		mPaintWhite.setColor(0xffffffff);
+		mPaintGray.setColor(0xffcbcbcb);
+	}
+
+	@Override
+	public void draw(Canvas canvas) {
+		canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
+	}
+
+	@Override
+	public int getOpacity() {
+		return 0;
+	}
+
+	@Override
+	public void setAlpha(int alpha) {
+		throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
+	}
+
+	@Override
+	public void setColorFilter(ColorFilter cf) {
+		throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
+	}
+
+	@Override
+	protected void onBoundsChange(Rect bounds) {
+		super.onBoundsChange(bounds);
+
+		int height = bounds.height();
+		int width = bounds.width();
+
+		numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
+		numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
+
+		generatePatternBitmap();
+
+	}
+
+	/**
+	 * This will generate a bitmap with the pattern
+	 * as big as the rectangle we were allow to draw on.
+	 * We do this to chache the bitmap so we don't need to
+	 * recreate it each time draw() is called since it
+	 * takes a few milliseconds.
+	 */
+	private void generatePatternBitmap(){
+
+		if(getBounds().width() <= 0 || getBounds().height() <= 0){
+			return;
+		}
+		
+		mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
+		Canvas canvas = new Canvas(mBitmap);
+
+		Rect r = new Rect();
+		boolean verticalStartWhite = true;
+		for (int i = 0; i <= numRectanglesVertical; i++) {
+
+			boolean isWhite = verticalStartWhite;
+			for (int j = 0; j <= numRectanglesHorizontal; j++) {
+
+				r.top = i * mRectangleSize;
+				r.left = j * mRectangleSize;
+				r.bottom = r.top + mRectangleSize;
+				r.right = r.left + mRectangleSize;
+
+				canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
+
+				isWhite = !isWhite;
+			}
+
+			verticalStartWhite = !verticalStartWhite;
+
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git src/net/margaritov/preference/colorpicker/ColorPickerDialog.java src/net/margaritov/preference/colorpicker/ColorPickerDialog.java
new file mode 100644
index 0000000..74cea76
--- /dev/null
+++ src/net/margaritov/preference/colorpicker/ColorPickerDialog.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 Daniel Nilsson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.margaritov.preference.colorpicker;
+
+
+import com.liato.bankdroid.R;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+
+public class ColorPickerDialog 
+	extends 
+		Dialog 
+	implements
+		ColorPickerView.OnColorChangedListener,
+		View.OnClickListener {
+
+	private ColorPickerView mColorPicker;
+
+	private ColorPickerPanelView mOldColor;
+	private ColorPickerPanelView mNewColor;
+
+	private OnColorChangedListener mListener;
+
+	public interface OnColorChangedListener {
+		public void onColorChanged(int color);
+	}
+	
+	public ColorPickerDialog(Context context, int initialColor) {
+		super(context);
+
+		init(initialColor);
+	}
+
+	private void init(int color) {
+		// To fight color branding.
+		getWindow().setFormat(PixelFormat.RGBA_8888);
+
+		setUp(color);
+
+	}
+
+	private void setUp(int color) {
+		
+		LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+		
+		View layout = inflater.inflate(R.layout.dialog_color_picker, null);
+
+		setContentView(layout);
+
+		setTitle(R.string.dialog_color_picker);
+		
+		mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
+		mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
+		mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
+		
+		((LinearLayout) mOldColor.getParent()).setPadding(
+			Math.round(mColorPicker.getDrawingOffset()), 
+			0, 
+			Math.round(mColorPicker.getDrawingOffset()), 
+			0
+		);	
+		
+		mOldColor.setOnClickListener(this);
+		mNewColor.setOnClickListener(this);
+		mColorPicker.setOnColorChangedListener(this);
+		mOldColor.setColor(color);
+		mColorPicker.setColor(color, true);
+
+	}
+
+	@Override
+	public void onColorChanged(int color) {
+
+		mNewColor.setColor(color);
+
+		/*
+		if (mListener != null) {
+			mListener.onColorChanged(color);
+		}
+		*/
+
+	}
+
+	public void setAlphaSliderVisible(boolean visible) {
+		mColorPicker.setAlphaSliderVisible(visible);
+	}
+	
+	/**
+	 * Set a OnColorChangedListener to get notified when the color
+	 * selected by the user has changed.
+	 * @param listener
+	 */
+	public void setOnColorChangedListener(OnColorChangedListener listener){
+		mListener = listener;
+	}
+
+	public int getColor() {
+		return mColorPicker.getColor();
+	}
+
+	@Override
+	public void onClick(View v) {
+		if (v.getId() == R.id.new_color_panel) {
+			if (mListener != null) {
+				mListener.onColorChanged(mNewColor.getColor());
+			}
+		}
+		dismiss();
+	}
+	
+}
diff --git src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
new file mode 100644
index 0000000..b000366
--- /dev/null
+++ src/net/margaritov/preference/colorpicker/ColorPickerPanelView.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2010 Daniel Nilsson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.margaritov.preference.colorpicker;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * This class draws a panel which which will be filled with a color which can be set.
+ * It can be used to show the currently selected color which you will get from
+ * the {@link ColorPickerView}.
+ * @author Daniel Nilsson
+ *
+ */
+public class ColorPickerPanelView extends View {
+
+	/**
+	 * The width in pixels of the border
+	 * surrounding the color panel.
+	 */
+	private final static float	BORDER_WIDTH_PX = 1;
+
+	private float mDensity = 1f;
+
+	private int 		mBorderColor = 0xff6E6E6E;
+	private int 		mColor = 0xff000000;
+
+	private Paint		mBorderPaint;
+	private Paint		mColorPaint;
+
+	private RectF		mDrawingRect;
+	private RectF		mColorRect;
+
+	private AlphaPatternDrawable mAlphaPattern;
+
+
+	public ColorPickerPanelView(Context context){
+		this(context, null);
+	}
+
+	public ColorPickerPanelView(Context context, AttributeSet attrs){
+		this(context, attrs, 0);
+	}
+
+	public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
+		super(context, attrs, defStyle);
+		init();
+	}
+
+	private void init(){
+		mBorderPaint = new Paint();
+		mColorPaint = new Paint();
+		mDensity = getContext().getResources().getDisplayMetrics().density;
+	}
+
+
+	@Override
+	protected void onDraw(Canvas canvas) {
+
+		final RectF	rect = mColorRect;
+
+		if(BORDER_WIDTH_PX > 0){
+			mBorderPaint.setColor(mBorderColor);
+			canvas.drawRect(mDrawingRect, mBorderPaint);
+		}
+
+		if(mAlphaPattern != null){
+			mAlphaPattern.draw(canvas);
+		}
+
+		mColorPaint.setColor(mColor);
+
+		canvas.drawRect(rect, mColorPaint);
+	}
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+		int width = MeasureSpec.getSize(widthMeasureSpec);
+		int height = MeasureSpec.getSize(heightMeasureSpec);
+
+		setMeasuredDimension(width, height);
+	}
+
+	@Override
+	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+		super.onSizeChanged(w, h, oldw, oldh);
+
+		mDrawingRect = new RectF();
+		mDrawingRect.left =  getPaddingLeft();
+		mDrawingRect.right  = w - getPaddingRight();
+		mDrawingRect.top = getPaddingTop();
+		mDrawingRect.bottom = h - getPaddingBottom();
+
+		setUpColorRect();
+
+	}
+
+	private void setUpColorRect(){
+		final RectF	dRect = mDrawingRect;
+
+		float left = dRect.left + BORDER_WIDTH_PX;
+		float top = dRect.top + BORDER_WIDTH_PX;
+		float bottom = dRect.bottom - BORDER_WIDTH_PX;
+		float right = dRect.right - BORDER_WIDTH_PX;
+
+		mColorRect = new RectF(left,top, right, bottom);
+
+		mAlphaPattern = new AlphaPatternDrawable((int)(5 * mDensity));
+
+		mAlphaPattern.setBounds(
+			Math.round(mColorRect.left),
+			Math.round(mColorRect.top),
+			Math.round(mColorRect.right),
+			Math.round(mColorRect.bottom)
+		);
+
+	}
+
+	/**
+	 * Set the color that should be shown by this view.
+	 * @param color
+	 */
+	public void setColor(int color){
+		mColor = color;
+		invalidate();
+	}
+
+	/**
+	 * Get the color currently show by this view.
+	 * @return
+	 */
+	public int getColor(){
+		return mColor;
+	}
+
+	/**
+	 * Set the color of the border surrounding the panel.
+	 * @param color
+	 */
+	public void setBorderColor(int color){
+		mBorderColor = color;
+		invalidate();
+	}
+
+	/**
+	 * Get the color of the border surrounding the panel.
+	 */
+	public int getBorderColor(){
+		return mBorderColor;
+	}
+
+}
\ No newline at end of file
diff --git src/net/margaritov/preference/colorpicker/ColorPickerPreference.java src/net/margaritov/preference/colorpicker/ColorPickerPreference.java
new file mode 100644
index 0000000..44bbf07
--- /dev/null
+++ src/net/margaritov/preference/colorpicker/ColorPickerPreference.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2011 Sergey Margaritov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.margaritov.preference.colorpicker;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Bitmap.Config;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+/**
+ * A preference type that allows a user to choose a time
+ * @author Sergey Margaritov
+ */
+public class ColorPickerPreference
+	extends
+		Preference
+	implements
+		Preference.OnPreferenceClickListener,
+		ColorPickerDialog.OnColorChangedListener {
+
+	View mView;
+	int mDefaultValue = Color.BLACK;
+	private int mValue = Color.BLACK;
+	private float mDensity = 0;
+	private boolean mAlphaSliderEnabled = false;
+
+	private static final String androidns = "http://schemas.android.com/apk/res/android";
+
+	public ColorPickerPreference(Context context) {
+		super(context);
+		init(context, null);
+	}
+
+	public ColorPickerPreference(Context context, AttributeSet attrs) {
+		super(context, attrs);
+		init(context, attrs);
+	}
+
+	public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
+		super(context, attrs, defStyle);
+		init(context, attrs);
+	}
+	
+	@Override
+	protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+		onColorChanged(restoreValue ? getValue() : (Integer) defaultValue);
+	}
+
+	private void init(Context context, AttributeSet attrs) {
+		mDensity = getContext().getResources().getDisplayMetrics().density;
+		setOnPreferenceClickListener(this);
+		if (attrs != null) {
+			String defaultValue = attrs.getAttributeValue(androidns, "defaultValue");
+			if (defaultValue.startsWith("#")) {
+				try {
+					mDefaultValue = convertToColorInt(defaultValue);
+				} catch (NumberFormatException e) {
+					Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
+					mDefaultValue = convertToColorInt("#FF000000");
+				}
+			} else {
+				int resourceId = attrs.getAttributeResourceValue(androidns, "defaultValue", 0);
+				if (resourceId != 0) {
+					mDefaultValue = context.getResources().getInteger(resourceId);
+				}
+			}
+			mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
+		}
+		mValue = mDefaultValue;
+	}
+
+	@Override
+	protected void onBindView(View view) {
+		super.onBindView(view);
+		mView = view;
+		setPreviewColor();
+	}
+
+	private void setPreviewColor() {
+		if (mView == null) return;
+		ImageView iView = new ImageView(getContext());
+		LinearLayout widgetFrameView = ((LinearLayout)mView.findViewById(android.R.id.widget_frame));
+		if (widgetFrameView == null) return;
+		widgetFrameView.setPadding(
+			widgetFrameView.getPaddingLeft(),
+			widgetFrameView.getPaddingTop(),
+			(int)(mDensity * 8),
+			widgetFrameView.getPaddingBottom()
+		);
+		// remove already create preview image
+		int count = widgetFrameView.getChildCount();
+		if (count > 0) {
+			widgetFrameView.removeViews(0, count);
+		}
+		widgetFrameView.setVisibility(View.VISIBLE);
+		widgetFrameView.addView(iView);
+		iView.setBackgroundDrawable(new AlphaPatternDrawable((int)(5 * mDensity)));
+		iView.setImageBitmap(getPreviewBitmap());
+	}
+
+	private Bitmap getPreviewBitmap() {
+		int d = (int) (mDensity * 31); //30dip
+		int color = getValue();
+		Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
+		int w = bm.getWidth();
+		int h = bm.getHeight();
+		int c = color;
+		for (int i = 0; i < w; i++) {
+			for (int j = i; j < h; j++) {
+				c = (i <= 1 || j <= 1 || i >= w-2 || j >= h-2) ? Color.GRAY : color;
+				bm.setPixel(i, j, c);
+				if (i != j) {
+					bm.setPixel(j, i, c);
+				}
+			}
+		}
+
+		return bm;
+	}
+
+	public int getValue() {
+		try {
+			if (isPersistent()) {
+				mValue = getPersistedInt(mDefaultValue);
+			}
+		} catch (ClassCastException e) {
+			mValue = mDefaultValue;
+		}
+
+		return mValue;
+	}
+
+	@Override
+	public void onColorChanged(int color) {
+		if (isPersistent()) {
+			persistInt(color);
+		}
+		mValue = color;
+		setPreviewColor();
+		try {
+			getOnPreferenceChangeListener().onPreferenceChange(this, color);
+		} catch (NullPointerException e) {
+
+		}
+	}
+
+	public boolean onPreferenceClick(Preference preference) {
+		ColorPickerDialog picker = new ColorPickerDialog(getContext(), getValue());
+		picker.setOnColorChangedListener(this);
+		if (mAlphaSliderEnabled) {
+			picker.setAlphaSliderVisible(true);
+		}
+		picker.show();
+
+		return false;
+	}
+
+	/**
+	 * Toggle Alpha Slider visibility (by default it's disabled)
+	 * @param enable
+	 */
+	public void setAlphaSliderEnabled(boolean enable) {
+		mAlphaSliderEnabled = enable;
+	}
+
+	/**
+	 * For custom purposes. Not used by ColorPickerPreferrence
+	 * @param color
+	 * @author Unknown
+	 */
+    public static String convertToARGB(int color) {
+        String alpha = Integer.toHexString(Color.alpha(color));
+        String red = Integer.toHexString(Color.red(color));
+        String green = Integer.toHexString(Color.green(color));
+        String blue = Integer.toHexString(Color.blue(color));
+
+        if (alpha.length() == 1) {
+            alpha = "0" + alpha;
+        }
+
+        if (red.length() == 1) {
+            red = "0" + red;
+        }
+
+        if (green.length() == 1) {
+            green = "0" + green;
+        }
+
+        if (blue.length() == 1) {
+            blue = "0" + blue;
+        }
+
+        return "#" + alpha + red + green + blue;
+    }
+
+    /**
+     * For custom purposes. Not used by ColorPickerPreferrence
+     * @param argb
+     * @throws NumberFormatException
+     * @author Unknown
+     */
+    public static int convertToColorInt(String argb) throws NumberFormatException {
+
+    	if (argb.startsWith("#")) {
+    		argb = argb.replace("#", "");
+    	}
+
+        int alpha = -1, red = -1, green = -1, blue = -1;
+
+        if (argb.length() == 8) {
+            alpha = Integer.parseInt(argb.substring(0, 2), 16);
+            red = Integer.parseInt(argb.substring(2, 4), 16);
+            green = Integer.parseInt(argb.substring(4, 6), 16);
+            blue = Integer.parseInt(argb.substring(6, 8), 16);
+        }
+        else if (argb.length() == 6) {
+            alpha = 255;
+            red = Integer.parseInt(argb.substring(0, 2), 16);
+            green = Integer.parseInt(argb.substring(2, 4), 16);
+            blue = Integer.parseInt(argb.substring(4, 6), 16);
+        }
+
+        return Color.argb(alpha, red, green, blue);
+    }
+
+}
\ No newline at end of file
diff --git src/net/margaritov/preference/colorpicker/ColorPickerView.java src/net/margaritov/preference/colorpicker/ColorPickerView.java
new file mode 100644
index 0000000..b935499
--- /dev/null
+++ src/net/margaritov/preference/colorpicker/ColorPickerView.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (C) 2010 Daniel Nilsson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.margaritov.preference.colorpicker;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ComposeShader;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.graphics.Paint.Align;
+import android.graphics.Paint.Style;
+import android.graphics.Shader.TileMode;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Displays a color picker to the user and allow them
+ * to select a color. A slider for the alpha channel is
+ * also available. Enable it by setting
+ * setAlphaSliderVisible(boolean) to true.
+ * @author Daniel Nilsson
+ */
+public class ColorPickerView extends View {
+
+	private final static int	PANEL_SAT_VAL = 0;
+	private final static int	PANEL_HUE = 1;
+	private final static int	PANEL_ALPHA = 2;
+
+	/**
+	 * The width in pixels of the border
+	 * surrounding all color panels.
+	 */
+	private final static float	BORDER_WIDTH_PX = 1;
+
+	/**
+	 * The width in dp of the hue panel.
+	 */
+	private float 		HUE_PANEL_WIDTH = 30f;
+	/**
+	 * The height in dp of the alpha panel
+	 */
+	private float		ALPHA_PANEL_HEIGHT = 20f;
+	/**
+	 * The distance in dp between the different
+	 * color panels.
+	 */
+	private float 		PANEL_SPACING = 10f;
+	/**
+	 * The radius in dp of the color palette tracker circle.
+	 */
+	private float 		PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
+	/**
+	 * The dp which the tracker of the hue or alpha panel
+	 * will extend outside of its bounds.
+	 */
+	private float		RECTANGLE_TRACKER_OFFSET = 2f;
+
+
+	private float 		mDensity = 1f;
+
+	private OnColorChangedListener	mListener;
+
+	private Paint 		mSatValPaint;
+	private Paint		mSatValTrackerPaint;
+
+	private Paint		mHuePaint;
+	private Paint		mHueTrackerPaint;
+
+	private Paint		mAlphaPaint;
+	private Paint		mAlphaTextPaint;
+
+	private Paint		mBorderPaint;
+
+	private Shader		mValShader;
+	private Shader		mSatShader;
+	private Shader		mHueShader;
+	private Shader		mAlphaShader;
+
+	private int			mAlpha = 0xff;
+	private float		mHue = 360f;
+	private float 		mSat = 0f;
+	private float 		mVal = 0f;
+
+	private String		mAlphaSliderText = "";
+	private int 		mSliderTrackerColor = 0xff1c1c1c;
+	private int 		mBorderColor = 0xff6E6E6E;
+	private boolean		mShowAlphaPanel = false;
+
+	/*
+	 * To remember which panel that has the "focus" when
+	 * processing hardware button data.
+	 */
+	private int			mLastTouchedPanel = PANEL_SAT_VAL;
+
+	/**
+	 * Offset from the edge we must have or else
+	 * the finger tracker will get clipped when
+	 * it is drawn outside of the view.
+	 */
+	private float 		mDrawingOffset;
+
+
+	/*
+	 * Distance form the edges of the view
+	 * of where we are allowed to draw.
+	 */
+	private RectF	mDrawingRect;
+
+	private RectF	mSatValRect;
+	private RectF 	mHueRect;
+	private RectF	mAlphaRect;
+
+	private AlphaPatternDrawable	mAlphaPattern;
+
+	private Point	mStartTouchPoint = null;
+
+	public interface OnColorChangedListener {
+		public void onColorChanged(int color);
+	}
+
+	public ColorPickerView(Context context){
+		this(context, null);
+	}
+
+	public ColorPickerView(Context context, AttributeSet attrs) {
+		this(context, attrs, 0);
+	}
+
+	public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
+		super(context, attrs, defStyle);
+		init();
+	}
+
+	private void init(){
+	    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+		mDensity = getContext().getResources().getDisplayMetrics().density;
+		PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
+		RECTANGLE_TRACKER_OFFSET *= mDensity;
+		HUE_PANEL_WIDTH *= mDensity;
+		ALPHA_PANEL_HEIGHT *= mDensity;
+		PANEL_SPACING = PANEL_SPACING * mDensity;
+
+		mDrawingOffset = calculateRequiredOffset();
+
+		initPaintTools();
+
+		//Needed for receiving trackball motion events.
+		setFocusable(true);
+		setFocusableInTouchMode(true);
+	}
+
+	private void initPaintTools(){
+
+		mSatValPaint = new Paint();
+		mSatValTrackerPaint = new Paint();
+		mHuePaint = new Paint();
+		mHueTrackerPaint = new Paint();
+		mAlphaPaint = new Paint();
+		mAlphaTextPaint = new Paint();
+		mBorderPaint = new Paint();
+
+
+		mSatValTrackerPaint.setStyle(Style.STROKE);
+		mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
+		mSatValTrackerPaint.setAntiAlias(true);
+
+		mHueTrackerPaint.setColor(mSliderTrackerColor);
+		mHueTrackerPaint.setStyle(Style.STROKE);
+		mHueTrackerPaint.setStrokeWidth(2f * mDensity);
+		mHueTrackerPaint.setAntiAlias(true);
+
+		mAlphaTextPaint.setColor(0xff1c1c1c);
+		mAlphaTextPaint.setTextSize(14f * mDensity);
+		mAlphaTextPaint.setAntiAlias(true);
+		mAlphaTextPaint.setTextAlign(Align.CENTER);
+		mAlphaTextPaint.setFakeBoldText(true);
+
+
+	}
+
+	private float calculateRequiredOffset(){
+		float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
+		offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
+
+		return offset * 1.5f;
+	}
+
+	private int[] buildHueColorArray(){
+
+		int[] hue = new int[361];
+
+		int count = 0;
+		for(int i = hue.length -1; i >= 0; i--, count++){
+			hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
+		}
+
+		return hue;
+	}
+
+
+	@Override
+	protected void onDraw(Canvas canvas) {
+
+		if(mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) return;
+
+		drawSatValPanel(canvas);
+		drawHuePanel(canvas);
+		drawAlphaPanel(canvas);
+
+	}
+
+	private void drawSatValPanel(Canvas canvas){
+
+		final RectF	rect = mSatValRect;
+
+		if(BORDER_WIDTH_PX > 0){
+			mBorderPaint.setColor(mBorderColor);
+			canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
+		}
+
+		if (mValShader == null) {
+			mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
+					0xffffffff, 0xff000000, TileMode.CLAMP);
+		}
+
+		int rgb = Color.HSVToColor(new float[]{mHue,1f,1f});
+
+		mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
+				0xffffffff, rgb, TileMode.CLAMP);
+		ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
+		mSatValPaint.setShader(mShader);
+
+		canvas.drawRect(rect, mSatValPaint);
+
+		Point p = satValToPoint(mSat, mVal);
+
+		mSatValTrackerPaint.setColor(0xff000000);
+		canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
+
+		mSatValTrackerPaint.setColor(0xffdddddd);
+		canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
+
+	}
+
+	private void drawHuePanel(Canvas canvas){
+
+		final RectF rect = mHueRect;
+
+		if(BORDER_WIDTH_PX > 0){
+			mBorderPaint.setColor(mBorderColor);
+			canvas.drawRect(rect.left - BORDER_WIDTH_PX,
+					rect.top - BORDER_WIDTH_PX,
+					rect.right + BORDER_WIDTH_PX,
+					rect.bottom + BORDER_WIDTH_PX,
+					mBorderPaint);
+		}
+
+		if (mHueShader == null) {
+			mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
+			mHuePaint.setShader(mHueShader);
+		}
+
+		canvas.drawRect(rect, mHuePaint);
+
+		float rectHeight = 4 * mDensity / 2;
+
+		Point p = hueToPoint(mHue);
+
+		RectF r = new RectF();
+		r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
+		r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
+		r.top = p.y - rectHeight;
+		r.bottom = p.y + rectHeight;
+
+
+		canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
+
+	}
+
+	private void drawAlphaPanel(Canvas canvas){
+
+		if(!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return;
+
+		final RectF rect = mAlphaRect;
+
+		if(BORDER_WIDTH_PX > 0){
+			mBorderPaint.setColor(mBorderColor);
+			canvas.drawRect(rect.left - BORDER_WIDTH_PX,
+					rect.top - BORDER_WIDTH_PX,
+					rect.right + BORDER_WIDTH_PX,
+					rect.bottom + BORDER_WIDTH_PX,
+					mBorderPaint);
+		}
+
+
+		mAlphaPattern.draw(canvas);
+
+		float[] hsv = new float[]{mHue,mSat,mVal};
+		int color = Color.HSVToColor(hsv);
+		int acolor = Color.HSVToColor(0, hsv);
+
+		mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
+				color, acolor, TileMode.CLAMP);
+
+
+		mAlphaPaint.setShader(mAlphaShader);
+
+		canvas.drawRect(rect, mAlphaPaint);
+
+		if(mAlphaSliderText != null && mAlphaSliderText!= ""){
+			canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
+		}
+
+		float rectWidth = 4 * mDensity / 2;
+
+		Point p = alphaToPoint(mAlpha);
+
+		RectF r = new RectF();
+		r.left = p.x - rectWidth;
+		r.right = p.x + rectWidth;
+		r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
+		r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
+
+		canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
+
+	}
+
+
+	private Point hueToPoint(float hue){
+
+		final RectF rect = mHueRect;
+		final float height = rect.height();
+
+		Point p = new Point();
+
+		p.y = (int) (height - (hue * height / 360f) + rect.top);
+		p.x = (int) rect.left;
+
+		return p;
+	}
+
+	private Point satValToPoint(float sat, float val){
+
+		final RectF rect = mSatValRect;
+		final float height = rect.height();
+		final float width = rect.width();
+
+		Point p = new Point();
+
+		p.x = (int) (sat * width + rect.left);
+		p.y = (int) ((1f - val) * height + rect.top);
+
+		return p;
+	}
+
+	private Point alphaToPoint(int alpha){
+
+		final RectF rect = mAlphaRect;
+		final float width = rect.width();
+
+		Point p = new Point();
+
+		p.x = (int) (width - (alpha * width / 0xff) + rect.left);
+		p.y = (int) rect.top;
+
+		return p;
+
+	}
+
+	private float[] pointToSatVal(float x, float y){
+
+		final RectF rect = mSatValRect;
+		float[] result = new float[2];
+
+		float width = rect.width();
+		float height = rect.height();
+
+		if (x < rect.left){
+			x = 0f;
+		}
+		else if(x > rect.right){
+			x = width;
+		}
+		else{
+			x = x - rect.left;
+		}
+
+		if (y < rect.top){
+			y = 0f;
+		}
+		else if(y > rect.bottom){
+			y = height;
+		}
+		else{
+			y = y - rect.top;
+		}
+
+
+		result[0] = 1.f / width * x;
+		result[1] = 1.f - (1.f / height * y);
+
+		return result;
+	}
+
+	private float pointToHue(float y){
+
+		final RectF rect = mHueRect;
+
+		float height = rect.height();
+
+		if (y < rect.top){
+			y = 0f;
+		}
+		else if(y > rect.bottom){
+			y = height;
+		}
+		else{
+			y = y - rect.top;
+		}
+
+		return 360f - (y * 360f / height);
+	}
+
+	private int pointToAlpha(int x){
+
+		final RectF rect = mAlphaRect;
+		final int width = (int) rect.width();
+
+		if(x < rect.left){
+			x = 0;
+		}
+		else if(x > rect.right){
+			x = width;
+		}
+		else{
+			x = x - (int)rect.left;
+		}
+
+		return 0xff - (x * 0xff / width);
+
+	}
+
+
+	@Override
+	public boolean onTrackballEvent(MotionEvent event) {
+
+		float x = event.getX();
+		float y = event.getY();
+
+		boolean update = false;
+
+
+		if(event.getAction() == MotionEvent.ACTION_MOVE){
+
+			switch(mLastTouchedPanel){
+
+			case PANEL_SAT_VAL:
+
+				float sat, val;
+
+				sat = mSat + x/50f;
+				val = mVal - y/50f;
+
+				if(sat < 0f){
+					sat = 0f;
+				}
+				else if(sat > 1f){
+					sat = 1f;
+				}
+
+				if(val < 0f){
+					val = 0f;
+				}
+				else if(val > 1f){
+					val = 1f;
+				}
+
+				mSat = sat;
+				mVal = val;
+
+				update = true;
+
+				break;
+
+			case PANEL_HUE:
+
+				float hue = mHue - y * 10f;
+
+				if(hue < 0f){
+					hue = 0f;
+				}
+				else if(hue > 360f){
+					hue = 360f;
+				}
+
+				mHue = hue;
+
+				update = true;
+
+				break;
+
+			case PANEL_ALPHA:
+
+				if(!mShowAlphaPanel || mAlphaRect == null){
+					update = false;
+				}
+				else{
+
+					int alpha = (int) (mAlpha - x*10);
+
+					if(alpha < 0){
+						alpha = 0;
+					}
+					else if(alpha > 0xff){
+						alpha = 0xff;
+					}
+
+					mAlpha = alpha;
+
+
+					update = true;
+				}
+
+				break;
+			}
+
+
+		}
+
+
+		if(update){
+
+			if(mListener != null){
+				mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
+			}
+
+			invalidate();
+			return true;
+		}
+
+
+		return super.onTrackballEvent(event);
+	}
+
+	@Override
+	public boolean onTouchEvent(MotionEvent event) {
+
+		boolean update = false;
+
+		switch(event.getAction()){
+
+		case MotionEvent.ACTION_DOWN:
+
+			mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
+
+			update = moveTrackersIfNeeded(event);
+
+			break;
+
+		case MotionEvent.ACTION_MOVE:
+
+			update = moveTrackersIfNeeded(event);
+
+			break;
+
+		case MotionEvent.ACTION_UP:
+
+			mStartTouchPoint = null;
+
+			update = moveTrackersIfNeeded(event);
+
+			break;
+
+		}
+
+		if(update){
+
+			if(mListener != null){
+				mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
+			}
+
+			invalidate();
+			return true;
+		}
+
+
+		return super.onTouchEvent(event);
+	}
+
+	private boolean moveTrackersIfNeeded(MotionEvent event){
+
+		if(mStartTouchPoint == null) return false;
+
+		boolean update = false;
+
+		int startX = mStartTouchPoint.x;
+		int startY = mStartTouchPoint.y;
+
+
+		if(mHueRect.contains(startX, startY)){
+			mLastTouchedPanel = PANEL_HUE;
+
+			mHue = pointToHue(event.getY());
+
+			update = true;
+		}
+		else if(mSatValRect.contains(startX, startY)){
+
+			mLastTouchedPanel = PANEL_SAT_VAL;
+
+			float[] result = pointToSatVal(event.getX(), event.getY());
+
+			mSat = result[0];
+			mVal = result[1];
+
+			update = true;
+		}
+		else if(mAlphaRect != null && mAlphaRect.contains(startX, startY)){
+
+			mLastTouchedPanel = PANEL_ALPHA;
+
+			mAlpha = pointToAlpha((int)event.getX());
+
+			update = true;
+		}
+
+
+		return update;
+	}
+
+	@Override
+	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+		int width = 0;
+		int height = 0;
+		
+		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+		
+		int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
+		int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
+		
+		widthAllowed = chooseWidth(widthMode, widthAllowed);
+		heightAllowed = chooseHeight(heightMode, heightAllowed);
+		
+		if(!mShowAlphaPanel){
+			
+			height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
+
+			//If calculated height (based on the width) is more than the allowed height.
+			if(height > heightAllowed || getTag().equals("landscape")) {
+				height = heightAllowed;
+				width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
+			}
+			else{
+				width = widthAllowed;
+			}
+		}
+		else{
+
+			width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
+
+			if(width > widthAllowed){
+				width = widthAllowed;
+				height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
+			}
+			else{
+				height = heightAllowed;
+			}
+
+		}
+		
+		setMeasuredDimension(width, height);
+	}
+
+	private int chooseWidth(int mode, int size){
+		if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
+			return size;
+		} else { // (mode == MeasureSpec.UNSPECIFIED)
+			return getPrefferedWidth();
+		}
+	}
+
+	private int chooseHeight(int mode, int size){
+		if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
+			return size;
+		} else { // (mode == MeasureSpec.UNSPECIFIED)
+			return getPrefferedHeight();
+		}
+	}
+
+	private int getPrefferedWidth(){
+
+		int width = getPrefferedHeight();
+
+		if(mShowAlphaPanel){
+			width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
+		}
+
+
+		return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
+
+	}
+
+	private int getPrefferedHeight(){
+
+		int height = (int)(200 * mDensity);
+
+		if(mShowAlphaPanel){
+			height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+		}
+
+		return height;
+	}
+
+
+
+	@Override
+	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+		super.onSizeChanged(w, h, oldw, oldh);
+
+		mDrawingRect = new RectF();
+		mDrawingRect.left = mDrawingOffset + getPaddingLeft();
+		mDrawingRect.right  = w - mDrawingOffset - getPaddingRight();
+		mDrawingRect.top = mDrawingOffset + getPaddingTop();
+		mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
+
+		setUpSatValRect();
+		setUpHueRect();
+		setUpAlphaRect();
+	}
+
+	private void setUpSatValRect(){
+
+		final RectF	dRect = mDrawingRect;
+		float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
+
+		if(mShowAlphaPanel){
+			panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
+		}
+
+		float left = dRect.left + BORDER_WIDTH_PX;
+		float top = dRect.top + BORDER_WIDTH_PX;
+		float bottom = top + panelSide;
+		float right = left + panelSide;
+
+		mSatValRect = new RectF(left,top, right, bottom);
+	}
+
+	private void setUpHueRect(){
+		final RectF	dRect = mDrawingRect;
+
+		float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
+		float top = dRect.top + BORDER_WIDTH_PX;
+		float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
+		float right = dRect.right - BORDER_WIDTH_PX;
+
+		mHueRect = new RectF(left, top, right, bottom);
+	}
+
+	private void setUpAlphaRect() {
+
+		if(!mShowAlphaPanel) return;
+
+		final RectF	dRect = mDrawingRect;
+
+		float left = dRect.left + BORDER_WIDTH_PX;
+		float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
+		float bottom = dRect.bottom - BORDER_WIDTH_PX;
+		float right = dRect.right - BORDER_WIDTH_PX;
+
+		mAlphaRect = new RectF(left, top, right, bottom);
+
+		mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
+		mAlphaPattern.setBounds(
+			Math.round(mAlphaRect.left), 
+			Math.round(mAlphaRect.top), 
+			Math.round(mAlphaRect.right), 
+			Math.round(mAlphaRect.bottom)
+		);
+
+	}
+
+
+	/**
+	 * Set a OnColorChangedListener to get notified when the color
+	 * selected by the user has changed.
+	 * @param listener
+	 */
+	public void setOnColorChangedListener(OnColorChangedListener listener){
+		mListener = listener;
+	}
+
+	/**
+	 * Set the color of the border surrounding all panels.
+	 * @param color
+	 */
+	public void setBorderColor(int color){
+		mBorderColor = color;
+		invalidate();
+	}
+
+	/**
+	 * Get the color of the border surrounding all panels.
+	 */
+	public int getBorderColor(){
+		return mBorderColor;
+	}
+
+	/**
+	 * Get the current color this view is showing.
+	 * @return the current color.
+	 */
+	public int getColor(){
+		return Color.HSVToColor(mAlpha, new float[]{mHue,mSat,mVal});
+	}
+
+	/**
+	 * Set the color the view should show.
+	 * @param color The color that should be selected.
+	 */
+	public void setColor(int color){
+		setColor(color, false);
+	}
+
+	/**
+	 * Set the color this view should show.
+	 * @param color The color that should be selected.
+	 * @param callback If you want to get a callback to
+	 * your OnColorChangedListener.
+	 */
+	public void setColor(int color, boolean callback){
+
+		int alpha = Color.alpha(color);
+		int red = Color.red(color);
+		int blue = Color.blue(color);
+		int green = Color.green(color);
+
+		float[] hsv = new float[3];
+
+		Color.RGBToHSV(red, green, blue, hsv);
+
+		mAlpha = alpha;
+		mHue = hsv[0];
+		mSat = hsv[1];
+		mVal = hsv[2];
+
+		if(callback && mListener != null){
+			mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
+		}
+
+		invalidate();
+	}
+
+	/**
+	 * Get the drawing offset of the color picker view.
+	 * The drawing offset is the distance from the side of
+	 * a panel to the side of the view minus the padding.
+	 * Useful if you want to have your own panel below showing
+	 * the currently selected color and want to align it perfectly.
+	 * @return The offset in pixels.
+	 */
+	public float getDrawingOffset(){
+		return mDrawingOffset;
+	}
+
+	/**
+	 * Set if the user is allowed to adjust the alpha panel. Default is false.
+	 * If it is set to false no alpha will be set.
+	 * @param visible
+	 */
+	public void setAlphaSliderVisible(boolean visible){
+
+		if(mShowAlphaPanel != visible){
+			mShowAlphaPanel = visible;
+
+			/*
+			 * Reset all shader to force a recreation.
+			 * Otherwise they will not look right after
+			 * the size of the view has changed.
+			 */
+			mValShader = null;
+			mSatShader = null;
+			mHueShader = null;
+			mAlphaShader = null;;
+
+			requestLayout();
+		}
+
+	}
+
+	public void setSliderTrackerColor(int color){
+		mSliderTrackerColor = color;
+
+		mHueTrackerPaint.setColor(mSliderTrackerColor);
+
+		invalidate();
+	}
+
+	public int getSliderTrackerColor(){
+		return mSliderTrackerColor;
+	}
+
+	/**
+	 * Set the text that should be shown in the
+	 * alpha slider. Set to null to disable text.
+	 * @param res string resource id.
+	 */
+	public void setAlphaSliderText(int res){
+		String text = getContext().getString(res);
+		setAlphaSliderText(text);
+	}
+
+	/**
+	 * Set the text that should be shown in the
+	 * alpha slider. Set to null to disable text.
+	 * @param text Text that should be shown.
+	 */
+	public void setAlphaSliderText(String text){
+		mAlphaSliderText = text;
+		invalidate();
+	}
+
+	/**
+	 * Get the current value of the text
+	 * that will be shown in the alpha
+	 * slider.
+	 * @return
+	 */
+	public String getAlphaSliderText(){
+		return mAlphaSliderText;
+	}
+}
\ No newline at end of file

commit 730f6992bf66837a0c87bde0d1e122aa9633570c
Author: Johan Sköld <johan@skold.cc>
Date:   Sat Dec 17 06:43:33 2011 +0100

    Updated Nordea to use the non-mobile page instead. The problem with the mobile page is that it shows "Kortköp" for everything, not where the purchase originated. The non-mobile page does not have this issue.
    
    Note this update does not include support for loans, credit cards or funds. Only regular accounts. This as I do not have any of the other three personally and don't know how the pages look.
    
    Also of note, Nordea is a pain with its variables that need to be sent between pages. Send one too few or too many and they send bad results.
    
    Signed-off-by: Johan Sköld <johan@skold.cc>

diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index 58f326a..4566469 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -17,6 +17,7 @@
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -24,12 +25,12 @@ import java.util.regex.Pattern;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpResponseException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -52,15 +53,24 @@ public class Nordea extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    
+    private static final int MAX_TRANSACTIONS = 50;
 
-    private Pattern reCurrency = Pattern.compile("list-left\">\\s*Valuta\\s*</dt>\\s*<dd[^>]+>([^<]+)</dd>", Pattern.CASE_INSENSITIVE);
-    private Pattern reBalance = Pattern.compile("list-left\">\\s*Summa\\s*([a-zA-Z]{3})\\s*</dt>\\s*<dd[^>]+>([^<]+)</", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
-	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reCards = Pattern.compile("/card/details\\.html\\?id=(\\d{1,})[^\"]*\".*?>\\s*<span[^>]*>\\s*<span>([^<]+)</span>\\s*<span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-
+    private Pattern reSimpleLoginLink = Pattern.compile("href=\"(engine\\?(?=[^\"]*usecase=commonlogin)(?=[^\"]*command=commonlogintabcommand)(?=[^\"]*commonlogintab=2)(?=[^\"]*guid=([\\w]*))(?=[^\"]*fpid=([\\w]*))(?=[^\"]*hash=([\\w]*))[^\"]*)", Pattern.CASE_INSENSITIVE);
+    private Pattern reLoginFormContents = Pattern.compile("<form[^>]+id=\"commonlogin\"[^>]*>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reNonTextInputField = Pattern.compile("<input(?=[^>]+type=\"((?!text)[^\"]*)\")(?=[^>]+name=\"([^\"]+)\")(?=[^>]+value=\"([^\"]+)\")", Pattern.CASE_INSENSITIVE);
+    
+    private Pattern reTransactionFormContents = Pattern.compile("<form(?=[^>]+id=\"accountTransactions\")(?=[^>]+action=\"([^\"]*)\").*?>(.*?)</form>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountLink = Pattern.compile("href=\"(engine\\?(?=[^\"]*usecase=accountsoverview)(?=[^\"]*command=getcurrenttransactions)(?=[^\"]*currentaccountsoverviewtable=([\\d]+))[^\"]*)[^>]*>(.*?)</a>.*?([*\\d]+).*?([\\d\\.,]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransaction = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})[\n\r <].*?<td.*?>(.*?)</td>.*?<td.*?>.*?</td>.*?<td.*?>([\\s\\d-+,.]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reCurrency = Pattern.compile("Saldo:.*?[\\d\\.,-]+[\\s]*</td>[\\s]*<td[^>]*>([^<]*)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    
+    private Pattern reAccountSelect = Pattern.compile("<select[^>]+name=\"transactionaccount\"[^>]*>(.*?)</select>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountOption = Pattern.compile("<option[^>]+value=\"([\\d]+)\"[^>]*>.*?([*\\d]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    
+    private String lastResponse;    // Nordea has variables that needs to be sent between every single page
+    private int currentPageType;	// Depending on what kind of page we're currently on, the variables will have to be retrieved differently
+    
 	public Nordea(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -81,30 +91,60 @@ public class Nordea extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
-        Matcher matcher;
-        String response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-        matcher = reCSRF.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-        }
-        String csrftoken = matcher.group(1);
-        List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("xyz", username));
-        postData.add(new BasicNameValuePair("zyx", password));
-        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-        return new LoginPackage(urlopen, postData, response, "https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+		urlopen = new Urllib();
+		Matcher matcher;
+		// Find "simple login" link
+		this.lastResponse = urlopen.open("https://internetbanken.privat.nordea.se/nsp/engine");
+		this.currentPageType = PageType.LOGIN;
+		matcher = reSimpleLoginLink.matcher(this.lastResponse);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login link.");
+		}
+		// Visit login link
+		String link = "https://internetbanken.privat.nordea.se/nsp/" + matcher.group(1);
+		this.lastResponse = urlopen.open(link);
+		this.currentPageType = PageType.SIMPLE_LOGIN;
+		matcher = reLoginFormContents.matcher(this.lastResponse);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login form.");
+		}
+		// Extract hidden fields
+		String formContents = matcher.group(1);
+		matcher = reNonTextInputField.matcher(formContents);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find).toString()+" login fields.");
+		}
+		matcher.reset();
+		List <NameValuePair> postData = new ArrayList <NameValuePair>();
+		while (matcher.find()) {
+			String name  = matcher.group(2);
+			String value = matcher.group(3);
+			// The non-mobile page requires javascript, so we'd best pretend we have it
+			if ("JAVASCRIPT_DETECTED".equals(name)) {
+				value = "true";
+			}
+			postData.add(new BasicNameValuePair(name, value));
+		}
+		// Login information
+		postData.add(new BasicNameValuePair("userid", username));
+		postData.add(new BasicNameValuePair("pin", password));
+		// Submit button is not contained within the form and thus cannot (should not) be found with the InputField matcher
+		postData.add(new BasicNameValuePair("commonlogin$loginLight", "Logga in"));
+		return new LoginPackage(urlopen, postData, this.lastResponse, "https://internetbanken.privat.nordea.se/nsp/engine");
     }
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		try {
 		    LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("felaktiga uppgifter")) {
+		    this.lastResponse = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		    this.currentPageType = PageType.ENTRY;
+			if (this.lastResponse.contains("felaktiga uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			
+		} catch (HttpResponseException e) {
+			throw new BankException(String.valueOf(e.getStatusCode()));
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
@@ -121,57 +161,24 @@ public class Nordea extends Bank {
 		}
 		
 		urlopen = login();
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			matcher = reAccounts.matcher(response);
+			matcher = reAccountLink.matcher(this.lastResponse);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+				accounts.add(new Account(
+						Html.fromHtml(matcher.group(3)).toString().trim(), 
+						Helpers.parseBalance(matcher.group(5)), 
+						Html.fromHtml(matcher.group(4)).toString().trim()
+						));
 			}
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Currency          SEK
-             * 2: Amount            56,78  
-             *   
-             */
-			matcher = reBalance.matcher(response);
-			String currency = "SEK";
-			if (matcher.find()) {
-			    balance = Helpers.parseBalance(matcher.group(2));
-			    currency = Html.fromHtml(matcher.group(1)).toString().trim();
-			}
-			this.setCurrency(currency);
 			
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
-			matcher = reFundsLoans.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f:"+matcher.group(1).trim(), -1L, Account.FUNDS));
-			}
-
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
-			matcher = reFundsLoans.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l:"+matcher.group(1).trim(), -1L, Account.LOANS));
-			}
-
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
-			matcher = reCards.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c:"+matcher.group(1).trim(), -1L, Account.CCARD));
-			}
+			// TODO(Rhoot): Put code for loan, funds and cards back. I don't have either of them so I cannot do it 
+			//              personally, as I don't know what the pages look like.
 
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
 		finally {
 		    super.updateComplete();
 		}
@@ -190,34 +197,85 @@ public class Nordea extends Bank {
 		int accType = account.getType();
 		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
 
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
-			matcher = reCurrency.matcher(response);
-            /*
-             * Capture groups:
-             * GROUP                EXAMPLE DATA
-             * 1: Currency          SEK 
-             *   
-             */
-			String currency = "SEK";
-			if (matcher.find()) {
-			    currency = matcher.group(1).trim();
+			// We must never browse to a random page without keeping the hashes and stuff from the current page.
+			// Thus, we need to handle it separately depending on if we're still on the entry page or not.
+			
+			String link = null;
+			List<NameValuePair> postData = new ArrayList<NameValuePair>();
+			if(currentPageType == PageType.ENTRY) {
+				// Find the link to the transaction page
+				matcher = reAccountLink.matcher(this.lastResponse);
+				while (matcher.find()) {
+					if (Html.fromHtml(matcher.group(4)).toString().trim().equals(account.getId())) {
+						link = matcher.group(1);
+						break;
+					}
+				}
+				if (link == null) {
+					throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions link.");
+				}
+			}
+			else if(currentPageType == PageType.TRANSACTIONS) {
+				// Find the account dropdown form
+				matcher = reTransactionFormContents.matcher(this.lastResponse);
+				if (!matcher.find()) {
+					throw new BankException(res.getText(R.string.unable_to_find).toString()+" account form.");
+				}
+				link = matcher.group(1);
+				matcher = reNonTextInputField.matcher(matcher.group(2));
+				if (!matcher.find()) {
+					throw new BankException(res.getText(R.string.unable_to_find).toString()+" input fields.");
+				}
+				matcher.reset();
+				// Input fields
+				while (matcher.find()) {
+					// For some odd reason, it does not like us sending the submit button... So don't.
+					if (!matcher.group(1).equals("submit")) {
+						postData.add(new BasicNameValuePair(matcher.group(2), matcher.group(3)));
+					}
+				}
+				postData.add(new BasicNameValuePair("transactionPeriod", "0"));
+				// Account id
+				matcher = reAccountSelect.matcher(this.lastResponse);
+				if (!matcher.find()) {
+					throw new BankException(res.getText(R.string.unable_to_find).toString()+" account selection.");
+				}
+				matcher = reAccountOption.matcher(matcher.group(1));
+				String id = null;
+				while (matcher.find()) {
+					if(matcher.group(2).equals(account.getId())) {
+						id = matcher.group(1);
+						break;
+					}
+				}
+				if (id == null) {
+					throw new BankException(res.getText(R.string.unable_to_find).toString()+" account id.");
+				}
+				postData.add(new BasicNameValuePair("transactionaccount", id));
 			}
 			else {
-			    Log.w(TAG, "Unable to find currency, assuming SEK.");
+				throw new BankException("This should never happen. If it does: Grats, you broke it.");
 			}
-			matcher = reTransactions.matcher(response);
+			// Navigate to it, and parse the results
+			this.lastResponse = urlopen.open("https://internetbanken.privat.nordea.se/nsp/" + link, postData);
+			this.currentPageType = PageType.TRANSACTIONS;
+			matcher = reTransaction.matcher(this.lastResponse);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-                Transaction transaction = new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)));
-                transaction.setCurrency(currency);
+			while (matcher.find() && transactions.size() < MAX_TRANSACTIONS) {
+				String date = Html.fromHtml(matcher.group(1)).toString().trim();
+				String text = Html.fromHtml(matcher.group(2)).toString().trim();
+				BigDecimal amount = Helpers.parseBalance(matcher.group(3));
+				Transaction transaction = new Transaction(date, text, amount);
 				transactions.add(transaction);
 			}
 			account.setTransactions(transactions);
-			account.setCurrency(currency);
+			// Currency
+			matcher = reCurrency.matcher(this.lastResponse);
+			if (matcher.find()) {
+				account.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
+			}
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
@@ -225,5 +283,12 @@ public class Nordea extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-	}	
+	}
+	
+	private static class PageType {
+		public static final int LOGIN = 0;
+		public static final int SIMPLE_LOGIN = 1;
+		public static final int ENTRY = 2;
+		public static final int TRANSACTIONS = 3;
+	}
 }
\ No newline at end of file

commit 35954bfd5ff590019dd504cc17e3c8f27fab9613
Author: liato <x@x00.us>
Date:   Mon Dec 5 02:04:22 2011 +0100

    Move referenced libs to project folder.

diff --git .classpath .classpath
index 6aee44b..7229329 100644
--- .classpath
+++ .classpath
@@ -3,7 +3,7 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
-	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
+	<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/google-collect-1.0.jar"/>
 	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git .gitignore .gitignore
index 29beabd..edd78cb 100644
--- .gitignore
+++ .gitignore
@@ -13,7 +13,6 @@ Desktop.ini
 bin
 gen
 local.properties
-*.jar
 dev/
 src/com/liato/bankdroid/db/Crypto.*
 src/com/liato/bankdroid/db/Crypto.java.dev
diff --git lib/commons-io-2.0.1.jar lib/commons-io-2.0.1.jar
new file mode 100644
index 0000000..5b64b7d
Binary files /dev/null and lib/commons-io-2.0.1.jar differ
diff --git lib/google-collect-1.0.jar lib/google-collect-1.0.jar
new file mode 100644
index 0000000..a7abdbb
Binary files /dev/null and lib/google-collect-1.0.jar differ

commit f030788fc87266bbf85b60fce47ffaf4bd352067
Author: liato <x@x00.us>
Date:   Sun Dec 4 14:56:28 2011 +0100

    Merge with MatsKarlsson/master. Fix for lansforsakringar. Closes #121. Closes #123. Bump version to 1.8.4.

diff --git AndroidManifest.xml AndroidManifest.xml
index 2aa3129..378ac5d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.4-RC1" android:versionCode="124">
+	android:versionName="1.8.4" android:versionCode="125">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git project.properties project.properties
index 7991aca..8f51418 100644
--- project.properties
+++ project.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-12
+target=android-14
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index 8334a01..c45f791 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -55,13 +55,14 @@ public class Lansforsakringar extends Bank {
 
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+>([^<]+)<.*?<td class=\"right\"[^>]+>([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa.*?internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_(?:[^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern rePension = Pattern.compile("AvtalsID=([0-9_]+)[^<]+><span\\s*id=\"occupationalPensionDataTable:\\d{1,}:pension_overview_\\d{1,}_[^>]+>([^<]+)</span></a></span><span[^>]+>\\s*<sup>\\s*</span><span[^>]+></span><span[^>]+>\\s*</sup>\\s*</span>\\s*<table[^>]+>\\s*<tbody[^>]+></tbody></table>\\s*</td><td[^>]+><span[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccountsLoans = Pattern.compile("LoanNumber=[^>]+>([^<]+)</a></td><td class=\"left\" width=\"25%\">([0-9.]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td><td class=\"right\" width=\"25%\">([0-9 .,-]+)</td", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern rePension = Pattern.compile("class=\"portlet-menu-item\" [^>]+>(.*)</a></td><td class=\"left\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td><td class=\"right\" width=\"25%\">([^>]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
-    private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+>(?:<a[^>]+>)?<span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>(?:</a>)?\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
+    private Pattern reHiddenToken = Pattern.compile("name=\"_token\" value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reUrl = Pattern.compile("<li class=\"bank\\s*\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("[^>]+>(\\d{4}-\\d{2}-\\d{2})<.*(\\d{4}-\\d{2}-\\d{2})<.*<span title=\"([^\"]+)\".*</span></td><td class=\"left\"><span title=\"([^\"]+)\".*</span></td><td class=\"right nowrap\" style=\"width:90px\">([^<]+)</td>.*style=\"width:90px\">([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private String accountsUrl = null;
     private String mRequestToken = null;
     private String mViewState = null;
@@ -90,7 +91,7 @@ public class Lansforsakringar extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(false, true);
         String response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
@@ -127,7 +128,7 @@ public class Lansforsakringar extends Bank {
 
             Matcher matcher = reToken.matcher(response);
             if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token0.");
             }
             mRequestToken = matcher.group(1);
 
@@ -176,10 +177,11 @@ public class Lansforsakringar extends Bank {
                  * 2: Name                  Personkonto
                  * 3: Amount                25 000 000
                  * 
-                 */    
+                 */
                 accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
                 balance = balance.add(Helpers.parseBalance(matcher.group(3)));
             }
+            //TODO: Don't have funds.
             matcher = reAccountsFunds.matcher(response);
             while (matcher.find()) {
                 /*
@@ -209,30 +211,34 @@ public class Lansforsakringar extends Bank {
             // Save token for next request
             matcher = reToken.matcher(response);
             if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token1.");
             }
             mRequestToken = matcher.group(1);
 
-            response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_pageLabel=pension_undermenyosynlig&newUc=true&isTopLevel=true&_token=" + mRequestToken);
+            response = urlopen.open("https://" + host + "/im/im/pension.jsf?newUc=true&_token=" + mRequestToken);
             matcher = rePension.matcher(response);
             while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
-                 * 1: ID                    00835742_0
-                 * 2: Name                  Avtalspension ITP - Fond
+                 * 1: Name                  Avtalspension ITP - Fond
+                 * 2: ID                    00835742_0
                  * 3: Amount                10 587,40
-                 * 
+                 * 4: Amount?				10 587,40
                  */
-                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim());
+                Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim());
                 account.setType(Account.OTHER);
                 accounts.add(account);
             }            
 
             // Save token for next request
+            //Helpers.slowDebug(TAG, response, 20);
             matcher = reToken.matcher(response);
             if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+                matcher = reHiddenToken.matcher(response);
+                if (!matcher.find()) {
+                    throw new BankException(res.getText(R.string.unable_to_find).toString()+" token2.");
+                }
             }
             mRequestToken = matcher.group(1);
             
@@ -261,7 +267,7 @@ public class Lansforsakringar extends Bank {
 
         if (mFirstTransactionPage) {
             try {
-                response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&isPortalLogLink=true&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
+                response = urlopen.open("https://" + host + "/im/index_account.jsf?dialog=dialog:account.viewAccountTransactions&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
                 matcher = reViewState.matcher(response);
                 if (!matcher.find()) {
                     Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
@@ -269,7 +275,7 @@ public class Lansforsakringar extends Bank {
                 }
                 mViewState = matcher.group(1);
 
-                matcher = reToken.matcher(response);
+                matcher = reHiddenToken.matcher(response);
                 if (!matcher.find()) {
                     Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
                     return;
@@ -294,7 +300,7 @@ public class Lansforsakringar extends Bank {
                 postData.add(new BasicNameValuePair("loginForm:_idcl", ""));            
                 postData.add(new BasicNameValuePair("loginForm:_link_hidden_", ""));            
                 postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
-                response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Findex_account.faces", postData);
+                response = urlopen.open("https://" + host + "/im/index_account.jsf", postData);
                 mFirstTransactionPage = false;
             }
             else {
@@ -304,7 +310,7 @@ public class Lansforsakringar extends Bank {
                 postData.add(new BasicNameValuePair("viewAccountListTransactionsForm:_link_hidden_", ""));            
                 postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
                 postData.add(new BasicNameValuePair("accountList", account.getId()));
-                response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Fjsp%2Faccount%2Fview%2FviewAccountTransactions.faces", postData);
+                response = urlopen.open("https://" + host + "/im/jsp/account/view/viewAccountTransactions.jsf", postData);
             }
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();

commit 19f62f55112ef7a658494b94148757b677e3b51c
Author: liato <x@x00.us>
Date:   Sun Nov 27 23:50:16 2011 +0100

    Bump version to 1.8.4-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 9a0aa60..2aa3129 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.3" android:versionCode="123">
+	android:versionName="1.8.4-RC1" android:versionCode="124">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 008f8f52e41e7f016a9e8302357fe8757d508954
Author: liato <x@x00.us>
Date:   Sun Nov 27 23:07:05 2011 +0100

    Add Everydaycard.

diff --git project.properties project.properties
new file mode 100644
index 0000000..7991aca
--- /dev/null
+++ project.properties
@@ -0,0 +1,13 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Indicates whether an apk should be generated for each density.
+split.density=false
+# Project target.
+target=android-12
diff --git res/drawable/logo_everydaycard.png res/drawable/logo_everydaycard.png
new file mode 100644
index 0000000..603d488
Binary files /dev/null and res/drawable/logo_everydaycard.png differ
diff --git res/values/styles.xml res/values/styles.xml
index 0206983..2617f06 100644
--- res/values/styles.xml
+++ res/values/styles.xml
@@ -59,7 +59,7 @@
 		<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
 	</style>
-    <style name="WindowTitleBackground" parent="@android:WindowTitleBackground">    
+    <style name="WindowTitleBackground" parent="@*android:WindowTitleBackground">    
         <item name="android:background">@android:color/transparent</item>        
     </style>
     <style name="listViewStyle" parent="@android:style/Widget.ListView">
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 7adffdb..0fda70f 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
 import com.liato.bankdroid.banking.banks.Eurocard;
+import com.liato.bankdroid.banking.banks.Everydaycard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.Handelsbanken;
 import com.liato.bankdroid.banking.banks.Hemkop;
@@ -198,7 +199,9 @@ public class BankFactory {
         case IBankTypes.NORDEA_DK:
         	return new NordeaDK(context);
         case IBankTypes.VASTTRAFIK:
-        	return new Vasttrafik(context);
+            return new Vasttrafik(context);
+        case IBankTypes.EVERYDAYCARD:
+            return new Everydaycard(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -261,6 +264,7 @@ public class BankFactory {
         banks.add(new DanskeBank(context));
         banks.add(new NordeaDK(context));
         banks.add(new Vasttrafik(context));
+        banks.add(new Everydaycard(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Everydaycard.java src/com/liato/bankdroid/banking/banks/Everydaycard.java
new file mode 100644
index 0000000..a9d9339
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Everydaycard.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2011 Andreas Gunnerås
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Everydaycard extends Bank {
+	private static final String TAG = "Everydaycard";
+	private static final String NAME = "Everydaycard";
+	private static final String NAME_SHORT = "everydaycard";
+	private static final String URL = "http://www.everydaycard.se/mobil/";
+	private static final int BANKTYPE_ID = IBankTypes.EVERYDAYCARD;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+	
+	private Pattern reSaldo = Pattern.compile("Utnyttjad kredit \\(sek\\)</td>\\s*<td class=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reBonus = Pattern.compile("Aktuell bonus \\(sek\\)</strong></td>\\s*<td class=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccountTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reBonusTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>.*</td>\\s*<td>.*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	public Everydaycard(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+	}
+
+	public Everydaycard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+    	return preLoginInternal("http://valuta.g2solutions.se/mobil/web/logonSubmit.do");
+    }
+    
+    private LoginPackage preLoginNonMobile() throws BankException,
+            ClientProtocolException, IOException {
+    	return preLoginInternal("https://valuta.g2solutions.se/valuta/web/logonSubmit.do");
+    }
+
+    private LoginPackage preLoginInternal(String url) throws BankException,
+    		ClientProtocolException, IOException {
+    	urlopen = new Urllib(true);
+    	List <NameValuePair> postData = new ArrayList <NameValuePair>();
+    	postData.add(new BasicNameValuePair("nextPage", "firstPage"));                
+    	postData.add(new BasicNameValuePair("username", username));
+    	postData.add(new BasicNameValuePair("password", password));
+    	return new LoginPackage(urlopen, postData, response, url);
+    }
+    
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLoginNonMobile();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (response.contains("Felaktigt Login")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+	
+		Matcher matcher = reBonus.matcher(response);
+ 		if (matcher.find()) {
+ 			BigDecimal bonusBalance = Helpers.parseBalance(matcher.group(1));
+			Account account = new Account("Bonus", bonusBalance, "Bonus", Account.OTHER);
+			balance = balance.add(bonusBalance);
+			accounts.add(account);
+		}
+
+		matcher = reSaldo.matcher(response);
+ 		if (matcher.find()) {
+ 			BigDecimal accountBalance = Helpers.parseBalance(matcher.group(1)).negate();
+			Account account = new Account("Everydaycard", accountBalance, "1", Account.CCARD);
+			balance = balance.add(accountBalance);
+			accounts.add(account);
+		}
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+        super.updateComplete();
+	}
+
+	@Override
+    public void updateAllTransactions() throws LoginException, BankException {
+		if (urlopen == null) {
+			urlopen = login();
+        }
+		try {
+			response = urlopen.open("https://valuta.g2solutions.se/valuta/web/manageCustomer.do?action=account");
+			for (Account account: accounts) {
+				Matcher matcher;
+				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            
+				switch (account.getType()) {
+				case Account.CCARD:
+					matcher = reAccountTransactions.matcher(response);
+					while (matcher.find()) {
+						transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(3)).negate()));
+					}
+					break;
+				// Bonus account
+				case Account.OTHER:
+					matcher = reBonusTransactions.matcher(response);
+					while (matcher.find()) {
+						if (!matcher.group(4).equals("0,00")) {
+							transactions.add(new Transaction(matcher.group(1), matcher.group(2) + " (-" + matcher.group(3) + ")", Helpers.parseBalance(matcher.group(4))));
+						}
+					}
+					break;
+				default:
+					return;
+				}
+
+				account.setTransactions(transactions);
+			}
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		} finally {
+			if (urlopen != null) {
+				urlopen.close();
+			}
+        }
+	}
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index b07d775..66352c8 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -76,4 +76,5 @@ public interface IBankTypes {
     public final static int DANSKEBANK = 52;
     public final static int NORDEA_DK = 53;
     public final static int VASTTRAFIK = 54;
+    public final static int EVERYDAYCARD = 55;
 }

commit 754b9e6cf2f9a4ebee5f769061d8b2d4e97ff60c
Author: liato <x@x00.us>
Date:   Sun Nov 27 22:48:11 2011 +0100

    Fix for Coop. Activate hardware acceleration.

diff --git .classpath .classpath
index 4417ebe..6aee44b 100644
--- .classpath
+++ .classpath
@@ -5,5 +5,5 @@
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
 	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
-	<classpathentry kind="output" path="bin"/>
+	<classpathentry kind="output" path="bin/classes"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index a4f5e26..9a0aa60 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -6,7 +6,8 @@
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
-		android:debuggable="false">
+		android:debuggable="false"
+	    android:hardwareAccelerated="true">
 		<activity
 			android:name=".MainActivity"
 			android:label="@string/app_name"
diff --git default.properties default.properties
deleted file mode 100644
index c174b25..0000000
--- default.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-# 
-# This file must be checked in Version Control Systems.
-# 
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Indicates whether an apk should be generated for each density.
-split.density=false
-# Project target.
-target=android-5
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index a38f93f..ba673d8 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -52,6 +52,7 @@ public class Coop extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.COOP;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
     private String response;
@@ -80,6 +81,11 @@ public class Coop extends Bank {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
         }
         String strViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
+        }
+        String strEventValidation = matcher.group(1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
         postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
@@ -87,6 +93,7 @@ public class Coop extends Bank {
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
         return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Oversikt/");
     }
 

commit 9f626b0dedb01cb90a16fb127a041c5f3dd1c579
Author: liato <x@x00.us>
Date:   Sun Nov 13 19:32:25 2011 +0100

    More reliable auto updates, maybe. Fixed swedish translation for "Save". Closes #116.

diff --git AndroidManifest.xml AndroidManifest.xml
index 9a5d1be..a4f5e26 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.2-RC1" android:versionCode="122">
+	android:versionName="1.8.3" android:versionCode="123">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
@@ -116,14 +116,16 @@
 				<action
 					android:name="android.intent.action.BOOT_COMPLETED" />
 				<action
-					android:name="android.intent.action.PACKAGE_ADDED"></action>
+					android:name="android.intent.action.PACKAGE_ADDED" />
 				<action
-					android:name="android.intent.action.PACKAGE_CHANGED"></action>
+					android:name="android.intent.action.PACKAGE_CHANGED" />
 				<action
 					android:name="android.intent.action.PACKAGE_REPLACED" />
-				<data
+				<action
+					android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+				<!-- <data
 					android:scheme="package"
-					android:path="com.liato.bankdroid" />
+					android:path="com.liato.bankdroid" /> -->
 			</intent-filter>
 		</receiver>
 		<service
@@ -168,6 +170,8 @@
 		android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 	<uses-permission
 		android:name="android.permission.VIBRATE" />
+	<uses-permission
+		android:name="android.permission.ACCESS_NETWORK_STATE" />
 	<uses-permission
 		android:name="com.sonyericsson.extras.liveview.permission.LIVEVIEW_API" />
 	<supports-screens
diff --git default.properties default.properties
index 19c9665..c174b25 100644
--- default.properties
+++ default.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-4
+target=android-5
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index f79f6ec..5e3a67b 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -28,6 +28,7 @@
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
     <string name="cancel">AVBRYT</string>
+    <string name="save">SPARA</string>
    
 	<string name="add_new_account">LÄGG TILL BANK</string>
 	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
diff --git res/values/styles.xml res/values/styles.xml
index 2617f06..0206983 100644
--- res/values/styles.xml
+++ res/values/styles.xml
@@ -59,7 +59,7 @@
 		<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
 	</style>
-    <style name="WindowTitleBackground" parent="@*android:WindowTitleBackground">    
+    <style name="WindowTitleBackground" parent="@android:WindowTitleBackground">    
         <item name="android:background">@android:color/transparent</item>        
     </style>
     <style name="listViewStyle" parent="@android:style/Widget.ListView">
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 202f36f..710ca31 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -20,10 +20,13 @@ import com.liato.bankdroid.appwidget.AutoRefreshService;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.Uri;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
@@ -33,7 +36,12 @@ public class StartupReceiver extends BroadcastReceiver{
 	@Override
 	public void onReceive(Context context, Intent intent) {
 		//Set alarms for auto updates on boot, package update, package replace and package new
-		setAlarm(context);
+		if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+	        updateNow(context);
+		}
+        else {
+            setAlarm(context);
+        }
 	}
 	
 	public static void setAlarm(Context context) {
@@ -52,8 +60,18 @@ public class StartupReceiver extends BroadcastReceiver{
 	        if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_refreshrate_in_seconds", false)) {
 	            secondsInMinute = 1;
 	        }
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*secondsInMinute*1000, refreshRate*secondsInMinute*1000, alarmSender);
+	        am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*secondsInMinute*1000, refreshRate*secondsInMinute*1000, alarmSender);
         }
 	
 	}
+	
+	public static void updateNow(Context context) {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        boolean autoUpdatesEnabled = prefs.getBoolean("autoupdates_enabled", true);
+        long lastUpdate = prefs.getLong("autoupdates_last_update", 0);
+        Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0")); 
+        if (autoUpdatesEnabled && System.currentTimeMillis() - lastUpdate > refreshRate*60*1000) {
+            context.startService(new Intent(context, AutoRefreshService.class));
+        }
+	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index e4fb210..4045b4e 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -29,7 +29,9 @@ import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.content.res.Resources;
+import android.net.ConnectivityManager;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.IBinder;
@@ -60,14 +62,32 @@ public class AutoRefreshService extends Service {
 
 	@Override
 	public void onCreate() {
-		if (InsideUpdatePeriod()){
-			new DataRetrieverTask().execute();
-		}
-		else{
-			Log.v(TAG, "Skipping update due to not in update period.");
-			stopSelf();
-		}
+
 	}
+	
+    @Override
+    public void onStart(Intent intent, int startId) {
+        handleStart(intent, startId);
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        handleStart(intent, startId);
+        return START_NOT_STICKY;
+    }
+    
+    private void handleStart(Intent intent, int startId) {
+        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
+        if (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnectedOrConnecting()) {
+            if (InsideUpdatePeriod()){
+                new DataRetrieverTask().execute();
+            }
+            else{
+                Log.v(TAG, "Skipping update due to not in update period.");
+                stopSelf();
+            }
+        }
+    }
 
     private boolean InsideUpdatePeriod() {
 		final SharedPreferences prefs = PreferenceManager
@@ -335,6 +355,9 @@ public class AutoRefreshService extends Service {
 					errormsg.append("\n");
 				}
 			}
+			Editor edit = prefs.edit();
+			edit.putLong("autoupdates_last_update", System.currentTimeMillis());
+			edit.commit();
 			AutoRefreshService.this.stopSelf();
 		}
 	}

commit cc38cd5f652163a4889a5a2d257e6da98f368cc8
Merge: 813023a ee2886c
Author: liato <x@x00.us>
Date:   Sun Nov 13 04:15:51 2011 +0100

    Merge branch 'master' of github.com:liato/android-bankdroid

commit 813023a3fcb25e9e7f3adfcddfe13bfe646d626b
Author: liato <x@x00.us>
Date:   Sun Nov 13 04:15:36 2011 +0100

    Test.

diff --git AndroidManifest.xml AndroidManifest.xml
index 19daf84..9a5d1be 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.1" android:versionCode="121">
+	android:versionName="1.8.2-RC1" android:versionCode="122">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/layout/listitem_accounts_item.xml res/layout/listitem_accounts_item.xml
index cbbec0d..4acad10 100644
--- res/layout/listitem_accounts_item.xml
+++ res/layout/listitem_accounts_item.xml
@@ -18,7 +18,7 @@
 		android:inputType="none"
 		android:text="Kontonamn"
 		android:textStyle="bold"
-		android:layout_height="fill_parent" android:paddingLeft="15dp"/>
+		android:layout_height="fill_parent" android:paddingLeft="15dp" android:layout_toLeftOf="@+id/txtListitemAccountsItemBalance"/>
 
 
 	<TextView
@@ -30,7 +30,6 @@
 		android:layout_alignParentTop="true"
 		android:id="@+id/txtListitemAccountsItemBalance"
 		android:inputType="none"
-		android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname"
 		android:gravity="right|center_vertical"
 		android:layout_height="fill_parent" android:textColor="#fff" android:paddingRight="10dp"/>
 
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index f8af537..bf947ce 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -240,8 +240,7 @@ public class BankFactory {
         banks.add(new SparbankenOresund(context));
         banks.add(new Opel(context));
         banks.add(new Skandiabanken(context));
-        //Not tested or not working
-        //banks.add(new AmericanExpress(context));
+        banks.add(new AmericanExpress(context));
         banks.add(new PlusGirot(context));
         banks.add(new Nordnetdirekt(context));
         banks.add(new Saab(context));

commit ee2886c16064a8ed7e6e18155b33ccf35072deda
Merge: 30538f3 72a0538
Author: liato <x@x00.us>
Date:   Thu Nov 10 17:04:37 2011 -0800

    Merge pull request #110 from erifre/master
    
    Västtrafik

commit 30538f362fb2c3b0feaffd5d70582c83e2f79d68
Merge: 4373f01 905d3dc
Author: liato <x@x00.us>
Date:   Thu Nov 10 16:44:25 2011 -0800

    Merge pull request #111 from fredriklindberg/master
    
    Fix SEB login.

commit 905d3dc1049ae2a3ba486d82c7d7345e05940c8d
Author: Fredrik Lindberg <fli@shapeshifter.se>
Date:   Thu Nov 10 15:09:08 2011 +0100

    Fix compile with newer SDKs.

diff --git res/values/styles.xml res/values/styles.xml
index cb77222..2617f06 100644
--- res/values/styles.xml
+++ res/values/styles.xml
@@ -59,7 +59,7 @@
 		<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
 	</style>
-    <style name="WindowTitleBackground" parent="android:WindowTitleBackground">    
+    <style name="WindowTitleBackground" parent="@*android:WindowTitleBackground">    
         <item name="android:background">@android:color/transparent</item>        
     </style>
     <style name="listViewStyle" parent="@android:style/Widget.ListView">

commit 7a9783d24e2c89bd6eede9d0d154ceb5d97a5ba2
Author: Fredrik Lindberg <fli@shapeshifter.se>
Date:   Thu Nov 10 14:58:27 2011 +0100

    Fix SEB login. m.seb.se have started to return different sites
    depending on user agent with slightly different login methods.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 4d75f6d..7cb2c1a 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -48,7 +48,7 @@ public class SEB extends Bank {
 	private static final String TAG = "SEB";
 	private static final String NAME = "SEB";
 	private static final String NAME_SHORT = "seb";
-	private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm";
+	private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/mpo0001.aspx";
 	private static final int BANKTYPE_ID = IBankTypes.SEB;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
@@ -85,7 +85,8 @@ public class SEB extends Bank {
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
-        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001b.aspx");
+        postData.add(new BasicNameValuePair("A3", "4"));
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001bm.aspx");
     }
 
 	@Override
@@ -93,8 +94,7 @@ public class SEB extends Bank {
 		try {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			
-			if (!response.contains("1100/mps1101.aspx?X1=passWord")) {
+			if (!response.contains("passwordLoginOK")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		} catch (ClientProtocolException e) {
@@ -115,7 +115,7 @@ public class SEB extends Bank {
 		urlopen = login();
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=passWord");
+			response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=digipassAppl1");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
                 /*

commit 72a0538bb94a59dc7ee6a5e7d9a25bb2a750ff03
Author: Erik Fredriksen <erik@fredriksen.se>
Date:   Wed Oct 12 23:14:49 2011 +0200

    Wrong text at the login check

diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
index 16d03e2..4b566da 100644
--- src/com/liato/bankdroid/banking/banks/Vasttrafik.java
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -93,7 +93,7 @@ public class Vasttrafik extends Bank {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Inloggningen misslyckades")) {
+            if (response.contains("Felaktig inloggning")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
         }

commit 55c6f5514c5652ddb917da993ea9cc36735173ab
Author: Erik Fredriksen <erik@fredriksen.se>
Date:   Wed Oct 12 19:43:18 2011 +0200

    Added support for Västtrafik

diff --git res/drawable/logo_vasttrafik.png res/drawable/logo_vasttrafik.png
new file mode 100644
index 0000000..71671aa
Binary files /dev/null and res/drawable/logo_vasttrafik.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index f8af537..35009dd 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -75,6 +75,7 @@ import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
+import com.liato.bankdroid.banking.banks.Vasttrafik;
 import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
@@ -196,6 +197,8 @@ public class BankFactory {
             return new DanskeBank(context);
         case IBankTypes.NORDEA_DK:
         	return new NordeaDK(context);
+        case IBankTypes.VASTTRAFIK:
+        	return new Vasttrafik(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -258,6 +261,7 @@ public class BankFactory {
         banks.add(new IKEA(context));
         banks.add(new DanskeBank(context));
         banks.add(new NordeaDK(context));
+        banks.add(new Vasttrafik(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Vasttrafik.java src/com/liato/bankdroid/banking/banks/Vasttrafik.java
new file mode 100644
index 0000000..16d03e2
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Vasttrafik.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Vasttrafik extends Bank {
+    private static final String TAG = "Västtrafik";
+    private static final String NAME = "Västtrafik";
+    private static final String NAME_SHORT = "vasttrafik";
+    private static final String URL = "http://vasttrafik.se/Mina-Sidor/";
+    private static final int BANKTYPE_ID = IBankTypes.VASTTRAFIK;
+
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+	private Pattern reAccounts = Pattern.compile("<td class=\"HeadingTop Col2of3\">\\s+([^<]+)\\s+</td>.*?<td class=\"Col2of3\">\\s+([^<]+)\\s+</td>.*?<div id=\"ctl00_FullRegion_MainAndFooterRegion_MainRegion_HandleCardsFormControl_TabContainerCards_TabPanelCards_ListViewActiveCards_ctrl\\d{0,3}_PanelDetail\" class=\"RowColor collapsePanel\" style=\"height:0px;\">(.*?)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);;
+	private Pattern reBalance = Pattern.compile("<tr class=\"(RowColor|AlternatingColor)\">\\s+<td>\\s+Kontoladdning\\s+</td>.*?<td>(.*?)<br />.*?</td>.*?</tr>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
+    private String response = null;
+
+    public Vasttrafik(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Vasttrafik(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+    ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        response = urlopen.open("https://www.vasttrafik.se/CustomerUtil/Common/Security/Login.aspx");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String strViewState = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+		postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+		postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+		postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+		postData.add(new BasicNameValuePair("LoginFormControl$TextBoxUsername", username));
+		postData.add(new BasicNameValuePair("LoginFormControl$TextBoxPassword", password));
+		postData.add(new BasicNameValuePair("LoginFormControl_CheckBoxPersistantLogin", ""));
+		postData.add(new BasicNameValuePair("LoginFormControl$LoginButton", "Logga in"));
+
+        return new LoginPackage(urlopen, postData, response, "https://www.vasttrafik.se/CustomerUtil/Common/Security/Login.aspx");
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("Inloggningen misslyckades")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException, BankChoiceException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            response = urlopen.open("https://www.vasttrafik.se/sv/Mina-sidor-inloggad/Mina-Vasttrafikskort/");
+            Matcher matcher;
+            Matcher matcher_b;
+            matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            }			
+            String strViewState = matcher.group(1);
+
+            matcher = reAccounts.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Name              Nytt
+                 * 2: Card number       1111111111
+                 * 3: Balance information
+                 * 
+                 */
+
+                matcher_b = reBalance.matcher(matcher.group(3));
+                if (matcher_b.find()) {
+                    /*
+                     * Capture groups:
+                     * GROUP                EXAMPLE DATA
+                     * 2: Amount            592,80 kr
+                     * 
+                     */
+
+					String balanceString = matcher_b.group(2).replaceAll("\\<a[^>]*>","").replaceAll("\\<[^>]*>","").trim();
+						
+                    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim() , Helpers.parseBalance(balanceString), matcher.group(2)));
+                    balance = balance.add(Helpers.parseBalance(balanceString));
+                }
+            }
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }		
+        finally {
+            super.updateComplete();
+        }
+    }
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 2bef52c..b07d775 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -75,4 +75,5 @@ public interface IBankTypes {
     public final static int SKANDIABANKEN = 51;
     public final static int DANSKEBANK = 52;
     public final static int NORDEA_DK = 53;
-}
\ No newline at end of file
+    public final static int VASTTRAFIK = 54;
+}

commit 4373f01449802d50b0d27d9c801652aa1fc2abf5
Merge: b5f637b e5d5ef8
Author: liato <x@x00.us>
Date:   Mon Oct 10 14:15:35 2011 -0700

    Merge pull request #106 from lawi75/master
    
    I have fixed the Amex bank support.

commit e5d5ef813314b8df7567ea30d74770f0a8b4448f
Merge: afefd03 b5f637b
Author: lawi75 <lars@wiklund.ws>
Date:   Thu Sep 29 13:59:41 2011 +0200

    Merge branch 'master' of https://lawi75@github.com/lawi75/android-bankdroid.git

commit afefd039914d5b9aaf10c96a1541132646d222b6
Author: liato <x@x00.us>
Date:   Thu Sep 29 13:49:05 2011 +0200

    Fixed regexp to add support for American Express. Regexp could be done
    more strict but no need because it works as is

diff --git AndroidManifest.xml AndroidManifest.xml
index da9731b..19daf84 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.0" android:versionCode="120">
+	android:versionName="1.8.1" android:versionCode="121">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
index 4fbe55a..aae791c 100644
--- src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
@@ -57,7 +57,7 @@ public class HessianHttpHeaderProxyFactory extends HessianHttpProxyFactory{
 	    	// Ugly hack: for some reason the path in the cookie is not as expected
             if (cookie.host.contentEquals("smartrefill.se"))
             {
-            	Log.d("Skandiabanken cookie", "using path / instead of " + cookie.path);
+            	//Log.d("Skandiabanken cookie", "using path / instead of " + cookie.path);
             	cookie.path = "/";
             }
             super.putCookie(cookie);
diff --git src/com/caucho/hessian/client/HessianHttpProxyFactory.java src/com/caucho/hessian/client/HessianHttpProxyFactory.java
index b3fdada..3371e3e 100644
--- src/com/caucho/hessian/client/HessianHttpProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpProxyFactory.java
@@ -122,7 +122,7 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
                 String host = conn.getURL().getHost();
                 for (String s : cookieStrings) {
                     Cookie cookie = CookieParser.parse(host, s);
-                    Log.d("Skandiabanken cookie", "Cookie string: " + s);
+                    //Log.d("Skandiabanken cookie", "Cookie string: " + s);
                     putCookie(cookie);
                 }
             }
@@ -142,11 +142,11 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
             String path = conn.getURL().getPath();
 
             while (path != null && 0 < path.length()) {
-                Log.d("Skandiabanken cookie", "Host:+" + host +",Path:"+path);
+                //Log.d("Skandiabanken cookie", "Host:+" + host +",Path:"+path);
                 Cookie cookie = getCookie(host, path);
                 if (cookie != null) {
                     conn.setRequestProperty("Cookie", cookie.value);
-                    Log.d("Skandiabanken cookie", "Cookie set in request:" + cookie.value);
+                    //Log.d("Skandiabanken cookie", "Cookie set in request:" + cookie.value);
                     break;
                 }
                 int i = path.lastIndexOf("/");
@@ -164,7 +164,7 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
 
 		protected void putCookie(Cookie cookie) {
             HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
-            Log.d("Skandiabanken cookie", "Cookie cached: " + cookie.host + cookie.path);
+            //Log.d("Skandiabanken cookie", "Cookie cached: " + cookie.host + cookie.path);
 		}
 	}
 }
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3de9334..3e72de9 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -231,13 +231,10 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 
 		protected Void doInBackground(final String... args) {
 			try {
-				Log.d(TAG, "Updating "+bank);
 				bank.update();
 				bank.updateAllTransactions();
 				bank.closeConnection();
-				Log.d(TAG, "Saving "+bank);
 				bank.save();
-				Log.d(TAG, "Disabled: " + bank.isDisabled());
 
 				// Transactions updated.
 				final SharedPreferences prefs = PreferenceManager
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index fd90c2c..76a42c9 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -84,15 +84,10 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 				continue;
 			}
 			try {
-				// Log.d("AA", "bank.update()");
 				bank.update();
-				// Log.d("AA", "bank.updateAllTransactions()");
 				bank.updateAllTransactions();
-				// Log.d("AA", "bank.closeConnction()");
 				bank.closeConnection();
-				// Log.d("AA", "bank.save()");
 				bank.save();
-				// Log.d("AA", "DONE!");
 				i++;
 			} catch (final BankException e) {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
@@ -105,7 +100,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
             catch (BankChoiceException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
-                Log.d(TAG, "BankChoiceError: " + e.getMessage());
+                Log.e(TAG, "BankChoiceError: " + e.getMessage());
             }
 
 			final SharedPreferences prefs = PreferenceManager
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 70bcfe6..1898be3 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -90,7 +90,7 @@ public class Helpers {
             ret = new BigDecimal(balance);
         }
         catch (NumberFormatException e) {
-            Log.d("parseBalance", "Unable to parse: "+balance);
+            Log.e("parseBalance", "Unable to parse: "+balance);
             ret = new BigDecimal(0);
         }
         return ret;
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index ccebd33..453703e 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -89,7 +89,6 @@ public class MainActivity extends LockableActivity {
 		lv.setAdapter(adapter);
 		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
 			public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
-				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
 				if (adapter.getItem(position) instanceof Account) {
 					selected_account = (Account)adapter.getItem(position);
 					final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
@@ -101,7 +100,6 @@ public class MainActivity extends LockableActivity {
 		});
 		lv.setOnItemClickListener(new OnItemClickListener() {
 			public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
-				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
 				if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
 					final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
@@ -335,8 +333,6 @@ public class MainActivity extends LockableActivity {
 
 		@Override
 		protected void onCreate() {
-			Log.d(TAG, "PopUpMenuAcc, oncreate");
-			// inflate layout
 			final LayoutInflater inflater =
 				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
diff --git src/com/liato/bankdroid/PairApplicationsActivity.java src/com/liato/bankdroid/PairApplicationsActivity.java
index 1e75a76..f785a2b 100644
--- src/com/liato/bankdroid/PairApplicationsActivity.java
+++ src/com/liato/bankdroid/PairApplicationsActivity.java
@@ -74,7 +74,7 @@ public class PairApplicationsActivity extends LockableActivity {
 			TextView appNameView = (TextView) findViewById(R.id.app_name);
 			appNameView.setText(appName);
 		} else {
-			Log.d(TAG, "Unknown application");
+			Log.w(TAG, "Unknown application");
 		}
 
 
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 664f56d..1eb74db 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -129,13 +129,11 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 	protected void onActivityResult(final int requestCode, final int resultCode,
 			final Intent data) {
 		super.onActivityResult(requestCode, resultCode, data);
-		Log.d(TAG, "onActivityResult: req:"+requestCode+"; res:"+resultCode);
 		if (requestCode == DISABLE_LOCKPATTERN) {
 			if (resultCode == RESULT_OK) {
 				mLockPatternUtils.setLockPatternEnabled(false);
 				mLockPatternUtils.saveLockPattern(null);
 				((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(false);
-				Log.d(TAG, "Pattern lock has been disabled.");
 			}
 			else {
 				Log.d(TAG, "User was unable to disable pattern lock.");
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index cececef..202f36f 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -33,7 +33,6 @@ public class StartupReceiver extends BroadcastReceiver{
 	@Override
 	public void onReceive(Context context, Intent intent) {
 		//Set alarms for auto updates on boot, package update, package replace and package new
-		Log.d("StartupReceiever", "Intent action: "+intent.getAction());
 		setAlarm(context);
 	}
 	
@@ -46,7 +45,6 @@ public class StartupReceiver extends BroadcastReceiver{
         AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         if (!autoUpdatesEnabled) {
         	am.cancel(alarmSender);
-        	Log.d(TAG,"Automatic updates have been disabled.");
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
@@ -55,7 +53,6 @@ public class StartupReceiver extends BroadcastReceiver{
 	            secondsInMinute = 1;
 	        }
 	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*secondsInMinute*1000, refreshRate*secondsInMinute*1000, alarmSender);
-        	Log.d(TAG,"Automatic updates set to "+refreshRate.toString()+" minutes.");
         }
 	
 	}
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index a2671f9..77ef2fb 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -64,7 +64,7 @@ public class TransactionsActivity extends LockableActivity {
 		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
 		icon.setImageResource(bank.getImageResource());
 		ArrayList<Transaction> transactions = account.getTransactions();
-		Log.d(TAG, "Transactions: "+transactions.size());
+
 		if (transactions.size() > 0) {
 			findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
 			TransactionsAdapter adapter = new TransactionsAdapter(transactions);
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 37d34c8..dc7a4c3 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -150,7 +150,6 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
 
         @Override
         public void onPageFinished(WebView view, String url) {
-            Log.d(TAG, "Finished loading: "+url);
             super.onPageFinished(view, url);
             if (!mFirstPageLoaded) {
                 //This is the generated POST page.
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index e72c0a9..e4fb210 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -112,9 +112,7 @@ public class AutoRefreshService extends Service {
 
 		// http://www.freesound.org/samplesViewSingle.php?id=75235
 		// http://www.freesound.org/samplesViewSingle.php?id=91924
-		Log.d(TAG,
-				"Notification sound: "
-						+ prefs.getString("notification_sound", "none"));
+		//Log.d(TAG, "Notification sound: " + prefs.getString("notification_sound", "none"));
 		if (prefs.getString("notification_sound", null) != null) {
 			notification.sound = Uri.parse(prefs.getString(
 					"notification_sound", null));
@@ -205,13 +203,10 @@ public class AutoRefreshService extends Service {
 					continue;
 				}
 				if (bank.isDisabled()) {
-					Log.d(TAG, bank.getName() + " (" + bank.getDisplayName()
-							+ ") is disabled. Skipping refresh.");
+					//Log.d(TAG, bank.getName() + " (" + bank.getDisplayName() + ") is disabled. Skipping refresh.");
 					continue;
 				}
-				Log.d(TAG,
-						"Refreshing " + bank.getName() + " ("
-								+ bank.getDisplayName() + ").");
+				//Log.d(TAG, "Refreshing " + bank.getName() + " (" + bank.getDisplayName() + ").");
 				try {
 					currentBalance = bank.getBalance();
 					accounts.clear();
@@ -250,10 +245,6 @@ public class AutoRefreshService extends Service {
 												"notify_for_other", false);
 										break;
 									}
-									Log.d(TAG,
-											"Account type: "
-													+ account.getType()
-													+ "; notify: " + notify);
 									if (account.isHidden()
 											|| !account.isNotify()) {
 										notify = false;
@@ -305,16 +296,16 @@ public class AutoRefreshService extends Service {
 					}
 				} catch (final BankException e) {
 					// Refresh widgets if an update fails
-					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
 							+ "'; BankException: " + e.getMessage());
 				} catch (final LoginException e) {
-					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
 							+ "'; LoginException: " + e.getMessage());
 					refreshWidgets = true;
 					db.disableBank(bank.getDbId());
 				}
                 catch (BankChoiceException e) {
-                    Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
                             + "'; LoginException: " + e.getMessage());
                 }
 			}
@@ -343,7 +334,6 @@ public class AutoRefreshService extends Service {
 					errormsg.append(err);
 					errormsg.append("\n");
 				}
-				Log.d("aa", errormsg.toString());
 			}
 			AutoRefreshService.this.stopSelf();
 		}
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 85eb75a..f4884fe 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -97,18 +97,16 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
     
     static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
-		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
 		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
 		long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
 		if (accountId == null) {
-			Log.d("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
+			Log.w("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 		}
-		Log.d("BankdroidWidgetProvider", "Account ID: "+accountId);
 		Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false);
 		if (account == null) {
-			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
+			Log.w("BankdroidWidgetProvider", "Account not found in db: "+accountId);
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 			
@@ -116,7 +114,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 		Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false);
 		if (bank == null) {
-			Log.d("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
+			Log.w("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 			
@@ -131,7 +129,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId, Account account) {
-		Log.d("Widget", "Building widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
@@ -145,12 +142,10 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		}
 		Bank bank = account.getBank();
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
-		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
         views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false)));
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
-		Log.d("Disabled", ""+bank.isDisabled());
 		if (bank.isDisabled()) {
 			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
 		}
@@ -208,7 +203,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 	static RemoteViews disableAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
-		Log.d("Widget", "Disabling widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
@@ -220,7 +214,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			}
 		}		
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
-		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
 		views.setTextViewText(R.id.txtWidgetAccountname, "");
 		views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR");
 		views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
@@ -250,7 +243,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		}
 
 
-		Log.d("BankdroidWidgetProvider", "intent=" + intent+"; action="+action);
 		if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH) || action.equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
 			AppWidgetManager appWM = AppWidgetManager.getInstance(context);
 			int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent());
@@ -267,7 +259,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		super.onDeleted(context, appWidgetIds);
 		final int N = appWidgetIds.length;
 		for (int i = 0; i < N; i++) {
-			Log.d("Widget", "Widget deleted: " + appWidgetIds[i]);
 			WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]);
 		}
 	}
@@ -277,7 +268,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		@Override
 		public void onStart(Intent intent, int startId) {
 			int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-			Log.d("WidgetService", "Updating widget: " + appWidgetId);
 			Context context = getApplicationContext();
 			String action = intent.getAction();
 			if (action == null) return; 
@@ -346,7 +336,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			protected Void doInBackground(Void... params) {
 				String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
 				if (accountId == null) {
-					Log.d("WidgetService", "Widget not found in db: "+appWidgetId);
+					Log.w("WidgetService", "Widget not found in db: "+appWidgetId);
 					return null;
 				}
 				long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
@@ -364,18 +354,16 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 						bank.closeConnection();
 						bank.save();
 					}
-					else {
-						Log.d("BankdroidWidgetProvider", "Bank is disabled, skipping refresh on "+bank.getDbId());
-					}
+
 				} 
 				catch (BankException e) {
-    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+    				Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
 				} catch (LoginException e) {
-					Log.d("", "Disabling bank: "+bank.getDbId());
+					Log.e("", "Disabling bank: "+bank.getDbId());
 					bank.disable();
 				}
                 catch (BankChoiceException e) {
-                    Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+                    Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
                 }
 
 				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index fbe7541..0f8acc2 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -361,13 +361,13 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             return new SessionPackage(html, cookies);
         }
         catch (ClientProtocolException e) {
-            Log.d(TAG, e.getMessage());
+            Log.e(TAG, e.getMessage());
         }
         catch (IOException e) {
-            Log.d(TAG, e.getMessage());
+            Log.e(TAG, e.getMessage());
         }
         catch (BankException e) {
-            Log.d(TAG, e.getMessage());
+            Log.e(TAG, e.getMessage());
         }
         String html = String.format(preloader,
                 String.format("function go(){window.location=\"%s\" }", this.URL), // Javascript function
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 6b959bd..f8af537 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -316,7 +316,6 @@ public class BankFactory {
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
 			c.moveToNext();
-			//Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
 			try {
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
 				
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 57531da..3f97c8c 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -53,8 +53,8 @@ public class AmericanExpress extends Bank {
 	private static final String URL = "https://home.americanexpress.com/home/se/home_c.shtml";
 	private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
 	
-	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a></div>\\s*</td>\\s*<td\\s*colspan=\"6\"\\s*id=\"headerSectionLeft\">\\s*<span\\s*class=\"cardTitle\">.*?BPIndex=(\\d{1,})&[^>]+>([^<]+)</a>.*?Utest&aring;ende skuld</div>\\s*<div[^>]+>[^<]+</div>\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTransactions = Pattern.compile("tableStandardText\"\\s*id=\"Roc\\d{1,}\">\\s*<td[^>]+>\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4})</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a>\\r*\\s*</div>\\r*\\s*</td>\\r*\\s*<td\\s*id=\"headerSectionLeft\"\\s*colspan=\"6\">\\r*\\s*<span\\s*class=\"cardTitle\">.*?sorted_index=(\\d{1,})&?[^>]+>([^<]+)</a>.*?Utest[\\&aring;|å]ende skuld\\s*</div>\\r*\\s*<div[^>]+>[^<]+</div>\\r*\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("id=\"Roc\\d{1,}\"\\s* class='tableStandardText'>\\r*\\s*<td[^>]+>\\r*\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4}).*?</a>\\r*\\s*([^<]*).*?amountPadding'>&nbsp;</td>\\r*\\s*<td\\s*class='amountPadding'>.*?(\\d{1,},?\\d{1,}\\s*kr)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	
 	private String response = null;
 
@@ -127,6 +127,7 @@ public class AmericanExpress extends Bank {
         Log.d(TAG, "Url after login: " + urlopen.getCurrentURI());
 		
 		Matcher matcher = reAccounts.matcher(response);
+		
 		while (matcher.find()) {
             /*
              * Capture groups:
@@ -154,7 +155,7 @@ public class AmericanExpress extends Bank {
 		super.updateTransactions(account, urlopen);
 
 		try {
-			response = urlopen.open("https://www99.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&sorted_index=0&BPIndex=" + account.getId());
+			response = urlopen.open("https://global.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&BPIndex=0&sorted_index=" + account.getId());
 			Matcher matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index 6d74146..93ec7a4 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -32,7 +32,6 @@ import org.apache.http.protocol.HTTP;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index f9bd62d..98d16c0 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -179,7 +179,6 @@ public class DinersClub extends Bank {
 		Matcher matcher;
 		try {
 			/* We're going to look at all the pages until we find one that has transactions on it */
-			Log.d(TAG, String.format("Opening: https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
 			response = urlopen.open(String.format("https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 46fa573..897c9f8 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -174,7 +174,6 @@ public class Eurocard extends Bank {
 		if (account.getType() == Account.OTHER) return;
 		try {
 		    String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index 95ebe8f..e09ef59 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -145,7 +145,6 @@ public class FirstCard extends Bank {
 		super.updateTransactions(account, urlopen);
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
 			response = urlopen.open("https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index e20360e..43641c2 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -106,11 +106,11 @@ public class Handelsbanken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.d(TAG, "ClientProtocolException: "+e.getMessage());
+			Log.w(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
-			Log.d(TAG, "IOException: "+e.getMessage());
+			Log.w(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
@@ -161,7 +161,6 @@ public class Handelsbanken extends Bank {
 		Matcher matcher;
 		try {
 			String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			Log.d(TAG, "Opening: https://m.handelsbanken.se/primary/_-"+accountWebId);
 			response = urlopen.open("https://m.handelsbanken.se/primary/_-"+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 6f8224b..1ad93cb 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -165,7 +165,6 @@ public class Hemkop extends Bank {
             }
             
             if (url != null) {
-                Log.d(TAG, "Opening "+url);
                 response = urlopen.open(url);
     
                 Matcher matcher = reTransaction.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index c0ab4eb..f4d8edc 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -121,11 +121,11 @@ public class ICABanken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.d(TAG, "ClientProtocolException: "+e.getMessage());
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
-			Log.d(TAG, "IOException: "+e.getMessage());
+			Log.e(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index e024fea..e31c665 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -84,7 +84,6 @@ public class IkanoBank extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         response = urlopen.open("https://secure.ikanobank.se/login");
-        //Log.d(TAG, "Url after first request: " + urlopen.getCurrentURI());
         Matcher matcher;
         if (response.contains("Banken är stängd")) {
             matcher = reErrorMessage.matcher(response);
@@ -118,7 +117,6 @@ public class IkanoBank extends Bank {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            //Log.d(TAG, "Url after login attempt: " + urlopen.getCurrentURI());
             if (response.contains("Ogiltigt personnummer") || response.contains("felaktigt personnummer")) {
                 Matcher matcher = reErrorMessage.matcher(response);
                 if (matcher.find()) {
@@ -192,7 +190,6 @@ public class IkanoBank extends Bank {
             postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));            
             postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));            
             response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
-            //Log.d(TAG, "Transactions url: " + urlopen.getCurrentURI());
 
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index eb5b533..8334a01 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -114,7 +114,6 @@ public class Lansforsakringar extends Bank {
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
         postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-        Log.d(TAG, "Posting to: "+urlopen.getCurrentURI());
         return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
     }
 
@@ -165,7 +164,6 @@ public class Lansforsakringar extends Bank {
         Matcher matcher;
         try {
             if (accountsUrl == null) {
-                Log.d(TAG, "accountsUrl is null, unable to update.");
                 return;
             }
             response = urlopen.open(accountsUrl);
@@ -266,14 +264,14 @@ public class Lansforsakringar extends Bank {
                 response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&isPortalLogLink=true&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
                 matcher = reViewState.matcher(response);
                 if (!matcher.find()) {
-                    Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
+                    Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
                     return;
                 }
                 mViewState = matcher.group(1);
 
                 matcher = reToken.matcher(response);
                 if (!matcher.find()) {
-                    Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
+                    Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
                     return;
                 }
                 mRequestToken = matcher.group(1);                  
@@ -333,7 +331,7 @@ public class Lansforsakringar extends Bank {
             // We need the second match, disregard the first one.
             matcher.find();
             if (!matcher.find()) {
-                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L334.");
+                Log.e(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L334.");
                 return;
             }
             mViewState = matcher.group(1);
@@ -341,7 +339,7 @@ public class Lansforsakringar extends Bank {
 
             matcher = reToken.matcher(response);
             if (!matcher.find()) {
-                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" token. L342.");
+                Log.w(TAG, res.getText(R.string.unable_to_find).toString()+" token. L342.");
                 return;
             }
             mRequestToken = matcher.group(1);            
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index ce60091..58f326a 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -100,10 +100,7 @@ public class Nordea extends Bank {
 	public Urllib login() throws LoginException, BankException {
 		try {
 		    LoginPackage lp = preLogin();
-			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
-			
 			if (response.contains("felaktiga uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -197,7 +194,6 @@ public class Nordea extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
 			matcher = reCurrency.matcher(response);
             /*
@@ -211,7 +207,7 @@ public class Nordea extends Bank {
 			    currency = matcher.group(1).trim();
 			}
 			else {
-			    Log.d(TAG, "Unable to find currency, assuming SEK.");
+			    Log.w(TAG, "Unable to find currency, assuming SEK.");
 			}
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java src/com/liato/bankdroid/banking/banks/NordeaDK.java
index 2474035..a796310 100644
--- src/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ src/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -3,11 +3,7 @@ package com.liato.bankdroid.banking.banks;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -25,7 +21,6 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.Bank.LoginPackage;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -126,10 +121,10 @@ public class NordeaDK extends Bank {
 			}
 			this.updatePrefix();
 		} catch (ClientProtocolException e) {
-			Log.d(TAG, "ClientProtocolException: " + e.getMessage());
+			Log.e(TAG, "ClientProtocolException: " + e.getMessage());
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
-			Log.d(TAG, "IOException: " + e.getMessage());
+			Log.e(TAG, "IOException: " + e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
@@ -213,7 +208,6 @@ public class NordeaDK extends Bank {
 
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: " + url);
 			urlopen.addHeader("referer", this.referer);
 			this.response = urlopen.open(url);
 			this.updatePrefix();
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index feecb1a..7c50886 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -167,7 +167,6 @@ public class OKQ8 extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		if (response == null) {
-			Log.d(TAG, "Response is null, login again.");
 			urlopen = login();
 		}
 		try {
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index ef362ca..0bdb09f 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -82,7 +82,6 @@ public class PayPal extends Bank {
         String strPostUrl;
         if (matcher.find()) {
             strPostUrl = Html.fromHtml(matcher.group(1)).toString();
-            Log.d(TAG, "Found post url: "+strPostUrl);
         }
         else {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 3e7c85b..f64ccae 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -172,7 +172,6 @@ public abstract class SEBKortBase extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, String.format("Opening: https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index 2b619eb..cf68296 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -157,7 +157,7 @@ public class Steam extends Bank {
                                                      Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(), "USD")));
                 }
                 catch (ParseException e) {
-                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                    Log.e(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
 		    }
 		    Collections.sort(transactions, Collections.reverseOrder());
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index bdc1e04..95e78dc 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -155,7 +155,6 @@ public class Villabanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
 			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
 
 			matcher = reAccounts.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 30d0486..edef11c 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -72,7 +72,6 @@ public class Volvofinans extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-		Log.d("Volvofinans", "preLogin");
         urlopen = new Urllib(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -85,8 +84,6 @@ public class Volvofinans extends Bank {
 
     @Override
 	public Urllib login() throws LoginException, BankException {
-		Log.d("Volvofinans", "login");
-	    
 	    try {
 	        LoginPackage lp = preLogin();
 	        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
@@ -111,7 +108,6 @@ public class Volvofinans extends Bank {
 	@Override
 	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
-		Log.d("Volvofinans", "update");
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
@@ -119,9 +115,6 @@ public class Volvofinans extends Bank {
 		String response = null;
 		try {
 			response = urlopen.open("https://www.volvokort.com/privat/kund/kortkonto/oversikt/kortkonton.html");
-			
-			Log.d("Volvofinans", response);
-
 			try {
 				JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
 				JSONArray data = object.getJSONArray("data");
@@ -129,9 +122,6 @@ public class Volvofinans extends Bank {
 				int length = data.length();
 				for (int index = 0; index < length; index++) {
 					JSONObject account = data.getJSONObject(index);
-
-					Log.d("Volvofinans", account.getString("kontonummer"));
-					
 					accounts.add(new Account(account.getString("kontonummer"), Helpers.parseBalance(account.getString("disponibeltBelopp")), "1"));
 				}
 			}
diff --git src/com/liato/bankdroid/db/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
index 91e3d25..bdcb0a1 100644
--- src/com/liato/bankdroid/db/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -152,7 +152,6 @@ public class DBAdapter {
         initialValues.put("updated", sdf.format(cal.getTime()));
         
         long bankId = bank.getDbId();
-        Log.d(TAG, "Updating bank, DbId: "+bankId);
         if (bankId == -1) {
         	bankId = mDb.insert("banks", null, initialValues);
         }
@@ -162,7 +161,6 @@ public class DBAdapter {
         }
         if (bankId != -1) {
 	        ArrayList<Account> accounts = bank.getAccounts();
-            Log.d(TAG, "Bank accounts: "+bank.getAccounts().size());
 	        for(Account acc : accounts) {
 	            ContentValues vals = new ContentValues();
 	            vals.put("bankid", bankId);
@@ -192,7 +190,6 @@ public class DBAdapter {
 	            }
 	        }
         }
-        Log.d(TAG, "Updated bank: "+bankId);
         return bankId;
     }
     

commit b5f637bbb301aa2fe997c9f3367cfb144d158633
Author: liato <x@x00.us>
Date:   Tue Sep 27 00:09:23 2011 +0200

    Remove some logging. Bump version to 1.8.1.

diff --git AndroidManifest.xml AndroidManifest.xml
index da9731b..19daf84 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.0" android:versionCode="120">
+	android:versionName="1.8.1" android:versionCode="121">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
index 4fbe55a..aae791c 100644
--- src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
@@ -57,7 +57,7 @@ public class HessianHttpHeaderProxyFactory extends HessianHttpProxyFactory{
 	    	// Ugly hack: for some reason the path in the cookie is not as expected
             if (cookie.host.contentEquals("smartrefill.se"))
             {
-            	Log.d("Skandiabanken cookie", "using path / instead of " + cookie.path);
+            	//Log.d("Skandiabanken cookie", "using path / instead of " + cookie.path);
             	cookie.path = "/";
             }
             super.putCookie(cookie);
diff --git src/com/caucho/hessian/client/HessianHttpProxyFactory.java src/com/caucho/hessian/client/HessianHttpProxyFactory.java
index b3fdada..3371e3e 100644
--- src/com/caucho/hessian/client/HessianHttpProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpProxyFactory.java
@@ -122,7 +122,7 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
                 String host = conn.getURL().getHost();
                 for (String s : cookieStrings) {
                     Cookie cookie = CookieParser.parse(host, s);
-                    Log.d("Skandiabanken cookie", "Cookie string: " + s);
+                    //Log.d("Skandiabanken cookie", "Cookie string: " + s);
                     putCookie(cookie);
                 }
             }
@@ -142,11 +142,11 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
             String path = conn.getURL().getPath();
 
             while (path != null && 0 < path.length()) {
-                Log.d("Skandiabanken cookie", "Host:+" + host +",Path:"+path);
+                //Log.d("Skandiabanken cookie", "Host:+" + host +",Path:"+path);
                 Cookie cookie = getCookie(host, path);
                 if (cookie != null) {
                     conn.setRequestProperty("Cookie", cookie.value);
-                    Log.d("Skandiabanken cookie", "Cookie set in request:" + cookie.value);
+                    //Log.d("Skandiabanken cookie", "Cookie set in request:" + cookie.value);
                     break;
                 }
                 int i = path.lastIndexOf("/");
@@ -164,7 +164,7 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
 
 		protected void putCookie(Cookie cookie) {
             HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
-            Log.d("Skandiabanken cookie", "Cookie cached: " + cookie.host + cookie.path);
+            //Log.d("Skandiabanken cookie", "Cookie cached: " + cookie.host + cookie.path);
 		}
 	}
 }
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3de9334..3e72de9 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -231,13 +231,10 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 
 		protected Void doInBackground(final String... args) {
 			try {
-				Log.d(TAG, "Updating "+bank);
 				bank.update();
 				bank.updateAllTransactions();
 				bank.closeConnection();
-				Log.d(TAG, "Saving "+bank);
 				bank.save();
-				Log.d(TAG, "Disabled: " + bank.isDisabled());
 
 				// Transactions updated.
 				final SharedPreferences prefs = PreferenceManager
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index fd90c2c..76a42c9 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -84,15 +84,10 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 				continue;
 			}
 			try {
-				// Log.d("AA", "bank.update()");
 				bank.update();
-				// Log.d("AA", "bank.updateAllTransactions()");
 				bank.updateAllTransactions();
-				// Log.d("AA", "bank.closeConnction()");
 				bank.closeConnection();
-				// Log.d("AA", "bank.save()");
 				bank.save();
-				// Log.d("AA", "DONE!");
 				i++;
 			} catch (final BankException e) {
 				this.errors.add(bank.getName() + " (" + bank.getUsername()
@@ -105,7 +100,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
             catch (BankChoiceException e) {
                 this.errors.add(bank.getName() + " (" + bank.getUsername()
                         + ")");
-                Log.d(TAG, "BankChoiceError: " + e.getMessage());
+                Log.e(TAG, "BankChoiceError: " + e.getMessage());
             }
 
 			final SharedPreferences prefs = PreferenceManager
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 70bcfe6..1898be3 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -90,7 +90,7 @@ public class Helpers {
             ret = new BigDecimal(balance);
         }
         catch (NumberFormatException e) {
-            Log.d("parseBalance", "Unable to parse: "+balance);
+            Log.e("parseBalance", "Unable to parse: "+balance);
             ret = new BigDecimal(0);
         }
         return ret;
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index ccebd33..453703e 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -89,7 +89,6 @@ public class MainActivity extends LockableActivity {
 		lv.setAdapter(adapter);
 		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
 			public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
-				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
 				if (adapter.getItem(position) instanceof Account) {
 					selected_account = (Account)adapter.getItem(position);
 					final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
@@ -101,7 +100,6 @@ public class MainActivity extends LockableActivity {
 		});
 		lv.setOnItemClickListener(new OnItemClickListener() {
 			public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
-				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
 				if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
 					final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
@@ -335,8 +333,6 @@ public class MainActivity extends LockableActivity {
 
 		@Override
 		protected void onCreate() {
-			Log.d(TAG, "PopUpMenuAcc, oncreate");
-			// inflate layout
 			final LayoutInflater inflater =
 				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
diff --git src/com/liato/bankdroid/PairApplicationsActivity.java src/com/liato/bankdroid/PairApplicationsActivity.java
index 1e75a76..f785a2b 100644
--- src/com/liato/bankdroid/PairApplicationsActivity.java
+++ src/com/liato/bankdroid/PairApplicationsActivity.java
@@ -74,7 +74,7 @@ public class PairApplicationsActivity extends LockableActivity {
 			TextView appNameView = (TextView) findViewById(R.id.app_name);
 			appNameView.setText(appName);
 		} else {
-			Log.d(TAG, "Unknown application");
+			Log.w(TAG, "Unknown application");
 		}
 
 
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 664f56d..1eb74db 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -129,13 +129,11 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 	protected void onActivityResult(final int requestCode, final int resultCode,
 			final Intent data) {
 		super.onActivityResult(requestCode, resultCode, data);
-		Log.d(TAG, "onActivityResult: req:"+requestCode+"; res:"+resultCode);
 		if (requestCode == DISABLE_LOCKPATTERN) {
 			if (resultCode == RESULT_OK) {
 				mLockPatternUtils.setLockPatternEnabled(false);
 				mLockPatternUtils.saveLockPattern(null);
 				((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(false);
-				Log.d(TAG, "Pattern lock has been disabled.");
 			}
 			else {
 				Log.d(TAG, "User was unable to disable pattern lock.");
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index cececef..202f36f 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -33,7 +33,6 @@ public class StartupReceiver extends BroadcastReceiver{
 	@Override
 	public void onReceive(Context context, Intent intent) {
 		//Set alarms for auto updates on boot, package update, package replace and package new
-		Log.d("StartupReceiever", "Intent action: "+intent.getAction());
 		setAlarm(context);
 	}
 	
@@ -46,7 +45,6 @@ public class StartupReceiver extends BroadcastReceiver{
         AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         if (!autoUpdatesEnabled) {
         	am.cancel(alarmSender);
-        	Log.d(TAG,"Automatic updates have been disabled.");
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
@@ -55,7 +53,6 @@ public class StartupReceiver extends BroadcastReceiver{
 	            secondsInMinute = 1;
 	        }
 	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*secondsInMinute*1000, refreshRate*secondsInMinute*1000, alarmSender);
-        	Log.d(TAG,"Automatic updates set to "+refreshRate.toString()+" minutes.");
         }
 	
 	}
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index a2671f9..77ef2fb 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -64,7 +64,7 @@ public class TransactionsActivity extends LockableActivity {
 		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
 		icon.setImageResource(bank.getImageResource());
 		ArrayList<Transaction> transactions = account.getTransactions();
-		Log.d(TAG, "Transactions: "+transactions.size());
+
 		if (transactions.size() > 0) {
 			findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
 			TransactionsAdapter adapter = new TransactionsAdapter(transactions);
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 37d34c8..dc7a4c3 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -150,7 +150,6 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
 
         @Override
         public void onPageFinished(WebView view, String url) {
-            Log.d(TAG, "Finished loading: "+url);
             super.onPageFinished(view, url);
             if (!mFirstPageLoaded) {
                 //This is the generated POST page.
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index e72c0a9..e4fb210 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -112,9 +112,7 @@ public class AutoRefreshService extends Service {
 
 		// http://www.freesound.org/samplesViewSingle.php?id=75235
 		// http://www.freesound.org/samplesViewSingle.php?id=91924
-		Log.d(TAG,
-				"Notification sound: "
-						+ prefs.getString("notification_sound", "none"));
+		//Log.d(TAG, "Notification sound: " + prefs.getString("notification_sound", "none"));
 		if (prefs.getString("notification_sound", null) != null) {
 			notification.sound = Uri.parse(prefs.getString(
 					"notification_sound", null));
@@ -205,13 +203,10 @@ public class AutoRefreshService extends Service {
 					continue;
 				}
 				if (bank.isDisabled()) {
-					Log.d(TAG, bank.getName() + " (" + bank.getDisplayName()
-							+ ") is disabled. Skipping refresh.");
+					//Log.d(TAG, bank.getName() + " (" + bank.getDisplayName() + ") is disabled. Skipping refresh.");
 					continue;
 				}
-				Log.d(TAG,
-						"Refreshing " + bank.getName() + " ("
-								+ bank.getDisplayName() + ").");
+				//Log.d(TAG, "Refreshing " + bank.getName() + " (" + bank.getDisplayName() + ").");
 				try {
 					currentBalance = bank.getBalance();
 					accounts.clear();
@@ -250,10 +245,6 @@ public class AutoRefreshService extends Service {
 												"notify_for_other", false);
 										break;
 									}
-									Log.d(TAG,
-											"Account type: "
-													+ account.getType()
-													+ "; notify: " + notify);
 									if (account.isHidden()
 											|| !account.isNotify()) {
 										notify = false;
@@ -305,16 +296,16 @@ public class AutoRefreshService extends Service {
 					}
 				} catch (final BankException e) {
 					// Refresh widgets if an update fails
-					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
 							+ "'; BankException: " + e.getMessage());
 				} catch (final LoginException e) {
-					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+					Log.e(TAG, "Error while updating bank '" + bank.getDbId()
 							+ "'; LoginException: " + e.getMessage());
 					refreshWidgets = true;
 					db.disableBank(bank.getDbId());
 				}
                 catch (BankChoiceException e) {
-                    Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+                    Log.e(TAG, "Error while updating bank '" + bank.getDbId()
                             + "'; LoginException: " + e.getMessage());
                 }
 			}
@@ -343,7 +334,6 @@ public class AutoRefreshService extends Service {
 					errormsg.append(err);
 					errormsg.append("\n");
 				}
-				Log.d("aa", errormsg.toString());
 			}
 			AutoRefreshService.this.stopSelf();
 		}
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 85eb75a..f4884fe 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -97,18 +97,16 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
     
     static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
-		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
 		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
 		long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
 		if (accountId == null) {
-			Log.d("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
+			Log.w("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 		}
-		Log.d("BankdroidWidgetProvider", "Account ID: "+accountId);
 		Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false);
 		if (account == null) {
-			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
+			Log.w("BankdroidWidgetProvider", "Account not found in db: "+accountId);
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 			
@@ -116,7 +114,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 		Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false);
 		if (bank == null) {
-			Log.d("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
+			Log.w("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 			
@@ -131,7 +129,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId, Account account) {
-		Log.d("Widget", "Building widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
@@ -145,12 +142,10 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		}
 		Bank bank = account.getBank();
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
-		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
         views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false)));
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
-		Log.d("Disabled", ""+bank.isDisabled());
 		if (bank.isDisabled()) {
 			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
 		}
@@ -208,7 +203,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 	static RemoteViews disableAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
-		Log.d("Widget", "Disabling widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
@@ -220,7 +214,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			}
 		}		
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
-		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
 		views.setTextViewText(R.id.txtWidgetAccountname, "");
 		views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR");
 		views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
@@ -250,7 +243,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		}
 
 
-		Log.d("BankdroidWidgetProvider", "intent=" + intent+"; action="+action);
 		if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH) || action.equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
 			AppWidgetManager appWM = AppWidgetManager.getInstance(context);
 			int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent());
@@ -267,7 +259,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		super.onDeleted(context, appWidgetIds);
 		final int N = appWidgetIds.length;
 		for (int i = 0; i < N; i++) {
-			Log.d("Widget", "Widget deleted: " + appWidgetIds[i]);
 			WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]);
 		}
 	}
@@ -277,7 +268,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		@Override
 		public void onStart(Intent intent, int startId) {
 			int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
-			Log.d("WidgetService", "Updating widget: " + appWidgetId);
 			Context context = getApplicationContext();
 			String action = intent.getAction();
 			if (action == null) return; 
@@ -346,7 +336,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			protected Void doInBackground(Void... params) {
 				String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
 				if (accountId == null) {
-					Log.d("WidgetService", "Widget not found in db: "+appWidgetId);
+					Log.w("WidgetService", "Widget not found in db: "+appWidgetId);
 					return null;
 				}
 				long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
@@ -364,18 +354,16 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 						bank.closeConnection();
 						bank.save();
 					}
-					else {
-						Log.d("BankdroidWidgetProvider", "Bank is disabled, skipping refresh on "+bank.getDbId());
-					}
+
 				} 
 				catch (BankException e) {
-    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+    				Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
 				} catch (LoginException e) {
-					Log.d("", "Disabling bank: "+bank.getDbId());
+					Log.e("", "Disabling bank: "+bank.getDbId());
 					bank.disable();
 				}
                 catch (BankChoiceException e) {
-                    Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+                    Log.e(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
                 }
 
 				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index fbe7541..0f8acc2 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -361,13 +361,13 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             return new SessionPackage(html, cookies);
         }
         catch (ClientProtocolException e) {
-            Log.d(TAG, e.getMessage());
+            Log.e(TAG, e.getMessage());
         }
         catch (IOException e) {
-            Log.d(TAG, e.getMessage());
+            Log.e(TAG, e.getMessage());
         }
         catch (BankException e) {
-            Log.d(TAG, e.getMessage());
+            Log.e(TAG, e.getMessage());
         }
         String html = String.format(preloader,
                 String.format("function go(){window.location=\"%s\" }", this.URL), // Javascript function
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 6b959bd..f8af537 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -316,7 +316,6 @@ public class BankFactory {
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
 			c.moveToNext();
-			//Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
 			try {
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
 				
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index 6d74146..93ec7a4 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -32,7 +32,6 @@ import org.apache.http.protocol.HTTP;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index f9bd62d..98d16c0 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -179,7 +179,6 @@ public class DinersClub extends Bank {
 		Matcher matcher;
 		try {
 			/* We're going to look at all the pages until we find one that has transactions on it */
-			Log.d(TAG, String.format("Opening: https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
 			response = urlopen.open(String.format("https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 46fa573..897c9f8 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -174,7 +174,6 @@ public class Eurocard extends Bank {
 		if (account.getType() == Account.OTHER) return;
 		try {
 		    String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index 95ebe8f..e09ef59 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -145,7 +145,6 @@ public class FirstCard extends Bank {
 		super.updateTransactions(account, urlopen);
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
 			response = urlopen.open("https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index e20360e..43641c2 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -106,11 +106,11 @@ public class Handelsbanken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.d(TAG, "ClientProtocolException: "+e.getMessage());
+			Log.w(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
-			Log.d(TAG, "IOException: "+e.getMessage());
+			Log.w(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
@@ -161,7 +161,6 @@ public class Handelsbanken extends Bank {
 		Matcher matcher;
 		try {
 			String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
-			Log.d(TAG, "Opening: https://m.handelsbanken.se/primary/_-"+accountWebId);
 			response = urlopen.open("https://m.handelsbanken.se/primary/_-"+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index 6f8224b..1ad93cb 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -165,7 +165,6 @@ public class Hemkop extends Bank {
             }
             
             if (url != null) {
-                Log.d(TAG, "Opening "+url);
                 response = urlopen.open(url);
     
                 Matcher matcher = reTransaction.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index c0ab4eb..f4d8edc 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -121,11 +121,11 @@ public class ICABanken extends Bank {
 			}
 		}
 		catch (ClientProtocolException e) {
-			Log.d(TAG, "ClientProtocolException: "+e.getMessage());
+			Log.e(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
-			Log.d(TAG, "IOException: "+e.getMessage());
+			Log.e(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index e024fea..e31c665 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -84,7 +84,6 @@ public class IkanoBank extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         response = urlopen.open("https://secure.ikanobank.se/login");
-        //Log.d(TAG, "Url after first request: " + urlopen.getCurrentURI());
         Matcher matcher;
         if (response.contains("Banken är stängd")) {
             matcher = reErrorMessage.matcher(response);
@@ -118,7 +117,6 @@ public class IkanoBank extends Bank {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            //Log.d(TAG, "Url after login attempt: " + urlopen.getCurrentURI());
             if (response.contains("Ogiltigt personnummer") || response.contains("felaktigt personnummer")) {
                 Matcher matcher = reErrorMessage.matcher(response);
                 if (matcher.find()) {
@@ -192,7 +190,6 @@ public class IkanoBank extends Bank {
             postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));            
             postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));            
             response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
-            //Log.d(TAG, "Transactions url: " + urlopen.getCurrentURI());
 
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index eb5b533..8334a01 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -114,7 +114,6 @@ public class Lansforsakringar extends Bank {
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
         postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-        Log.d(TAG, "Posting to: "+urlopen.getCurrentURI());
         return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
     }
 
@@ -165,7 +164,6 @@ public class Lansforsakringar extends Bank {
         Matcher matcher;
         try {
             if (accountsUrl == null) {
-                Log.d(TAG, "accountsUrl is null, unable to update.");
                 return;
             }
             response = urlopen.open(accountsUrl);
@@ -266,14 +264,14 @@ public class Lansforsakringar extends Bank {
                 response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&isPortalLogLink=true&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
                 matcher = reViewState.matcher(response);
                 if (!matcher.find()) {
-                    Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
+                    Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
                     return;
                 }
                 mViewState = matcher.group(1);
 
                 matcher = reToken.matcher(response);
                 if (!matcher.find()) {
-                    Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
+                    Log.w(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
                     return;
                 }
                 mRequestToken = matcher.group(1);                  
@@ -333,7 +331,7 @@ public class Lansforsakringar extends Bank {
             // We need the second match, disregard the first one.
             matcher.find();
             if (!matcher.find()) {
-                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L334.");
+                Log.e(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L334.");
                 return;
             }
             mViewState = matcher.group(1);
@@ -341,7 +339,7 @@ public class Lansforsakringar extends Bank {
 
             matcher = reToken.matcher(response);
             if (!matcher.find()) {
-                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" token. L342.");
+                Log.w(TAG, res.getText(R.string.unable_to_find).toString()+" token. L342.");
                 return;
             }
             mRequestToken = matcher.group(1);            
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index ce60091..58f326a 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -100,10 +100,7 @@ public class Nordea extends Bank {
 	public Urllib login() throws LoginException, BankException {
 		try {
 		    LoginPackage lp = preLogin();
-			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
-			
 			if (response.contains("felaktiga uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -197,7 +194,6 @@ public class Nordea extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
 			matcher = reCurrency.matcher(response);
             /*
@@ -211,7 +207,7 @@ public class Nordea extends Bank {
 			    currency = matcher.group(1).trim();
 			}
 			else {
-			    Log.d(TAG, "Unable to find currency, assuming SEK.");
+			    Log.w(TAG, "Unable to find currency, assuming SEK.");
 			}
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java src/com/liato/bankdroid/banking/banks/NordeaDK.java
index 2474035..a796310 100644
--- src/com/liato/bankdroid/banking/banks/NordeaDK.java
+++ src/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -3,11 +3,7 @@ package com.liato.bankdroid.banking.banks;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -25,7 +21,6 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.Bank.LoginPackage;
 import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
@@ -126,10 +121,10 @@ public class NordeaDK extends Bank {
 			}
 			this.updatePrefix();
 		} catch (ClientProtocolException e) {
-			Log.d(TAG, "ClientProtocolException: " + e.getMessage());
+			Log.e(TAG, "ClientProtocolException: " + e.getMessage());
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
-			Log.d(TAG, "IOException: " + e.getMessage());
+			Log.e(TAG, "IOException: " + e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		return urlopen;
@@ -213,7 +208,6 @@ public class NordeaDK extends Bank {
 
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: " + url);
 			urlopen.addHeader("referer", this.referer);
 			this.response = urlopen.open(url);
 			this.updatePrefix();
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index feecb1a..7c50886 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -167,7 +167,6 @@ public class OKQ8 extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		if (response == null) {
-			Log.d(TAG, "Response is null, login again.");
 			urlopen = login();
 		}
 		try {
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index ef362ca..0bdb09f 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -82,7 +82,6 @@ public class PayPal extends Bank {
         String strPostUrl;
         if (matcher.find()) {
             strPostUrl = Html.fromHtml(matcher.group(1)).toString();
-            Log.d(TAG, "Found post url: "+strPostUrl);
         }
         else {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 3e7c85b..f64ccae 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -172,7 +172,6 @@ public abstract class SEBKortBase extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, String.format("Opening: https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index 2b619eb..cf68296 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -157,7 +157,7 @@ public class Steam extends Bank {
                                                      Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(), "USD")));
                 }
                 catch (ParseException e) {
-                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                    Log.e(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
 		    }
 		    Collections.sort(transactions, Collections.reverseOrder());
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index bdc1e04..95e78dc 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -155,7 +155,6 @@ public class Villabanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
 			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
 
 			matcher = reAccounts.matcher(response);
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 30d0486..edef11c 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -72,7 +72,6 @@ public class Volvofinans extends Bank {
 	@Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-		Log.d("Volvofinans", "preLogin");
         urlopen = new Urllib(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -85,8 +84,6 @@ public class Volvofinans extends Bank {
 
     @Override
 	public Urllib login() throws LoginException, BankException {
-		Log.d("Volvofinans", "login");
-	    
 	    try {
 	        LoginPackage lp = preLogin();
 	        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
@@ -111,7 +108,6 @@ public class Volvofinans extends Bank {
 	@Override
 	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
-		Log.d("Volvofinans", "update");
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
@@ -119,9 +115,6 @@ public class Volvofinans extends Bank {
 		String response = null;
 		try {
 			response = urlopen.open("https://www.volvokort.com/privat/kund/kortkonto/oversikt/kortkonton.html");
-			
-			Log.d("Volvofinans", response);
-
 			try {
 				JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
 				JSONArray data = object.getJSONArray("data");
@@ -129,9 +122,6 @@ public class Volvofinans extends Bank {
 				int length = data.length();
 				for (int index = 0; index < length; index++) {
 					JSONObject account = data.getJSONObject(index);
-
-					Log.d("Volvofinans", account.getString("kontonummer"));
-					
 					accounts.add(new Account(account.getString("kontonummer"), Helpers.parseBalance(account.getString("disponibeltBelopp")), "1"));
 				}
 			}
diff --git src/com/liato/bankdroid/db/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
index 91e3d25..bdcb0a1 100644
--- src/com/liato/bankdroid/db/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -152,7 +152,6 @@ public class DBAdapter {
         initialValues.put("updated", sdf.format(cal.getTime()));
         
         long bankId = bank.getDbId();
-        Log.d(TAG, "Updating bank, DbId: "+bankId);
         if (bankId == -1) {
         	bankId = mDb.insert("banks", null, initialValues);
         }
@@ -162,7 +161,6 @@ public class DBAdapter {
         }
         if (bankId != -1) {
 	        ArrayList<Account> accounts = bank.getAccounts();
-            Log.d(TAG, "Bank accounts: "+bank.getAccounts().size());
 	        for(Account acc : accounts) {
 	            ContentValues vals = new ContentValues();
 	            vals.put("bankid", bankId);
@@ -192,7 +190,6 @@ public class DBAdapter {
 	            }
 	        }
         }
-        Log.d(TAG, "Updated bank: "+bankId);
         return bankId;
     }
     

commit 7e6dd5b874d590efd4fdd59dd713663447298ec4
Merge: bed9d30 42b1b06
Author: liato <x@x00.us>
Date:   Mon Sep 26 23:10:20 2011 +0200

    Merge with goober/master

commit 42b1b0610a7d55579ab811ffb31efceb5c03bc81
Author: Mathias Aahsberg <mathias.ahsberg@gmail.com>
Date:   Sun Sep 25 17:02:06 2011 +0200

    Adds Nordea Denmark as a new bank.
    
    * Both balance and transactions works.
    Note: Only the current- and last month's transactions will be scraped to
    prevent a time consuming update process.

diff --git res/drawable/logo_nordea_dk.png res/drawable/logo_nordea_dk.png
new file mode 100644
index 0000000..7b5d539
Binary files /dev/null and res/drawable/logo_nordea_dk.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index f00b159..3325f2e 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -48,6 +48,7 @@ import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Nordea;
+import com.liato.bankdroid.banking.banks.NordeaDK;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
@@ -193,6 +194,8 @@ public class BankFactory {
             return new Skandiabanken(context);
         case IBankTypes.DANSKEBANK:
             return new DanskeBank(context);
+        case IBankTypes.NORDEA_DK:
+        	return new NordeaDK(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -254,6 +257,7 @@ public class BankFactory {
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
         //banks.add(new DanskeBank(context));
+        banks.add(new NordeaDK(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/NordeaDK.java src/com/liato/bankdroid/banking/banks/NordeaDK.java
new file mode 100644
index 0000000..2474035
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/NordeaDK.java
@@ -0,0 +1,267 @@
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.Bank.LoginPackage;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class NordeaDK extends Bank {
+
+	private static final String TAG = "NordeaDK";
+	private static final String NAME = "Nordea DK";
+	private static final String NAME_SHORT = "nordea_dk";
+	private static final String URL = "https://m.nordea.dk/";
+	private static final int BANKTYPE_ID = IBankTypes.NORDEA_DK;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+	private static final String INPUT_HINT_USERNAME = "DDMMÅÅ-XXXX";
+
+	private final String currency = "DKK";
+
+	private String prefix;
+	private String referer;
+
+	private Pattern reLoginUrl = Pattern.compile(
+			"<input.*?name=\"prefix\".*?value=\"([^\"]+)\"",
+			Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern
+			.compile(
+					"<a.*?href=\"(.*?AccountTransactions.*?productidx=([0-9]+).*?)[^>]+>\\s*<span[^>]+>(.*?)</span>\\s*<span[^>]+>\\s*(.*?)</span>",
+					Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern
+			.compile(
+					"<tr [^>]+>\\s*<td.*?[^>]+>\\s*(.*?)[.]{1}\\s*</td>\\s*<td[^>]*>\\s*(.*?)\\s*</td>\\s*<td[^>]+>\\s*(.*?)\\s*</td>\\s*</tr>",
+					Pattern.CASE_INSENSITIVE);
+	private Pattern rePrefix = Pattern.compile(
+			"<a id=\"logout\" href=.*?prefix=([0-9-]+)",
+			Pattern.CASE_INSENSITIVE);
+	private Pattern reOldTransactions = Pattern.compile("<a.*?class=\".*?prev_btn.*?\".*?href=\".*?AccountTransactions",Pattern.CASE_INSENSITIVE);
+	
+	private Pattern reTransactionYear = Pattern.compile("<h3[^>]+>.*?([0-9]{4})</h3>",Pattern.CASE_INSENSITIVE);
+	
+	private String response;
+
+	public NordeaDK(Context context) {
+		super(context);
+
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.currency = "DKK";
+		this.response = null;
+		this.prefix = "";
+	}
+
+	public NordeaDK(String username, String password, Context context)
+			throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	protected LoginPackage preLogin() throws BankException,
+			ClientProtocolException, IOException {
+		if (urlopen == null) {
+			urlopen = new Urllib();
+		}
+		response = urlopen
+				.open("https://www.netbank.nordea.dk/mnetbank/index.jsp");
+		Matcher matcher = reLoginUrl.matcher(response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find)
+					.toString() + " login url.");
+		}
+		String strLoginUrl = "https://www.netbank.nordea.dk/mnetbank/servlet/Logon";
+		this.referer = strLoginUrl;
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		postData.add(new BasicNameValuePair("user_id", username));
+		postData.add(new BasicNameValuePair("logon_code", password));
+		postData.add(new BasicNameValuePair("command", "1"));
+		this.prefix = matcher.group(1);
+		postData.add(new BasicNameValuePair("prefix", matcher.group(1)));
+		return new LoginPackage(urlopen, postData, response, strLoginUrl);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (response.contains("class=\"icon error_icon\"")) {
+				throw new LoginException(res.getText(
+						R.string.invalid_username_password).toString());
+			}
+			this.updatePrefix();
+		} catch (ClientProtocolException e) {
+			Log.d(TAG, "ClientProtocolException: " + e.getMessage());
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			Log.d(TAG, "IOException: " + e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException,
+			BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0
+				|| password.length() == 0) {
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		Matcher matcher;
+		try {
+			matcher = reAccounts.matcher(response);
+
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find)
+						.toString() + " accounts url.");
+			}
+			matcher.reset();
+			while (matcher.find()) {
+				/*
+				 * Capture groups: 
+				 * GROUP 		EXAMPLE DATA 
+				 * 1: Link		https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions
+				 * 2: ID 		0 
+				 * 3: Name 		Check-in-konto 
+				 * 4: Amount	1.234,56
+				 */
+				String name = Html.fromHtml(matcher.group(3)).toString().trim();
+				String id = matcher.group(2).toString().trim();
+				BigDecimal amount = Helpers.parseBalance(matcher.group(4));
+
+				accounts.add(new Account(name, amount, id, Account.REGULAR,
+						this.currency));
+				balance = balance.add(amount);
+
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found)
+						.toString());
+			}
+			this.updatePrefix();
+		} finally {
+			super.updateComplete();
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen)
+			throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+		transactions.addAll(updateMonthTransactions(account, urlopen, false));
+
+		//Get last months' transactions
+		Matcher oldTransactionMatcher = reOldTransactions.matcher(response);
+		if(oldTransactionMatcher.find()) {
+			transactions.addAll(updateMonthTransactions(account,urlopen,true));
+		}
+		
+		account.setTransactions(transactions);
+
+	}
+
+	private ArrayList<Transaction> updateMonthTransactions(Account account,
+			Urllib urlopen, boolean oldTransactions) throws BankException {
+		String command = "command=";
+		command += (oldTransactions) ? "1" : "0";
+		String url = "https://www.netbank.nordea.dk/mnetbank/servlet/AccountTransactions?productidx="
+				+ account.getId() + "&prefix=" + this.prefix + "&" + command;
+
+		ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: " + url);
+			urlopen.addHeader("referer", this.referer);
+			this.response = urlopen.open(url);
+			this.updatePrefix();
+			this.referer = url;
+			
+			Matcher transYear = reTransactionYear.matcher(response);
+			String year = "";
+			if(transYear.find()) {
+				year = Html.fromHtml(transYear.group(1)).toString().trim();
+			}
+			
+			matcher = reTransactions.matcher(response);
+			/*
+			 * Capture groups: 
+			 * GROUP 	EXAMPLE 	DATA 
+			 * 1: 		Date 		29.07 
+			 * 2: 		Transaction	Bgs Check-in-konto 
+			 * 3: 		Amount 		906.56
+			 */
+
+			while (matcher.find()) {
+				String monthDate = Html.fromHtml(matcher.group(1)).toString().trim();
+				String text = Html.fromHtml(matcher.group(2)).toString().trim();
+				BigDecimal amount = Helpers.parseBalance(matcher.group(3));
+				String date = year+"-"+monthDate.substring(3,5)+"-"+monthDate.substring(0,2);
+				
+				Transaction transaction = new Transaction(date, text, amount,
+						super.currency);
+				transactions.add(transaction);
+			}
+			
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return transactions;
+
+	}
+
+	private void updatePrefix() throws BankException {
+		Matcher matcher = rePrefix.matcher(this.response);
+		if (!matcher.find()) {
+			throw new BankException(res.getText(R.string.unable_to_find)
+					.toString());
+		}
+		this.prefix = Html.fromHtml(matcher.group(1)).toString().trim();
+	}
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 13ad581..2bef52c 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -74,4 +74,5 @@ public interface IBankTypes {
     public final static int NORDNETDIREKT = 50;
     public final static int SKANDIABANKEN = 51;
     public final static int DANSKEBANK = 52;
+    public final static int NORDEA_DK = 53;
 }
\ No newline at end of file

commit bed9d309d3bae9ac63935e3bf6aeb24a6a676e7d
Author: liato <x@x00.us>
Date:   Fri Sep 23 01:04:36 2011 +0200

    Fix for Danske Bank.

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index f00b159..1fe59e2 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -253,7 +253,7 @@ public class BankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
-        //banks.add(new DanskeBank(context));
+        banks.add(new DanskeBank(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index da4aba3..6d74146 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@ public class DanskeBank extends Bank {
 	private static final String URL = "https://mobil.danskebank.se/XI?WP=XAI&WO=Logon&WA=MBSELogon&gsSprog=SE&gsBrand=OEB";
 	private static final int BANKTYPE_ID = IBankTypes.DANSKEBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
     private Pattern reSessionId = Pattern.compile("WSES=([^\"& ]+)", Pattern.CASE_INSENSITIVE);
@@ -73,6 +74,7 @@ public class DanskeBank extends Bank {
 		super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
 	}
 
 	public DanskeBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -120,8 +122,6 @@ public class DanskeBank extends Bank {
 		try {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            Log.d(TAG, "Url after login attempt: " + urlopen.getCurrentURI());
-			
 			if (response.contains("et personnummer eller servicekod du angett")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -151,7 +151,7 @@ public class DanskeBank extends Bank {
 		}
         matcher = rePersonnr.matcher(response);
         if (matcher.find()) {
-            mSessionId = matcher.group(1);
+            mPersonnr = matcher.group(1);
         }
         else {
             throw new BankException(res.getText(R.string.unable_to_find).toString() + " personnummer.");
@@ -159,15 +159,14 @@ public class DanskeBank extends Bank {
 		
 		try {
 			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s", mSessionId, mPersonnr));
-            Log.d(TAG, "Accounts url: " + urlopen.getCurrentURI());
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
-                 * 1: Account number        ?
-                 * 2: Account name          L÷nekonto
-                 * 3: Account number        ? | Same as #1?
+                 * 1: Internal acc number?  0123456789
+                 * 2: Account name          Danske Direkt Bas
+                 * 3: Account number        01234567890
                  * 4: Balance               1.124,56
                  * 5: Balance (disp.)       1.124,56
                  * 
@@ -209,7 +208,6 @@ public class DanskeBank extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s", mPersonnr, mSessionId, account.getId()));
-            Log.d(TAG, "Transactions url: " + urlopen.getCurrentURI());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit 8c80d3d3d545ff02bea76188844d29414978d9bf
Merge: 899e4b9 15d9a34
Author: liato <x@x00.us>
Date:   Wed Sep 21 14:57:55 2011 -0700

    Merge pull request #103 from woody2/master
    
    Fix för Skandiabanken (problem med cookiehantering)

commit 15d9a3473c4e268979d842e944820f84140a97b0
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Thu Sep 8 18:29:30 2011 +0200

    Change ugly hack for session cookie for Skandiabanken.
    Use the session cookie for all requests to smartrefill.se no mather the path in the cookie or in the request.

diff --git src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
index 5721a4f..4fbe55a 100644
--- src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
@@ -7,7 +7,10 @@ import java.net.URL;
 import java.net.URLConnection;
 import java.util.Map;
 
+import android.util.Log;
+
 import com.ast.util.CookieParser.Cookie;
+import com.caucho.hessian.client.HessianHttpProxyFactory.HessianHttpProxy;
 import com.caucho.hessian.io.HessianRemoteObject;
 
 // This class is added in the bankdroid project to enable adding some http-headers required by Skandiabanken
@@ -48,19 +51,16 @@ public class HessianHttpHeaderProxyFactory extends HessianHttpProxyFactory{
 			for (Map.Entry<String, String> header : mHeaderMap.entrySet())
 				conn.setRequestProperty(header.getKey(), header.getValue());
 		}
-		
+
 	    @Override
-		protected Cookie getCookie(String host, String path) {
-			Cookie cookie = super.getCookie(host, path);
-			
-			// Ugly hack: For some reason the cookie has the wrong path in the response from Skandiabanken.
-			if (cookie == null && 
-					host.contentEquals("smartrefill.se") && 
-					path.contentEquals("/")){
-				cookie = super.getCookie("smartrefill.se", "/BankServices");
-			}
-			
-			return cookie;
+		protected void putCookie(Cookie cookie) {
+	    	// Ugly hack: for some reason the path in the cookie is not as expected
+            if (cookie.host.contentEquals("smartrefill.se"))
+            {
+            	Log.d("Skandiabanken cookie", "using path / instead of " + cookie.path);
+            	cookie.path = "/";
+            }
+            super.putCookie(cookie);
 		}
 	}
 }
diff --git src/com/caucho/hessian/client/HessianHttpProxyFactory.java src/com/caucho/hessian/client/HessianHttpProxyFactory.java
index 332b07d..b3fdada 100644
--- src/com/caucho/hessian/client/HessianHttpProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpProxyFactory.java
@@ -15,6 +15,8 @@
  */
 package com.caucho.hessian.client;
 
+import android.util.Log;
+
 import com.ast.util.CookieParser;
 import com.ast.util.CookieParser.Cookie;
 import com.caucho.hessian.io.HessianRemoteObject;
@@ -120,8 +122,8 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
                 String host = conn.getURL().getHost();
                 for (String s : cookieStrings) {
                     Cookie cookie = CookieParser.parse(host, s);
-                    HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
-                   // Log.d("Cookies", "Cookie cached: " + cookie.host + cookie.path + ":" + s);
+                    Log.d("Skandiabanken cookie", "Cookie string: " + s);
+                    putCookie(cookie);
                 }
             }
         }
@@ -140,11 +142,11 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
             String path = conn.getURL().getPath();
 
             while (path != null && 0 < path.length()) {
-                //Log.d("Cookies", "Host:+" + host +",Path:"+path);
+                Log.d("Skandiabanken cookie", "Host:+" + host +",Path:"+path);
                 Cookie cookie = getCookie(host, path);
                 if (cookie != null) {
                     conn.setRequestProperty("Cookie", cookie.value);
-                    //Log.d("Cookies", "Cookie set in request:" + cookie.value);
+                    Log.d("Skandiabanken cookie", "Cookie set in request:" + cookie.value);
                     break;
                 }
                 int i = path.lastIndexOf("/");
@@ -159,5 +161,10 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
 		protected Cookie getCookie(String host, String path) {
 			return HessianHttpProxy.cookieMap.get(host + path);
 		}
+
+		protected void putCookie(Cookie cookie) {
+            HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
+            Log.d("Skandiabanken cookie", "Cookie cached: " + cookie.host + cookie.path);
+		}
 	}
 }

commit 899e4b957e512bf5525418754669bfb06b2cf023
Author: liato <x@x00.us>
Date:   Wed Aug 24 00:56:43 2011 +0200

    Remove Danske Bank. Bump version to 1.8.0.

diff --git AndroidManifest.xml AndroidManifest.xml
index 00e9ed0..da9731b 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.0-RC3" android:versionCode="118">
+	android:versionName="1.8.0" android:versionCode="120">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 1fe59e2..f00b159 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -253,7 +253,7 @@ public class BankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
-        banks.add(new DanskeBank(context));
+        //banks.add(new DanskeBank(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index 10e93e1..da4aba3 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -32,6 +32,7 @@ import org.apache.http.protocol.HTTP;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
+import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -84,7 +85,7 @@ public class DanskeBank extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
-        urlopen.addHeader("Referer", "https://mobil.danskebank.se/XI");
+        urlopen.addHeader("Referer", "https://mobil.danskebank.se/");
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm - dd.MM.yyyy");
@@ -119,6 +120,7 @@ public class DanskeBank extends Bank {
 		try {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            Log.d(TAG, "Url after login attempt: " + urlopen.getCurrentURI());
 			
 			if (response.contains("et personnummer eller servicekod du angett")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -157,6 +159,7 @@ public class DanskeBank extends Bank {
 		
 		try {
 			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s", mSessionId, mPersonnr));
+            Log.d(TAG, "Accounts url: " + urlopen.getCurrentURI());
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
                 /*
@@ -206,6 +209,7 @@ public class DanskeBank extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s", mPersonnr, mSessionId, account.getId()));
+            Log.d(TAG, "Transactions url: " + urlopen.getCurrentURI());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index 7495f94..e024fea 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -57,7 +57,7 @@ public class IkanoBank extends Bank {
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reAccounts = Pattern.compile("(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reErrorMessage = Pattern.compile("<div\\s*class=\"message-box-inner\">\\s*<div>\\s*<p>([^<]+)<");
+    private Pattern reErrorMessage = Pattern.compile("<div\\s*class=\"(?:error|message)-box-inner\">\\s*<div>\\s*<p>(.+)</p");
     private String response = null;
 
     public IkanoBank(Context context) {
@@ -84,11 +84,12 @@ public class IkanoBank extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         response = urlopen.open("https://secure.ikanobank.se/login");
+        //Log.d(TAG, "Url after first request: " + urlopen.getCurrentURI());
         Matcher matcher;
         if (response.contains("Banken är stängd")) {
             matcher = reErrorMessage.matcher(response);
             if (matcher.find()) {
-                throw new BankException(Helpers.removeHtml(matcher.group(1)));
+                throw new BankException(Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
             } 
         }
         matcher = reViewState.matcher(response);
@@ -117,8 +118,16 @@ public class IkanoBank extends Bank {
         try {
             LoginPackage lp = preLogin();
             response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-            if (response.contains("Ogiltigt personnummer eller")) {
-                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            //Log.d(TAG, "Url after login attempt: " + urlopen.getCurrentURI());
+            if (response.contains("Ogiltigt personnummer") || response.contains("felaktigt personnummer")) {
+                Matcher matcher = reErrorMessage.matcher(response);
+                if (matcher.find()) {
+                    throw new LoginException(Helpers.removeHtml(matcher.group(1).replace("<BR>", "\n")));
+                }
+                else {
+                    throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+                }
+                
             }
         }
         catch (ClientProtocolException e) {
@@ -167,12 +176,12 @@ public class IkanoBank extends Bank {
         Matcher matcher;
         matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            Log.d(TAG, "Unable to find ViewState. L156.");
+            Log.e(TAG, "Unable to find ViewState. L156.");
         }
         String strViewState = matcher.group(1);
         matcher = reEventValidation.matcher(response);
         if (!matcher.find()) {
-            Log.d(TAG, "Unable to find EventValidation. L161.");
+            Log.e(TAG, "Unable to find EventValidation. L161.");
         }
         String strEventValidation = matcher.group(1);       
 
@@ -183,6 +192,7 @@ public class IkanoBank extends Bank {
             postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));            
             postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));            
             response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
+            //Log.d(TAG, "Transactions url: " + urlopen.getCurrentURI());
 
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -202,9 +212,9 @@ public class IkanoBank extends Bank {
             account.setTransactions(transactions);
 
         } catch (ClientProtocolException e) {
-            Log.e(TAG, e.getMessage());
+            Log.e(TAG, "CPE: " + e.getMessage());
         } catch (IOException e) {
-            Log.e(TAG, e.getMessage());
+            Log.e(TAG, "IOE: "+ e.getMessage());
         }
         finally {
             super.updateComplete();

commit bf9be1dcfdfcc3623e2955450d5e644ac61f6410
Author: liato <x@x00.us>
Date:   Sun Aug 21 11:50:01 2011 +0200

    Don't show inactive cards for jojo.

diff --git AndroidManifest.xml AndroidManifest.xml
index 89f1151..00e9ed0 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.0-RC2" android:versionCode="117">
+	android:versionName="1.8.0-RC3" android:versionCode="118">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index 715ffb5..70da853 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -48,7 +48,7 @@ public class Jojo extends Bank {
     private static final int BANKTYPE_ID = IBankTypes.JOJO;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reAccounts = Pattern.compile("1_mRepeaterMyCards_ctl(\\d{2,3})_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>\\s*</td>\\s*<td[^>]+>\\s*<a\\s*id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl\\d{2,3}_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("\"></a>\\s*</td>\\s*<td\\s*class=\"cardinfoaligntop\">\\s*<a\\s*id=\"ctl\\d*_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl(\\d{2,3})_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>\\s*</td>\\s*<td[^>]+>\\s*<a\\s*id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl\\d{2,3}_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>", Pattern.CASE_INSENSITIVE);
     private Pattern reBalance = Pattern.compile("labelsaldoinfo\">([^<]+)<", Pattern.CASE_INSENSITIVE);
     private String response = null;
 

commit 690eb5072aaa9aae6f7dfe43c38d27735dd93105
Author: liato <x@x00.us>
Date:   Sun Aug 21 11:19:52 2011 +0200

    Mark Sparbanken Oresund and Sparbanken Syd as broken. Bump version to 1.8.0-RC2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 028ac3c..89f1151 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.8.0-RC1" android:versionCode="116">
+	android:versionName="1.8.0-RC2" android:versionCode="117">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/SparbankenOresund.java src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index 8ee31c0..cc72aa1 100644
--- src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -37,6 +37,7 @@ public class SparbankenOresund extends MobilbankenBase {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
+        super.BROKEN = true;
         this.targetId = "0003";
     }
 
diff --git src/com/liato/bankdroid/banking/banks/SparbankenSyd.java src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index 74afa0d..fbe37eb 100644
--- src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -37,6 +37,7 @@ public class SparbankenSyd extends MobilbankenBase {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
+        super.BROKEN = true;
         this.targetId = "0004";
     }
 

commit e80d61cb17ec72cb1431e39d3da2e2df0a3509c9
Author: liato <x@x00.us>
Date:   Sun Aug 21 02:32:25 2011 +0200

    Add referer header to DanskeBank.

diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
index 00fa0b4..10e93e1 100644
--- src/com/liato/bankdroid/banking/banks/DanskeBank.java
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -84,6 +84,7 @@ public class DanskeBank extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
+        urlopen.addHeader("Referer", "https://mobil.danskebank.se/XI");
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm - dd.MM.yyyy");

commit 051b4d8abf8ea198e801f08ca6cba0d88535393b
Author: liato <x@x00.us>
Date:   Sun Aug 21 02:29:52 2011 +0200

    Display error message when Ikano Bank is closed.

diff --git res/layout/about.xml res/layout/about.xml
index e38c338..3120cda 100644
--- res/layout/about.xml
+++ res/layout/about.xml
@@ -14,21 +14,17 @@
 			android:id="@+id/LinearLayout03"
 			android:orientation="vertical"
 			android:layout_height="fill_parent"
-			android:layout_width="wrap_content"
 			android:paddingLeft="20dp"
-			android:paddingRight="20dp">
+			android:paddingRight="20dp" android:layout_width="fill_parent">
 			<RelativeLayout
 			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_marginBottom="20dp">
+			android:layout_marginBottom="20dp" android:layout_width="fill_parent">
 			<ImageView
 				android:layout_height="wrap_content"
 				android:src="@drawable/logo_text_big"
 				android:adjustViewBounds="true"
-				android:layout_width="fill_parent"
-				android:scaleType="fitXY"
 				android:id="@+id/imgTextLogo"
-				android:layout_marginTop="20dp"></ImageView>
+				android:layout_marginTop="20dp" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_centerHorizontal="true"></ImageView>
 			<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imgTextLogo" android:id="@+id/imgNullbyteLogo" android:src="@drawable/nullbyte_logo" android:layout_alignRight="@+id/imgTextLogo" android:layout_alignBottom="@+id/txtVersion"></ImageView>
 			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtVersion" android:text="@string/version" android:textSize="15dp" android:layout_below="@+id/imgTextLogo" android:gravity="right" android:textColor="#78ffffff" android:layout_toLeftOf="@+id/imgNullbyteLogo" android:layout_marginRight="4dp"></TextView>
 </RelativeLayout>
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 4e90ca8..70bcfe6 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -205,5 +205,15 @@ public class Helpers {
         }
         return sdf.format(cal.getTime());
     }
+    
+    /**
+     * Remove HTML from a string.
+     * 
+     * @param text      The string containing HTML.
+     * @return          The same string with all HTML removed.
+     */
+    public static String removeHtml(String text) {
+        return text.replaceAll("<[^>]+>", "");
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index 09d27b2..7495f94 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -57,6 +57,7 @@ public class IkanoBank extends Bank {
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reAccounts = Pattern.compile("(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reErrorMessage = Pattern.compile("<div\\s*class=\"message-box-inner\">\\s*<div>\\s*<p>([^<]+)<");
     private String response = null;
 
     public IkanoBank(Context context) {
@@ -83,7 +84,14 @@ public class IkanoBank extends Bank {
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         response = urlopen.open("https://secure.ikanobank.se/login");
-        Matcher matcher = reViewState.matcher(response);
+        Matcher matcher;
+        if (response.contains("Banken är stängd")) {
+            matcher = reErrorMessage.matcher(response);
+            if (matcher.find()) {
+                throw new BankException(Helpers.removeHtml(matcher.group(1)));
+            } 
+        }
+        matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
         }

commit e4560351cbd5a296f22abaa0157e96c0af665ca7
Author: liato <x@x00.us>
Date:   Mon Jul 11 02:28:54 2011 +0200

    Move about dialog to separate activity. Add donate button. Bump version to 1.8.0-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 98644a2..028ac3c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,8 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.7.3"
-	android:versionCode="115">
+	android:versionName="1.8.0-RC1" android:versionCode="116">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
@@ -44,6 +43,11 @@
 			android:label="@string/app_name"
 			android:theme="@style/BankdroidTheme">
 		</activity>
+		<activity
+			android:name=".AboutActivity"
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
+		</activity>
 		<activity
 			android:label="@string/app_name"
 			android:theme="@style/BankdroidTheme"
diff --git logos.psd logos.psd
index 095eade..1f99362 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable-hdpi-v4/ic_menu_donate.png res/drawable-hdpi-v4/ic_menu_donate.png
new file mode 100644
index 0000000..248589f
Binary files /dev/null and res/drawable-hdpi-v4/ic_menu_donate.png differ
diff --git res/drawable-hdpi-v4/logo_text_big.png res/drawable-hdpi-v4/logo_text_big.png
index ccb77b9..ad17416 100644
Binary files res/drawable-hdpi-v4/logo_text_big.png and res/drawable-hdpi-v4/logo_text_big.png differ
diff --git res/drawable-hdpi-v4/nullbyte_logo.png res/drawable-hdpi-v4/nullbyte_logo.png
new file mode 100644
index 0000000..c38f50b
Binary files /dev/null and res/drawable-hdpi-v4/nullbyte_logo.png differ
diff --git res/drawable-hdpi-v4/title_icon_donate.png res/drawable-hdpi-v4/title_icon_donate.png
new file mode 100644
index 0000000..0aea001
Binary files /dev/null and res/drawable-hdpi-v4/title_icon_donate.png differ
diff --git res/drawable-hdpi-v4/title_icon_web.png res/drawable-hdpi-v4/title_icon_web.png
new file mode 100644
index 0000000..8247847
Binary files /dev/null and res/drawable-hdpi-v4/title_icon_web.png differ
diff --git res/layout/about.xml res/layout/about.xml
index 3955db6..e38c338 100644
--- res/layout/about.xml
+++ res/layout/about.xml
@@ -17,56 +17,28 @@
 			android:layout_width="wrap_content"
 			android:paddingLeft="20dp"
 			android:paddingRight="20dp">
-			
-			<ImageView android:id="@+id/ImageView02" android:layout_height="wrap_content" android:src="@drawable/logo_text_big" android:adjustViewBounds="true" android:layout_width="fill_parent" android:scaleType="fitXY"></ImageView><LinearLayout
-				android:id="@+id/LinearLayout01"
+			<RelativeLayout
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:layout_marginBottom="20dp">
+			<ImageView
 				android:layout_height="wrap_content"
-				android:orientation="horizontal"
-				android:layout_width="fill_parent">
-				<ImageView
-					android:id="@+id/ImageView01"
-					android:layout_width="100dp"
-					android:layout_height="100dp"
-					android:layout_gravity="center_horizontal"
-					android:visibility="visible"
-					android:src="@drawable/icon_large"
-					android:maxHeight="100dp"
-					android:maxWidth="100dp"
-					android:minHeight="100dp"
-					android:minWidth="100dp"
-					android:scaleType="fitXY"></ImageView>
-				<LinearLayout
-					android:id="@+id/LinearLayout02"
-					android:layout_height="wrap_content"
-					android:orientation="vertical"
-					android:layout_width="fill_parent">
-					<TextView
-						android:layout_height="wrap_content"
-						android:id="@+id/txtVersion"
-						android:layout_width="fill_parent"
-						android:textSize="17dp"
-						android:text="@string/version"></TextView>
-
-
-					<TextView
-						android:id="@+id/TextView02"
-						android:layout_width="wrap_content"
-						android:layout_height="wrap_content"
-						android:text="http://liato.github.com/android-bankdroid/"
-						android:autoLink="web"
-						android:fitsSystemWindows="false"></TextView>
-				</LinearLayout>
-
-
-			</LinearLayout>
+				android:src="@drawable/logo_text_big"
+				android:adjustViewBounds="true"
+				android:layout_width="fill_parent"
+				android:scaleType="fitXY"
+				android:id="@+id/imgTextLogo"
+				android:layout_marginTop="20dp"></ImageView>
+			<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imgTextLogo" android:id="@+id/imgNullbyteLogo" android:src="@drawable/nullbyte_logo" android:layout_alignRight="@+id/imgTextLogo" android:layout_alignBottom="@+id/txtVersion"></ImageView>
+			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtVersion" android:text="@string/version" android:textSize="15dp" android:layout_below="@+id/imgTextLogo" android:gravity="right" android:textColor="#78ffffff" android:layout_toLeftOf="@+id/imgNullbyteLogo" android:layout_marginRight="4dp"></TextView>
+</RelativeLayout>
 			<TextView
 				android:id="@+id/TextView04"
 				android:layout_height="wrap_content"
 				android:text="@string/thanks_to"
-				android:textSize="20sp"
 				android:textStyle="bold"
 				android:layout_marginTop="10dp"
-				android:layout_width="fill_parent"></TextView>
+				android:layout_width="fill_parent" android:textSize="20dp"></TextView>
 			<TextView
 				android:id="@+id/TextView03"
 				android:layout_height="wrap_content"
@@ -74,9 +46,9 @@
 				android:layout_width="fill_parent"
 				android:paddingLeft="10dp"
 				android:typeface="serif"
-				android:textSize="12sp"></TextView>
-		
-</LinearLayout>
+				android:textSize="12sp" android:layout_marginBottom="10dp"></TextView>
+
+		</LinearLayout>
 
 
 
diff --git res/menu-sv/menu.xml res/menu-sv/menu.xml
index da14f73..f4f6f1e 100644
--- res/menu-sv/menu.xml
+++ res/menu-sv/menu.xml
@@ -9,8 +9,12 @@
 		android:id="@+id/toggle_hidden"
 		android:title="@string/menu_show_hidden"
 		android:icon="@drawable/ic_menu_view"/>
+	<item
+		android:id="@+id/donate"
+		android:title="Donera"
+		android:icon="@drawable/ic_menu_donate" />
 	<item
 		android:id="@+id/about"
 		android:title="Om"
-		android:icon="@android:drawable/ic_menu_info_details" />
+		android:icon="@drawable/ic_menu_info_details" />
 </menu>
\ No newline at end of file
diff --git res/menu/menu.xml res/menu/menu.xml
index 083c539..14b5e6b 100644
--- res/menu/menu.xml
+++ res/menu/menu.xml
@@ -9,8 +9,12 @@
 		android:id="@+id/toggle_hidden"
 		android:title="@string/menu_show_hidden"
 		android:icon="@drawable/ic_menu_view"/>
+	<item
+		android:id="@+id/donate"
+		android:title="Donate"
+		android:icon="@drawable/ic_menu_donate" />
 	<item
 		android:id="@+id/about"
 		android:title="About"
-		android:icon="@android:drawable/ic_menu_info_details" />
+		android:icon="@drawable/ic_menu_info_details" />
 </menu>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 8db117c..f79f6ec 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -3,7 +3,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     
     <string name="about">Om</string>
-    <string name="version">Version $version av liato</string>
+    <string name="version">Version $version av</string>
     <string name="widget_name_small">Bankdroid (Liten)</string>
     <string name="widget_name_large">Bankdroid (Stor)</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
diff --git res/values/strings.xml res/values/strings.xml
index 0203ad3..7d5de9b 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources  xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="version">Version $version by liato</string>
+    <string name="version">Version $version by</string>
     <string name="app_name">Bankdroid</string>
     <string name="widget_name_small">Bankdroid (Small)</string>
     <string name="widget_name_large">Bankdroid (Large)</string>
diff --git src/com/liato/bankdroid/AboutActivity.java src/com/liato/bankdroid/AboutActivity.java
new file mode 100644
index 0000000..1731940
--- /dev/null
+++ src/com/liato/bankdroid/AboutActivity.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+public class AboutActivity extends LockableActivity implements OnClickListener {
+	final static String TAG = "AboutActivity";
+	
+    @Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+	    setContentView(R.layout.about);
+        PackageInfo pInfo;
+        String version = "v1.x.x";
+        try {
+            pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
+            version = pInfo.versionName;
+        } catch (final NameNotFoundException e) {
+            e.printStackTrace();
+        }
+        ((TextView)findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));	    
+        this.addTitleButton(R.drawable.title_icon_donate, "donate", this);
+        this.addTitleButton(R.drawable.title_icon_web, "web", this);
+ 
+    }
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+	}
+
+    @Override
+    public void onClick(View v) {
+        String tag = (String)v.getTag();
+        Intent i = new Intent(Intent.ACTION_VIEW);
+        
+        if ("web".equals(tag)) {
+            i.setData(Uri.parse("https://github.com/liato/android-bankdroid"));
+        }
+        else if ("donate".equals(tag)) {
+            i.setData(Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KWRCBB4PAA3LC"));
+        }
+        startActivity(i);
+    }
+	
+}
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 388457d..ccebd33 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -29,6 +29,7 @@ import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.util.Log;
@@ -149,9 +150,7 @@ public class MainActivity extends LockableActivity {
 	};
 
 	public void refreshView() {
-		Log.d(TAG, "refreshView()");
 		final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
-		Log.d(TAG, "Bank count: "+banks.size());
 		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
 			showTitleButton("refresh");
@@ -214,10 +213,16 @@ public class MainActivity extends LockableActivity {
 			this.startActivity(intent);
 			//Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
 			return true;
-		case R.id.about:
-			showDialog(0);
-			return true;
-		}
+        case R.id.about:
+            intent = new Intent(this, AboutActivity.class);
+            startActivity(intent);
+            return true;
+        case R.id.donate:
+            intent = new Intent(Intent.ACTION_VIEW);
+            intent.setData(Uri.parse("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KWRCBB4PAA3LC"));
+            startActivity(intent);
+            return true;
+        }
 		return false;
 	}
 

commit bad9cf024e95c1858993e301dff3a104eaa7f768
Author: liato <x@x00.us>
Date:   Sun Jul 10 23:55:59 2011 +0200

    Add support for Danske Bank.

diff --git res/drawable/logo_danskebank.png res/drawable/logo_danskebank.png
new file mode 100644
index 0000000..6cfbeb2
Binary files /dev/null and res/drawable/logo_danskebank.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 517e204..1fe59e2 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -32,6 +32,7 @@ import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.Coop;
+import com.liato.bankdroid.banking.banks.DanskeBank;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
@@ -189,7 +190,9 @@ public class BankFactory {
         case IBankTypes.NORDNETDIREKT:
             return new Nordnetdirekt(context);
         case IBankTypes.SKANDIABANKEN:
-                return new Skandiabanken(context);
+            return new Skandiabanken(context);
+        case IBankTypes.DANSKEBANK:
+            return new DanskeBank(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -250,6 +253,7 @@ public class BankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
+        banks.add(new DanskeBank(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/DanskeBank.java src/com/liato/bankdroid/banking/banks/DanskeBank.java
new file mode 100644
index 0000000..00fa0b4
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/DanskeBank.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class DanskeBank extends Bank {
+	private static final String TAG = "DanskeBank";
+	private static final String NAME = "DanskeBank";
+	private static final String NAME_SHORT = "danskebank";
+	private static final String URL = "https://mobil.danskebank.se/XI?WP=XAI&WO=Logon&WA=MBSELogon&gsSprog=SE&gsBrand=OEB";
+	private static final int BANKTYPE_ID = IBankTypes.DANSKEBANK;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+	
+    private Pattern reSessionId = Pattern.compile("WSES=([^\"& ]+)", Pattern.CASE_INSENSITIVE);
+    private Pattern rePersonnr = Pattern.compile("WAFT=([^\"& ]+)", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("<a\\shref=\"[^\"]+KBList[^\"]+WCI=([^\"]+)\">([^<]+)</a><br/>([^<]+)<br/>Saldo:([^<]+)<br/>Disponibelt:([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<a\\shref=\"[^\"]+KBDetVis[^\"]+\">([^<]+)</a><br/>Datum:([^<]+)<br/>Belopp:([^<]+)<br/>Status:([^<]+)<", Pattern.CASE_INSENSITIVE);
+	
+	private String response = null;
+	private String mSessionId = null;
+	private String mPersonnr = null;
+
+	public DanskeBank(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+	}
+
+	public DanskeBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm - dd.MM.yyyy");
+        postData.add(new BasicNameValuePair("gsSprog", "SE"));
+        postData.add(new BasicNameValuePair("gsBrand", "OEB"));
+        postData.add(new BasicNameValuePair("gsSession", ""));
+        postData.add(new BasicNameValuePair("gsProdukt", "XAS"));
+        postData.add(new BasicNameValuePair("gsNextObj", "Forside"));
+        postData.add(new BasicNameValuePair("gsNextAkt", "MBForside"));
+        postData.add(new BasicNameValuePair("gsNextUObj", "SC"));
+        postData.add(new BasicNameValuePair("gsCurItem", ""));
+        postData.add(new BasicNameValuePair("gsCurItem2", ""));
+        postData.add(new BasicNameValuePair("gsCurItem3", ""));
+        postData.add(new BasicNameValuePair("gsCurItem4", ""));
+        postData.add(new BasicNameValuePair("gsCurItem5", ""));
+        postData.add(new BasicNameValuePair("gsCurObj", "Logon"));
+        postData.add(new BasicNameValuePair("gsCurAkt", "MBSELogon"));
+        postData.add(new BasicNameValuePair("gsCurUObj", "SC"));
+        postData.add(new BasicNameValuePair("hidStatusType", "A00"));
+        postData.add(new BasicNameValuePair("hidStatusTekst", ""));
+        postData.add(new BasicNameValuePair("hidStatusTid", sdf.format(new Date())));
+        postData.add(new BasicNameValuePair("gsSikSystem", "KO"));
+        postData.add(new BasicNameValuePair("gsLand", "SE"));
+        postData.add(new BasicNameValuePair("gsAftlnr", username));
+        postData.add(new BasicNameValuePair("gsLogon", password));
+       
+        return new LoginPackage(urlopen, postData, response, "https://mobil.danskebank.se/XI");
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
+			if (response.contains("et personnummer eller servicekod du angett")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		urlopen = login();
+		Matcher matcher;
+		matcher = reSessionId.matcher(response);
+		if (matcher.find()) {
+		    mSessionId = matcher.group(1);
+		}
+		else {
+		    throw new BankException(res.getText(R.string.unable_to_find).toString() + " session id.");
+		}
+        matcher = rePersonnr.matcher(response);
+        if (matcher.find()) {
+            mSessionId = matcher.group(1);
+        }
+        else {
+            throw new BankException(res.getText(R.string.unable_to_find).toString() + " personnummer.");
+        }
+		
+		try {
+			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WO=Konto&WA=KTList&WSES=%s&WAFT=%s", mSessionId, mPersonnr));
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Account number        ?
+                 * 2: Account name          L÷nekonto
+                 * 3: Account number        ? | Same as #1?
+                 * 4: Balance               1.124,56
+                 * 5: Balance (disp.)       1.124,56
+                 * 
+                 */   		
+			    String name = Html.fromHtml(matcher.group(2)).toString().trim();
+			    Account account = new Account(name, Helpers.parseBalance(matcher.group(5)), matcher.group(1).trim());
+			    if (name.contains("lån") || name.contains("Lån")) {
+			        account.setType(Account.LOANS);
+			    }
+			    else {
+		             balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+			    }
+				accounts.add(account);
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		    super.updateComplete();
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		//No transaction history for loans, funds and credit cards.
+		int accType = account.getType();
+		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
+
+		Matcher matcher;
+		try {
+			response = urlopen.open(String.format("https://mobil.danskebank.se/XI?WP=XAS&WAFT=%s&WSES=%s&WO=Konto&WA=KBList&WCI=%s", mPersonnr, mSessionId, account.getId()));
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Transaction           Till Fondsparande
+                 * 2: Date                  2011-07-28
+                 * 3: Amount                ?
+                 * 4: Status                Väntar | Utförd 
+                 * 
+                 */
+				transactions.add(new Transaction(Html.fromHtml(matcher.group(2)).toString().trim(), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 510c4ef..13ad581 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -73,4 +73,5 @@ public interface IBankTypes {
     public final static int SPARBANKEN_ORESUND = 49;
     public final static int NORDNETDIREKT = 50;
     public final static int SKANDIABANKEN = 51;
+    public final static int DANSKEBANK = 52;
 }
\ No newline at end of file

commit d649b927027966b13a203173eb18548fc82d70d8
Author: liato <x@x00.us>
Date:   Sun Jul 10 03:20:08 2011 +0200

    Fix security bug where the lockscreen can be bypassed if the app is restarted too fast.

diff --git res/xml/settings.xml res/xml/settings.xml
index 97af55f..b09c4ec 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -105,12 +105,12 @@
 			android:title="@string/vibrate_title"
 			android:summary="@string/vibrate_summary"
 			android:dependency="notify_on_change" />
-		<CheckBoxPreference
+		<!--  <CheckBoxPreference
 			android:key="notify_delta_only"
 			android:defaultValue="false"
 			android:title="@string/vibrate_title"
 			android:summary="@string/vibrate_summary"
-			android:dependency="notify_on_change" />
+			android:dependency="notify_on_change" />-->
 		<EditTextPreference
 			android:key="notify_min_delta"
 			android:defaultValue="0"
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 05324f3..4f30794 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -40,9 +40,10 @@ import com.liato.bankdroid.lockpattern.LockPatternUtils;
 
 public class LockableActivity extends Activity {
     private static int PATTERNLOCK_UNLOCK = 42;
-	private SharedPreferences prefs;
-	private Editor editor;
+	private SharedPreferences mPrefs;
+	private Editor mEditor;
 	private LockPatternUtils mLockPatternUtils;
+	private boolean mHasLoaded = false;
 	
 	private LinearLayout mTitlebarButtons;
 	private LayoutInflater mInflater;
@@ -54,10 +55,10 @@ public class LockableActivity extends Activity {
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
 		mLockPatternUtils = new LockPatternUtils(this);		
-        mLockPatternUtils.setVisiblePatternEnabled(prefs.getBoolean("patternlock_visible_pattern", true));
-        mLockPatternUtils.setTactileFeedbackEnabled(prefs.getBoolean("patternlock_tactile_feedback", false));
+        mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
+        mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
     }
 	
@@ -158,16 +159,30 @@ public class LockableActivity extends Activity {
     @Override
 	protected void onPause() {
 		super.onPause();
-		// Don't do anything if not lock pattern is set
+		// Don't do anything if no lock pattern is set
 		if (!mLockPatternUtils.isLockPatternEnabled()) return;
-        // Save the current time If a lock pattern has been set
-		writeLockTime();
+        /*
+		Save the current time If a lock pattern has been set
+		If this activity never loaded set the lock time to
+		10 seconds ago.
+		This is to prevent the following scenario:
+		    1. Activity Starts 
+		    2. Lock screen is displayed
+            3. User presses the home button
+            4. "lock time" is set in onPause to when the home button was pressed
+            5. Activity is started again within 2 seconds and no lock screen is shown this time.
+	    */ 
+		if (mHasLoaded) {
+		    writeLockTime();
+		} else {
+		    writeLockTime(System.currentTimeMillis()-10000);
+		}
 	}
 
 	@Override
 	protected void onResume() {
 		super.onResume();
-        // Don't do anything if not lock pattern is set
+        // Don't do anything if no lock pattern is set
 		if (!mLockPatternUtils.isLockPatternEnabled()) {
 		    return;
 		}
@@ -175,11 +190,15 @@ public class LockableActivity extends Activity {
 		// activity was open. If it's been more than two seconds the user
 		// will have to enter the lock pattern to continue.
 		long currentTime = System.currentTimeMillis();
-		long lockedAt = prefs.getLong("locked_at", currentTime-10000);
+		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
 		long timedif = currentTime - lockedAt;
 		if (timedif > 2000) {
+            mHasLoaded = false;         
 		    launchPatternLock();
 		}
+		else {
+		    mHasLoaded = true;		    
+		}
 	}
 
 	private void launchPatternLock() {
@@ -190,10 +209,14 @@ public class LockableActivity extends Activity {
 	}
 	
 	private void writeLockTime() {
-        editor = prefs.edit();
-        editor.putLong("locked_at", System.currentTimeMillis());
-        editor.commit();	    
+        writeLockTime(System.currentTimeMillis());
 	}
+
+    private void writeLockTime(long time) {
+        mEditor = mPrefs.edit();
+        mEditor.putLong("locked_at", time);
+        mEditor.commit();       
+    }
 	
     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index c0384de..13146c2 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -28,17 +28,18 @@ import android.preference.PreferenceManager;
 
 public class LockablePreferenceActivity extends PreferenceActivity {
     private static int PATTERNLOCK_UNLOCK = 42;
-	private SharedPreferences prefs;
-	private Editor editor;
+	private SharedPreferences mPrefs;
+	private Editor mEditor;
 	private LockPatternUtils mLockPatternUtils;
+    private boolean mHasLoaded = false;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
 		mLockPatternUtils = new LockPatternUtils(this);
-        mLockPatternUtils.setVisiblePatternEnabled(prefs.getBoolean("patternlock_visible_pattern", true));
-        mLockPatternUtils.setTactileFeedbackEnabled(prefs.getBoolean("patternlock_tactile_feedback", false));
+        mLockPatternUtils.setVisiblePatternEnabled(mPrefs.getBoolean("patternlock_visible_pattern", true));
+        mLockPatternUtils.setTactileFeedbackEnabled(mPrefs.getBoolean("patternlock_tactile_feedback", false));
 	}
 
 	@Override
@@ -46,9 +47,23 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		super.onPause();
 		// Don't do anything if not lock pattern is set
 		if (!mLockPatternUtils.isLockPatternEnabled()) return;
-        // Save the current time If a lock pattern has been set
-		writeLockTime();
-	}
+        /*
+        Save the current time If a lock pattern has been set
+        If this activity never loaded set the lock time to
+        10 seconds ago.
+        This is to prevent the following scenario:
+            1. Activity Starts 
+            2. Lock screen is displayed
+            3. User presses the home button
+            4. "lock time" is set in onPause to when the home button was pressed
+            5. Activity is started again within 2 seconds and no lock screen is shown this time.
+        */ 
+        if (mHasLoaded) {
+            writeLockTime();
+        } else {
+            writeLockTime(System.currentTimeMillis()-10000);
+        }
+    }
 
 	@Override
 	protected void onResume() {
@@ -61,11 +76,14 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 		// activity was open. If it's been more than two seconds the user
 		// will have to enter the lock pattern to continue.
 		long currentTime = System.currentTimeMillis();
-		long lockedAt = prefs.getLong("locked_at", currentTime-10000);
+		long lockedAt = mPrefs.getLong("locked_at", currentTime-10000);
 		long timedif = currentTime - lockedAt;
 		if (timedif > 2000) {
 		    launchPatternLock();
 		}
+        else {
+            mHasLoaded = true;          
+        }
 	}
 
 	private void launchPatternLock() {
@@ -75,20 +93,24 @@ public class LockablePreferenceActivity extends PreferenceActivity {
         startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
 	}
 	
-	private void writeLockTime() {
-        editor = prefs.edit();
-        editor.putLong("locked_at", System.currentTimeMillis());
-        editor.commit();	    
-	}
+    private void writeLockTime() {
+        writeLockTime(System.currentTimeMillis());
+    }
+
+    private void writeLockTime(long time) {
+        mEditor = mPrefs.edit();
+        mEditor.putLong("locked_at", time);
+        mEditor.commit();       
+    }
 
 	protected void setLockEnabled(boolean enabled) {
-        editor = prefs.edit();
-        editor.putBoolean("lock_enabled", enabled);
-        editor.commit();        
+        mEditor = mPrefs.edit();
+        mEditor.putBoolean("lock_enabled", enabled);
+        mEditor.commit();        
 	}
 
     protected boolean isLockEnabled() {
-        return prefs.getBoolean("lock_enabled", true);       
+        return mPrefs.getBoolean("lock_enabled", true);       
     }	
     protected void onActivityResult(int requestCode, int resultCode,
             Intent data) {

commit 37a75e4c7576c914f300231e3751c74e88487736
Merge: b06a335 0be4cea
Author: liato <x@x00.us>
Date:   Sat Jul 9 17:21:08 2011 -0700

    Merge pull request #92 from woody2/master
    
    FIx #2 Update between [time] and [time]

commit b06a3357c2f306e6a61bad095773dde593eb38c7
Author: liato <x@x00.us>
Date:   Sun Jul 10 01:49:37 2011 +0200

    Accept invalid certificates for ICA.

diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index 72e7735..f1caa19 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -75,7 +75,7 @@ public class ICA extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(true);
         String response = urlopen.open("https://www.ica.se/Logga-in/");
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {

commit 0be4cea25461937875922c9e6ecad96a0464c54b
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun Jun 26 22:11:45 2011 +0200

    Fix problem with AutoRefresehService not being stopped outside the update period

diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 95be934..e72c0a9 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -60,10 +60,13 @@ public class AutoRefreshService extends Service {
 
 	@Override
 	public void onCreate() {
-		if (InsideUpdatePeriod())
+		if (InsideUpdatePeriod()){
 			new DataRetrieverTask().execute();
-		else
+		}
+		else{
 			Log.v(TAG, "Skipping update due to not in update period.");
+			stopSelf();
+		}
 	}
 
     private boolean InsideUpdatePeriod() {

commit 0af64a0a35466d12107569e0420a1331a56b717f
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Mon Jun 20 21:34:51 2011 +0200

    Fix bug in TimePreference last value was not retrived correctly.

diff --git src/com/liato/bankdroid/TimePreference.java src/com/liato/bankdroid/TimePreference.java
index 1f50114..eebc58b 100644
--- src/com/liato/bankdroid/TimePreference.java
+++ src/com/liato/bankdroid/TimePreference.java
@@ -62,5 +62,7 @@ public class TimePreference extends DialogPreference {
 				val = Integer.parseInt(defaultValue.toString());
 			} catch (NumberFormatException e) { }
 		}
+		
+		lastValue = val;
 	}
 }
\ No newline at end of file

commit cf63d9b59c733a6ef873214cc79c56010395258d
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Fri Jun 17 23:21:56 2011 +0200

    Fix request #2 Update between [time] and [time]
    
    No check that start time is before stop time is implemented. If start time is after stop time update will always occur.
    AutoRefreshService will not start an update if outside the preferred time intervall.
    DEfault values are 00:00 and 00:00 which means update will always occcur as start equals to stop.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index b0c3754..8db117c 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -51,6 +51,8 @@
 	<string name="autoupdates_enabled_title">Aktivera</string>
 	<string name="autoupdates_enabled_summary">Aktivera automatiska uppdateringar</string>
 	<string name="update_frequency_title">Uppdateringsfrekvens</string>
+	<string name="update_start_title">Starttid uppdatering</string>
+	<string name="update_stop_title">Sluttid uppdatering</string>
 	<string name="update_transaction_history_title">Uppdatera kontoutdrag</string>
 	<string name="update_transaction_history_summary">Uppdatera kontoutdrag vid automatiska uppdateringar</string>
 	<string name="appearance_title">Utseende</string>
diff --git res/values/strings.xml res/values/strings.xml
index 4d36969..0203ad3 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -54,6 +54,8 @@
 	<string name="autoupdates_enabled_title">Enable</string>
 	<string name="autoupdates_enabled_summary">Enable automatic updates</string>
 	<string name="update_frequency_title">Update frequency</string>
+	<string name="update_start_title">Update start time</string>
+	<string name="update_stop_title">Update end time</string>
 	<string name="update_transaction_history_title">Update transaction history</string>
 	<string name="update_transaction_history_summary">Update transaction history when updating automatically</string>
 	<string name="appearance_title">Appearance</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index f4abf5f..97af55f 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -76,6 +76,16 @@
 			android:entries="@array/refreshrateNames"
 			android:entryValues="@array/refreshrateValues"
 			android:dependency="autoupdates_enabled" />
+		<com.liato.bankdroid.TimePreference
+			android:title="@string/update_start_title"
+			android:key="refresh_start_minutes"
+			android:defaultValue="0"
+			android:dependency="autoupdates_enabled" />
+		<com.liato.bankdroid.TimePreference
+			android:title="@string/update_stop_title"
+			android:key="refresh_stop_minutes"
+			android:defaultValue="0"
+			android:dependency="autoupdates_enabled" />
 		<CheckBoxPreference
 			android:key="autoupdates_transactions_enabled"
 			android:defaultValue="true"
diff --git src/com/liato/bankdroid/TimePreference.java src/com/liato/bankdroid/TimePreference.java
new file mode 100644
index 0000000..1f50114
--- /dev/null
+++ src/com/liato/bankdroid/TimePreference.java
@@ -0,0 +1,66 @@
+//This class  based on tutorial found here https://github.com/commonsguy/cw-lunchlist/blob/master/19-Alarm/LunchList/src/apt/tutorial/TimePreference.java
+package com.liato.bankdroid;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TimePicker;
+
+public class TimePreference extends DialogPreference {
+	private int lastValue = 0;
+	private TimePicker picker = null;
+
+	public TimePreference(Context ctxt, AttributeSet attrs) {
+		super(ctxt, attrs);
+
+		setPositiveButtonText("Set");
+		setNegativeButtonText("Cancel");
+	}
+
+	@Override
+	protected View onCreateDialogView() {
+		picker = new TimePicker(getContext());
+		picker.setIs24HourView(true);
+		return picker;
+	}
+
+	@Override
+	protected void onBindDialogView(View v) {
+		super.onBindDialogView(v);
+
+		picker.setCurrentHour(lastValue / 60);
+		picker.setCurrentMinute(lastValue % 60);
+	}
+
+	@Override
+	protected void onDialogClosed(boolean positiveResult) {
+		super.onDialogClosed(positiveResult);
+
+		if (positiveResult) {
+			lastValue = picker.getCurrentHour() * 60 + picker.getCurrentMinute(); 
+
+			if (callChangeListener(lastValue))
+				persistInt(lastValue);
+		}
+	}
+
+	@Override
+	protected Object onGetDefaultValue(TypedArray a, int index) {
+		return (a.getInt(index, 0));
+	}
+
+	@Override
+	protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+		int val = 0;
+		
+		if (restoreValue) {
+			val = getPersistedInt(val);
+		} else {
+			try{
+				val = Integer.parseInt(defaultValue.toString());
+			} catch (NumberFormatException e) { }
+		}
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 8c58d0b..95be934 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.appwidget;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 
 import android.app.Notification;
@@ -59,10 +60,31 @@ public class AutoRefreshService extends Service {
 
 	@Override
 	public void onCreate() {
-		new DataRetrieverTask().execute();
+		if (InsideUpdatePeriod())
+			new DataRetrieverTask().execute();
+		else
+			Log.v(TAG, "Skipping update due to not in update period.");
 	}
 
-    @Override
+    private boolean InsideUpdatePeriod() {
+		final SharedPreferences prefs = PreferenceManager
+			.getDefaultSharedPreferences(this);
+		
+		int start = prefs.getInt("refresh_start_minutes", 0);
+		int stop = prefs.getInt("refresh_stop_minutes", 0);
+		
+		// If start is bigger than stop we always update. It should perhaps 
+		// be possible to set start to 17:00 and stop to 07:00 and have to 
+		// updates working from 17 to 07 around midnight
+		if (start >= stop)
+			return true;
+		
+        Date now = new Date();
+		int minutesSinceMidnight = now.getHours() * 60 + now.getMinutes();
+		return minutesSinceMidnight > start && minutesSinceMidnight < stop;
+	}
+
+	@Override
 	public void onDestroy() {
 	}
 

commit 20e7578faf693411bb01d2b2e02e2be03facfc7d
Author: liato <x@x00.us>
Date:   Mon Jun 13 02:24:33 2011 +0200

    Fix for Skandiabanken where accounts without an alias wouldn't be added to the database. Add skandiabanken logo.

diff --git logos.psd logos.psd
index 3e9bead..095eade 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_skandiabanken.png res/drawable/logo_skandiabanken.png
new file mode 100644
index 0000000..561b3ed
Binary files /dev/null and res/drawable/logo_skandiabanken.png differ
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index aabc3a7..22e92d8 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -15,7 +15,6 @@ import se.smartrefill.remoting.domain.exception.CustomerBlockedException;
 import se.smartrefill.remoting.domain.exception.InvalidLoginException;
 import se.smartrefill.remoting.domain.exception.InvalidSecurityCodeException;
 import se.smartrefill.remoting.domain.exception.UnauthenticatedUserException;
-
 import android.content.Context;
 import android.provider.Settings.Secure;
 import android.text.InputType;
@@ -35,7 +34,17 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Skandiabanken extends Bank {
-	private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android2/";
+    private static final String TAG = "Skandiabanken";
+    private static final String NAME = "Skandiabanken";
+    private static final String NAME_SHORT = "skandiabanken";
+    private static final int BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
+    private static final String URL = "http://www.skandiabanken.se/hem/";
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
+    
+    private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android2/";
 	private static final String LOGIN_URL = BASE_URL + "customer.service";
 	private static final String BALANCE_URL = BASE_URL + "balance.service";
 	
@@ -55,15 +64,13 @@ public class Skandiabanken extends Bank {
 
 	public Skandiabanken(Context context) {
 		super(context);
-		TAG = "Skandiabanken";
-		NAME = "Skandiabanken";
-		NAME_SHORT = "Skandiabanken";
-		BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
-		;
-		URL = "http://www.skandiabanken.se/hem/";
-		INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-		INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
-		INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
 	}
 
 	public Skandiabanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
@@ -141,7 +148,6 @@ public class Skandiabanken extends Bank {
 					.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
 			
 			List<AdAccount> adAccounts = balanceService.getAccounts(customerId);
-			
 			for (AdAccount adAccount : adAccounts) {
 				String amount = adAccount.getAmount();
 				if (amount == null)
@@ -154,8 +160,9 @@ public class Skandiabanken extends Bank {
 				if (typeDescription.contentEquals("Allt i Ett-konto") || typeDescription.contentEquals("Sparkonto"))
 					type = Account.REGULAR;
 				
-				accounts.add(new Account(adAccount.getAlias(), Helpers
-						.parseBalance(amount), adAccount.getId(), type));
+				accounts.add(new Account(
+				        adAccount.getAlias() != null ? adAccount.getAlias() : adAccount.getAccountNumber(),
+				        Helpers.parseBalance(amount), adAccount.getId(), type));
 			}
 		} catch (IOException e) {
 			throw new BankException(e.getMessage());

commit eaff2d2efb7d831524cb5b82c5f2b2180cdd5ae3
Author: liato <x@x00.us>
Date:   Sun Jun 12 17:46:57 2011 +0200

    Disable the home button in the action bar for the pair application view.

diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 3c10aab..05324f3 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -47,6 +47,9 @@ public class LockableActivity extends Activity {
 	private LinearLayout mTitlebarButtons;
 	private LayoutInflater mInflater;
 	private ProgressBar mProgressBar;
+	
+    private ImageView mHomeButton;
+    private View mHomeButtonCont;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
@@ -66,8 +69,8 @@ public class LockableActivity extends Activity {
         mTitlebarButtons = (LinearLayout)titlebar.findViewById(R.id.layTitleButtons);
         mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-        ImageView homeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
-        View homeButtonCont = titlebar.findViewById(R.id.layLogoContainer);
+        mHomeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
+        mHomeButtonCont = titlebar.findViewById(R.id.layLogoContainer);
         mProgressBar = (ProgressBar)titlebar.findViewById(R.id.progressBar);
         OnClickListener listener = new View.OnClickListener() {
             public void onClick(View v) {
@@ -77,12 +80,9 @@ public class LockableActivity extends Activity {
                 LockableActivity.this.finish();
             }
         };
-        homeButton.setOnClickListener(listener);
-        homeButton.setFocusable(true);
-        homeButton.setClickable(true);
-        homeButtonCont.setOnClickListener(listener);
-        homeButtonCont.setFocusable(true);
-        homeButtonCont.setClickable(true);
+        mHomeButton.setOnClickListener(listener);
+        mHomeButtonCont.setOnClickListener(listener);
+        setHomeButtonEnabled(true);
     }
 
     protected void addTitleButton(int imageResourceId, String tag, OnClickListener listener) {
@@ -122,6 +122,13 @@ public class LockableActivity extends Activity {
         }
     }
     
+    protected void setHomeButtonEnabled(boolean enabled) {
+        mHomeButtonCont.setFocusable(enabled);
+        mHomeButtonCont.setClickable(enabled);
+        mHomeButton.setFocusable(enabled);
+        mHomeButton.setClickable(enabled);
+    }    
+    
     protected void setProgressBar(int progress) {
         mProgressBar.setProgress(progress);
     }
diff --git src/com/liato/bankdroid/PairApplicationsActivity.java src/com/liato/bankdroid/PairApplicationsActivity.java
index 25a7e05..1e75a76 100644
--- src/com/liato/bankdroid/PairApplicationsActivity.java
+++ src/com/liato/bankdroid/PairApplicationsActivity.java
@@ -49,7 +49,8 @@ public class PairApplicationsActivity extends LockableActivity {
 	protected void onCreate(final Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.pair_applications_layout);
-
+		setHomeButtonEnabled(false);
+		
 		Bundle bundle = getIntent().getExtras();
 
 		if(bundle.containsKey(PAIR_APP_NAME)) {

commit a9d1ad79f7337fb809596c8dea959e5b164b2358
Author: liato <x@x00.us>
Date:   Sun Jun 12 02:22:26 2011 +0200

    Make pairing process pattern lock protected. Closes #90.

diff --git .classpath .classpath
index ca186e0..4417ebe 100644
--- .classpath
+++ .classpath
@@ -3,7 +3,7 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
-	<classpathentry kind="lib" path="lib/google-collect-1.0.jar"/>
+	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git res/drawable/logo_ekonomipuls.png res/drawable/applogo_ekonomipuls.png
similarity index 100%
rename from res/drawable/logo_ekonomipuls.png
rename to res/drawable/applogo_ekonomipuls.png
diff --git src/com/liato/bankdroid/PairApplicationsActivity.java src/com/liato/bankdroid/PairApplicationsActivity.java
index 694a44e..25a7e05 100644
--- src/com/liato/bankdroid/PairApplicationsActivity.java
+++ src/com/liato/bankdroid/PairApplicationsActivity.java
@@ -15,14 +15,6 @@
  */
 package com.liato.bankdroid;
 
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-import com.liato.bankdroid.provider.BankTransactionsProvider;
-import com.liato.bankdroid.provider.IBankTransactionsProvider;
-
-import com.liato.bankdroid.R;
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -37,11 +29,14 @@ import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.liato.bankdroid.provider.BankTransactionsProvider;
+import com.liato.bankdroid.provider.IBankTransactionsProvider;
+
 /**
  * @author Magnus Andersson
  * @since 8 jun 2011
  */
-public class PairApplicationsActivity extends Activity {
+public class PairApplicationsActivity extends LockableActivity {
 
 	/**
 	 * 
@@ -61,7 +56,7 @@ public class PairApplicationsActivity extends Activity {
 			String appName = bundle.getString(PAIR_APP_NAME);
 
 			ImageView img = (ImageView) findViewById(R.id.imageView1);
-			String logoUri = "drawable/logo_"+appName.toLowerCase();
+			String logoUri = "drawable/applogo_"+appName.toLowerCase();
 
 			// Dynamically load logo
 			int imageResource = getResources().getIdentifier(logoUri, null, getPackageName());
@@ -78,7 +73,7 @@ public class PairApplicationsActivity extends Activity {
 			TextView appNameView = (TextView) findViewById(R.id.app_name);
 			appNameView.setText(appName);
 		} else {
-			Log.d(TAG, "Unkown application");
+			Log.d(TAG, "Unknown application");
 		}
 
 

commit 3fb857ffd9763fd8eff08b223e91a1f61a953312
Merge: 9c59cc7 82ff351
Author: liato <x@x00.us>
Date:   Sat Jun 11 15:44:53 2011 -0700

    Merge pull request #91 from woody2/master
    
    Skandiabanken mot deras ny API

commit 82ff351e86a051f80a8aa2a15b76dab17e0a69a3
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sat Jun 11 22:38:59 2011 +0200

    Opps missed a lot of files last commit

diff --git .classpath .classpath
index e7b211d..ca186e0 100644
--- .classpath
+++ .classpath
@@ -3,7 +3,7 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
-	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/google-collect-1.0.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git src/com/caucho/hessian/client/HessianHttpProxyFactory.java src/com/caucho/hessian/client/HessianHttpProxyFactory.java
index eeca0ad..332b07d 100644
--- src/com/caucho/hessian/client/HessianHttpProxyFactory.java
+++ src/com/caucho/hessian/client/HessianHttpProxyFactory.java
@@ -26,7 +26,6 @@ import java.net.URL;
 import java.net.URLConnection;
 import java.util.HashMap;
 import java.util.List;
-import java.util.logging.Logger;
 
 /**
  * <code>HessianHttpProxyFactory</code> extends the
@@ -98,8 +97,7 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
      * Header Field: server (Apache-Coyote/1.1)
      * Header Field: set-cookie (JSESSIONID=5930D0459F0CE1B769ED5D08B031F9D2; Path=/Server)
      */
-    private static class HessianHttpProxy extends HessianProxy {
-        private static final Logger log = Logger.getLogger(HessianHttpProxy.class.getName());
+    protected static class HessianHttpProxy extends HessianProxy {
         private static final HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>();
 
         private static final String COOKIE_SET = "set-cookie";
@@ -123,7 +121,7 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
                 for (String s : cookieStrings) {
                     Cookie cookie = CookieParser.parse(host, s);
                     HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
-                    log.finest("Cookie cached: " + cookie.host + cookie.path + ":" + s);
+                   // Log.d("Cookies", "Cookie cached: " + cookie.host + cookie.path + ":" + s);
                 }
             }
         }
@@ -142,11 +140,11 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
             String path = conn.getURL().getPath();
 
             while (path != null && 0 < path.length()) {
-                log.info("Host:+" + host +",Path:"+path);
-                Cookie cookie = HessianHttpProxy.cookieMap.get(host + path);
+                //Log.d("Cookies", "Host:+" + host +",Path:"+path);
+                Cookie cookie = getCookie(host, path);
                 if (cookie != null) {
                     conn.setRequestProperty("Cookie", cookie.value);
-                    log.finest("Cookie set in request:" + cookie.value);
+                    //Log.d("Cookies", "Cookie set in request:" + cookie.value);
                     break;
                 }
                 int i = path.lastIndexOf("/");
@@ -157,5 +155,9 @@ public class HessianHttpProxyFactory extends HessianProxyFactory {
                 }
 			}
 		}
+
+		protected Cookie getCookie(String host, String path) {
+			return HessianHttpProxy.cookieMap.get(host + path);
+		}
 	}
 }
diff --git src/com/caucho/hessian/client/HessianProxy.java src/com/caucho/hessian/client/HessianProxy.java
index 5beea3e..1767a32 100644
--- src/com/caucho/hessian/client/HessianProxy.java
+++ src/com/caucho/hessian/client/HessianProxy.java
@@ -48,6 +48,8 @@
 
 package com.caucho.hessian.client;
 
+import android.util.Log;
+
 import com.caucho.hessian.io.*;
 import com.caucho.services.server.AbstractSkeleton;
 
@@ -216,6 +218,11 @@ public class HessianProxy implements InvocationHandler {
 				is = new HessianDebugInputStream(is, dbg);
 			}
 
+//			if (false) {
+//				PrintWriter dbg = new PrintWriter(new LogCatLogWriter());
+//				is = new HessianDebugInputStream(is, dbg);
+//			}
+
 			AbstractHessianInput in = _factory.getHessianInput(is);
 
 			in.startReply();
@@ -418,7 +425,7 @@ public class HessianProxy implements InvocationHandler {
 		LogWriter(Logger log) {
 			_log = log;
 		}
-
+		
 		public void write(char ch) {
 			if (ch == '\n' && _sb.length() > 0) {
 				_log.fine(_sb.toString());
@@ -432,7 +439,7 @@ public class HessianProxy implements InvocationHandler {
 				char ch = buffer[offset + i];
 
 				if (ch == '\n' && _sb.length() > 0) {
-					_log.log(_level, _sb.toString());
+					_log.fine(_sb.toString());
 					_sb.setLength(0);
 				} else
 					_sb.append((char) ch);
@@ -444,7 +451,40 @@ public class HessianProxy implements InvocationHandler {
 
 		public void close() {
 			if (_sb.length() > 0)
-				_log.log(_level, _sb.toString());
+				_log.fine(_sb.toString());
+		}
+	}	
+	
+	static class LogCatLogWriter extends Writer {
+		private StringBuilder _sb = new StringBuilder();
+
+		public void write(char ch) {
+			if (ch == '\n' && _sb.length() > 0) {
+				Log.d("HessianLogCatLogWriter", _sb.toString());
+				_sb.setLength(0);
+			} else
+				_sb.append((char) ch);
+		}
+
+		public void write(char[] buffer, int offset, int length) {
+			for (int i = 0; i < length; i++) {
+				char ch = buffer[offset + i];
+
+				if (ch == '\n' && _sb.length() > 0) {
+					Log.d("HessianLogCatLogWriter", _sb.toString());
+					_sb.setLength(0);
+				} else
+					_sb.append((char) ch);
+			}
+		}
+
+		public void flush() {
+		}
+
+		public void close() {
+			if (_sb.length() > 0){
+				Log.d("HessianLogCatLogWriter", _sb.toString());
+			}
 		}
 	}
 }
diff --git src/com/caucho/hessian/io/HessianDebugInputStream.java src/com/caucho/hessian/io/HessianDebugInputStream.java
index a7546a3..d2504e5 100644
--- src/com/caucho/hessian/io/HessianDebugInputStream.java
+++ src/com/caucho/hessian/io/HessianDebugInputStream.java
@@ -103,6 +103,7 @@ public class HessianDebugInputStream extends InputStream
       ch = is.read();
     }
 
+    //Log.d("Hessian",(int)ch);
     _state.next(ch);
 
     return ch;
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index ba7a4cc..aabc3a7 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -2,22 +2,26 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 import se.smartrefill.ad.bank.domain.AdAccount;
 import se.smartrefill.ad.bank.domain.AdBalanceInformationTransaction;
+import se.smartrefill.ad.bank.domain.AdLoginRequest;
 import se.smartrefill.ad.bank.remoting.service.RemoteBalanceService;
 import se.smartrefill.ad.bank.remoting.service.RemoteCustomerService;
 import se.smartrefill.ad.domain.AdCustomer;
-import se.smartrefill.exception.CustomerBlockedException;
-import se.smartrefill.exception.InvalidLoginException;
-import se.smartrefill.exception.InvalidSecurityCodeException;
-import se.smartrefill.exception.UnauthenticatedUserException;
+import se.smartrefill.remoting.domain.exception.CustomerBlockedException;
+import se.smartrefill.remoting.domain.exception.InvalidLoginException;
+import se.smartrefill.remoting.domain.exception.InvalidSecurityCodeException;
+import se.smartrefill.remoting.domain.exception.UnauthenticatedUserException;
 
 import android.content.Context;
+import android.provider.Settings.Secure;
 import android.text.InputType;
 
-import com.caucho.hessian.client.HessianProxyFactory;
+import com.caucho.hessian.client.HessianConnectionException;
+import com.caucho.hessian.client.HessianHttpHeaderProxyFactory;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
@@ -31,16 +35,23 @@ import com.liato.bankdroid.provider.IBankTypes;
 import eu.nullbyte.android.urllib.Urllib;
 
 public class Skandiabanken extends Bank {
-	private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android/";
+	private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android2/";
 	private static final String LOGIN_URL = BASE_URL + "customer.service";
 	private static final String BALANCE_URL = BASE_URL + "balance.service";
 	
-	private final static String customerOwner = "SKANDIABANKEN";
-	private final static String countryCode = "SE";
+	  private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_ID = "x-smartrefill-application";
+	  private static final String HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION = "x-smartrefill-version";
+	  private static final String HTTP_HEADER_SMARTREFILL_COUNTRY_CODE = "x-smartrefill-country-code";
+	  private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_ID = "x-smartrefill-customer";
+	  private static final String HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER = "x-smartrefill-customer-owner";
+	  private static final String HTTP_HEADER_SMARTREFILL_DEVICE_ID = "x-smartrefill-device";
+	  private static final String HTTP_HEADER_SMARTREFILL_INFLOW = "x-smartrefill-inflow";
+	  private static final String HTTP_HEADER_SMARTREFILL_SECURITY_CODE = "x-smartrefill-security-code";
+	  private static final String INFLOW_ANDROID = "Android";
+	  private final static String customerOwner = "SKANDIABANKEN";
+	  private final static String countryCode = "SE";
 	
-	// Does not seem to matter, should perhaps be the password of the user
-	private final static String securityCode = "unknown"; 
-	private int customerBalanceServiceId = 0;
+	private int customerId = 0;
 
 	public Skandiabanken(Context context) {
 		super(context);
@@ -64,11 +75,15 @@ public class Skandiabanken extends Bank {
 	public Urllib login() throws LoginException, BankException {
 
 		try {
-			RemoteCustomerService test = (RemoteCustomerService) getHessianProxy()
-					.create(RemoteCustomerService.class, LOGIN_URL, context.getClassLoader());
-			AdCustomer customer = test.login(username, password, customerOwner,
-					countryCode);
-			customerBalanceServiceId = customer.getBalanceService().getId();
+			HessianHttpHeaderProxyFactory proxyFactory = getHessianProxy();
+			
+			RemoteCustomerService test = (RemoteCustomerService) proxyFactory
+				.create(RemoteCustomerService.class, LOGIN_URL, context.getClassLoader());
+			
+			AdCustomer customer = test.login(new AdLoginRequest(username, password));
+			customerId = customer.getId();
+			proxyFactory.addHeader(HTTP_HEADER_SMARTREFILL_CUSTOMER_ID, String.valueOf(customerId));
+			proxyFactory.addHeader(HTTP_HEADER_SMARTREFILL_SECURITY_CODE, password);
 		} catch (InvalidLoginException e) {
 			throw new LoginException(res.getText(
 					R.string.invalid_username_password).toString());
@@ -79,14 +94,36 @@ public class Skandiabanken extends Bank {
 			throw new LoginException(res.getText(
 					R.string.invalid_username_password).toString());
 		} catch (CustomerBlockedException e) {
-			// TODO other message!
-			throw new LoginException(res.getText(
-					R.string.invalid_username_password).toString());
+			// TODO hard coded string!
+			throw new LoginException("User has been blocked.");
 		} catch (IOException e) {
 			throw new BankException(e.getMessage());
-		}
+		} catch (HessianConnectionException e) {
+			throw new BankException(e.getMessage());
+		} 
 		return urlopen;
 	}
+	
+	public void logout() throws BankException {
+
+		try {
+			HessianHttpHeaderProxyFactory proxyFactory = getHessianProxy();
+			
+			RemoteCustomerService test = (RemoteCustomerService) proxyFactory
+					.create(RemoteCustomerService.class, LOGIN_URL, context.getClassLoader());
+			
+			test.logout(customerId);
+			customerId = 0;
+			proxyFactory.removeHeader(HTTP_HEADER_SMARTREFILL_CUSTOMER_ID);
+			proxyFactory.removeHeader(HTTP_HEADER_SMARTREFILL_SECURITY_CODE);
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		} catch (HessianConnectionException e) {
+			throw new BankException(e.getMessage());
+		} catch (RuntimeException e) {
+			throw new BankException("Unexpected error connecting to Skandiabanken: " + e.getMessage());
+		}
+	}
 
 	@Override
 	public void update() throws BankException, LoginException, BankChoiceException {
@@ -102,8 +139,9 @@ public class Skandiabanken extends Bank {
 		try {
 			RemoteBalanceService balanceService = (RemoteBalanceService) getHessianProxy()
 					.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
-			List<AdAccount> adAccounts = balanceService.getAccounts(
-					customerBalanceServiceId, securityCode);
+			
+			List<AdAccount> adAccounts = balanceService.getAccounts(customerId);
+			
 			for (AdAccount adAccount : adAccounts) {
 				String amount = adAccount.getAmount();
 				if (amount == null)
@@ -121,9 +159,13 @@ public class Skandiabanken extends Bank {
 			}
 		} catch (IOException e) {
 			throw new BankException(e.getMessage());
+		} catch (RuntimeException e) {
+			throw new BankException("Unexpected error getting balance from Skandiabanken: " + e.getMessage());
 		} finally {
 			super.updateComplete();
 		}
+		
+		logout();
 	}
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
@@ -134,7 +176,7 @@ public class Skandiabanken extends Bank {
 			RemoteBalanceService balanceService = (RemoteBalanceService) getHessianProxy()
 				.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
 			AdAccount adAccount = null;
-			List<AdAccount> adAccounts = balanceService.getAccounts(customerBalanceServiceId, securityCode);
+			List<AdAccount> adAccounts = balanceService.getAccounts(customerId);
 			for (AdAccount adAccounti : adAccounts) {
 				if (adAccounti.getId().contentEquals(account.getId())){
 					adAccount = adAccounti;
@@ -143,7 +185,7 @@ public class Skandiabanken extends Bank {
 			}
 			// TODO Check null
 			
-			AdAccount accountWithTransactions =  balanceService.getAccountTransactions(adAccount, "f", securityCode);
+			AdAccount accountWithTransactions =  balanceService.getAccountTransactions(customerId, adAccount, "f");
     		List<AdBalanceInformationTransaction> adTransactions = accountWithTransactions.getTransactions();
     		for (AdBalanceInformationTransaction transaction : adTransactions) {
 				String transactionAmount = transaction.getAmount();
@@ -153,19 +195,62 @@ public class Skandiabanken extends Bank {
 			}
 			account.setTransactions(transactions);
 		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			throw new BankException(e.getMessage());
+		} catch (RuntimeException e) {
+			throw new BankException("Unexpected error getting transactions from Skandiabanken: " + e.getMessage());
 		}
 	}
+	
+	private HessianHttpHeaderProxyFactory mProxyFactory = null;
 
-	private HessianProxyFactory getHessianProxy() {
-		HessianProxyFactory localHessianProxyFactory = new HessianProxyFactory();
-		localHessianProxyFactory.setHessian2Request(false);
-		localHessianProxyFactory.setHessian2Reply(false);
-		localHessianProxyFactory.setChunkedPost(false);
-		localHessianProxyFactory.setReadTimeout(30000L);
-		localHessianProxyFactory.setOverloadEnabled(false);
-		return localHessianProxyFactory;
+	private HessianHttpHeaderProxyFactory getHessianProxy() {
+		if (mProxyFactory == null)
+		{
+			HashMap<String, String> headers = new HashMap<String, String>();
+			headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_ID, "se.skandiabanken.android.wallet");
+			headers.put(HTTP_HEADER_SMARTREFILL_APPLICATION_VERSION, "6");
+			headers.put(HTTP_HEADER_SMARTREFILL_COUNTRY_CODE, countryCode);
+			headers.put(HTTP_HEADER_SMARTREFILL_CUSTOMER_OWNER, customerOwner);
+			headers.put(HTTP_HEADER_SMARTREFILL_DEVICE_ID, getDeviceId());
+			headers.put(HTTP_HEADER_SMARTREFILL_INFLOW, INFLOW_ANDROID);
+			
+			HessianHttpHeaderProxyFactory localHessianProxyFactory = 
+				new HessianHttpHeaderProxyFactory(headers);
+			
+			localHessianProxyFactory.setHessian2Request(false);
+			localHessianProxyFactory.setHessian2Reply(false);
+			localHessianProxyFactory.setChunkedPost(false);
+			localHessianProxyFactory.setReadTimeout(30000L);
+			localHessianProxyFactory.setOverloadEnabled(false);
+			mProxyFactory = localHessianProxyFactory;
+		}
+		
+		return mProxyFactory;
 	}
-
+	
+	  public String getDeviceId()
+	  {
+//		    TelephonyManager localTelephonyManager = (TelephonyManager)context.getSystemService("phone");
+//			if (localTelephonyManager.getDeviceId() != null) // null for emulator
+//				return localTelephonyManager.getDeviceId();
+//			else
+//				return "000000000000000"; 
+		  // We should return the imei of the phone (se code above)
+		  // As we would need permission to read imei we use something else that is unique and constant
+		  // Bankdroid should have as less permissions as possible...
+		  String test = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
+		  
+		  if (test == null) // null for emulator
+			  test = "0";
+		  
+		  // convert to decimal string (imei is decimal)
+		  try{
+			  test = String.valueOf(Integer.parseInt(test, 16));
+		  } catch (NumberFormatException e) {}
+		  
+		  while (test.length() < 16)
+			  test += "0";
+		  
+		  return test.substring(0, 15);
+	  }
 }
diff --git src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
index bf4c404..c55f130 100644
--- src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
+++ src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
@@ -7,6 +7,7 @@ public class AdPendingCreditCard
 {
   private static final long serialVersionUID = 1L;
   private String alias;
+  private int customerId;
   private String number;
   private String partner;
   private String phoneNumber;
@@ -15,6 +16,9 @@ public class AdPendingCreditCard
 	public String getAlias() {
 		return alias;
 	}
+	  public int getCustomerId() {
+			return customerId;
+		}
 
 	public String getNumber() {
 		return number;
diff --git src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
index f00b949..f801bcf 100644
--- src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
+++ src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
@@ -5,6 +5,6 @@ import se.smartrefill.ad.bank.domain.AdAccount;
 
 public abstract interface RemoteBalanceService
 {
-  public abstract AdAccount getAccountTransactions(AdAccount account, String scrollDirection, String securityCode);
-  public abstract List<AdAccount> getAccounts(int customerBalanceServiceId, String securityCode);
+  public abstract AdAccount getAccountTransactions(int customerId, AdAccount account, String scrollDirection);
+  public abstract List<AdAccount> getAccounts(int customerId);
 }
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
index a3e4964..4a5ac4e 100644
--- src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
+++ src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
@@ -1,17 +1,11 @@
 package se.smartrefill.ad.bank.remoting.service;
 
+import se.smartrefill.ad.bank.domain.AdLoginRequest;
 import se.smartrefill.ad.domain.AdCustomer;
-import se.smartrefill.exception.UnauthenticatedUserException;
 
 public abstract interface RemoteCustomerService
 {
-  public abstract AdCustomer getCustomer(String username, String password, String customerOwner, String countryCode)
-    throws UnauthenticatedUserException;
-
-  public abstract AdCustomer getCustomerWithoutBalanceInformation(String paramString1, String paramString2, String paramString3, String paramString4)
-    throws UnauthenticatedUserException;
-
-  public abstract AdCustomer login(String username, String password, String customerOwner, String countryCode)
-    throws UnauthenticatedUserException;
-
-}
\ No newline at end of file
+  public abstract AdCustomer login(AdLoginRequest paramAdLoginRequest);
+  
+  public abstract void logout(int customerId);
+}
diff --git src/se/smartrefill/ad/domain/AdAbstractCustomer.java src/se/smartrefill/ad/domain/AdAbstractCustomer.java
index d7c515a..6238819 100644
--- src/se/smartrefill/ad/domain/AdAbstractCustomer.java
+++ src/se/smartrefill/ad/domain/AdAbstractCustomer.java
@@ -23,4 +23,8 @@ public abstract class AdAbstractCustomer
     this.services = new ArrayList<AdService>();
     this.paymentCards = new ArrayList<AdPaymentCard>();
   }
+  
+  public int getId(){
+	  return id;
+  }
 }

commit 183aaf6239d123b2e1fdc7aa406ed1bb075dccae
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sat Jun 11 22:29:15 2011 +0200

    Fix implementation for Skandiabanken after their API-upgrade
    Also enable som debug logging using logcat in hessdroid. the logging code is commented at the moment to avoid logging the sensible data of bankdroid
    
    Most important changes in Skandiabankens API
    Login method new takes an AdLoginResuest object instead of username and password.
    Customer id country code etc.  is supplied as http-headers instead of using parameters
    Additional http-headers added. Probably for Skandiabankens statistics

diff --git src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
new file mode 100644
index 0000000..5721a4f
--- /dev/null
+++ src/com/caucho/hessian/client/HessianHttpHeaderProxyFactory.java
@@ -0,0 +1,66 @@
+package com.caucho.hessian.client;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Map;
+
+import com.ast.util.CookieParser.Cookie;
+import com.caucho.hessian.io.HessianRemoteObject;
+
+// This class is added in the bankdroid project to enable adding some http-headers required by Skandiabanken
+// The class also takes care of a ugly hack for some strange cookie-handling for Skandiabanken (see getCookie)
+public class HessianHttpHeaderProxyFactory extends HessianHttpProxyFactory{
+
+	Map<String, String> mHeaderMap;
+	
+	public HessianHttpHeaderProxyFactory(Map<String, String> headers){
+		mHeaderMap = headers;
+	}
+	
+    @SuppressWarnings({"unchecked"})
+    @Override
+    public <T> T create(Class<T> api, String urlName, ClassLoader loader) throws MalformedURLException {
+        InvocationHandler handler = new HessianHttpHeaderProxy(this, new URL(urlName));
+        return (T) Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
+    }
+    
+    public void addHeader(String key, String value){
+    	mHeaderMap.put(key, value);
+    }
+    
+    public void removeHeader(String key){
+    	mHeaderMap.remove(key);
+    }
+	
+	class HessianHttpHeaderProxy extends HessianHttpProxy{
+
+		HessianHttpHeaderProxy(HessianProxyFactory factory, URL url) {
+			super(factory, url);
+		}
+		
+		@Override
+		protected void addRequestHeaders(URLConnection conn) {
+			super.addRequestHeaders(conn);
+
+			for (Map.Entry<String, String> header : mHeaderMap.entrySet())
+				conn.setRequestProperty(header.getKey(), header.getValue());
+		}
+		
+	    @Override
+		protected Cookie getCookie(String host, String path) {
+			Cookie cookie = super.getCookie(host, path);
+			
+			// Ugly hack: For some reason the cookie has the wrong path in the response from Skandiabanken.
+			if (cookie == null && 
+					host.contentEquals("smartrefill.se") && 
+					path.contentEquals("/")){
+				cookie = super.getCookie("smartrefill.se", "/BankServices");
+			}
+			
+			return cookie;
+		}
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdLoginRequest.java src/se/smartrefill/ad/bank/domain/AdLoginRequest.java
new file mode 100644
index 0000000..2adb55d
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdLoginRequest.java
@@ -0,0 +1,30 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+
+public class AdLoginRequest implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private String password;
+	private String username;
+
+	public AdLoginRequest(String username, String password) {
+		this.username = username;
+		this.password = password;
+	}
+
+	public String getPassword() {
+		return password;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public void setUsername(String userName) {
+		this.username = userName;
+	}
+}
\ No newline at end of file
diff --git src/se/smartrefill/remoting/domain/exception/CustomerBlockedException.java src/se/smartrefill/remoting/domain/exception/CustomerBlockedException.java
new file mode 100644
index 0000000..32a06b3
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/CustomerBlockedException.java
@@ -0,0 +1,12 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class CustomerBlockedException extends SmartrefillException {
+	private static final long serialVersionUID = 1L;
+
+	public CustomerBlockedException() {
+	}
+
+	public CustomerBlockedException(String paramString) {
+		super(paramString);
+	}
+}
diff --git src/se/smartrefill/remoting/domain/exception/InvalidLoginException.java src/se/smartrefill/remoting/domain/exception/InvalidLoginException.java
new file mode 100644
index 0000000..7fc2bbd
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/InvalidLoginException.java
@@ -0,0 +1,12 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class InvalidLoginException extends SmartrefillException{
+	private static final long serialVersionUID = 1L;
+
+	public InvalidLoginException() {
+	}
+
+	public InvalidLoginException(String paramString) {
+		super(paramString);
+	}
+}
\ No newline at end of file
diff --git src/se/smartrefill/remoting/domain/exception/InvalidSecurityCodeException.java src/se/smartrefill/remoting/domain/exception/InvalidSecurityCodeException.java
new file mode 100644
index 0000000..dde2f1b
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/InvalidSecurityCodeException.java
@@ -0,0 +1,15 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class InvalidSecurityCodeException extends ValidationException
+{
+  private static final long serialVersionUID = 1L;
+
+  public InvalidSecurityCodeException()
+  {
+  }
+
+  public InvalidSecurityCodeException(String paramString)
+  {
+    super(paramString);
+  }
+}
\ No newline at end of file
diff --git src/se/smartrefill/remoting/domain/exception/NoSessionException.java src/se/smartrefill/remoting/domain/exception/NoSessionException.java
new file mode 100644
index 0000000..7614fd7
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/NoSessionException.java
@@ -0,0 +1,8 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class NoSessionException extends SmartrefillException {
+	private static final long serialVersionUID = 1L;
+
+	public NoSessionException() {
+	}
+}
diff --git src/se/smartrefill/remoting/domain/exception/SmartrefillException.java src/se/smartrefill/remoting/domain/exception/SmartrefillException.java
new file mode 100644
index 0000000..a02d003
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/SmartrefillException.java
@@ -0,0 +1,13 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class SmartrefillException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+
+	public SmartrefillException() {
+		this(null);
+	}
+
+	public SmartrefillException(String paramString) {
+		super(paramString);
+	}
+}
diff --git src/se/smartrefill/remoting/domain/exception/UnauthenticatedUserException.java src/se/smartrefill/remoting/domain/exception/UnauthenticatedUserException.java
new file mode 100644
index 0000000..a7b77be
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/UnauthenticatedUserException.java
@@ -0,0 +1,12 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class UnauthenticatedUserException extends SmartrefillException {
+	private static final long serialVersionUID = 1L;
+
+	public UnauthenticatedUserException() {
+	}
+
+	public UnauthenticatedUserException(String paramString) {
+		super(paramString);
+	}
+}
diff --git src/se/smartrefill/remoting/domain/exception/ValidationException.java src/se/smartrefill/remoting/domain/exception/ValidationException.java
new file mode 100644
index 0000000..559efe3
--- /dev/null
+++ src/se/smartrefill/remoting/domain/exception/ValidationException.java
@@ -0,0 +1,15 @@
+package se.smartrefill.remoting.domain.exception;
+
+public class ValidationException extends SmartrefillException
+{
+  private static final long serialVersionUID = 1L;
+
+  public ValidationException()
+  {
+  }
+
+  public ValidationException(String paramString)
+  {
+    super(paramString);
+  }
+}
\ No newline at end of file

commit 9c59cc7fe008ca1f1e44a72d8f2fde2ae3fbaee8
Merge: 2e6d825 c1a6b4f
Author: liato <x@x00.us>
Date:   Sat Jun 11 08:13:14 2011 -0700

    Merge pull request #89 from magnusart/master
    
    Fix for issue #68: Add account balance to Content Provider

commit c1a6b4f3c0d2953f5006d0813f1f8ec62bb892a1
Merge: 6bf2f96 2e6d825
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jun 11 16:45:36 2011 +0200

    Merge branch 'master' of https://github.com/liato/android-bankdroid

commit 6bf2f966f8c51ce381754ac03550e5491ae1e6d8
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jun 11 16:44:09 2011 +0200

    Updated the Provider Interface with balance information for Account
    Entity.
    
    Signed-off-by: Magnus Andersson <magnus@magnusart.com>

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 0d7dabe..180a4d9 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -54,7 +54,9 @@ public class BankTransactionsProvider extends ContentProvider implements
 	private final static int BANK_ACCOUNTS = 1;
 	private static final String WILD_CARD = "*";
 
-	private static final String BANK_ACCOUNT_TABLES = "banks LEFT JOIN accounts ON banks."
+	private static final String BANK_TABLE = "banks"; 
+	private static final String ACCOUNT_TABLE = "accounts";
+	private static final String BANK_ACCOUNT_TABLES = BANK_TABLE + " LEFT JOIN " + ACCOUNT_TABLE + " ON banks."
 			+ BANK_ID + " = accounts.bankid";
 	private static final String TRANSACTIONS_TABLE = "transactions";
 
@@ -81,6 +83,8 @@ public class BankTransactionsProvider extends ContentProvider implements
 		bankAccountProjectionMap.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED);
 		bankAccountProjectionMap.put(ACC_ID, ACC_ID);
 		bankAccountProjectionMap.put(ACC_NAME, ACC_NAME);
+		// Table name has to be explicitly included here since Banks also have a column named balance.
+		bankAccountProjectionMap.put(ACC_BALANCE, ACCOUNT_TABLE + "." + ACC_BALANCE); 
 		bankAccountProjectionMap.put(ACC_TYPE, ACC_TYPE);
 
 		transProjectionMap = new HashMap<String, String>();
@@ -186,6 +190,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 			throw new IllegalArgumentException("Unsupported URI: " + uri);
 		}
 
+				
 		final Cursor cur = qb.query(db, projection, selection, selectionArgs,
 				null, null, sortOrder);
 
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index c650c42..a79c958 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -39,8 +39,7 @@ import java.math.BigDecimal;
  * <pre>
  * final Uri uri = Uri.parse(&quot;content://&quot; + AUTHORITY + &quot;/&quot; + TRANSACTIONS_CAT
  * 		+ &quot;/&quot; + API_KEY + apiKey);
- * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION,
- * 		ACCOUNT_SELECTION_FILTER, new String[] { currentAccountId }, null);
+ * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION, ACCOUNT_SELECTION_FILTER, new String[] { currentAccountId }, null);
  * startManagingCursor(cur);
  * </pre>
  * 
@@ -49,7 +48,7 @@ import java.math.BigDecimal;
  * 
  * @author Magnus Andersson
  * @since 8 jan 2011
- * @version 1.0-RC1
+ * @version 1.0-RC2
  * @see BankTransactionsProvider
  */
 public interface IBankTransactionsProvider {
@@ -160,6 +159,17 @@ public interface IBankTransactionsProvider {
 	 */
 	String ACC_TYPE = "acctype";
 
+	/**
+	 * <p>
+	 * The account balance.
+	 * </p>
+	 * <p>
+	 * <i>Note! This will most likely differ from the total amount that can be
+	 * calculated from transactions.</i>
+	 * </p>
+	 */
+	String ACC_BALANCE = "balance";
+
 	/**
 	 * Defines if an account is hidden.
 	 */
@@ -172,7 +182,7 @@ public interface IBankTransactionsProvider {
 	 * </p>
 	 */
 	String[] BANK_ACCOUNT_PROJECTION = { BANK_ID, BANK_NAME, BANK_TYPE,
-			BANK_LAST_UPDATED, ACC_ID, ACC_NAME, ACC_TYPE };
+			BANK_LAST_UPDATED, ACC_ID, ACC_BALANCE, ACC_NAME, ACC_TYPE };
 
 	/**
 	 * <p>
@@ -183,6 +193,14 @@ public interface IBankTransactionsProvider {
 	 */
 	String NO_HIDDEN_ACCOUNTS_FILTER = ACC_HIDDEN + " = 0";
 
+	/**
+	 * <p>
+	 * Use this order by to make sure that all account belonging to one Bank
+	 * comes clustered.
+	 * </p>
+	 */
+	String ORDER_BY_BANK_ACCOUNT = BANK_ID + " DESC";
+
 	// ===================================TRANSACTION_FIELDS===============================
 	/**
 	 * <p>

commit 2e6d825c12521b55223920fd721f10925489ee94
Merge: f0d0935 af40fa0
Author: liato <x@x00.us>
Date:   Fri Jun 10 17:41:29 2011 -0700

    Merge pull request #88 from magnusart/master
    
    Changed accept button icon and merged with upstream

commit f0d09359fc05cb5a192421e79ec678562ae85894
Author: liato <x@x00.us>
Date:   Sat Jun 11 02:09:41 2011 +0200

    Fix for bank balance calculation. Closes #85.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 8b86e03..fbe7541 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -161,7 +161,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             BigDecimal bal = new BigDecimal(0); 
             for (Account account : accounts) {
                 if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
-                    if (!account.isHidden() || (account.getAliasfor() == null || account.getAliasfor().length() == 0)) {
+                    if (!account.isHidden() && (account.getAliasfor() == null || account.getAliasfor().length() == 0)) {
                         bal = bal.add(account.getBalance());
                     }
                 }

commit 45c75d7b18ea0f317fc83700d1c94f986f086d9b
Author: liato <x@x00.us>
Date:   Sat Jun 11 01:56:57 2011 +0200

    Fix Manifest. Add missing images. Enable all banks for testing.

diff --git .classpath .classpath
index ffbea45..e7b211d 100644
--- .classpath
+++ .classpath
@@ -3,7 +3,7 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="lib" path="/home/magnus/Dokument/JavaBibliotek/google-collect-1.0/google-collect-1.0.jar"/>
-	<classpathentry kind="lib" path="/home/magnus/Dokument/JavaBibliotek/commons-io-2.0.1/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
+	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index f3731bc..98644a2 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -122,7 +122,6 @@
 					android:path="com.liato.bankdroid" />
 			</intent-filter>
 		</receiver>
-<<<<<<< Updated upstream
 		<service
 			android:name=".liveview.LiveViewService"
 			android:label="LiveView plugin service">
@@ -148,22 +147,6 @@
 			android:multiprocess="false"
 			android:alwaysRetainTaskState="false"
 			android:theme="@style/BankdroidTheme">
-=======
-<<<<<<< Updated upstream
-	<provider 
-		android:name=".provider.BankTransactionsProvider" 
-		android:syncable="false"
-		android:multiprocess="true"
-		android:exported="true"
-		android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
-		android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS"/>
-	<activity 
-		android:name="PairApplicationsActivity" 
-		android:label="@string/app_name"
-		android:multiprocess="false"
-		android:alwaysRetainTaskState="false"
-		android:theme="@style/BankdroidTheme">
->>>>>>> Stashed changes
 			<intent-filter>
 				<action
 					android:name="com.liato.bankroid.PAIR_APPLICATION_ACTION" />
@@ -171,22 +154,7 @@
 					android:name="android.intent.category.DEFAULT" />
 			</intent-filter>
 		</activity>
-<<<<<<< Updated upstream
-	</application>
-
-=======
-</application>
-=======
-		<provider
-			android:name=".provider.BankTransactionsProvider"
-			android:syncable="false"
-			android:multiprocess="true"
-			android:exported="true"
-			android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider"
-			android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS" />
 	</application>
->>>>>>> Stashed changes
->>>>>>> Stashed changes
 	<uses-sdk
 		android:targetSdkVersion="4"
 		android:minSdkVersion="4" />
diff --git res/drawable-hdpi-v4/btn_check_label_background.9.png res/drawable-hdpi-v4/btn_check_label_background.9.png
new file mode 100644
index 0000000..97e6806
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_label_background.9.png differ
diff --git res/drawable-hdpi-v4/btn_check_off.png res/drawable-hdpi-v4/btn_check_off.png
new file mode 100644
index 0000000..d28e232
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_off.png differ
diff --git res/drawable-hdpi-v4/btn_check_off_disable.png res/drawable-hdpi-v4/btn_check_off_disable.png
new file mode 100644
index 0000000..922737e
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_off_disable.png differ
diff --git res/drawable-hdpi-v4/btn_check_off_disable_focused.png res/drawable-hdpi-v4/btn_check_off_disable_focused.png
new file mode 100644
index 0000000..992f0fe
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_off_disable_focused.png differ
diff --git res/drawable-hdpi-v4/btn_check_off_pressed.png res/drawable-hdpi-v4/btn_check_off_pressed.png
new file mode 100644
index 0000000..c6195ab
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_off_pressed.png differ
diff --git res/drawable-hdpi-v4/btn_check_off_selected.png res/drawable-hdpi-v4/btn_check_off_selected.png
new file mode 100644
index 0000000..d467769
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_off_selected.png differ
diff --git res/drawable-hdpi-v4/btn_check_on.png res/drawable-hdpi-v4/btn_check_on.png
new file mode 100644
index 0000000..9e87139
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_on.png differ
diff --git res/drawable-hdpi-v4/btn_check_on_disable.png res/drawable-hdpi-v4/btn_check_on_disable.png
new file mode 100644
index 0000000..6472087
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_on_disable.png differ
diff --git res/drawable-hdpi-v4/btn_check_on_disable_focused.png res/drawable-hdpi-v4/btn_check_on_disable_focused.png
new file mode 100644
index 0000000..58ba72d
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_on_disable_focused.png differ
diff --git res/drawable-hdpi-v4/btn_check_on_pressed.png res/drawable-hdpi-v4/btn_check_on_pressed.png
new file mode 100644
index 0000000..42b8edc
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_on_pressed.png differ
diff --git res/drawable-hdpi-v4/btn_check_on_selected.png res/drawable-hdpi-v4/btn_check_on_selected.png
new file mode 100644
index 0000000..7c94adf
Binary files /dev/null and res/drawable-hdpi-v4/btn_check_on_selected.png differ
diff --git res/drawable/btn_check.xml res/drawable/btn_check.xml
new file mode 100644
index 0000000..a876642
--- /dev/null
+++ res/drawable/btn_check.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<!-- Enabled states -->
+	<item
+		android:state_checked="true"
+		android:state_window_focused="false"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_on" />
+	<item
+		android:state_checked="false"
+		android:state_window_focused="false"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_off" />
+	<item
+		android:state_checked="true"
+		android:state_pressed="true"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_on_pressed" />
+	<item
+		android:state_checked="false"
+		android:state_pressed="true"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_off_pressed" />
+	<item
+		android:state_checked="true"
+		android:state_focused="true"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_on_selected" />
+	<item
+		android:state_checked="false"
+		android:state_focused="true"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_off_selected" />
+	<item
+		android:state_checked="false"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_off" />
+	<item
+		android:state_checked="true"
+		android:state_enabled="true"
+		android:drawable="@drawable/btn_check_on" />
+
+	<!-- Disabled states -->
+	<item
+		android:state_checked="true"
+		android:state_window_focused="false"
+		android:drawable="@drawable/btn_check_on_disable" />
+	<item
+		android:state_checked="false"
+		android:state_window_focused="false"
+		android:drawable="@drawable/btn_check_off_disable" />
+	<item
+		android:state_checked="true"
+		android:state_focused="true"
+		android:drawable="@drawable/btn_check_on_disable_focused" />
+	<item
+		android:state_checked="false"
+		android:state_focused="true"
+		android:drawable="@drawable/btn_check_off_disable_focused" />
+	<item
+		android:state_checked="false"
+		android:drawable="@drawable/btn_check_off_disable" />
+	<item
+		android:state_checked="true"
+		android:drawable="@drawable/btn_check_on_disable" />
+</selector>
+
+ 
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 5979308..517e204 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -236,20 +236,20 @@ public class BankFactory {
         banks.add(new Skandiabanken(context));
         //Not tested or not working
         //banks.add(new AmericanExpress(context));
-        //banks.add(new PlusGirot(context));
-        //banks.add(new Nordnetdirekt(context));
-        //banks.add(new Saab(context));
-        //banks.add(new Wallet(context));
-        //banks.add(new Chevrolet(context));
-        //banks.add(new Djurgarden(context));
-        //banks.add(new Quintessentially(context));
-        //banks.add(new Shell(context));
-        //banks.add(new Volkswagen(context));
-        //banks.add(new Audi(context));
-        //banks.add(new Preem(context));
-        //banks.add(new Seat(context));
-        //banks.add(new Skoda(context));
-        //banks.add(new IKEA(context));
+        banks.add(new PlusGirot(context));
+        banks.add(new Nordnetdirekt(context));
+        banks.add(new Saab(context));
+        banks.add(new Wallet(context));
+        banks.add(new Chevrolet(context));
+        banks.add(new Djurgarden(context));
+        banks.add(new Quintessentially(context));
+        banks.add(new Shell(context));
+        banks.add(new Volkswagen(context));
+        banks.add(new Audi(context));
+        banks.add(new Preem(context));
+        banks.add(new Seat(context));
+        banks.add(new Skoda(context));
+        banks.add(new IKEA(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));

commit af40fa0b1f3e900e5420c0bd5d5200c7b3431d2a
Merge: 589440a a3db7c6
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Fri Jun 10 22:51:53 2011 +0200

    Merge branch 'master' of https://github.com/liato/android-bankdroid

commit 589440a7dcb425ec8b9aee9169804a7f0212b733
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Fri Jun 10 22:50:55 2011 +0200

    Change accept icon to a different standard icon.
    Icon retrieved from: Olof Brickarp www.yay.se
    Change-Id: Iba4aa19b7e9ed48453a731c5f80388fef95e1fe4
    Signed-off-by: Magnus Andersson <magnus@magnusart.com>

diff --git res/drawable-hdpi-v4/button_accept.png res/drawable-hdpi-v4/button_accept.png
index c34249c..fdebd7e 100644
Binary files res/drawable-hdpi-v4/button_accept.png and res/drawable-hdpi-v4/button_accept.png differ

commit a3db7c6c35acb954ee59da305867b17a395f0de8
Author: liato <x@x00.us>
Date:   Fri Jun 10 02:02:17 2011 +0200

    Replaced pattern lock images.

diff --git AndroidManifest.xml AndroidManifest.xml
index 58cfebd..f3731bc 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -60,6 +60,7 @@
 			android:name=".lockpattern.ChooseLockPatternTutorial">
 		</activity>
 		<activity
+			android:theme="@style/BankdroidTheme"
 			android:label="@string/app_name"
 			android:name=".lockpattern.ConfirmLockPattern">
 		</activity>
@@ -121,6 +122,7 @@
 					android:path="com.liato.bankdroid" />
 			</intent-filter>
 		</receiver>
+<<<<<<< Updated upstream
 		<service
 			android:name=".liveview.LiveViewService"
 			android:label="LiveView plugin service">
@@ -146,6 +148,22 @@
 			android:multiprocess="false"
 			android:alwaysRetainTaskState="false"
 			android:theme="@style/BankdroidTheme">
+=======
+<<<<<<< Updated upstream
+	<provider 
+		android:name=".provider.BankTransactionsProvider" 
+		android:syncable="false"
+		android:multiprocess="true"
+		android:exported="true"
+		android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
+		android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS"/>
+	<activity 
+		android:name="PairApplicationsActivity" 
+		android:label="@string/app_name"
+		android:multiprocess="false"
+		android:alwaysRetainTaskState="false"
+		android:theme="@style/BankdroidTheme">
+>>>>>>> Stashed changes
 			<intent-filter>
 				<action
 					android:name="com.liato.bankroid.PAIR_APPLICATION_ACTION" />
@@ -153,8 +171,22 @@
 					android:name="android.intent.category.DEFAULT" />
 			</intent-filter>
 		</activity>
+<<<<<<< Updated upstream
 	</application>
 
+=======
+</application>
+=======
+		<provider
+			android:name=".provider.BankTransactionsProvider"
+			android:syncable="false"
+			android:multiprocess="true"
+			android:exported="true"
+			android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider"
+			android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS" />
+	</application>
+>>>>>>> Stashed changes
+>>>>>>> Stashed changes
 	<uses-sdk
 		android:targetSdkVersion="4"
 		android:minSdkVersion="4" />
diff --git res/drawable-hdpi-v4/btn_code_lock_default.png res/drawable-hdpi-v4/btn_code_lock_default.png
index df3137f..6feeda8 100644
Binary files res/drawable-hdpi-v4/btn_code_lock_default.png and res/drawable-hdpi-v4/btn_code_lock_default.png differ
diff --git res/drawable-hdpi-v4/btn_code_lock_touched.png res/drawable-hdpi-v4/btn_code_lock_touched.png
index bf9e46a..a97a955 100644
Binary files res/drawable-hdpi-v4/btn_code_lock_touched.png and res/drawable-hdpi-v4/btn_code_lock_touched.png differ
diff --git res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png
new file mode 100644
index 0000000..72b84e2
Binary files /dev/null and res/drawable-hdpi-v4/indicator_code_lock_drag_direction_green_up.png differ
diff --git res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png
new file mode 100644
index 0000000..ef21b32
Binary files /dev/null and res/drawable-hdpi-v4/indicator_code_lock_drag_direction_red_up.png differ
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png
new file mode 100644
index 0000000..b6ebe4b
Binary files /dev/null and res/drawable-hdpi-v4/indicator_code_lock_point_area_default.png differ
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png
new file mode 100644
index 0000000..e8a0bb0
Binary files /dev/null and res/drawable-hdpi-v4/indicator_code_lock_point_area_green.png differ
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png
new file mode 100644
index 0000000..a844745
Binary files /dev/null and res/drawable-hdpi-v4/indicator_code_lock_point_area_green2.png differ
diff --git res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png
new file mode 100644
index 0000000..f990fb8
Binary files /dev/null and res/drawable-hdpi-v4/indicator_code_lock_point_area_red.png differ
diff --git res/drawable/indicator_code_lock_drag_direction_green_up.png res/drawable/indicator_code_lock_drag_direction_green_up.png
deleted file mode 100644
index ef91dc4..0000000
Binary files res/drawable/indicator_code_lock_drag_direction_green_up.png and /dev/null differ
diff --git res/drawable/indicator_code_lock_drag_direction_red_up.png res/drawable/indicator_code_lock_drag_direction_red_up.png
deleted file mode 100644
index f3d4204..0000000
Binary files res/drawable/indicator_code_lock_drag_direction_red_up.png and /dev/null differ
diff --git res/drawable/indicator_code_lock_point_area_default.png res/drawable/indicator_code_lock_point_area_default.png
deleted file mode 100644
index 4e88b37..0000000
Binary files res/drawable/indicator_code_lock_point_area_default.png and /dev/null differ
diff --git res/drawable/indicator_code_lock_point_area_green.png res/drawable/indicator_code_lock_point_area_green.png
deleted file mode 100644
index 8020846..0000000
Binary files res/drawable/indicator_code_lock_point_area_green.png and /dev/null differ
diff --git res/drawable/indicator_code_lock_point_area_red.png res/drawable/indicator_code_lock_point_area_red.png
deleted file mode 100644
index b7aee1b..0000000
Binary files res/drawable/indicator_code_lock_point_area_red.png and /dev/null differ
diff --git res/layout/choose_lock_pattern.xml res/layout/choose_lock_pattern.xml
index 665599e..59b75d6 100644
--- res/layout/choose_lock_pattern.xml
+++ res/layout/choose_lock_pattern.xml
@@ -18,8 +18,7 @@
     android:id="@+id/topLayout"
     android:orientation="vertical"
     android:layout_width="wrap_content"
-    android:layout_height="fill_parent"
-    android:background="@color/black">
+    android:layout_height="fill_parent" android:background="#00000000">
 
     <TextView android:id="@+id/headerText"
         android:layout_width="fill_parent"
diff --git res/layout/confirm_lock_pattern.xml res/layout/confirm_lock_pattern.xml
index c48d232..a5c4f01 100644
--- res/layout/confirm_lock_pattern.xml
+++ res/layout/confirm_lock_pattern.xml
@@ -18,8 +18,7 @@
     android:id="@+id/topLayout"
     android:orientation="vertical"
     android:layout_width="wrap_content"
-    android:layout_height="fill_parent"
-    android:background="@drawable/background_repeat">
+    android:layout_height="fill_parent" android:background="#00000000">
 
     <TextView android:id="@+id/headerText"
         android:layout_width="fill_parent"
diff --git res/values/styles.xml res/values/styles.xml
index 7751164..cb77222 100644
--- res/values/styles.xml
+++ res/values/styles.xml
@@ -61,6 +61,13 @@
 	</style>
     <style name="WindowTitleBackground" parent="android:WindowTitleBackground">    
         <item name="android:background">@android:color/transparent</item>        
-    </style>    
+    </style>
+    <style name="listViewStyle" parent="@android:style/Widget.ListView">
+    	<item name="android:cacheColorHint">@android:color/transparent</item>  
+    </style>
+    <style name="checkBoxStyle" parent="@android:style/Widget.CompoundButton.CheckBox">
+    	<item name="android:button">@drawable/btn_check</item>
+    	<item name="android:background">@drawable/btn_check_label_background</item>
+    </style>
  	
 </resources>
diff --git res/values/themes.xml res/values/themes.xml
index e606b55..959c839 100644
--- res/values/themes.xml
+++ res/values/themes.xml
@@ -2,10 +2,16 @@
 <resources>
 	<style
 		name="BankdroidTheme"
-		parent="android:Theme">
+		parent="android:Theme.Black">
 		<item
 			name="android:windowTitleSize">40dp</item>
 		<item
 			name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item>
+		<item
+			name="android:windowBackground">@drawable/background_repeat</item>
+		<item
+			name="android:listViewStyle">@style/listViewStyle</item>
+		<item
+			name="android:checkboxStyle">@style/checkBoxStyle</item>
 	</style>
 </resources>
\ No newline at end of file
diff --git res/xml/settings.xml res/xml/settings.xml
index 06bbdf8..f4abf5f 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -95,18 +95,18 @@
 			android:title="@string/vibrate_title"
 			android:summary="@string/vibrate_summary"
 			android:dependency="notify_on_change" />
+		<CheckBoxPreference
+			android:key="notify_delta_only"
+			android:defaultValue="false"
+			android:title="@string/vibrate_title"
+			android:summary="@string/vibrate_summary"
+			android:dependency="notify_on_change" />
 		<EditTextPreference
 			android:key="notify_min_delta"
 			android:defaultValue="0"
 			android:title="@string/notify_min_delta_title"
 			android:summary="@string/notify_min_delta_summary"
 			android:dependency="notify_on_change" />
-		<CheckBoxPreference
-			android:key="notify_with_vibration"
-			android:defaultValue="true"
-			android:title="@string/vibrate_title"
-			android:summary="@string/vibrate_summary"
-			android:dependency="notify_on_change" />
 		<RingtonePreference
 			android:key="notification_sound"
 			android:title="@string/notification_sound_title"
diff --git src/com/liato/bankdroid/lockpattern/LockPatternView.java src/com/liato/bankdroid/lockpattern/LockPatternView.java
index f7a5d04..a4a40f7 100644
--- src/com/liato/bankdroid/lockpattern/LockPatternView.java
+++ src/com/liato/bankdroid/lockpattern/LockPatternView.java
@@ -20,6 +20,8 @@ package com.liato.bankdroid.lockpattern;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.liato.bankdroid.R;
+
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -241,25 +243,26 @@ public class LockPatternView extends View {
         mPathPaint.setStrokeCap(Paint.Cap.ROUND);
 
         // lot's of bitmaps!
-        /*
+        
         mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default);
         mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched);
         mBitmapCircleDefault = getBitmapFor(R.drawable.indicator_code_lock_point_area_default);
+        
         mBitmapCircleGreen = getBitmapFor(R.drawable.indicator_code_lock_point_area_green);
         mBitmapCircleRed = getBitmapFor(R.drawable.indicator_code_lock_point_area_red);
 
         mBitmapArrowGreenUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_green_up);
         mBitmapArrowRedUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_red_up);
-        */
         
-        mBitmapBtnDefault = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_default", null, null));
-        mBitmapBtnTouched = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_touched", null, null));
-        mBitmapCircleDefault = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_default", null, null));
-        mBitmapCircleGreen = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_green", null, null));
-        mBitmapCircleRed = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_red", null, null));
         
-        mBitmapArrowGreenUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_green_up", null, null));
-        mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));
+        //mBitmapBtnDefault = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_default", null, null));
+        //mBitmapBtnTouched = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_touched", null, null));
+        //mBitmapCircleDefault = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_default", null, null));
+        //mBitmapCircleGreen = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_green", null, null));
+        //mBitmapCircleRed = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_red", null, null));
+        
+        //mBitmapArrowGreenUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_green_up", null, null));
+        //mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));
 
         // we assume all bitmaps have the same size
         mBitmapWidth = mBitmapBtnDefault.getWidth();

commit ff84d02883f722983cd264c4c9362212c0445485
Author: liato <x@x00.us>
Date:   Fri Jun 10 01:57:28 2011 +0200

    Fix merge issues.

diff --git src/com/liato/bankdroid/liveview/LiveViewService.java src/com/liato/bankdroid/liveview/LiveViewService.java
index 2e4946c..c47affa 100644
--- src/com/liato/bankdroid/liveview/LiveViewService.java
+++ src/com/liato/bankdroid/liveview/LiveViewService.java
@@ -1,263 +1,263 @@
-/*
- * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Copyright (c) 2010 Sony Ericsson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- *
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.liato.bankdroid.liveview;
-
-import com.liato.bankdroid.MainActivity;
-import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
-import com.sonyericsson.extras.liveview.IPluginServiceV1;
-
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Implementation of the Live View plug-in service.
- * 
- * @author firetech
- */
-public class LiveViewService extends Service {
-	// Announce intent information keys
-	public static final String INTENT_EXTRA_ANNOUNCE = "isAnnounce";
-	public static final String INTENT_EXTRA_TITLE = "title";
-	public static final String INTENT_EXTRA_TEXT = "text";
-
-    // Template menu icon file name.
-    private static final String MENU_ICON_FILENAME = "plugin_icon.png";
-
-    // There should only be one instance of the service
-    protected static boolean alreadyRunning = false;
-
-    // Plugin name
-    protected String mPluginName = null;
-
-    // Current plugin Id
-    protected int mPluginId = 0;
-    
-    // Reference to LiveView application stub
-    private IPluginServiceV1 mLiveView = null;
-
-    // Menu icon that will be shown in LiveView unit
-    protected String mMenuIcon = null;
-
-    /**
-     * LiveView callback interface method.
-     */
-    private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
-        Handler mCallbackHandler = new Handler();
-
-        @Override
-        public String getPluginName() throws RemoteException {
-            return mPluginName;
-        }
-
-        @Override
-        public void openInPhone(final String openInPhoneAction) throws RemoteException {
-            mCallbackHandler.post(new Runnable() {
-                public void run() {
-                    LiveViewService.this.openInPhone(openInPhoneAction);
-                }
-            });
-        }
-
-		//Unused methods required by API.
-		public void startPlugin() throws RemoteException {}
-		public void stopPlugin() throws RemoteException {}
-		public void onUnregistered() throws RemoteException {}
-		public void displayCaps(int displayWidthPixels, int displayHeigthPixels)
-				throws RemoteException {}
-		public void button(String buttonType, boolean doublepress,
-				boolean longpress) throws RemoteException {}
-		public void screenMode(int screenMode) throws RemoteException {}
-    }
-
-    /**
-     * Check if service is already running.
-     * 
-     * @return running?
-     */
-    public static boolean isAlreadyRunning() {
-        return alreadyRunning;
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
-
-        // Load menu icon
-        int iconId = PluginUtils.getDynamicResourceId(this, "icon", "drawable");
-        mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onDestroy.");
-
-        // Unbind from LiveView service
-        if (mServiceConnection != null) {
-            unbindService(mServiceConnection);
-        }
-
-        // No longer a running service
-        alreadyRunning = false;
-    }
-
-	@Override
-	public void onStart(Intent intent, int startId) {
-        super.onStart(intent, startId);
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
-        
-		if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
-			Bundle extras = intent.getExtras();
-			if (extras != null) {
-				try {
-					if(mLiveView != null) {
-						mLiveView.sendAnnounce(mPluginId, mMenuIcon, extras.getString(INTENT_EXTRA_TITLE), 
-					    		extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(), "");
-						Log.d(PluginConstants.LOG_TAG, "Announce sent to LiveView Application");
-					} else {
-						Log.d(PluginConstants.LOG_TAG, "LiveView Application not reachable");
-					}
-				} catch(Exception e) {
-					Log.e(PluginConstants.LOG_TAG, "Failed to send announce", e);
-				}
-			}
-			
-		} else {
-			// We end up here when LiveView Application probes the plugin
-	        if (isAlreadyRunning()) {
-	            Log.d(PluginConstants.LOG_TAG, "Already started.");
-	        } else {
-	            // Init
-	            mPluginName = PluginUtils.getDynamicResourceString(this,
-	                    PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
-
-	            // Bind to LiveView
-	            connectToLiveView();
-
-	            // Singleton
-	            alreadyRunning = true;
-	        }
-		}
-	}
-
-    @Override
-    public IBinder onBind(final Intent intent) {
-        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onBind.");
-        return null;
-    }
-
-    /**
-     * The service connection that is used to bind the plugin to the LiveView
-     * service.
-     * 
-     * When connected to the service, the plugin is registered. When
-     * disconnected to the service, the plugin is unregistered.
-     */
-    private ServiceConnection mServiceConnection = new ServiceConnection() {
-
-        @Override
-        public void onServiceConnected(final ComponentName className, IBinder service) {
-            Log.d(PluginConstants.LOG_TAG,
-                    "Enter LiveViewService.ServiceConnection.onServiceConnected.");
-
-            mLiveView = IPluginServiceV1.Stub.asInterface(service);
-
-            // Init adapter
-            LiveViewCallback lvCallback = new LiveViewCallback();
-
-            // Install plugin
-            try {
-            	if(mLiveView != null) {
-	                // Register
-	                mPluginId = mLiveView.register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
-	                Log.d(PluginConstants.LOG_TAG, "Plugin registered with id: " + mPluginId);
-	            }
-            } catch (RemoteException re) {
-                Log.e(PluginConstants.LOG_TAG, "Failed to install plugin. Stop self.");
-                stopSelf();
-            }
-
-            Log.d(PluginConstants.LOG_TAG, "Plugin registered. mPluginId: " + mPluginId);
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName className) {
-            Log.d(PluginConstants.LOG_TAG,
-                    "Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
-            stopSelf();
-        }
-
-    };
-
-    /**
-     * Connects to the LiveView service.
-     */
-    private void connectToLiveView() {
-        boolean result = bindService(new Intent(PluginConstants.LIVEVIEW_SERVICE_BIND_INTENT),
-                mServiceConnection, 0);
-        if (result) {
-            Log.d(PluginConstants.LOG_TAG, "Bound to LiveView.");
-        } else {
-            Log.d(PluginConstants.LOG_TAG, "No bind.");
-            stopSelf();
-        }
-    }
-
-	/**
-	 * When a user presses the "open in phone" button on the LiveView device, this method is called.
-	 * 
-	 * Opens the MainActivity on the phone.
-	 */
-	protected void openInPhone(String openInPhoneAction) {
-		Log.d(PluginConstants.LOG_TAG, "openInPhone");
-		Intent i = new Intent(this, MainActivity.class)
-			.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-		startActivity(i);
-	}
-
-}
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ *
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+import com.liato.bankdroid.MainActivity;
+import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
+import com.sonyericsson.extras.liveview.IPluginServiceV1;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Implementation of the Live View plug-in service.
+ * 
+ * @author firetech
+ */
+public class LiveViewService extends Service {
+	// Announce intent information keys
+	public static final String INTENT_EXTRA_ANNOUNCE = "isAnnounce";
+	public static final String INTENT_EXTRA_TITLE = "title";
+	public static final String INTENT_EXTRA_TEXT = "text";
+
+    // Template menu icon file name.
+    private static final String MENU_ICON_FILENAME = "plugin_icon.png";
+
+    // There should only be one instance of the service
+    protected static boolean alreadyRunning = false;
+
+    // Plugin name
+    protected String mPluginName = null;
+
+    // Current plugin Id
+    protected int mPluginId = 0;
+    
+    // Reference to LiveView application stub
+    private IPluginServiceV1 mLiveView = null;
+
+    // Menu icon that will be shown in LiveView unit
+    protected String mMenuIcon = null;
+
+    /**
+     * LiveView callback interface method.
+     */
+    private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
+        Handler mCallbackHandler = new Handler();
+
+        @Override
+        public String getPluginName() throws RemoteException {
+            return mPluginName;
+        }
+
+        @Override
+        public void openInPhone(final String openInPhoneAction) throws RemoteException {
+            mCallbackHandler.post(new Runnable() {
+                public void run() {
+                    LiveViewService.this.openInPhone(openInPhoneAction);
+                }
+            });
+        }
+
+		//Unused methods required by API.
+		public void startPlugin() throws RemoteException {}
+		public void stopPlugin() throws RemoteException {}
+		public void onUnregistered() throws RemoteException {}
+		public void displayCaps(int displayWidthPixels, int displayHeigthPixels)
+				throws RemoteException {}
+		public void button(String buttonType, boolean doublepress,
+				boolean longpress) throws RemoteException {}
+		public void screenMode(int screenMode) throws RemoteException {}
+    }
+
+    /**
+     * Check if service is already running.
+     * 
+     * @return running?
+     */
+    public static boolean isAlreadyRunning() {
+        return alreadyRunning;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
+
+        // Load menu icon
+        int iconId = PluginUtils.getDynamicResourceId(this, "icon", "drawable");
+        mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onDestroy.");
+
+        // Unbind from LiveView service
+        if (mServiceConnection != null) {
+            unbindService(mServiceConnection);
+        }
+
+        // No longer a running service
+        alreadyRunning = false;
+    }
+
+	@Override
+	public void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
+        
+		if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
+			Bundle extras = intent.getExtras();
+			if (extras != null) {
+				try {
+					if(mLiveView != null) {
+						mLiveView.sendAnnounce(mPluginId, mMenuIcon, extras.getString(INTENT_EXTRA_TITLE), 
+					    		extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(), "");
+						Log.d(PluginConstants.LOG_TAG, "Announce sent to LiveView Application");
+					} else {
+						Log.d(PluginConstants.LOG_TAG, "LiveView Application not reachable");
+					}
+				} catch(Exception e) {
+					Log.e(PluginConstants.LOG_TAG, "Failed to send announce", e);
+				}
+			}
+			
+		} else {
+			// We end up here when LiveView Application probes the plugin
+	        if (isAlreadyRunning()) {
+	            Log.d(PluginConstants.LOG_TAG, "Already started.");
+	        } else {
+	            // Init
+	            mPluginName = PluginUtils.getDynamicResourceString(this,
+	                    PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+
+	            // Bind to LiveView
+	            connectToLiveView();
+
+	            // Singleton
+	            alreadyRunning = true;
+	        }
+		}
+	}
+
+    @Override
+    public IBinder onBind(final Intent intent) {
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onBind.");
+        return null;
+    }
+
+    /**
+     * The service connection that is used to bind the plugin to the LiveView
+     * service.
+     * 
+     * When connected to the service, the plugin is registered. When
+     * disconnected to the service, the plugin is unregistered.
+     */
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+
+        @Override
+        public void onServiceConnected(final ComponentName className, IBinder service) {
+            Log.d(PluginConstants.LOG_TAG,
+                    "Enter LiveViewService.ServiceConnection.onServiceConnected.");
+
+            mLiveView = IPluginServiceV1.Stub.asInterface(service);
+
+            // Init adapter
+            LiveViewCallback lvCallback = new LiveViewCallback();
+
+            // Install plugin
+            try {
+            	if(mLiveView != null) {
+	                // Register
+	                mPluginId = mLiveView.register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
+	                Log.d(PluginConstants.LOG_TAG, "Plugin registered with id: " + mPluginId);
+	            }
+            } catch (RemoteException re) {
+                Log.e(PluginConstants.LOG_TAG, "Failed to install plugin. Stop self.");
+                stopSelf();
+            }
+
+            Log.d(PluginConstants.LOG_TAG, "Plugin registered. mPluginId: " + mPluginId);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            Log.d(PluginConstants.LOG_TAG,
+                    "Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
+            stopSelf();
+        }
+
+    };
+
+    /**
+     * Connects to the LiveView service.
+     */
+    private void connectToLiveView() {
+        boolean result = bindService(new Intent(PluginConstants.LIVEVIEW_SERVICE_BIND_INTENT),
+                mServiceConnection, 0);
+        if (result) {
+            Log.d(PluginConstants.LOG_TAG, "Bound to LiveView.");
+        } else {
+            Log.d(PluginConstants.LOG_TAG, "No bind.");
+            stopSelf();
+        }
+    }
+
+	/**
+	 * When a user presses the "open in phone" button on the LiveView device, this method is called.
+	 * 
+	 * Opens the MainActivity on the phone.
+	 */
+	protected void openInPhone(String openInPhoneAction) {
+		Log.d(PluginConstants.LOG_TAG, "openInPhone");
+		Intent i = new Intent(this, MainActivity.class)
+			.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+		startActivity(i);
+	}
+
+}
diff --git src/com/liato/bankdroid/liveview/PluginConstants.java src/com/liato/bankdroid/liveview/PluginConstants.java
index a1da367..58f337f 100644
--- src/com/liato/bankdroid/liveview/PluginConstants.java
+++ src/com/liato/bankdroid/liveview/PluginConstants.java
@@ -1,65 +1,65 @@
-/*
- * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Copyright (c) 2010 Sony Ericsson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * 
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.liato.bankdroid.liveview;
-
-/**
- * Plugin common constants.
- * 
- * @author firetech
- */
-public final class PluginConstants {
-    private PluginConstants() {}
-
-    // Broadcast receiver constants
-    public static final String BROADCAST_COMMAND = "CMD";
-    public static final String BROADCAST_COMMAND_PREFERENCES = "preferences";
-    public static final String BROADCAST_COMMAND_START = "start";
-    public static final String BROADCAST_COMMAND_PLUGIN_NAME = "pluginName";
-
-    // Resource string constants
-    public static final String RESOURCE_STRING_PLUGIN_NAME = "app_name";
-
-    // LiveView Plugin interface intents
-    public static final String LIVEVIEW_SERVICE_BIND_INTENT = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
-    public static final String LIVEVIEW_BROADCAST_LAUNCH_EVENT = "com.sonyericsson.extras.liveview.LAUNCH_PLUGIN";
-
-    // Log tag
-    public static final String LOG_TAG = "BankDroidLiveViewPlugin";
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+/**
+ * Plugin common constants.
+ * 
+ * @author firetech
+ */
+public final class PluginConstants {
+    private PluginConstants() {}
+
+    // Broadcast receiver constants
+    public static final String BROADCAST_COMMAND = "CMD";
+    public static final String BROADCAST_COMMAND_PREFERENCES = "preferences";
+    public static final String BROADCAST_COMMAND_START = "start";
+    public static final String BROADCAST_COMMAND_PLUGIN_NAME = "pluginName";
+
+    // Resource string constants
+    public static final String RESOURCE_STRING_PLUGIN_NAME = "app_name";
+
+    // LiveView Plugin interface intents
+    public static final String LIVEVIEW_SERVICE_BIND_INTENT = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
+    public static final String LIVEVIEW_BROADCAST_LAUNCH_EVENT = "com.sonyericsson.extras.liveview.LAUNCH_PLUGIN";
+
+    // Log tag
+    public static final String LOG_TAG = "BankDroidLiveViewPlugin";
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/liveview/PluginReceiver.java src/com/liato/bankdroid/liveview/PluginReceiver.java
index 7859f70..0a30876 100644
--- src/com/liato/bankdroid/liveview/PluginReceiver.java
+++ src/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -1,89 +1,89 @@
-/*
- * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Copyright (c) 2010 Sony Ericsson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * 
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.liato.bankdroid.liveview;
-
-import com.liato.bankdroid.SettingsActivity;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-/**
- * Receives broadcast intents from LiveView service.
- * 
- * @author firetech
- */
-public class PluginReceiver extends BroadcastReceiver {
-	
-	@Override
-	public void onReceive(Context context, Intent intent) {
-		String command = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND);
-		Log.d(PluginConstants.LOG_TAG, "Received command: " + command);
-		
-		if(command == null) {
-			return;
-		}
-		
-		if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_PREFERENCES)) {
-			String pluginName = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND_PLUGIN_NAME);
-			String myPluginName = PluginUtils.getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
-
-			if(pluginName != null && pluginName.contentEquals(myPluginName)) {
-				Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
-				
-				Intent prefsIntent = new Intent(context, SettingsActivity.class);
-				prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-				context.startActivity(prefsIntent);
-			}
-		}
-		else if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_START)) {
-			if(LiveViewService.isAlreadyRunning()) {
-			    Log.d(PluginConstants.LOG_TAG, "Service is already running.");
-			} else {
-				Log.d(PluginConstants.LOG_TAG, "Starting service!");
-				
-				context.startService(new Intent(context, LiveViewService.class));
-			}
-		}
-		
-	}
-	
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+import com.liato.bankdroid.SettingsActivity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * Receives broadcast intents from LiveView service.
+ * 
+ * @author firetech
+ */
+public class PluginReceiver extends BroadcastReceiver {
+	
+	@Override
+	public void onReceive(Context context, Intent intent) {
+		String command = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND);
+		Log.d(PluginConstants.LOG_TAG, "Received command: " + command);
+		
+		if(command == null) {
+			return;
+		}
+		
+		if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_PREFERENCES)) {
+			String pluginName = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND_PLUGIN_NAME);
+			String myPluginName = PluginUtils.getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+
+			if(pluginName != null && pluginName.contentEquals(myPluginName)) {
+				Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
+				
+				Intent prefsIntent = new Intent(context, SettingsActivity.class);
+				prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+				context.startActivity(prefsIntent);
+			}
+		}
+		else if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_START)) {
+			if(LiveViewService.isAlreadyRunning()) {
+			    Log.d(PluginConstants.LOG_TAG, "Service is already running.");
+			} else {
+				Log.d(PluginConstants.LOG_TAG, "Starting service!");
+				
+				context.startService(new Intent(context, LiveViewService.class));
+			}
+		}
+		
+	}
+	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/liveview/PluginUtils.java src/com/liato/bankdroid/liveview/PluginUtils.java
index 4803295..d14a0bb 100644
--- src/com/liato/bankdroid/liveview/PluginUtils.java
+++ src/com/liato/bankdroid/liveview/PluginUtils.java
@@ -1,118 +1,118 @@
-/*
- * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Copyright (c) 2010 Sony Ericsson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * 
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.liato.bankdroid.liveview;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * Utils for LiveView plugin.
- * 
- * @author firetech
- */
-public final class PluginUtils {
-    
-    private PluginUtils() {
-        
-    }
-    
-    /**
-     * Stores icon to phone file system
-     * 
-     * @param resources Reference to project resources
-     * @param resource Reference to specific resource
-     * @param fileName The icon file name
-     */
-    public static String storeIconToFile(Context ctx, Resources resources, int resource, String fileName) {
-        Log.d(PluginConstants.LOG_TAG, "Store icon to file.");
-        
-        if(resources == null) {
-            return "";
-        }
-        
-        Bitmap bitmap = BitmapFactory.decodeStream(resources.openRawResource(resource));
-        
-        try {
-            FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
-            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
-            fos.flush();
-            fos.close(); 
-        } 
-        catch (IOException e) { 
-            Log.e(PluginConstants.LOG_TAG, "Failed to store to device", e);
-        }
-        
-        File iconFile = ctx.getFileStreamPath(fileName);
-        Log.d(PluginConstants.LOG_TAG, "Icon stored. " + iconFile.getAbsolutePath());
-        
-        return iconFile.getAbsolutePath();
-    }
-    
-    /**
-     * Gets resource id dynamically
-     * 
-     * @param context
-     * @param resourceName
-     * @param resourceType
-     * @return
-     */
-    public static int getDynamicResourceId(Context context, String resourceName, String resourceType) {
-        return context.getResources().getIdentifier(resourceName, resourceType, context.getPackageName());
-    }
-    
-    /**
-     * Gets resource string dynamically
-     * 
-     * @param context
-     * @param resourceName
-     * @return
-     */
-    public static String getDynamicResourceString(Context context, String resourceName) {
-        int resourceId = getDynamicResourceId(context, resourceName, "string");
-        return context.getString(resourceId);
-    }
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Utils for LiveView plugin.
+ * 
+ * @author firetech
+ */
+public final class PluginUtils {
+    
+    private PluginUtils() {
+        
+    }
+    
+    /**
+     * Stores icon to phone file system
+     * 
+     * @param resources Reference to project resources
+     * @param resource Reference to specific resource
+     * @param fileName The icon file name
+     */
+    public static String storeIconToFile(Context ctx, Resources resources, int resource, String fileName) {
+        Log.d(PluginConstants.LOG_TAG, "Store icon to file.");
+        
+        if(resources == null) {
+            return "";
+        }
+        
+        Bitmap bitmap = BitmapFactory.decodeStream(resources.openRawResource(resource));
+        
+        try {
+            FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
+            fos.flush();
+            fos.close(); 
+        } 
+        catch (IOException e) { 
+            Log.e(PluginConstants.LOG_TAG, "Failed to store to device", e);
+        }
+        
+        File iconFile = ctx.getFileStreamPath(fileName);
+        Log.d(PluginConstants.LOG_TAG, "Icon stored. " + iconFile.getAbsolutePath());
+        
+        return iconFile.getAbsolutePath();
+    }
+    
+    /**
+     * Gets resource id dynamically
+     * 
+     * @param context
+     * @param resourceName
+     * @param resourceType
+     * @return
+     */
+    public static int getDynamicResourceId(Context context, String resourceName, String resourceType) {
+        return context.getResources().getIdentifier(resourceName, resourceType, context.getPackageName());
+    }
+    
+    /**
+     * Gets resource string dynamically
+     * 
+     * @param context
+     * @param resourceName
+     * @return
+     */
+    public static String getDynamicResourceString(Context context, String resourceName) {
+        int resourceId = getDynamicResourceId(context, resourceName, "string");
+        return context.getString(resourceId);
+    }
 }
\ No newline at end of file
diff --git src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
index 43c808e..0a1a0d0 100644
--- src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
+++ src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
@@ -1,56 +1,56 @@
-/*
- * Copyright (c) 2010 Sony Ericsson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * 
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.sonyericsson.extras.liveview;
-
-interface IPluginServiceCallbackV1 {
-	// Start the plugin.
-	void startPlugin();
-	
-	// Stop the plugin.
-	// A stopped plugin should stop its polling, but can stay alive
-	void stopPlugin();
-	
-	// Should return the name the plugin used to register itself with
-	String getPluginName();
-
- 	// Give the action needed to open the current announcement on the phone
-	// such as a view in browser action or something else that your application
-	// responds to.
-	void openInPhone(in String openInPhoneAction);      
-
-	// Kicked out by framework. Implement this with stopSelf()
-	void onUnregistered();
-	
-	// displayWidthPixels equals 0 and displayheigthPixels equals 0
-	// means no available device is attached, or has no display
-	void displayCaps(in int displayWidthPixels, in int displayHeigthPixels);
-	
-	// Button event - note that doublepress is not implemented for the V1
-	// interface but still left here for compatibility reasons.
-	void button(in String buttonType, in boolean doublepress, in boolean longpress);
-
-	// Screen mode changed event - this notifies the current active sandbox plugin that the screen has been 
-	// turned on or off. 0 = Screen OFF, 1 = Screen ON
-	void screenMode(in int screenMode);
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.sonyericsson.extras.liveview;
+
+interface IPluginServiceCallbackV1 {
+	// Start the plugin.
+	void startPlugin();
+	
+	// Stop the plugin.
+	// A stopped plugin should stop its polling, but can stay alive
+	void stopPlugin();
+	
+	// Should return the name the plugin used to register itself with
+	String getPluginName();
+
+ 	// Give the action needed to open the current announcement on the phone
+	// such as a view in browser action or something else that your application
+	// responds to.
+	void openInPhone(in String openInPhoneAction);      
+
+	// Kicked out by framework. Implement this with stopSelf()
+	void onUnregistered();
+	
+	// displayWidthPixels equals 0 and displayheigthPixels equals 0
+	// means no available device is attached, or has no display
+	void displayCaps(in int displayWidthPixels, in int displayHeigthPixels);
+	
+	// Button event - note that doublepress is not implemented for the V1
+	// interface but still left here for compatibility reasons.
+	void button(in String buttonType, in boolean doublepress, in boolean longpress);
+
+	// Screen mode changed event - this notifies the current active sandbox plugin that the screen has been 
+	// turned on or off. 0 = Screen OFF, 1 = Screen ON
+	void screenMode(in int screenMode);
 }
\ No newline at end of file
diff --git src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
index 8ab48f9..07985aa 100644
--- src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
+++ src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
@@ -1,113 +1,113 @@
-/*
- * Copyright (c) 2010 Sony Ericsson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * 
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.sonyericsson.extras.liveview;
-
-import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
-
-interface IPluginServiceV1 {
-
-	// Register to the Liveview application
-	// cb - callback instance
-    // imageMenu - path to the menu bitmap
-    // pluginName - name of the plugin - must be unique
-    // selectableMenu - is set to true if controlling display and getting buttons. Set to false to only handle announces
-    // packageName - the package name (use getPackageName()).
-    // returns id of plugin in system, 0 means that the registration failed
-    int register(in IPluginServiceCallbackV1 cb, in String imageMenu, in String pluginName, in boolean selectableMenu, in String packageName);
-    
-    // This method should be called if the application/service is uninstalled using the phone application handler 
-    // id - the plugin id received in registerPlugin
-    // cb - the callback
-    void unregister( in int id, in IPluginServiceCallbackV1 cb);
-    
-    // Used to send announcements to the device - can only be used when _not_ registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    // imageAnnounce - the path to the announce bitmap
-    // header - header text
-    // body - body text
-    // time - timestamp for this announce in milliseconds
-    // openInPhoneAction - a tag to use for openInPhone callback. Set to null when announce not selectable
-    void sendAnnounce(in int id, in String imageAnnounce, in String header, in String body, in long timestamp, in String openInPhoneAction);
-    
-    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    // x - from left side
-    // y - from top side
-    // image - the path to the image on file system
-    void sendImage(in int id, in int x, in int y, in String image);
-
-    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    // x - from left side
-    // y - from top side
-    // bitmapData - the bitmap to send
-    void sendImageAsBitmap(in int id, in int x, in int y, in Bitmap bitmapData);
-    
-    // Clears the display, for example if several images are sent while in sandbox mode - Can only be used if you registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    void clearDisplay(in int id);
-    
-    // Provide the Liveview application with means to launch the service 
-    // that shoul receive and send data in sandbox mode - Must be called if you registered as "selectableMenu"
-    // launcherIntent - the intent to start the plugin service
-    // pluginName - the name of the plugin, must match the name you registered with! 
-    // returns -1 for failure, 0 for already registered, anything else for success
-    int notifyInstalled(in String launcherIntent, in String pluginName);
-
-    // Controls LED - can only be used if you registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    // rgb565 - the color to use
-    // delayTime - the delay in ms
-    // onTime - the on time in ms
-    void ledControl(in int id, int rgb565, int delayTime, int onTime);
-
-    // Controls Vibration - can only be used if you registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    // delayTime - the delay in ms
-    // onTime - the on time in ms
-    void vibrateControl(in int id, int delayTime, int onTime);
-
-    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
-    // id - the plugin id received in registerPlugin
-    // x - from left side
-    // y - from top side
-    // bitmapBytes - the byteArray containing the bitmap data
-    void sendImageAsBitmapByteArray(in int id, in int x, in int y, in byte[] bitmapByteArray);
-
-    // Used to put the screen in powersave mode
-    // id - the plugin id received in registerPlugin
-    void screenOff(in int id);
-
-    // Used to put the screen in dimmed mode
-    // id - the plugin id received in registerPlugin
-    void screenDim(in int id);
-
-    // Used to wake the screen from powersave mode
-    // id - the plugin id received in registerPlugin
-    void screenOn(in int id);
-
-    // Used to set the to powersave mode "AUTO"
-    // id - the plugin id received in registerPlugin
-    void screenOnAuto(in int id);
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.sonyericsson.extras.liveview;
+
+import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
+
+interface IPluginServiceV1 {
+
+	// Register to the Liveview application
+	// cb - callback instance
+    // imageMenu - path to the menu bitmap
+    // pluginName - name of the plugin - must be unique
+    // selectableMenu - is set to true if controlling display and getting buttons. Set to false to only handle announces
+    // packageName - the package name (use getPackageName()).
+    // returns id of plugin in system, 0 means that the registration failed
+    int register(in IPluginServiceCallbackV1 cb, in String imageMenu, in String pluginName, in boolean selectableMenu, in String packageName);
+    
+    // This method should be called if the application/service is uninstalled using the phone application handler 
+    // id - the plugin id received in registerPlugin
+    // cb - the callback
+    void unregister( in int id, in IPluginServiceCallbackV1 cb);
+    
+    // Used to send announcements to the device - can only be used when _not_ registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // imageAnnounce - the path to the announce bitmap
+    // header - header text
+    // body - body text
+    // time - timestamp for this announce in milliseconds
+    // openInPhoneAction - a tag to use for openInPhone callback. Set to null when announce not selectable
+    void sendAnnounce(in int id, in String imageAnnounce, in String header, in String body, in long timestamp, in String openInPhoneAction);
+    
+    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // x - from left side
+    // y - from top side
+    // image - the path to the image on file system
+    void sendImage(in int id, in int x, in int y, in String image);
+
+    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // x - from left side
+    // y - from top side
+    // bitmapData - the bitmap to send
+    void sendImageAsBitmap(in int id, in int x, in int y, in Bitmap bitmapData);
+    
+    // Clears the display, for example if several images are sent while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    void clearDisplay(in int id);
+    
+    // Provide the Liveview application with means to launch the service 
+    // that shoul receive and send data in sandbox mode - Must be called if you registered as "selectableMenu"
+    // launcherIntent - the intent to start the plugin service
+    // pluginName - the name of the plugin, must match the name you registered with! 
+    // returns -1 for failure, 0 for already registered, anything else for success
+    int notifyInstalled(in String launcherIntent, in String pluginName);
+
+    // Controls LED - can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // rgb565 - the color to use
+    // delayTime - the delay in ms
+    // onTime - the on time in ms
+    void ledControl(in int id, int rgb565, int delayTime, int onTime);
+
+    // Controls Vibration - can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // delayTime - the delay in ms
+    // onTime - the on time in ms
+    void vibrateControl(in int id, int delayTime, int onTime);
+
+    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // x - from left side
+    // y - from top side
+    // bitmapBytes - the byteArray containing the bitmap data
+    void sendImageAsBitmapByteArray(in int id, in int x, in int y, in byte[] bitmapByteArray);
+
+    // Used to put the screen in powersave mode
+    // id - the plugin id received in registerPlugin
+    void screenOff(in int id);
+
+    // Used to put the screen in dimmed mode
+    // id - the plugin id received in registerPlugin
+    void screenDim(in int id);
+
+    // Used to wake the screen from powersave mode
+    // id - the plugin id received in registerPlugin
+    void screenOn(in int id);
+
+    // Used to set the to powersave mode "AUTO"
+    // id - the plugin id received in registerPlugin
+    void screenOnAuto(in int id);
 }
\ No newline at end of file

commit 9be8cb6dc866cf11716088d340441b9f69dec348
Merge: 397ccee 24446b1
Author: liato <x@x00.us>
Date:   Fri Jun 10 01:56:44 2011 +0200

    Fix merge issues.

commit 397ccee4a851cac4ca2cfe1abed2d2dd64526d65
Merge: daf33ea 3afbab6
Author: liato <x@x00.us>
Date:   Thu Jun 9 16:28:27 2011 -0700

    Merge pull request #82 from woody2/master
    
    Skandiabanken

commit daf33eacdebd9b091768f6b2dd0e32a593844bcc
Merge: 05a1de8 7b40038
Author: liato <x@x00.us>
Date:   Thu Jun 9 16:24:00 2011 -0700

    Merge pull request #87 from magnusart/master
    
    BankDroid pairing wizard

commit 7b400380784bfbe03e455ecff583990133660bb0
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Thu Jun 9 22:54:41 2011 +0200

    Remove file that was added by mistake
            org.eclipse.jdt.ui.prefs

diff --git .classpath .classpath
index e7b211d..ffbea45 100644
--- .classpath
+++ .classpath
@@ -3,7 +3,7 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
-	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
-	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
+	<classpathentry kind="lib" path="/home/magnus/Dokument/JavaBibliotek/google-collect-1.0/google-collect-1.0.jar"/>
+	<classpathentry kind="lib" path="/home/magnus/Dokument/JavaBibliotek/commons-io-2.0.1/commons-io-2.0.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git .settings/org.eclipse.jdt.ui.prefs .settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 27c5ff2..0000000
--- .settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,55 +0,0 @@
-#Wed Jun 08 22:26:41 CEST 2011
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=false
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=true
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=true
-sp_cleanup.correct_indentation=true
-sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=false
-sp_cleanup.make_local_variable_final=true
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=true
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=false
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=false
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=false
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=true
-sp_cleanup.remove_unused_imports=true
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=false
-sp_cleanup.remove_unused_private_members=true
-sp_cleanup.remove_unused_private_methods=false
-sp_cleanup.remove_unused_private_types=false
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=true
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=true
-sp_cleanup.use_this_for_non_static_field_access=false
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=false
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

commit 3742049482d9b1be96f0f5f3a85be6cf84d5eda6
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Thu Jun 9 22:40:19 2011 +0200

    Added intent that allows for pairing with other applications, to allow
    data provider access with an API-key. This is to improve the user
    experience.
    
    If the application recognizes the application name the correct logo
    will be displayed (other applications will have to request their logo
    to be included) otherwise an questionmark logo is displayed.
    
    http://github.com/magnusart/Ekonomipuls/issues/issue/7
    Signed-off-by: Magnus Andersson <magnus@magnusart.com>
    
    Change-Id: Ibd32f809c4735905cc5aeb5d08c309231029bb76

diff --git .settings/org.eclipse.jdt.ui.prefs .settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..27c5ff2
--- /dev/null
+++ .settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+#Wed Jun 08 22:26:41 CEST 2011
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=false
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=true
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=true
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=false
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=false
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=false
+sp_cleanup.remove_unused_private_members=true
+sp_cleanup.remove_unused_private_methods=false
+sp_cleanup.remove_unused_private_types=false
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=true
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git AndroidManifest.xml AndroidManifest.xml
index 06d37dd..45bbc6c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -5,8 +5,7 @@
 	android:versionName="1.7.3" android:versionCode="115">
 	<application
 		android:icon="@drawable/icon"
-		android:label="@string/app_name"
-		android:debuggable="false">
+		android:label="@string/app_name" android:debuggable="false">
 		<activity
 			android:name=".MainActivity"
 			android:label="@string/app_name"
@@ -118,6 +117,17 @@
 		android:exported="true"
 		android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
 		android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS"/>
+	<activity 
+		android:name="PairApplicationsActivity" 
+		android:label="@string/app_name"
+		android:multiprocess="false"
+		android:alwaysRetainTaskState="false"
+		android:theme="@style/BankdroidTheme">
+			<intent-filter>
+				<action android:name="com.liato.bankroid.PAIR_APPLICATION_ACTION" />
+				<category android:name="android.intent.category.DEFAULT" />
+			</intent-filter>
+		</activity>
 </application>
 	<uses-sdk
 		android:targetSdkVersion="4"
diff --git logo_unknown_app.svg logo_unknown_app.svg
new file mode 100644
index 0000000..6288dcb
--- /dev/null
+++ logo_unknown_app.svg
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg3453"
+   version="1.1"
+   inkscape:version="0.48.1 r9760"
+   width="533.88751"
+   height="534.2149"
+   sodipodi:docname="Budget2.png">
+  <metadata
+     id="metadata3459">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3457">
+    <linearGradient
+       id="linearGradient7450">
+      <stop
+         style="stop-color:#860000;stop-opacity:1;"
+         offset="0"
+         id="stop7452" />
+      <stop
+         style="stop-color:#ce5151;stop-opacity:1;"
+         offset="1"
+         id="stop7454" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6928">
+      <stop
+         style="stop-color:#c3c3c3;stop-opacity:1;"
+         offset="0"
+         id="stop6930" />
+      <stop
+         style="stop-color:#7b7b7b;stop-opacity:1;"
+         offset="1"
+         id="stop6932" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6928"
+       id="linearGradient6934"
+       x1="181.98225"
+       y1="402.17392"
+       x2="179.11639"
+       y2="260.31375"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(12.734389,0,0,12.734389,-2046.2974,-4155.2153)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7450"
+       id="linearGradient7456"
+       x1="279.42157"
+       y1="741.77856"
+       x2="279.42157"
+       y2="307.59811"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(51.58552,227.83604)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6928"
+       id="linearGradient7473"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(12.734389,0,0,12.734389,-1966.0533,-4474.7589)"
+       x1="181.98225"
+       y1="402.17392"
+       x2="179.11639"
+       y2="260.31375" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6928"
+       id="linearGradient7478"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(12.734389,0,0,12.734389,-1966.0533,-4474.7589)"
+       x1="181.98225"
+       y1="402.17392"
+       x2="179.11639"
+       y2="260.31375" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6928"
+       id="linearGradient7480"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(12.734389,0,0,12.734389,-2046.2974,-4155.2153)"
+       x1="181.98225"
+       y1="402.17392"
+       x2="179.11639"
+       y2="260.31375" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6928"
+       id="linearGradient7483"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(12.734389,0,0,12.734389,-2011.9071,-4238.3253)"
+       x1="181.98225"
+       y1="402.17392"
+       x2="179.11639"
+       y2="260.31375" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient6928"
+       id="linearGradient7486"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(12.734389,0,0,12.734389,-2011.9071,-4238.3253)"
+       x1="181.98225"
+       y1="402.17392"
+       x2="179.11639"
+       y2="260.31375" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7450"
+       id="linearGradient7488"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(51.58552,227.83604)"
+       x1="279.42157"
+       y1="741.77856"
+       x2="279.42157"
+       y2="307.59811" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7450-3"
+       id="linearGradient7488-5"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(51.58552,227.83604)"
+       x1="279.42157"
+       y1="741.77856"
+       x2="279.42157"
+       y2="307.59811" />
+    <linearGradient
+       id="linearGradient7450-3">
+      <stop
+         style="stop-color:#860000;stop-opacity:1;"
+         offset="0"
+         id="stop7452-9" />
+      <stop
+         style="stop-color:#c73939;stop-opacity:1;"
+         offset="1"
+         id="stop7454-9" />
+    </linearGradient>
+    <linearGradient
+       y2="307.59811"
+       x2="279.42157"
+       y1="741.77856"
+       x1="279.42157"
+       gradientTransform="translate(-56.07073,-303.19521)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7582"
+       xlink:href="#linearGradient7450-3"
+       inkscape:collect="always" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7450-3-2"
+       id="linearGradient7488-5-4"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(51.58552,227.83604)"
+       x1="279.42157"
+       y1="741.77856"
+       x2="279.42157"
+       y2="307.59811" />
+    <linearGradient
+       id="linearGradient7450-3-2">
+      <stop
+         style="stop-color:#ff3131;stop-opacity:1;"
+         offset="0"
+         id="stop7452-9-7" />
+      <stop
+         style="stop-color:#ff6666;stop-opacity:1;"
+         offset="1"
+         id="stop7454-9-5" />
+    </linearGradient>
+    <linearGradient
+       y2="307.59811"
+       x2="279.42157"
+       y1="741.77856"
+       x1="279.42157"
+       gradientTransform="translate(51.58552,227.83604)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient7649"
+       xlink:href="#linearGradient7450-3-2"
+       inkscape:collect="always" />
+    <filter
+       id="filter7668"
+       inkscape:label="In and Out"
+       inkscape:menu="Shadows and Glows"
+       inkscape:menu-tooltip="Inner colorized shadow, outer black shadow"
+       color-interpolation-filters="sRGB">
+      <feGaussianBlur
+         id="feGaussianBlur7670"
+         result="result0"
+         in="SourceAlpha"
+         stdDeviation="4" />
+      <feOffset
+         id="feOffset7672"
+         dx="5"
+         dy="5"
+         result="result4" />
+      <feComposite
+         id="feComposite7674"
+         in2="result4"
+         in="SourceGraphic"
+         operator="xor"
+         result="result3" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7450-3-2"
+       id="linearGradient7701"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-11.580105,-258.67729)"
+       x1="279.42157"
+       y1="741.77856"
+       x2="279.42157"
+       y2="307.59811" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient7450-3"
+       id="linearGradient7703"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-11.580105,-258.67729)"
+       x1="279.42157"
+       y1="741.77856"
+       x2="279.42157"
+       y2="307.59811" />
+  </defs>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1056"
+     id="namedview3455"
+     showgrid="false"
+     inkscape:zoom="0.69787026"
+     inkscape:cx="287.33783"
+     inkscape:cy="-18.682581"
+     inkscape:window-x="1920"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3453"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <path
+     style="color:#000000;fill:url(#linearGradient7703);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     d="m 65.709375,44.517911 -6.3125,3.34375 c -3.47343,1.83376 -8.26066,6.08064 -10.625,9.4375 l -4.28125,6.09375 0,203.218759 0,203.21875 4.3125,6.15625 c 4.6083,6.5568 11.02443,11.0369 18.375,12.8125 2.49024,0.6016 93.553475,0.9996 202.375005,0.875 l 197.875,-0.25 6.96875,-4.3125 c 5.08758,-3.1456 8.08514,-6.38905 11,-11.96875 l 4,-7.6875 -0.0312,-198.65625 c -0.0301,-189.622829 -0.1465,-198.903899 -2.65625,-204.375009 -3.22361,-7.02729 -9.39345,-13.37468 -15.53125,-15.96875 -3.81373,-1.61183 -39.25598,-1.9375 -205.03125,-1.9375 l -200.437495,0 z m 203.375005,36.90625 c 16.91273,3.7e-4 32.18449,2.0738 45.78125,6.21875 13.59645,3.97985 25.11101,9.86343 34.5625,17.656249 9.4511,7.79352 16.68166,17.23465 21.65625,28.34375 5.13995,11.10974 7.68727,23.80293 7.6875,38.06251 -2.3e-4,10.44644 -1.1476,19.80339 -3.46875,28.09375 -2.3216,8.12505 -5.79497,15.77655 -10.4375,22.90625 -4.47713,6.96434 -10.19232,13.74272 -17.15625,20.375 -6.7985,6.46688 -14.78674,13.3607 -23.90625,20.65625 -6.96429,5.47199 -12.67948,10.26112 -17.15625,14.40625 -4.31127,3.97967 -7.70046,7.78979 -10.1875,11.4375 -2.48733,3.64802 -4.22402,7.48941 -5.21875,11.46875 -0.8292,3.81383 -1.25014,8.35039 -1.25,13.65625 l 0,14.9375 -65.65626,0 0,-18.40625 c -6e-5,-8.45628 0.81056,-16.07654 2.46875,-22.875 1.82387,-6.96395 4.48662,-13.52102 7.96875,-19.65625 3.6478,-6.30068 8.2998,-12.35262 13.9375,-18.15625 5.63753,-5.96904 12.41591,-12.10517 20.37501,-18.40625 6.96399,-5.47158 12.87881,-10.37615 17.6875,-14.6875 4.80841,-4.31089 8.70273,-8.54195 11.6875,-12.6875 2.98447,-4.31087 5.14211,-8.76325 6.46875,-13.40625 1.32634,-4.64248 1.96859,-10.05217 1.96875,-16.1875 -1.6e-4,-9.45102 -3.22096,-17.23965 -9.6875,-23.375 -6.30101,-6.13475 -15.99471,-9.1872 -29.09375,-9.1875 -11.44115,3e-4 -23.79761,2.4105 -37.06251,7.21875 -13.09924,4.80886 -26.71849,10.69242 -40.8125,17.65625 l -25.34375,-54.96876 c 7.12992,-4.14497 14.83436,-8.03928 23.125,-11.6875 8.45639,-3.813329 17.17109,-7.149579 26.125,-9.968749 9.11962,-2.98426 18.30819,-5.31026 27.59375,-6.96875 9.2854,-1.65776 18.38978,-2.46838 27.34376,-2.46875 z m -8.9375,291.000009 c 5.80332,8e-5 11.26594,0.72651 16.40625,2.21875 5.30586,1.49238 9.95786,3.90257 13.9375,7.21875 3.97935,3.31631 7.11599,7.71575 9.4375,13.1875 2.32123,5.30604 3.49986,11.86312 3.5,19.65625 -1.4e-4,7.46159 -1.17877,13.85028 -3.5,19.15625 -2.32151,5.30601 -5.45815,9.70545 -9.4375,13.1875 -3.97964,3.48206 -8.63164,5.94519 -13.9375,7.4375 -5.14031,1.65812 -10.60293,2.49999 -16.40625,2.5 -6.13516,-1e-5 -11.93454,-0.84188 -17.40626,-2.5 -5.30608,-1.49231 -9.95808,-3.95544 -13.9375,-7.4375 -3.97956,-3.48205 -7.11619,-7.88149 -9.4375,-13.1875 -2.15562,-5.30597 -3.25006,-11.69466 -3.25,-19.15625 -6e-5,-7.79313 1.09438,-14.35021 3.25,-19.65625 2.32131,-5.47175 5.45794,-9.87119 9.4375,-13.1875 3.97942,-3.31618 8.63142,-5.72637 13.9375,-7.21875 5.47172,-1.49224 11.2711,-2.21867 17.40626,-2.21875 z"
+     id="path7448"
+     inkscape:connector-curvature="0"
+     inkscape:export-filename="/home/magnus/Dokument/Programmering/Ekonomipuls/magnusart-bankdroid/android-bankdroid/res/drawable/logo_unknown_app.png"
+     inkscape:export-xdpi="10.78879"
+     inkscape:export-ydpi="10.78879" />
+  <g
+     style="font-size:509.37557983px;font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient7480);fill-opacity:1;stroke:none;font-family:Century Schoolbook L;-inkscape-font-specification:Century Schoolbook L Medium"
+     id="text6924"
+     transform="translate(67.231105,333.12325)" />
+  <path
+     inkscape:connector-curvature="0"
+     style="color:#000000;fill:url(#linearGradient7701);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter7668);enable-background:accumulate"
+     d="m 65.709375,44.517911 -6.3125,3.34375 c -3.47343,1.83376 -8.26066,6.08064 -10.625,9.4375 l -4.28125,6.09375 0,203.218759 0,203.21875 4.3125,6.15625 c 4.6083,6.5568 11.02443,11.0369 18.375,12.8125 2.49024,0.6016 93.553475,0.9996 202.375005,0.875 l 197.875,-0.25 6.96875,-4.3125 c 5.08758,-3.1456 8.08514,-6.38905 11,-11.96875 l 4,-7.6875 -0.0312,-198.65625 c -0.03,-189.622829 -0.1465,-198.903899 -2.65625,-204.375009 -3.22361,-7.02729 -9.39345,-13.37468 -15.53125,-15.96875 -3.81373,-1.61183 -39.25598,-1.9375 -205.03125,-1.9375 l -200.437495,0 z m 203.375005,36.90625 c 16.91273,3.7e-4 32.18449,2.0738 45.78125,6.21875 13.59645,3.97985 25.11101,9.86343 34.5625,17.656249 9.4511,7.79352 16.68166,17.23465 21.65625,28.34375 5.13995,11.10974 7.68727,23.80293 7.6875,38.06251 -2.3e-4,10.44644 -1.1476,19.80339 -3.46875,28.09375 -2.3216,8.12505 -5.79497,15.77655 -10.4375,22.90625 -4.47713,6.96434 -10.19232,13.74272 -17.15625,20.375 -6.7985,6.46688 -14.78674,13.3607 -23.90625,20.65625 -6.96429,5.47199 -12.67948,10.26112 -17.15625,14.40625 -4.31127,3.97967 -7.70046,7.78979 -10.1875,11.4375 -2.48733,3.64802 -4.22402,7.48941 -5.21875,11.46875 -0.8292,3.81383 -1.25014,8.35039 -1.25,13.65625 l 0,14.9375 -65.65626,0 0,-18.40625 c -6e-5,-8.45628 0.81056,-16.07654 2.46875,-22.875 1.82387,-6.96395 4.48662,-13.52102 7.96875,-19.65625 3.6478,-6.30068 8.2998,-12.35262 13.9375,-18.15625 5.63753,-5.96904 12.41591,-12.10517 20.37501,-18.40625 6.96399,-5.47158 12.87881,-10.37615 17.6875,-14.6875 4.80841,-4.31089 8.70273,-8.54195 11.6875,-12.6875 2.98447,-4.31087 5.14211,-8.76325 6.46875,-13.40625 1.32634,-4.64248 1.96859,-10.05217 1.96875,-16.1875 -1.6e-4,-9.45102 -3.22096,-17.23965 -9.6875,-23.375 -6.30101,-6.13475 -15.99471,-9.1872 -29.09375,-9.1875 -11.44115,3e-4 -23.79761,2.4105 -37.06251,7.21875 -13.09924,4.80886 -26.71849,10.69242 -40.8125,17.65625 l -25.34375,-54.96876 c 7.12992,-4.14497 14.83436,-8.03928 23.125,-11.6875 8.45639,-3.813329 17.17109,-7.149579 26.125,-9.968749 9.11962,-2.98426 18.30819,-5.31026 27.59375,-6.96875 9.2854,-1.65776 18.38978,-2.46838 27.34376,-2.46875 z m -8.9375,291.000009 c 5.80332,8e-5 11.26594,0.72651 16.40625,2.21875 5.30586,1.49238 9.95786,3.90257 13.9375,7.21875 3.97935,3.31631 7.11599,7.71575 9.4375,13.1875 2.32123,5.30604 3.49986,11.86312 3.5,19.65625 -1.4e-4,7.46159 -1.17877,13.85028 -3.5,19.15625 -2.32151,5.30601 -5.45815,9.70545 -9.4375,13.1875 -3.97964,3.48206 -8.63164,5.94519 -13.9375,7.4375 -5.14031,1.65812 -10.60293,2.49999 -16.40625,2.5 -6.13516,-1e-5 -11.93454,-0.84188 -17.40626,-2.5 -5.30608,-1.49231 -9.95808,-3.95544 -13.9375,-7.4375 -3.97956,-3.48205 -7.11619,-7.88149 -9.4375,-13.1875 -2.15562,-5.30597 -3.25006,-11.69466 -3.25,-19.15625 -6e-5,-7.79313 1.09438,-14.35021 3.25,-19.65625 2.32131,-5.47175 5.45794,-9.87119 9.4375,-13.1875 3.97942,-3.31618 8.63142,-5.72637 13.9375,-7.21875 5.47172,-1.49224 11.2711,-2.21867 17.40626,-2.21875 z"
+     id="path7448-5"
+     inkscape:export-filename="/home/magnus/Dokument/Programmering/Ekonomipuls/magnusart-bankdroid/android-bankdroid/res/drawable/logo_unknown_app.png"
+     inkscape:export-xdpi="10.78879"
+     inkscape:export-ydpi="10.78879" />
+</svg>
diff --git res/drawable-hdpi-v4/button_accept.png res/drawable-hdpi-v4/button_accept.png
new file mode 100644
index 0000000..c34249c
Binary files /dev/null and res/drawable-hdpi-v4/button_accept.png differ
diff --git res/drawable/logo_ekonomipuls.png res/drawable/logo_ekonomipuls.png
new file mode 100644
index 0000000..e3b32ac
Binary files /dev/null and res/drawable/logo_ekonomipuls.png differ
diff --git res/drawable/logo_unknown_app.png res/drawable/logo_unknown_app.png
new file mode 100644
index 0000000..b2d7779
Binary files /dev/null and res/drawable/logo_unknown_app.png differ
diff --git res/layout/pair_applications_layout.xml res/layout/pair_applications_layout.xml
new file mode 100644
index 0000000..739e02c
--- /dev/null
+++ res/layout/pair_applications_layout.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_width="wrap_content"
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat">
+	<LinearLayout
+			android:id="@+id/LinearLayout01"
+			android:layout_height="wrap_content"
+			android:layout_below="@+id/txtErrorDesc"
+			android:layout_width="fill_parent"
+			android:orientation="vertical"
+			android:layout_alignParentTop="true"
+			android:padding="10dp">
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="16sp"
+				android:text="@string/pair_message" />
+				
+		<ImageView 
+			android:layout_width="wrap_content" 
+			android:src="@drawable/logo_unknown_app" 
+			android:layout_height="wrap_content" 
+			android:id="@+id/imageView1" 
+			android:layout_gravity="center_horizontal"
+			android:paddingTop="40dp"
+			/>
+			<TextView
+				android:id="@+id/app_name"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="25sp"
+				android:layout_gravity="center_horizontal"
+				android:text="@string/pair_app_name"
+				/>
+		</LinearLayout>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:stretchColumns="0,2"
+		android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentRight="true"
+		android:layout_width="wrap_content"
+		android:layout_below="@+id/LinearLayout01"
+		android:gravity="bottom">
+		<TableRow
+			android:id="@+id/TableRow01"
+			android:layout_height="wrap_content"
+			android:gravity="center_vertical|center_horizontal"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent">
+			<Button
+				android:onClick="cancelPairing"
+				android:text="@string/cancel"
+				android:drawableLeft="@drawable/button_cancel"
+				android:id="@+id/btnSettingsCancel"
+				style="@style/Menu_Button"></Button>
+			<ImageView
+				android:layout_height="wrap_content"
+				android:focusable="false"
+				android:src="@drawable/menu_separator"
+				android:adjustViewBounds="true"
+				android:scaleType="fitXY"
+				android:minWidth="3dp"
+				android:maxWidth="3dp"
+				android:layout_width="wrap_content"></ImageView>
+			<Button
+				android:onClick="confirmPairing"
+				android:id="@+id/btnSettingsOk"
+				android:drawableLeft="@drawable/button_accept"
+				android:text="@string/approve"
+				style="@style/Menu_Button"></Button>
+		</TableRow>		
+	</TableLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index a23a78c..8423c76 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -28,8 +28,7 @@
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
     <string name="cancel">AVBRYT</string>
-    <string name="save">SPARA</string>
-    
+   
 	<string name="add_new_account">LÄGG TILL BANK</string>
 	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
 	
@@ -231,4 +230,7 @@
 	<string name="nordnetdirekt_extras_title">Nyckel</string>
 	<string name="select_a_bank">Välj en bank</string>
 	<string name="invalid_integer">%1$s är inte ett giltigt positivt heltal, var god försök igen.</string>
+	<string name="pair_message">Applikationen nedan vill ta del av kontotyp och transaktionsdata från BankDroid.</string>
+	<string name="approve">GODKÄNN</string>
+	<string name="pair_app_name">Okänd applikation</string>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index b305b08..9e7f911 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -282,5 +282,8 @@
 
 	<string name="nordnetdirekt_extras_title">Key</string>
 	<string name="select_a_bank">Select a bank</string>
-	<string name="invalid_integer">%1$s is not a valid positive integer, please try again.</string>	
+	<string name="invalid_integer">%1$s is not a valid positive integer, please try again.</string>
+	<string name="pair_message">The Application below wants to access account types and transaction data from BankDroid.</string>
+	<string name="approve">APPROVE</string>
+	<string name="pair_app_name">Unknown application</string>	
 </resources>
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 2674c94..388457d 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -64,7 +64,8 @@ public class MainActivity extends LockableActivity {
 	public void onCreate(final Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
-		initialSetupApiKey();
+		PairApplicationsActivity.initialSetupApiKey(this);
+		
 		setContentView(R.layout.main);
 		final OnClickListener listener = new View.OnClickListener() {
 			public void onClick(final View v) {
@@ -129,20 +130,7 @@ public class MainActivity extends LockableActivity {
 		}
 	}
 
-	private void initialSetupApiKey() {
-		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		final String apiKey = prefs.getString("content_provider_api_key", "");
-		if(apiKey.equals("")) {
-			final SharedPreferences.Editor editor = prefs.edit();
-
-			// Create a random HEX String
-			final String genKey = Long.toHexString(Double.doubleToLongBits(Math.random()));
-
-			// Commit to preferences
-			editor.putString("content_provider_api_key", genKey.toUpperCase());
-			editor.commit();
-		}
-	}
+	
 
 	@Override
 	public void onResume() {
diff --git src/com/liato/bankdroid/PairApplicationsActivity.java src/com/liato/bankdroid/PairApplicationsActivity.java
new file mode 100644
index 0000000..694a44e
--- /dev/null
+++ src/com/liato/bankdroid/PairApplicationsActivity.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright 2011 Magnus Andersson
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import com.liato.bankdroid.provider.BankTransactionsProvider;
+import com.liato.bankdroid.provider.IBankTransactionsProvider;
+
+import com.liato.bankdroid.R;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.res.Resources.NotFoundException;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * @author Magnus Andersson
+ * @since 8 jun 2011
+ */
+public class PairApplicationsActivity extends Activity {
+
+	/**
+	 * 
+	 */
+	private static final String TAG = "Pair Application";
+	private static final String PAIR_APP_NAME = "com.liato.bankdroid.PAIR_APP_NAME";
+
+	/** {@inheritDoc} */
+	@Override
+	protected void onCreate(final Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.pair_applications_layout);
+
+		Bundle bundle = getIntent().getExtras();
+
+		if(bundle.containsKey(PAIR_APP_NAME)) {
+			String appName = bundle.getString(PAIR_APP_NAME);
+
+			ImageView img = (ImageView) findViewById(R.id.imageView1);
+			String logoUri = "drawable/logo_"+appName.toLowerCase();
+
+			// Dynamically load logo
+			int imageResource = getResources().getIdentifier(logoUri, null, getPackageName());
+
+			try {
+				Drawable d = getResources().getDrawable(imageResource);
+				img.setImageDrawable(d);
+				img.requestLayout();
+			} catch (NotFoundException e) {
+				Log.e(TAG, "Could not find the requested image using uri " + logoUri);
+				e.printStackTrace();
+			}
+			// Change application name
+			TextView appNameView = (TextView) findViewById(R.id.app_name);
+			appNameView.setText(appName);
+		} else {
+			Log.d(TAG, "Unkown application");
+		}
+
+
+	}
+
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event) {
+		//Handle the back button
+		if (keyCode == KeyEvent.KEYCODE_BACK) {
+			setResult(RESULT_CANCELED);
+			finish();
+			return true;
+		}
+
+		return super.onKeyDown(keyCode, event);
+	} 
+
+	public void cancelPairing(final View v) {
+		setResult(RESULT_CANCELED);
+		finish();
+	}
+
+	public void confirmPairing(final View v) {
+		Intent intent = this.getIntent();
+
+		Context ctx = getBaseContext();
+
+		// Make sure sharing is enabled
+		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx);
+		Editor editor = pref.edit();
+		editor.putBoolean("content_provider_enabled", true);
+		editor.commit();
+
+		String apiKey = BankTransactionsProvider.getApiKey(ctx);
+
+		// Make sure we actually have an generated API-key
+		if(apiKey == null || apiKey.equals("")) {
+			initialSetupApiKey(ctx);
+		}
+
+		intent.putExtra(IBankTransactionsProvider.API_KEY,apiKey);
+		setResult(RESULT_OK, intent);
+
+		finish();
+	}
+
+	public static void initialSetupApiKey(Context ctx) {
+		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+		final String apiKey = prefs.getString("content_provider_api_key", "");
+		if(apiKey.equals("")) {
+			final SharedPreferences.Editor editor = prefs.edit();
+
+			// Create a random HEX String
+			final String genKey = Long.toHexString(Double.doubleToLongBits(Math.random()));
+
+			// Commit to preferences
+			editor.putString("content_provider_api_key", genKey.toUpperCase());
+			editor.commit();
+		}
+	}
+}
diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index fb47b37..0d7dabe 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -203,7 +203,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 				"This provider does not implement the update method");
 	}
 
-	private static String getApiKey(final Context ctx) {
+	public static String getApiKey(final Context ctx) {
 		final SharedPreferences prefs = PreferenceManager
 				.getDefaultSharedPreferences(ctx);
 		if (!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {

commit 05a1de88497c7d85df625694562a86f3eb251101
Author: liato <x@x00.us>
Date:   Sun May 29 12:13:53 2011 +0200

    Fix for SkodaKortet and other Ikano based banks.

diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index d30b5cc..167637a 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -51,6 +51,7 @@ public abstract class IkanoPartnerBase extends Bank {
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reCtl = Pattern.compile("(ctl\\d{1,})_CustomValidationSummary", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Transaktioner</", Pattern.CASE_INSENSITIVE);
+    private Pattern reCreditInfoUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Kredit-? ?uppgifter</", Pattern.CASE_INSENSITIVE);
     private Pattern reAccounts = Pattern.compile("captionLabel\">([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
     private Pattern reTransactions = Pattern.compile("<td\\s*class=\"TransactionDateRow\">([^>]+)</td><td[^>]+>(.+?)</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>");
     private String response = null;
@@ -127,12 +128,24 @@ public abstract class IkanoPartnerBase extends Bank {
 		urlopen = login();
 		Matcher matcher;
 		try {
+            String creditPageUrl = null;
+            String transactionsPageUrl = null;
+		    matcher = reCreditInfoUrl.matcher(response);
+            if (matcher.find()) {
+                creditPageUrl = matcher.group(1);
+            }
+		    
 	        matcher = reTransactionsUrl.matcher(response);
-	        if (!matcher.find()) {
+	        if (!matcher.find() && creditPageUrl == null) {
 	            throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions url.");
 	        }
+	        transactionsPageUrl = matcher.group(1);
 		    
-			response = urlopen.open("https://partner.ikanobank.se/web/engines/"+matcher.group(1));
+	        // If a url for the credit page is found we request that page first. If no url for the credit page is
+	        // found we only need to request the transactions page as all the credit info should be available on
+	        // that page.
+            response = urlopen.open("https://partner.ikanobank.se/web/engines/"+(creditPageUrl == null ? transactionsPageUrl : creditPageUrl));
+	            
 			matcher = reAccounts.matcher(response);
 			int accId = 0;
 			while (matcher.find()) {
@@ -144,19 +157,27 @@ public abstract class IkanoPartnerBase extends Bank {
 	             * 3: Currency          &nbsp;kr 
 	             *   
 	             */
-				accounts.add(new Account(
-				        Html.fromHtml(matcher.group(1)).toString().trim(),
-				        Helpers.parseBalance(matcher.group(2)),
-				        Integer.toString(accId)));
+			    Account account = new Account(
+                        Html.fromHtml(matcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(2)),
+                        Integer.toString(accId));
+			    if (accId > 0) {
+			        account.setAliasfor("0");
+			    }
+				accounts.add(account);
 				accId++;
 			}
 			
+			
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			 // Use the amount from "Kvar att handla för" which should be the last account in the list.
 		    this.balance = accounts.get(accounts.size()-1).getBalance();
 		    
+		    if (creditPageUrl != null) {
+		        response = urlopen.open("https://partner.ikanobank.se/web/engines/"+transactionsPageUrl);
+		    }
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
             matcher = reTransactions.matcher(response);
             while (matcher.find()) {

commit 27d3093910c08fdbaa077d0d0c41bc5a9ca4b22f
Author: liato <x@x00.us>
Date:   Sun May 29 11:30:23 2011 +0200

    Changed url for Sparbanken Oresund.

diff --git AndroidManifest.xml AndroidManifest.xml
index 56a5c11..06d37dd 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="114" android:versionName="1.7.3">
+	android:versionName="1.7.3" android:versionCode="115">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/SparbankenOresund.java src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index b956125..8ee31c0 100644
--- src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -27,7 +27,7 @@ public class SparbankenOresund extends MobilbankenBase {
 	private static final String TAG = "SparbankenOresund";
 	private static final String NAME = "Sparbanken Öresund";
 	private static final String NAME_SHORT = "sparbanken_oresund";
-	private static final String URL = "https://mobil-banken.se/0002/login.html";
+	private static final String URL = "https://mobil-banken.se/0003/login.html";
 	private static final int BANKTYPE_ID = Bank.SPARBANKEN_ORESUND;
 
     public SparbankenOresund(Context context) {
@@ -37,7 +37,7 @@ public class SparbankenOresund extends MobilbankenBase {
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
-        this.targetId = "0002";
+        this.targetId = "0003";
     }
 
     public SparbankenOresund(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {

commit 3afbab6d4027808e142dc17fe7465e03779cfd66
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun May 8 20:43:17 2011 +0200

    Remove some debugging code

diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
index 4911c35..ba7a4cc 100644
--- src/com/liato/bankdroid/banking/banks/Skandiabanken.java
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -34,12 +34,7 @@ public class Skandiabanken extends Bank {
 	private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android/";
 	private static final String LOGIN_URL = BASE_URL + "customer.service";
 	private static final String BALANCE_URL = BASE_URL + "balance.service";
-	private static final String TRANSACTIONS_URL = BASE_URL + "balance.service";
 	
-//	private final static String LOGIN_URL = "http://www.peterbjorkman.se/hessian/real.dat";
-//	private final static String BALANCE_URL = "http://www.peterbjorkman.se/hessian/getAccounts.dat";
-//	private final static String TRANSACTIONS_URL = "http://www.peterbjorkman.se/hessian/GetTransactions.dat";
-
 	private final static String customerOwner = "SKANDIABANKEN";
 	private final static String countryCode = "SE";
 	
@@ -148,9 +143,7 @@ public class Skandiabanken extends Bank {
 			}
 			// TODO Check null
 			
-			// TODO Reuse the service only for debugging against my webserver
-			RemoteBalanceService balanceService2 = (RemoteBalanceService) getHessianProxy().create(RemoteBalanceService.class, TRANSACTIONS_URL, context.getClassLoader());			
-    		AdAccount accountWithTransactions =  balanceService2.getAccountTransactions(adAccount, "f", securityCode);
+			AdAccount accountWithTransactions =  balanceService.getAccountTransactions(adAccount, "f", securityCode);
     		List<AdBalanceInformationTransaction> adTransactions = accountWithTransactions.getTransactions();
     		for (AdBalanceInformationTransaction transaction : adTransactions) {
 				String transactionAmount = transaction.getAmount();

commit 7ee292a0684742f1d8f5bd2ab692d7bb3b6f739c
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun May 8 20:41:15 2011 +0200

    Implement new bank Skandiabanken using their hessian api

diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 42ae14b..5979308 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -65,6 +65,7 @@ import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
+import com.liato.bankdroid.banking.banks.Skandiabanken;
 import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
@@ -187,6 +188,8 @@ public class BankFactory {
             return new SparbankenOresund(context);
         case IBankTypes.NORDNETDIREKT:
             return new Nordnetdirekt(context);
+        case IBankTypes.SKANDIABANKEN:
+                return new Skandiabanken(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -230,6 +233,7 @@ public class BankFactory {
         banks.add(new SparbankenSyd(context));
         banks.add(new SparbankenOresund(context));
         banks.add(new Opel(context));
+        banks.add(new Skandiabanken(context));
         //Not tested or not working
         //banks.add(new AmericanExpress(context));
         //banks.add(new PlusGirot(context));
diff --git src/com/liato/bankdroid/banking/banks/Skandiabanken.java src/com/liato/bankdroid/banking/banks/Skandiabanken.java
new file mode 100644
index 0000000..4911c35
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Skandiabanken.java
@@ -0,0 +1,178 @@
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import se.smartrefill.ad.bank.domain.AdAccount;
+import se.smartrefill.ad.bank.domain.AdBalanceInformationTransaction;
+import se.smartrefill.ad.bank.remoting.service.RemoteBalanceService;
+import se.smartrefill.ad.bank.remoting.service.RemoteCustomerService;
+import se.smartrefill.ad.domain.AdCustomer;
+import se.smartrefill.exception.CustomerBlockedException;
+import se.smartrefill.exception.InvalidLoginException;
+import se.smartrefill.exception.InvalidSecurityCodeException;
+import se.smartrefill.exception.UnauthenticatedUserException;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.caucho.hessian.client.HessianProxyFactory;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Skandiabanken extends Bank {
+	private static final String BASE_URL = "https://smartrefill.se/mobile/bank/android/";
+	private static final String LOGIN_URL = BASE_URL + "customer.service";
+	private static final String BALANCE_URL = BASE_URL + "balance.service";
+	private static final String TRANSACTIONS_URL = BASE_URL + "balance.service";
+	
+//	private final static String LOGIN_URL = "http://www.peterbjorkman.se/hessian/real.dat";
+//	private final static String BALANCE_URL = "http://www.peterbjorkman.se/hessian/getAccounts.dat";
+//	private final static String TRANSACTIONS_URL = "http://www.peterbjorkman.se/hessian/GetTransactions.dat";
+
+	private final static String customerOwner = "SKANDIABANKEN";
+	private final static String countryCode = "SE";
+	
+	// Does not seem to matter, should perhaps be the password of the user
+	private final static String securityCode = "unknown"; 
+	private int customerBalanceServiceId = 0;
+
+	public Skandiabanken(Context context) {
+		super(context);
+		TAG = "Skandiabanken";
+		NAME = "Skandiabanken";
+		NAME_SHORT = "Skandiabanken";
+		BANKTYPE_ID = IBankTypes.SKANDIABANKEN;
+		;
+		URL = "http://www.skandiabanken.se/hem/";
+		INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+		INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+		INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+	}
+
+	public Skandiabanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+
+		try {
+			RemoteCustomerService test = (RemoteCustomerService) getHessianProxy()
+					.create(RemoteCustomerService.class, LOGIN_URL, context.getClassLoader());
+			AdCustomer customer = test.login(username, password, customerOwner,
+					countryCode);
+			customerBalanceServiceId = customer.getBalanceService().getId();
+		} catch (InvalidLoginException e) {
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+		} catch (InvalidSecurityCodeException e) {
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+		} catch (UnauthenticatedUserException e) {
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+		} catch (CustomerBlockedException e) {
+			// TODO other message!
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException, BankChoiceException {
+		super.update();
+
+		if (username == null || password == null || username.length() == 0
+				|| password.length() == 0)
+			throw new LoginException(res.getText(
+					R.string.invalid_username_password).toString());
+
+		login();
+
+		try {
+			RemoteBalanceService balanceService = (RemoteBalanceService) getHessianProxy()
+					.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
+			List<AdAccount> adAccounts = balanceService.getAccounts(
+					customerBalanceServiceId, securityCode);
+			for (AdAccount adAccount : adAccounts) {
+				String amount = adAccount.getAmount();
+				if (amount == null)
+					continue;
+				String typeDescription = adAccount.getAccountTypeDescription();
+				if (typeDescription.contentEquals("Upplagt konto"))
+					continue;
+				
+				int type = Account.OTHER;
+				if (typeDescription.contentEquals("Allt i Ett-konto") || typeDescription.contentEquals("Sparkonto"))
+					type = Account.REGULAR;
+				
+				accounts.add(new Account(adAccount.getAlias(), Helpers
+						.parseBalance(amount), adAccount.getId(), type));
+			}
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		} finally {
+			super.updateComplete();
+		}
+	}
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		try {
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			RemoteBalanceService balanceService = (RemoteBalanceService) getHessianProxy()
+				.create(RemoteBalanceService.class, BALANCE_URL, context.getClassLoader());
+			AdAccount adAccount = null;
+			List<AdAccount> adAccounts = balanceService.getAccounts(customerBalanceServiceId, securityCode);
+			for (AdAccount adAccounti : adAccounts) {
+				if (adAccounti.getId().contentEquals(account.getId())){
+					adAccount = adAccounti;
+					break;
+				}
+			}
+			// TODO Check null
+			
+			// TODO Reuse the service only for debugging against my webserver
+			RemoteBalanceService balanceService2 = (RemoteBalanceService) getHessianProxy().create(RemoteBalanceService.class, TRANSACTIONS_URL, context.getClassLoader());			
+    		AdAccount accountWithTransactions =  balanceService2.getAccountTransactions(adAccount, "f", securityCode);
+    		List<AdBalanceInformationTransaction> adTransactions = accountWithTransactions.getTransactions();
+    		for (AdBalanceInformationTransaction transaction : adTransactions) {
+				String transactionAmount = transaction.getAmount();
+				String time = transaction.getTime();
+				String merchant = transaction.getMerchant();
+				transactions.add(new Transaction(time, merchant, Helpers.parseBalance(transactionAmount)));	
+			}
+			account.setTransactions(transactions);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	private HessianProxyFactory getHessianProxy() {
+		HessianProxyFactory localHessianProxyFactory = new HessianProxyFactory();
+		localHessianProxyFactory.setHessian2Request(false);
+		localHessianProxyFactory.setHessian2Reply(false);
+		localHessianProxyFactory.setChunkedPost(false);
+		localHessianProxyFactory.setReadTimeout(30000L);
+		localHessianProxyFactory.setOverloadEnabled(false);
+		return localHessianProxyFactory;
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 0d50420..510c4ef 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -72,4 +72,5 @@ public interface IBankTypes {
     public final static int SPARBANKEN_SYD = 48;
     public final static int SPARBANKEN_ORESUND = 49;
     public final static int NORDNETDIREKT = 50;
+    public final static int SKANDIABANKEN = 51;
 }
\ No newline at end of file

commit e44af14f95c9dd40cd9827dde746b08c795c7668
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun May 8 20:32:44 2011 +0200

    Add sources for the hessdroid library.
    http://code.google.com/p/hessdroid/
    rev a1c0504b5811
    License Apache 2.0

diff --git src/com/ast/util/CookieParser.java src/com/ast/util/CookieParser.java
new file mode 100644
index 0000000..ebd6418
--- /dev/null
+++ src/com/ast/util/CookieParser.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 hessdroid@gmail.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ast.util;
+
+/**
+ * Parses Set-Cookie HTTP response header and returns the corresponding {@link Cookie} which can be
+ * used for storing cookie information in java collections.
+ * <p/>
+ * <a href="http://www.ietf.org/rfc/rfc2109">RFC 2109</a>
+ *
+ * @author hessdroid@gmail.com
+ */
+public class CookieParser {
+
+    /**
+     * Abstract representation of an HTTP cookie.
+     */
+    public static class Cookie {
+
+        public String host;
+        public String value; // cookie string without the leading intro: "Set-Cookie: "
+        public String expires;
+        public String path;
+        public String domain;
+        public String sessionId;
+        public boolean secure;
+    }
+
+    /**
+     * Parses the given <tt>setCookieString</tt> from an HTTP response and creates a {@link Cookie} from it.
+     * The {@link Cookie} can be used by clients to send cookie on subsequent requests.
+     *
+     * @param host <code>String</code> cookie host
+     * @param setCookieString <code>String</code> complete cookie string
+     * @return a {@link Cookie} that was created from the given <tt>setCookieString</tt>
+     */
+    public static Cookie parse(String host, String setCookieString) {
+
+        if (host == null) throw new IllegalArgumentException("Parameter \"host\" must not be null");
+        if (setCookieString == null)
+            throw new IllegalArgumentException("Parameter \"setCookieString\" must not be null");
+
+        Cookie result = new Cookie();
+
+        // split the cookie string on any semicolon or space(s)
+        String[] fields = setCookieString.split(";\\s*");
+        result.host = host;
+
+        // ignore leading cookie intro 
+        result.value = fields[0].startsWith("Set-Cookie: ") ? fields[0].substring(12) : fields[0];
+        if (result.value.startsWith("JSESSIONID=")) {
+            result.sessionId = result.value.substring(11);
+        }
+
+        // Parse each field
+        for (int j = 1; j < fields.length; j++) {
+            if ("secure".equalsIgnoreCase(fields[j])) {
+                result.secure = true;
+            } else if (fields[j].indexOf('=') > 0) {
+                String[] f = fields[j].split("=");
+                if ("expires".equalsIgnoreCase(f[0])) {
+                    result.expires = f[1];
+                } else if ("domain".equalsIgnoreCase(f[0])) {
+                    result.domain = f[1];
+                } else if ("path".equalsIgnoreCase(f[0])) {
+                    result.path = f[1];
+                }
+            }
+        }
+        return result;
+    }
+
+}
diff --git src/com/caucho/hessian/HessianException.java src/com/caucho/hessian/HessianException.java
new file mode 100644
index 0000000..3b8f510
--- /dev/null
+++ src/com/caucho/hessian/HessianException.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+package com.caucho.hessian;
+
+/**
+ * Base runtime exception for Hessian exceptions.
+ */
+public class HessianException extends RuntimeException {
+	/**
+	 * Zero-arg constructor.
+	 */
+	public HessianException() {
+	}
+
+	/**
+	 * Create the exception.
+	 */
+	public HessianException(String message) {
+		super(message);
+	}
+
+	/**
+	 * Create the exception.
+	 */
+	public HessianException(String message, Throwable rootCause) {
+		super(message, rootCause);
+	}
+
+	/**
+	 * Create the exception.
+	 */
+	public HessianException(Throwable rootCause) {
+		super(rootCause);
+	}
+}
diff --git src/com/caucho/hessian/client/HessianConnectionException.java src/com/caucho/hessian/client/HessianConnectionException.java
new file mode 100644
index 0000000..7f31eee
--- /dev/null
+++ src/com/caucho/hessian/client/HessianConnectionException.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.client;
+
+import com.caucho.hessian.HessianException;
+
+/**
+ * Exception caused by failure of the client proxy to connect to the server.
+ */
+public class HessianConnectionException extends HessianException {
+  /**
+   * Zero-arg constructor.
+   */
+  public HessianConnectionException()
+  {
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianConnectionException(String message)
+  {
+    super(message);
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianConnectionException(String message, Throwable rootCause)
+  {
+    super(message, rootCause);
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianConnectionException(Throwable rootCause)
+  {
+    super(rootCause);
+  }
+}
diff --git src/com/caucho/hessian/client/HessianHttpProxyFactory.java src/com/caucho/hessian/client/HessianHttpProxyFactory.java
new file mode 100644
index 0000000..eeca0ad
--- /dev/null
+++ src/com/caucho/hessian/client/HessianHttpProxyFactory.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2009 hessdroid@gmail.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.caucho.hessian.client;
+
+import com.ast.util.CookieParser;
+import com.ast.util.CookieParser.Cookie;
+import com.caucho.hessian.io.HessianRemoteObject;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * <code>HessianHttpProxyFactory</code> extends the
+ * <code>HessianProxyFactory</code>'s capabilities, by adding support for HTTP
+ * Cookies. A cookie map is used to map Server/Paths to cookies
+ *
+ * @author <a href="mailto:wolf@wolfpaulus.com">Wolf Paulus</a>
+ * @version 1.0 Date: Nov 17, 2009
+ */
+
+public class HessianHttpProxyFactory extends HessianProxyFactory {
+    /*
+      * public Object create2(Class api, String urlName, ClassLoader loader)
+      * throws MalformedURLException { InvocationHandler handler = new
+      * HessianHttpProxy(this, new URL(urlName)); return
+      * Proxy.newProxyInstance(api.getClassLoader(), new Class[]{api,
+      * HessianRemoteObject.class}, handler); }
+      */
+
+    /**
+     * Creates a new proxy with the specified URL. The returned object is a
+     * proxy with the interface specified by api.
+     * <p/>
+     * <p/>
+     * <pre>
+     * String url = "http://localhost:8080/ejb/hello");
+     * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
+     * </pre>
+     *
+     * @param api     the interface the proxy class needs to implement
+     * @param urlName the URL where the client object is located.
+     * @param loader  <code>ClassLoader</code> to be used loading the proxy
+     *                instance's class
+     * @return a proxy to the object with the specified interface.
+     * @throws java.net.MalformedURLException if URL object cannot be created with the provided urlName
+     */
+    @SuppressWarnings({"unchecked"})
+    @Override
+    public <T> T create(Class<T> api, String urlName, ClassLoader loader) throws MalformedURLException {
+        //
+        // todo: since the api is already loaded, maybe the api class' classloader should be tried,
+        // in case the provided classloader fails.
+
+        InvocationHandler handler = new HessianHttpProxy(this, new URL(urlName));
+        return (T) Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
+    }
+
+    /**
+     * Clear the Cookie Cache, should be run on every logout.
+     */
+    public static void clearCookieCache() {
+        HessianHttpProxy.cookieMap.clear();
+    }
+
+    /**
+     * The <code>HessianHttpProxy</code> intercepts request and response, so that
+     * cookies can be read in the incoming response and written before an
+     * outgoing request is sent. Cookie strings are stored in a
+     * <code>Hashtable</code>; and the URL's host+path is used for the key.
+     * <p/>
+     * When the cookie string is retrieved, the path is shortened, all the way
+     * to / until a match is found.
+     * <p/>
+     * Available Header Fields are:
+     * <p/>
+     * Header Field: date (Wed, 18 Nov 2009 21:01:44 GMT)
+     * Header Field: content-type (application/x-hessian)
+     * Header Field: transfer-encoding (chunked)
+     * Header Field: server (Apache-Coyote/1.1)
+     * Header Field: set-cookie (JSESSIONID=5930D0459F0CE1B769ED5D08B031F9D2; Path=/Server)
+     */
+    private static class HessianHttpProxy extends HessianProxy {
+        private static final Logger log = Logger.getLogger(HessianHttpProxy.class.getName());
+        private static final HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>();
+
+        private static final String COOKIE_SET = "set-cookie";
+
+        HessianHttpProxy(HessianProxyFactory factory, URL url) {
+            super(url, factory);
+        }
+
+        /**
+         * Read cookies found in a server's response, so we can send them back
+         * with the next request. The response-header field names are the key
+         * values of the map.
+         *
+         * @param conn <code>URLConnection</code>
+         */
+        protected void parseResponseHeaders(URLConnection conn) {
+
+            List<String> cookieStrings = conn.getHeaderFields().get(HessianHttpProxy.COOKIE_SET);
+            if (cookieStrings != null) {
+                String host = conn.getURL().getHost();
+                for (String s : cookieStrings) {
+                    Cookie cookie = CookieParser.parse(host, s);
+                    HessianHttpProxy.cookieMap.put(cookie.host + cookie.path, cookie);
+                    log.finest("Cookie cached: " + cookie.host + cookie.path + ":" + s);
+                }
+            }
+        }
+
+        /**
+         * Add the cookies we received in a previous response, into the current
+         * request. The getUrl().getPath() might return something like this:
+         * /Server/comm Here we look for a close match in the cookiemap,
+         * starting with the most specific.
+         *
+         * @param conn <code>URLConnection</code>
+         */
+        protected void addRequestHeaders(URLConnection conn) {
+
+            String host = conn.getURL().getHost();
+            String path = conn.getURL().getPath();
+
+            while (path != null && 0 < path.length()) {
+                log.info("Host:+" + host +",Path:"+path);
+                Cookie cookie = HessianHttpProxy.cookieMap.get(host + path);
+                if (cookie != null) {
+                    conn.setRequestProperty("Cookie", cookie.value);
+                    log.finest("Cookie set in request:" + cookie.value);
+                    break;
+                }
+                int i = path.lastIndexOf("/");
+				if (0==i && 1<path.length()) {
+                    path = "/";
+                } else {
+                    path = path.substring(0, i);
+                }
+			}
+		}
+	}
+}
diff --git src/com/caucho/hessian/client/HessianMetaInfoAPI.java src/com/caucho/hessian/client/HessianMetaInfoAPI.java
new file mode 100644
index 0000000..74b528f
--- /dev/null
+++ src/com/caucho/hessian/client/HessianMetaInfoAPI.java
@@ -0,0 +1,66 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.client;
+
+/**
+ * API retrieving hessian meta information.
+ */
+public interface HessianMetaInfoAPI {
+  /**
+   * Returns a service attribute.
+   *
+   * <ul>
+   * <li>java.api.class - the Java interface for the object interface.
+   * <li>java.ejb.home.class - the EJB home interface
+   * <li>java.ejb.remote.class - the EJB remote interface
+   * <li>java.primary.key.class - the EJB primary key class
+   * </ul>
+   */
+  public Object _hessian_getAttribute(String name);
+}
diff --git src/com/caucho/hessian/client/HessianProxy.java src/com/caucho/hessian/client/HessianProxy.java
new file mode 100644
index 0000000..5beea3e
--- /dev/null
+++ src/com/caucho/hessian/client/HessianProxy.java
@@ -0,0 +1,450 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.client;
+
+import com.caucho.hessian.io.*;
+import com.caucho.services.server.AbstractSkeleton;
+
+import java.io.*;
+import java.util.logging.*;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.WeakHashMap;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+
+/**
+ * Proxy implementation for Hessian clients. Applications will generally use
+ * HessianProxyFactory to create proxy clients.
+ */
+public class HessianProxy implements InvocationHandler {
+	private static final Logger log = Logger.getLogger(HessianProxy.class
+			.getName());
+
+	protected HessianProxyFactory _factory;
+	private WeakHashMap<Method, String> _mangleMap = new WeakHashMap<Method, String>();
+	private URL _url;
+
+	/**
+	 * Package protected constructor for factory
+	 */
+	HessianProxy(HessianProxyFactory factory, URL url) {
+		_factory = factory;
+		_url = url;
+	}
+
+	/**
+	 * Protected constructor for subclassing
+	 */
+	protected HessianProxy(URL url, HessianProxyFactory factory) {
+		_factory = factory;
+		_url = url;
+	}
+
+	/**
+	 * Returns the proxy's URL.
+	 */
+	public URL getURL() {
+		return _url;
+	}
+
+	/**
+	 * Handles the object invocation.
+	 * 
+	 * @param proxy
+	 *            the proxy object to invoke
+	 * @param method
+	 *            the method to call
+	 * @param args
+	 *            the arguments to the proxy object
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args)
+			throws Throwable {
+		String mangleName;
+
+		synchronized (_mangleMap) {
+			mangleName = _mangleMap.get(method);
+		}
+
+		if (mangleName == null) {
+			String methodName = method.getName();
+			Class[] params = method.getParameterTypes();
+
+			// equals and hashCode are special cased
+			if (methodName.equals("equals") && params.length == 1
+					&& params[0].equals(Object.class)) {
+				Object value = args[0];
+				if (value == null || !Proxy.isProxyClass(value.getClass()))
+					return Boolean.FALSE;
+
+				HessianProxy handler = (HessianProxy) Proxy
+						.getInvocationHandler(value);
+
+				return Boolean.valueOf(_url.equals(handler.getURL()));
+			} else if (methodName.equals("hashCode") && params.length == 0)
+				return Integer.valueOf(_url.hashCode());
+			else if (methodName.equals("getHessianType"))
+				return proxy.getClass().getInterfaces()[0].getName();
+			else if (methodName.equals("getHessianURL"))
+				return _url.toString();
+			else if (methodName.equals("toString") && params.length == 0)
+				return "HessianProxy[" + _url + "]";
+
+			if (!_factory.isOverloadEnabled())
+				mangleName = method.getName();
+			else
+				mangleName = mangleName(method);
+
+			synchronized (_mangleMap) {
+				_mangleMap.put(method, mangleName);
+			}
+		}
+
+		InputStream is = null;
+		URLConnection conn = null;
+		HttpURLConnection httpConn = null;
+
+		try {
+			if (log.isLoggable(Level.FINER))
+				log.finer("Hessian[" + _url + "] calling " + mangleName);
+
+			conn = sendRequest(mangleName, args);
+
+			if (conn instanceof HttpURLConnection) {
+				httpConn = (HttpURLConnection) conn;
+				int code = 500;
+
+				try {
+					code = httpConn.getResponseCode();
+				} catch (Exception e) {
+				}
+
+				parseResponseHeaders(conn);
+
+				if (code != 200) {
+					StringBuffer sb = new StringBuffer();
+					int ch;
+
+					try {
+						is = httpConn.getInputStream();
+
+						if (is != null) {
+							while ((ch = is.read()) >= 0)
+								sb.append((char) ch);
+
+							is.close();
+						}
+
+						is = httpConn.getErrorStream();
+						if (is != null) {
+							while ((ch = is.read()) >= 0)
+								sb.append((char) ch);
+						}
+					} catch (FileNotFoundException e) {
+						throw new HessianConnectionException(
+								"HessianProxy cannot connect to '" + _url, e);
+					} catch (IOException e) {
+						if (is == null)
+							throw new HessianConnectionException(code + ": "
+									+ e, e);
+						else
+							throw new HessianConnectionException(code + ": "
+									+ sb, e);
+					}
+
+					if (is != null)
+						is.close();
+
+					throw new HessianConnectionException(code + ": "
+							+ sb.toString());
+				}
+			}
+
+			is = conn.getInputStream();
+
+			if (log.isLoggable(Level.FINEST)) {
+				PrintWriter dbg = new PrintWriter(new LogWriter(log));
+				is = new HessianDebugInputStream(is, dbg);
+			}
+
+			AbstractHessianInput in = _factory.getHessianInput(is);
+
+			in.startReply();
+
+			Object value = in.readObject(method.getReturnType());
+
+			if (value instanceof InputStream) {
+				value = new ResultInputStream(httpConn, is, in,
+						(InputStream) value);
+				is = null;
+				httpConn = null;
+			} else
+				in.completeReply();
+
+			return value;
+		} catch (HessianProtocolException e) {
+			throw new HessianRuntimeException(e);
+		} finally {
+			try {
+				if (is != null)
+					is.close();
+			} catch (Exception e) {
+				log.log(Level.FINE, e.toString(), e);
+			}
+
+			try {
+				if (httpConn != null)
+					httpConn.disconnect();
+			} catch (Exception e) {
+				log.log(Level.FINE, e.toString(), e);
+			}
+		}
+	}
+
+	protected String mangleName(Method method) {
+		Class[] param = method.getParameterTypes();
+
+		if (param == null || param.length == 0)
+			return method.getName();
+		else
+			return AbstractSkeleton.mangleName(method, false);
+	}
+
+	/**
+	 * Method that allows subclasses to parse response headers such as cookies.
+	 * Default implementation is empty.
+	 * 
+	 * @param conn
+	 */
+	protected void parseResponseHeaders(URLConnection conn) {
+
+	}
+
+	protected URLConnection sendRequest(String methodName, Object[] args)
+			throws IOException {
+		URLConnection conn = null;
+
+		conn = _factory.openConnection(_url);
+		boolean isValid = false;
+
+		try {
+			// Used chunked mode when available, i.e. JDK 1.5.
+			if (_factory.isChunkedPost() && conn instanceof HttpURLConnection) {
+				try {
+					HttpURLConnection httpConn = (HttpURLConnection) conn;
+
+					httpConn.setChunkedStreamingMode(8 * 1024);
+				} catch (Throwable e) {
+				}
+			}
+
+			addRequestHeaders(conn);
+
+			OutputStream os = null;
+
+			try {
+				os = conn.getOutputStream();
+			} catch (Exception e) {
+				throw new HessianRuntimeException(e);
+			}
+
+			if (log.isLoggable(Level.FINEST)) {
+				PrintWriter dbg = new PrintWriter(new LogWriter(log));
+				os = new HessianDebugOutputStream(os, dbg);
+			}
+
+			AbstractHessianOutput out = _factory.getHessianOutput(os);
+
+			out.call(methodName, args);
+			out.flush();
+
+			isValid = true;
+
+			return conn;
+		} finally {
+			if (!isValid && conn instanceof HttpURLConnection)
+				((HttpURLConnection) conn).disconnect();
+		}
+	}
+
+	/**
+	 * Method that allows subclasses to add request headers such as cookies.
+	 * Default implementation is empty.
+	 */
+	protected void addRequestHeaders(URLConnection conn) {
+
+	}
+
+	static class ResultInputStream extends InputStream {
+		private HttpURLConnection _conn;
+		private InputStream _connIs;
+		private AbstractHessianInput _in;
+		private InputStream _hessianIs;
+
+		ResultInputStream(HttpURLConnection conn, InputStream is,
+				AbstractHessianInput in, InputStream hessianIs) {
+			_conn = conn;
+			_connIs = is;
+			_in = in;
+			_hessianIs = hessianIs;
+		}
+
+		public int read() throws IOException {
+			if (_hessianIs != null) {
+				int value = _hessianIs.read();
+
+				if (value < 0)
+					close();
+
+				return value;
+			} else
+				return -1;
+		}
+
+		public int read(byte[] buffer, int offset, int length)
+				throws IOException {
+			if (_hessianIs != null) {
+				int value = _hessianIs.read(buffer, offset, length);
+
+				if (value < 0)
+					close();
+
+				return value;
+			} else
+				return -1;
+		}
+
+		public void close() throws IOException {
+			HttpURLConnection conn = _conn;
+			_conn = null;
+
+			InputStream connIs = _connIs;
+			_connIs = null;
+
+			AbstractHessianInput in = _in;
+			_in = null;
+
+			InputStream hessianIs = _hessianIs;
+			_hessianIs = null;
+
+			try {
+				if (hessianIs != null)
+					hessianIs.close();
+			} catch (Exception e) {
+				log.log(Level.FINE, e.toString(), e);
+			}
+
+			try {
+				if (in != null) {
+					in.completeReply();
+					in.close();
+				}
+			} catch (Exception e) {
+				log.log(Level.FINE, e.toString(), e);
+			}
+
+			try {
+				if (connIs != null) {
+					connIs.close();
+				}
+			} catch (Exception e) {
+				log.log(Level.FINE, e.toString(), e);
+			}
+
+			try {
+				if (conn != null) {
+					conn.disconnect();
+				}
+			} catch (Exception e) {
+				log.log(Level.FINE, e.toString(), e);
+			}
+		}
+	}
+
+	static class LogWriter extends Writer {
+		private Logger _log;
+		private Level _level = Level.FINEST;
+		private StringBuilder _sb = new StringBuilder();
+
+		LogWriter(Logger log) {
+			_log = log;
+		}
+
+		public void write(char ch) {
+			if (ch == '\n' && _sb.length() > 0) {
+				_log.fine(_sb.toString());
+				_sb.setLength(0);
+			} else
+				_sb.append((char) ch);
+		}
+
+		public void write(char[] buffer, int offset, int length) {
+			for (int i = 0; i < length; i++) {
+				char ch = buffer[offset + i];
+
+				if (ch == '\n' && _sb.length() > 0) {
+					_log.log(_level, _sb.toString());
+					_sb.setLength(0);
+				} else
+					_sb.append((char) ch);
+			}
+		}
+
+		public void flush() {
+		}
+
+		public void close() {
+			if (_sb.length() > 0)
+				_log.log(_level, _sb.toString());
+		}
+	}
+}
diff --git src/com/caucho/hessian/client/HessianProxyFactory.java src/com/caucho/hessian/client/HessianProxyFactory.java
new file mode 100644
index 0000000..39a8887
--- /dev/null
+++ src/com/caucho/hessian/client/HessianProxyFactory.java
@@ -0,0 +1,440 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.client;
+
+import com.caucho.hessian.io.*;
+import com.caucho.services.client.ServiceProxyFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.logging.Logger;
+
+/**
+ * Factory for creating Hessian client stubs.  The returned stub will
+ * call the remote object for all methods.
+ * <p/>
+ * <pre>
+ * String url = "http://localhost:8080/ejb/hello";
+ * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
+ * </pre>
+ * <p/>
+ * After creation, the stub can be like a regular Java class.  Because
+ * it makes remote calls, it can throw more exceptions than a Java class.
+ * In particular, it may throw protocol exceptions.
+ * <p/>
+ * <h3>Authentication</h3>
+ * <p/>
+ * <p>The proxy can use HTTP basic authentication if the user and the
+ * password are set.
+ */
+@SuppressWarnings({"UnusedDeclaration"})
+public class HessianProxyFactory implements ServiceProxyFactory {
+    protected static Logger log = Logger.getLogger(HessianProxyFactory.class.getName());
+
+    private SerializerFactory _serializerFactory;
+    private HessianRemoteResolver _resolver;
+
+    private String _user;
+    private String _password;
+    private String _basicAuth;
+
+    private boolean _isOverloadEnabled = false;
+
+    private boolean _isHessian2Reply = true;
+    private boolean _isHessian2Request = false;
+
+    private boolean _isChunkedPost = true;
+    private boolean _isDebug = false;
+
+    private long _readTimeout = -1;
+
+    /**
+     * Creates the new proxy factory.
+     */
+    public HessianProxyFactory() {
+        _resolver = new HessianProxyResolver(this);
+    }
+
+    /**
+     * Sets the user.
+     *
+     * @param user <code>String</code>
+     */
+    public void setUser(String user) {
+        _user = user;
+        _basicAuth = null;
+    }
+
+    /**
+     * Sets the password.
+     *
+     * @param password <code>String</code>
+     */
+    public void setPassword(String password) {
+        _password = password;
+        _basicAuth = null;
+    }
+
+    /**
+     * Sets the debug
+     *
+     * @param isDebug <code>boolean</code>
+     */
+    public void setDebug(boolean isDebug) {
+        _isDebug = isDebug;
+    }
+
+    /**
+     * Gets the debug
+     *
+     * @return <code>boolean</code>
+     */
+    public boolean isDebug() {
+        return _isDebug;
+    }
+
+    /**
+     * Returns true if overloaded methods are allowed (using mangling)
+     *
+     * @return <code>boolean</code>
+     */
+    public boolean isOverloadEnabled() {
+        return _isOverloadEnabled;
+    }
+
+    /**
+     * set true if overloaded methods are allowed (using mangling)
+     *
+     * @param isOverloadEnabled <code>boolean</code>
+     */
+    public void setOverloadEnabled(boolean isOverloadEnabled) {
+        _isOverloadEnabled = isOverloadEnabled;
+    }
+
+    /**
+     * Set true if should use chunked encoding on the request.
+     *
+     * @param isChunked <code>boolean</code>
+     */
+    public void setChunkedPost(boolean isChunked) {
+        _isChunkedPost = isChunked;
+    }
+
+    /**
+     * Set true if should use chunked encoding on the request.
+     *
+     * @return <code>boolean</code>
+     */
+    public boolean isChunkedPost() {
+        return _isChunkedPost;
+    }
+
+    /**
+     * The socket timeout on requests in milliseconds.
+     *
+     * @return <code>long</code>
+     */
+    public long getReadTimeout() {
+        return _readTimeout;
+    }
+
+    /**
+     * The socket timeout on requests in milliseconds.
+     *
+     * @param timeout <code>long</code>
+     */
+    public void setReadTimeout(long timeout) {
+        _readTimeout = timeout;
+    }
+
+    /**
+     * True if the proxy can read Hessian 2 responses.
+     *
+     * @param isHessian2 <code>boolean</code>
+     */
+    public void setHessian2Reply(boolean isHessian2) {
+        _isHessian2Reply = isHessian2;
+    }
+
+    /**
+     * True if the proxy should send Hessian 2 requests.
+     *
+     * @param isHessian2 <code>boolean</code>
+     */
+    public void setHessian2Request(boolean isHessian2) {
+        _isHessian2Request = isHessian2;
+
+        if (isHessian2)
+            _isHessian2Reply = true;
+    }
+
+    /**
+     * @return <code>HessianRemoteResolver</code> the remote resolver.
+     */
+    public HessianRemoteResolver getRemoteResolver() {
+        return _resolver;
+    }
+
+    /**
+     * Sets the serializer factory.
+     *
+     * @param factory <code>SerializerFactory</code>
+     */
+    public void setSerializerFactory(SerializerFactory factory) {
+        _serializerFactory = factory;
+    }
+
+    /**
+     * Gets the serializer factory.
+     *
+     * @return <code>SerializerFactory</code>
+     */
+    public SerializerFactory getSerializerFactory() {
+        if (_serializerFactory == null)
+            _serializerFactory = new SerializerFactory();
+
+        return _serializerFactory;
+    }
+
+    /**
+     * Creates the URL connection.
+     *
+     * @param url <coe>URL</code>
+     * @return <code>URLConnection</code>
+     * @throws IOException if connection cannot be opened
+     */
+    protected URLConnection openConnection(URL url)
+            throws IOException {
+        URLConnection conn = url.openConnection();
+
+        conn.setDoOutput(true);
+
+        if (_readTimeout > 0) {
+            try {
+                conn.setReadTimeout((int) _readTimeout);
+            } catch (Throwable e) { // intentionally empty
+            }
+        }
+
+        conn.setRequestProperty("Content-Type", "x-application/hessian");
+
+        if (_basicAuth != null)
+            conn.setRequestProperty("Authorization", _basicAuth);
+        else if (_user != null && _password != null) {
+            _basicAuth = "Basic " + base64(_user + ":" + _password);
+            conn.setRequestProperty("Authorization", _basicAuth);
+        }
+
+        return conn;
+    }
+
+    /**
+     * Creates a new proxy with the specified URL.  The API class uses
+     * the java.api.class value from _hessian_
+     *
+     * @param urlName the URL where the client object is located.
+     * @return a proxy to the object with the specified interface.
+     * @throws java.net.MalformedURLException if URL object cannot be created with the provided urlName
+     * @throws ClassNotFoundException         if the current Thread's contextClassLoader cannot find the api class
+     */
+    @SuppressWarnings({"unchecked"})
+    public Object create(String urlName) throws MalformedURLException, ClassNotFoundException {
+        HessianMetaInfoAPI metaInfo = create(HessianMetaInfoAPI.class, urlName);
+        String apiClassName = (String) metaInfo._hessian_getAttribute("java.api.class");
+
+        if (apiClassName == null) {
+            throw new HessianRuntimeException(urlName + " has an unknown api.");
+        }
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        Class<Object> apiClass = (Class<Object>) Class.forName(apiClassName, false, loader);
+        return create(apiClass, urlName);
+    }
+
+    /**
+     * Creates a new proxy with the specified URL.  The returned object
+     * is a proxy with the interface specified by api.
+     * <p/>
+     * <pre>
+     * String url = "http://localhost:8080/ejb/hello");
+     * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
+     * </pre>
+     *
+     * @param api     the interface the proxy class needs to implement
+     * @param urlName the URL where the client object is located.
+     * @return a proxy to the object with the specified interface.
+     */
+    public <T>T create(Class<T> api, String urlName) throws MalformedURLException {
+        return create(api, urlName, Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Creates a new proxy with the specified URL.  The returned object
+     * is a proxy with the interface specified by api.
+     * <p/>
+     * <pre>
+     * String url = "http://localhost:8080/ejb/hello");
+     * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
+     * </pre>
+     *
+     * @param api     the interface the proxy class needs to implement
+     * @param urlName the URL where the client object is located.
+     * @param loader  <code>ClassLoader</code> to be used loading the proxy instance's class
+     * @return a proxy to the object with the specified interface.
+     * @throws java.net.MalformedURLException if URL object cannot be created with the provided urlName
+     */
+    @SuppressWarnings({"unchecked"})
+    public <T>T create(Class<T> api, String urlName, ClassLoader loader) throws MalformedURLException {
+        if (api == null) {
+            throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
+        }
+        InvocationHandler handler;
+        URL url = new URL(urlName);
+        handler = new HessianProxy(this, url);
+        return (T) Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
+    }
+
+    public AbstractHessianInput getHessianInput(InputStream is) {
+        AbstractHessianInput in;
+
+        if (_isDebug)
+            is = new HessianDebugInputStream(is, new PrintWriter(System.out));
+
+        in = new Hessian2Input(is);
+
+        in.setRemoteResolver(getRemoteResolver());
+
+        in.setSerializerFactory(getSerializerFactory());
+
+        return in;
+    }
+
+    public AbstractHessianOutput getHessianOutput(OutputStream os) {
+        AbstractHessianOutput out;
+
+        if (_isHessian2Request)
+            out = new Hessian2Output(os);
+        else {
+            HessianOutput out1 = new HessianOutput(os);
+            out = out1;
+
+            if (_isHessian2Reply)
+                out1.setVersion(2);
+        }
+
+        out.setSerializerFactory(getSerializerFactory());
+
+        return out;
+    }
+
+
+    /**
+     * Creates the Base64 value.
+     *
+     * @param value <code>String</code>
+     * @return <code>String</code> base65 encoded String
+     */
+    private String base64(String value) {
+        StringBuffer cb = new StringBuffer();
+
+        int i;
+        for (i = 0; i + 2 < value.length(); i += 3) {
+            long chunk = (int) value.charAt(i);
+            chunk = (chunk << 8) + (int) value.charAt(i + 1);
+            chunk = (chunk << 8) + (int) value.charAt(i + 2);
+
+            cb.append(encode(chunk >> 18));
+            cb.append(encode(chunk >> 12));
+            cb.append(encode(chunk >> 6));
+            cb.append(encode(chunk));
+        }
+
+        if (i + 1 < value.length()) {
+            long chunk = (int) value.charAt(i);
+            chunk = (chunk << 8) + (int) value.charAt(i + 1);
+            chunk <<= 8;
+
+            cb.append(encode(chunk >> 18));
+            cb.append(encode(chunk >> 12));
+            cb.append(encode(chunk >> 6));
+            cb.append('=');
+        } else if (i < value.length()) {
+            long chunk = (int) value.charAt(i);
+            chunk <<= 16;
+
+            cb.append(encode(chunk >> 18));
+            cb.append(encode(chunk >> 12));
+            cb.append('=');
+            cb.append('=');
+        }
+
+        return cb.toString();
+    }
+
+    public static char encode(long d) {
+        d &= 0x3f;
+        if (d < 26)
+            return (char) (d + 'A');
+        else if (d < 52)
+            return (char) (d + 'a' - 26);
+        else if (d < 62)
+            return (char) (d + '0' - 52);
+        else if (d == 62)
+            return '+';
+        else
+            return '/';
+    }
+}
+
diff --git src/com/caucho/hessian/client/HessianProxyResolver.java src/com/caucho/hessian/client/HessianProxyResolver.java
new file mode 100644
index 0000000..36a1a7c
--- /dev/null
+++ src/com/caucho/hessian/client/HessianProxyResolver.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.client;
+
+import com.caucho.hessian.io.HessianRemoteResolver;
+
+import java.io.IOException;
+
+/**
+ * Looks up remote objects in the proxy.
+ */
+public class HessianProxyResolver implements HessianRemoteResolver {
+  private HessianProxyFactory _factory;
+  
+  /**
+   * Creates an uninitialized Hessian remote resolver.
+   */
+  public HessianProxyResolver(HessianProxyFactory factory)
+  {
+    _factory = factory;
+  }
+
+  /**
+   * Looks up a proxy object.
+   */
+  public Object lookup(String type, String url)
+    throws IOException
+  {
+    ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+    try {
+      Class api = Class.forName(type, false, loader);
+
+      return _factory.create(api, url);
+    } catch (Exception e) {
+      throw new IOException(String.valueOf(e));
+    }
+  }
+}
diff --git src/com/caucho/hessian/client/HessianRuntimeException.java src/com/caucho/hessian/client/HessianRuntimeException.java
new file mode 100644
index 0000000..8487a10
--- /dev/null
+++ src/com/caucho/hessian/client/HessianRuntimeException.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.client;
+
+/**
+ * Wrapper for protocol exceptions thrown in the proxy.
+ */
+public class HessianRuntimeException extends RuntimeException {
+  private Throwable rootCause;
+
+  /**
+   * Zero-arg constructor.
+   */
+  public HessianRuntimeException()
+  {
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianRuntimeException(String message)
+  {
+    super(message);
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianRuntimeException(String message, Throwable rootCause)
+  {
+    super(message);
+
+    this.rootCause = rootCause;
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianRuntimeException(Throwable rootCause)
+  {
+    super(String.valueOf(rootCause));
+
+    this.rootCause = rootCause;
+  }
+
+  /**
+   * Returns the underlying cause.
+   */
+  public Throwable getRootCause()
+  {
+    return this.rootCause;
+  }
+
+  /**
+   * Returns the underlying cause.
+   */
+  public Throwable getCause()
+  {
+    return getRootCause();
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractDeserializer.java src/com/caucho/hessian/io/AbstractDeserializer.java
new file mode 100644
index 0000000..75c1a99
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractDeserializer.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Deserializing an object. 
+ */
+abstract public class AbstractDeserializer implements Deserializer {
+  public Class getType()
+  {
+    return Object.class;
+  }
+
+  public Object readObject(AbstractHessianInput in)
+    throws IOException
+  {
+    Object obj = in.readObject();
+
+    String className = getClass().getName();
+
+    if (obj != null)
+      throw error(className + ": unexpected object " + obj.getClass().getName() + " (" + obj + ")");
+    else
+      throw error(className + ": unexpected null value");
+  }
+  
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    throw new UnsupportedOperationException(String.valueOf(this));
+  }
+  
+  public Object readLengthList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    throw new UnsupportedOperationException(String.valueOf(this));
+  }
+  
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    Object obj = in.readObject();
+
+    String className = getClass().getName();
+
+    if (obj != null)
+      throw error(className + ": unexpected object " + obj.getClass().getName() + " (" + obj + ")");
+    else
+      throw error(className + ": unexpected null value");
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    throw new UnsupportedOperationException(String.valueOf(this));
+  }
+
+  protected HessianProtocolException error(String msg)
+  {
+    return new HessianProtocolException(msg);
+  }
+
+  protected String codeName(int ch)
+  {
+    if (ch < 0)
+      return "end of file";
+    else
+      return "0x" + Integer.toHexString(ch & 0xff);
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractHessianInput.java src/com/caucho/hessian/io/AbstractHessianInput.java
new file mode 100644
index 0000000..5bfa196
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractHessianInput.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Abstract base class for Hessian requests.  Hessian users should only
+ * need to use the methods in this class.
+ *
+ * <pre>
+ * AbstractHessianInput in = ...; // get input
+ * String value;
+ *
+ * in.startReply();         // read reply header
+ * value = in.readString(); // read string value
+ * in.completeReply();      // read reply footer
+ * </pre>
+ */
+abstract public class AbstractHessianInput {
+  private HessianRemoteResolver resolver;
+  
+  /**
+   * Initialize the Hessian stream with the underlying input stream.
+   */
+  public void init(InputStream is)
+  {
+  }
+
+  /**
+   * Returns the call's method
+   */
+  abstract public String getMethod();
+
+  /**
+   * Sets the resolver used to lookup remote objects.
+   */
+  public void setRemoteResolver(HessianRemoteResolver resolver)
+  {
+    this.resolver = resolver;
+  }
+
+  /**
+   * Sets the resolver used to lookup remote objects.
+   */
+  public HessianRemoteResolver getRemoteResolver()
+  {
+    return resolver;
+  }
+
+  /**
+   * Sets the serializer factory.
+   */
+  public void setSerializerFactory(SerializerFactory ser)
+  {
+  }
+
+  /**
+   * Reads the call
+   *
+   * <pre>
+   * c major minor
+   * </pre>
+   */
+  abstract public int readCall()
+    throws IOException;
+
+  /**
+   * For backward compatibility with HessianSkeleton
+   */
+  public void skipOptionalCall()
+    throws IOException
+  {
+  }
+
+  /**
+   * Reads a header, returning null if there are no headers.
+   *
+   * <pre>
+   * H b16 b8 value
+   * </pre>
+   */
+  abstract public String readHeader()
+    throws IOException;
+
+  /**
+   * Starts reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * m b16 b8 method
+   * </pre>
+   */
+  abstract public String readMethod()
+    throws IOException;
+
+  /**
+   * Starts reading the call, including the headers.
+   *
+   * <p>The call expects the following protocol data
+   *
+   * <pre>
+   * c major minor
+   * m b16 b8 method
+   * </pre>
+   */
+  abstract public void startCall()
+    throws IOException;
+
+  /**
+   * Completes reading the call
+   *
+   * <p>The call expects the following protocol data
+   *
+   * <pre>
+   * Z
+   * </pre>
+   */
+  abstract public void completeCall()
+    throws IOException;
+
+  /**
+   * Reads a reply as an object.
+   * If the reply has a fault, throws the exception.
+   */
+  abstract public Object readReply(Class expectedClass)
+    throws Throwable;
+  
+  /**
+   * Starts reading the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * r
+   * v
+   * </pre>
+   */
+  abstract public void startReply()
+    throws Throwable;
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  abstract public void completeReply()
+    throws IOException;
+
+  /**
+   * Reads a boolean
+   *
+   * <pre>
+   * T
+   * F
+   * </pre>
+   */
+  abstract public boolean readBoolean()
+    throws IOException;
+
+  /**
+   * Reads a null
+   *
+   * <pre>
+   * N
+   * </pre>
+   */
+  abstract public void readNull()
+    throws IOException;
+
+  /**
+   * Reads an integer
+   *
+   * <pre>
+   * I b32 b24 b16 b8
+   * </pre>
+   */
+  abstract public int readInt()
+    throws IOException;
+
+  /**
+   * Reads a long
+   *
+   * <pre>
+   * L b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  abstract public long readLong()
+    throws IOException;
+
+  /**
+   * Reads a double.
+   *
+   * <pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  abstract public double readDouble()
+    throws IOException;
+
+  /**
+   * Reads a date.
+   *
+   * <pre>
+   * T b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  abstract public long readUTCDate()
+    throws IOException;
+
+  /**
+   * Reads a string encoded in UTF-8
+   *
+   * <pre>
+   * s b16 b8 non-final string chunk
+   * S b16 b8 final string chunk
+   * </pre>
+   */
+  abstract public String readString()
+    throws IOException;
+
+  /**
+   * Reads an XML node encoded in UTF-8
+   *
+   * <pre>
+   * x b16 b8 non-final xml chunk
+   * X b16 b8 final xml chunk
+   * </pre>
+   */
+  abstract public org.w3c.dom.Node readNode()
+    throws IOException;
+  
+  /**
+   * Starts reading a string.  All the characters must be read before
+   * calling the next method.  The actual characters will be read with
+   * the reader's read() or read(char [], int, int).
+   *
+   * <pre>
+   * s b16 b8 non-final string chunk
+   * S b16 b8 final string chunk
+   * </pre>
+   */
+  abstract public Reader getReader()
+    throws IOException;
+
+  /**
+   * Starts reading a byte array using an input stream.  All the bytes
+   * must be read before calling the following method.
+   *
+   * <pre>
+   * b b16 b8 non-final binary chunk
+   * B b16 b8 final binary chunk
+   * </pre>
+   */
+  abstract public InputStream readInputStream()
+    throws IOException;
+
+  /**
+   * Reads a byte array.
+   *
+   * <pre>
+   * b b16 b8 non-final binary chunk
+   * B b16 b8 final binary chunk
+   * </pre>
+   */
+  abstract public byte []readBytes()
+    throws IOException;
+
+  /**
+   * Reads an arbitrary object from the input stream.
+   *
+   * @param expectedClass the expected class if the protocol doesn't supply it.
+   */
+  abstract public Object readObject(Class expectedClass)
+    throws IOException;
+
+  /**
+   * Reads an arbitrary object from the input stream.
+   */
+  abstract public Object readObject()
+    throws IOException;
+
+  /**
+   * Reads a remote object reference to the stream.  The type is the
+   * type of the remote interface.
+   *
+   * <code><pre>
+   * 'r' 't' b16 b8 type url
+   * </pre></code>
+   */
+  abstract public Object readRemote()
+    throws IOException;
+
+  /**
+   * Reads a reference
+   *
+   * <pre>
+   * R b32 b24 b16 b8
+   * </pre>
+   */
+  abstract public Object readRef()
+    throws IOException;
+
+  /**
+   * Adds an object reference.
+   */
+  abstract public int addRef(Object obj)
+    throws IOException;
+
+  /**
+   * Sets an object reference.
+   */
+  abstract public void setRef(int i, Object obj)
+    throws IOException;
+
+  /**
+   * Resets the references for streaming.
+   */
+  public void resetReferences()
+  {
+  }
+
+  /**
+   * Reads the start of a list
+   */
+  abstract public int readListStart()
+    throws IOException;    
+
+  /**
+   * Reads the length of a list.
+   */
+  abstract public int readLength()
+    throws IOException;    
+
+  /**
+   * Reads the start of a map
+   */
+  abstract public int readMapStart()
+    throws IOException;    
+
+  /**
+   * Reads an object type.
+   */
+  abstract public String readType()
+    throws IOException;    
+
+  /**
+   * Returns true if the data has ended.
+   */
+  abstract public boolean isEnd()
+    throws IOException;
+
+  /**
+   * Read the end byte
+   */
+  abstract public void readEnd()
+    throws IOException;
+
+  /**
+   * Read the end byte
+   */
+  abstract public void readMapEnd()
+    throws IOException;
+
+  /**
+   * Read the end byte
+   */
+  abstract public void readListEnd()
+    throws IOException;
+  
+  public void close()
+    throws IOException
+  {
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractHessianOutput.java src/com/caucho/hessian/io/AbstractHessianOutput.java
new file mode 100644
index 0000000..9cb209e
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractHessianOutput.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Abstract output stream for Hessian requests.
+ *
+ * <pre>
+ * OutputStream os = ...; // from http connection
+ * AbstractOutput out = new HessianSerializerOutput(os);
+ * String value;
+ *
+ * out.startCall("hello");  // start hello call
+ * out.writeString("arg1"); // write a string argument
+ * out.completeCall();      // complete the call
+ * </pre>
+ */
+abstract public class AbstractHessianOutput {
+  // serializer factory
+  protected SerializerFactory _serializerFactory;
+
+  /**
+   * Sets the serializer factory.
+   */
+  public void setSerializerFactory(SerializerFactory factory)
+  {
+    _serializerFactory = factory;
+  }
+
+  /**
+   * Gets the serializer factory.
+   */
+  public SerializerFactory getSerializerFactory()
+  {
+    return _serializerFactory;
+  }
+
+  /**
+   * Gets the serializer factory.
+   */
+  public final SerializerFactory findSerializerFactory()
+  {
+    SerializerFactory factory = _serializerFactory;
+
+    if (factory == null)
+      _serializerFactory = factory = new SerializerFactory();
+
+    return factory;
+  }
+  
+  /**
+   * Initialize the output with a new underlying stream.
+   */
+  public void init(OutputStream os)
+  {
+  }
+
+  /**
+   * Writes a complete method call.
+   */
+  public void call(String method, Object []args)
+    throws IOException
+  {
+    startCall(method);
+    
+    if (args != null) {
+      for (int i = 0; i < args.length; i++)
+        writeObject(args[i]);
+    }
+    
+    completeCall();
+  }
+
+  /**
+   * Starts the method call:
+   *
+   * <code><pre>
+   * c major minor
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  abstract public void startCall()
+    throws IOException;
+
+  /**
+   * Starts the method call:
+   *
+   * <code><pre>
+   * c major minor
+   * m b16 b8 method-namek
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  abstract public void startCall(String method)
+    throws IOException;
+
+  /**
+   * Writes a header name.  The header value must immediately follow.
+   *
+   * <code><pre>
+   * H b16 b8 foo <em>value</em>
+   * </pre></code>
+   */
+  abstract public void writeHeader(String name)
+    throws IOException;
+
+  /**
+   * Writes the method tag.
+   *
+   * <code><pre>
+   * m b16 b8 method-name
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  abstract public void writeMethod(String method)
+    throws IOException;
+
+  /**
+   * Completes the method call:
+   *
+   * <code><pre>
+   * z
+   * </pre></code>
+   */
+  abstract public void completeCall()
+    throws IOException;
+
+  /**
+   * Writes a boolean value to the stream.  The boolean will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * T
+   * F
+   * </pre></code>
+   *
+   * @param value the boolean value to write.
+   */
+  abstract public void writeBoolean(boolean value)
+    throws IOException;
+
+  /**
+   * Writes an integer value to the stream.  The integer will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * I b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the integer value to write.
+   */
+  abstract public void writeInt(int value)
+    throws IOException;
+
+  /**
+   * Writes a long value to the stream.  The long will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * L b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the long value to write.
+   */
+  abstract public void writeLong(long value)
+    throws IOException;
+
+  /**
+   * Writes a double value to the stream.  The double will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the double value to write.
+   */
+  abstract public void writeDouble(double value)
+    throws IOException;
+
+  /**
+   * Writes a date to the stream.
+   *
+   * <code><pre>
+   * T  b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param time the date in milliseconds from the epoch in UTC
+   */
+  abstract public void writeUTCDate(long time)
+    throws IOException;
+
+  /**
+   * Writes a null value to the stream.
+   * The null will be written with the following syntax
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeNull()
+    throws IOException;
+
+  /**
+   * Writes a string value to the stream using UTF-8 encoding.
+   * The string will be written with the following syntax:
+   *
+   * <code><pre>
+   * S b16 b8 string-value
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeString(String value)
+    throws IOException;
+
+  /**
+   * Writes a string value to the stream using UTF-8 encoding.
+   * The string will be written with the following syntax:
+   *
+   * <code><pre>
+   * S b16 b8 string-value
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeString(char []buffer, int offset, int length)
+    throws IOException;
+
+  /**
+   * Writes a byte array to the stream.
+   * The array will be written with the following syntax:
+   *
+   * <code><pre>
+   * B b16 b18 bytes
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeBytes(byte []buffer)
+    throws IOException;
+  /**
+   * Writes a byte array to the stream.
+   * The array will be written with the following syntax:
+   *
+   * <code><pre>
+   * B b16 b18 bytes
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeBytes(byte []buffer, int offset, int length)
+    throws IOException;
+  
+  /**
+   * Writes a byte buffer to the stream.
+   */
+  abstract public void writeByteBufferStart()
+    throws IOException;
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * b b16 b18 bytes
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeByteBufferPart(byte []buffer,
+					   int offset,
+					   int length)
+    throws IOException;
+  
+  /**
+   * Writes the last chunk of a byte buffer to the stream.
+   *
+   * <code><pre>
+   * b b16 b18 bytes
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  abstract public void writeByteBufferEnd(byte []buffer,
+					  int offset,
+					  int length)
+    throws IOException;
+
+  /**
+   * Writes a reference.
+   *
+   * <code><pre>
+   * R b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the integer value to write.
+   */
+  abstract public void writeRef(int value)
+    throws IOException;
+
+  /**
+   * Removes a reference.
+   */
+  abstract public boolean removeRef(Object obj)
+    throws IOException;
+
+  /**
+   * Replaces a reference from one object to another.
+   */
+  abstract public boolean replaceRef(Object oldRef, Object newRef)
+    throws IOException;
+
+  /**
+   * Adds an object to the reference list.  If the object already exists,
+   * writes the reference, otherwise, the caller is responsible for
+   * the serialization.
+   *
+   * <code><pre>
+   * R b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param object the object to add as a reference.
+   *
+   * @return true if the object has already been written.
+   */
+  abstract public boolean addRef(Object object)
+    throws IOException;
+
+  /**
+   * Resets the references for streaming.
+   */
+  public void resetReferences()
+  {
+  }
+
+  /**
+   * Writes a generic object to the output stream.
+   */
+  abstract public void writeObject(Object object)
+    throws IOException;
+
+  /**
+   * Writes the list header to the stream.  List writers will call
+   * <code>writeListBegin</code> followed by the list contents and then
+   * call <code>writeListEnd</code>.
+   *
+   * <code><pre>
+   * &lt;list>
+   *   &lt;type>java.util.ArrayList&lt;/type>
+   *   &lt;length>3&lt;/length>
+   *   &lt;int>1&lt;/int>
+   *   &lt;int>2&lt;/int>
+   *   &lt;int>3&lt;/int>
+   * &lt;/list>
+   * </pre></code>
+   */
+  abstract public boolean writeListBegin(int length, String type)
+    throws IOException;
+
+  /**
+   * Writes the tail of the list to the stream.
+   */
+  abstract public void writeListEnd()
+    throws IOException;
+
+  /**
+   * Writes the map header to the stream.  Map writers will call
+   * <code>writeMapBegin</code> followed by the map contents and then
+   * call <code>writeMapEnd</code>.
+   *
+   * <code><pre>
+   * Mt b16 b8 type (<key> <value>)z
+   * </pre></code>
+   */
+  abstract public void writeMapBegin(String type)
+    throws IOException;
+
+  /**
+   * Writes the tail of the map to the stream.
+   */
+  abstract public void writeMapEnd()
+    throws IOException;
+
+  /**
+   * Writes the object header to the stream (for Hessian 2.0), or a
+   * Map for Hessian 1.0.  Object writers will call
+   * <code>writeObjectBegin</code> followed by the map contents and then
+   * call <code>writeObjectEnd</code>.
+   *
+   * <code><pre>
+   * Ot b16 b8 type (<key> <value>)* z
+   * o b32 b24 b16 b8 <value>* z
+   * </pre></code>
+   *
+   * @return true if the object has already been defined.
+   */
+  public int writeObjectBegin(String type)
+    throws IOException
+  {
+    writeMapBegin(type);
+    
+    return -2;
+  }
+
+  /**
+   * Writes the end of the class.
+   */
+  public void writeClassFieldLength(int len)
+    throws IOException
+  {
+  }
+
+  /**
+   * Writes the tail of the object to the stream.
+   */
+  public void writeObjectEnd()
+    throws IOException
+  {
+  }
+
+  /**
+   * Writes a remote object reference to the stream.  The type is the
+   * type of the remote interface.
+   *
+   * <code><pre>
+   * 'r' 't' b16 b8 type url
+   * </pre></code>
+   */
+  abstract public void writeRemote(String type, String url)
+    throws IOException;
+  
+  public void startReply()
+    throws IOException
+  {
+  }
+  
+  public void completeReply()
+    throws IOException
+  {
+  }
+  
+  public void writeFault(String code, String message, Object detail)
+    throws IOException
+  {
+  }
+
+  public void flush()
+    throws IOException
+  {
+  }
+
+  public void close()
+    throws IOException
+  {
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractHessianResolver.java src/com/caucho/hessian/io/AbstractHessianResolver.java
new file mode 100644
index 0000000..8c86482
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractHessianResolver.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Looks up remote objects.  The default just returns a HessianRemote object.
+ */
+public class AbstractHessianResolver implements HessianRemoteResolver {
+  /**
+   * Looks up a proxy object.
+   */
+  public Object lookup(String type, String url)
+    throws IOException
+  {
+    return new HessianRemote(type, url);
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractListDeserializer.java src/com/caucho/hessian/io/AbstractListDeserializer.java
new file mode 100644
index 0000000..2fb3fd9
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractListDeserializer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Deserializing a JDK 1.2 Collection.
+ */
+public class AbstractListDeserializer extends AbstractDeserializer {
+  public Object readObject(AbstractHessianInput in)
+    throws IOException
+  {
+    Object obj = in.readObject();
+
+    if (obj != null)
+      throw error("expected list at " + obj.getClass().getName() + " (" + obj + ")");
+    else
+      throw error("expected list at null");
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractMapDeserializer.java src/com/caucho/hessian/io/AbstractMapDeserializer.java
new file mode 100644
index 0000000..d0203ce
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractMapDeserializer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class AbstractMapDeserializer extends AbstractDeserializer {
+  
+  public Class getType()
+  {
+    return HashMap.class;
+  }
+  
+  public Object readObject(AbstractHessianInput in)
+    throws IOException
+  {
+    Object obj = in.readObject();
+
+    if (obj != null)
+      throw error("expected map/object at " + obj.getClass().getName() + " (" + obj + ")");
+    else
+      throw error("expected map/object at null");
+  }
+}
diff --git src/com/caucho/hessian/io/AbstractSerializer.java src/com/caucho/hessian/io/AbstractSerializer.java
new file mode 100644
index 0000000..0939680
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractSerializer.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.logging.*;
+
+/**
+ * Serializing an object. 
+ */
+abstract public class AbstractSerializer implements Serializer {
+  protected static final Logger log
+    = Logger.getLogger(AbstractSerializer.class.getName());
+  
+  abstract public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException;
+}
diff --git src/com/caucho/hessian/io/AbstractSerializerFactory.java src/com/caucho/hessian/io/AbstractSerializerFactory.java
new file mode 100644
index 0000000..6fbe292
--- /dev/null
+++ src/com/caucho/hessian/io/AbstractSerializerFactory.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+/**
+ * Factory for returning serialization methods.
+ */
+abstract public class AbstractSerializerFactory {
+  /**
+   * Returns the serializer for a class.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  abstract public Serializer getSerializer(Class cl)
+    throws HessianProtocolException;
+
+  /**
+   * Returns the deserializer for a class.
+   *
+   * @param cl the class of the object that needs to be deserialized.
+   *
+   * @return a deserializer object for the serialization.
+   */
+  abstract public Deserializer getDeserializer(Class cl)
+    throws HessianProtocolException;
+}
diff --git src/com/caucho/hessian/io/ArrayDeserializer.java src/com/caucho/hessian/io/ArrayDeserializer.java
new file mode 100644
index 0000000..ed9b53f
--- /dev/null
+++ src/com/caucho/hessian/io/ArrayDeserializer.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+
+/**
+ * Deserializing a Java array
+ */
+public class ArrayDeserializer extends AbstractListDeserializer {
+  private Class _componentType;
+  private Class _type;
+  
+  public ArrayDeserializer(Class componentType)
+  {
+    _componentType = componentType;
+    
+    if (_componentType != null) {
+      try {
+        _type = Array.newInstance(_componentType, 0).getClass();
+      } catch (Exception e) {
+      }
+    }
+
+    if (_type == null)
+      _type = Object[].class;
+  }
+
+  public Class getType()
+  {
+    return _type;
+  }
+
+  /**
+   * Reads the array.
+   */
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    if (length >= 0) {
+      Object []data = createArray(length);
+
+      in.addRef(data);
+      
+      if (_componentType != null) {
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readObject(_componentType);
+      }
+      else {
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readObject();
+      }
+
+      in.readListEnd();
+
+      return data;
+    }
+    else {
+      ArrayList list = new ArrayList();
+
+      in.addRef(list);
+
+      if (_componentType != null) {
+        while (! in.isEnd())
+          list.add(in.readObject(_componentType));
+      }
+      else {
+        while (! in.isEnd())
+          list.add(in.readObject());
+      }
+
+      in.readListEnd();
+
+      Object []data = createArray(list.size());
+      for (int i = 0; i < data.length; i++)
+        data[i] = list.get(i);
+
+      return data;
+    }
+  }
+
+  /**
+   * Reads the array.
+   */
+  public Object readLengthList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    Object []data = createArray(length);
+
+    in.addRef(data);
+      
+    if (_componentType != null) {
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readObject(_componentType);
+    }
+    else {
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readObject();
+    }
+
+    return data;
+  }
+
+  protected Object []createArray(int length)
+  {
+    if (_componentType != null)
+      return (Object []) Array.newInstance(_componentType, length);
+    else
+      return new Object[length];
+  }
+
+  public String toString()
+  {
+    return "ArrayDeserializer[" + _componentType + "]";
+  }
+}
diff --git src/com/caucho/hessian/io/ArraySerializer.java src/com/caucho/hessian/io/ArraySerializer.java
new file mode 100644
index 0000000..85d033e
--- /dev/null
+++ src/com/caucho/hessian/io/ArraySerializer.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Serializing a Java array.
+ */
+public class ArraySerializer extends AbstractSerializer {
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (out.addRef(obj))
+      return;
+
+    Object []array = (Object []) obj;
+
+    boolean hasEnd = out.writeListBegin(array.length,
+					getArrayType(obj.getClass()));
+
+    for (int i = 0; i < array.length; i++)
+      out.writeObject(array[i]);
+
+    if (hasEnd)
+      out.writeListEnd();
+  }
+
+  /**
+   * Returns the &lt;type> name for a &lt;list>.
+   */
+  private String getArrayType(Class cl)
+  {
+    if (cl.isArray())
+      return '[' + getArrayType(cl.getComponentType());
+
+    String name = cl.getName();
+
+    if (name.equals("java.lang.String"))
+      return "string";
+    else if (name.equals("java.lang.Object"))
+      return "object";
+    else if (name.equals("java.util.Date"))
+      return "date";
+    else
+      return name;
+  }
+}
diff --git src/com/caucho/hessian/io/BasicDeserializer.java src/com/caucho/hessian/io/BasicDeserializer.java
new file mode 100644
index 0000000..807abc0
--- /dev/null
+++ src/com/caucho/hessian/io/BasicDeserializer.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class BasicDeserializer extends AbstractDeserializer {
+  public static final int NULL = BasicSerializer.NULL;
+  public static final int BOOLEAN = BasicSerializer.BOOLEAN;
+  public static final int BYTE = BasicSerializer.BYTE;
+  public static final int SHORT = BasicSerializer.SHORT;
+  public static final int INTEGER = BasicSerializer.INTEGER;
+  public static final int LONG = BasicSerializer.LONG;
+  public static final int FLOAT = BasicSerializer.FLOAT;
+  public static final int DOUBLE = BasicSerializer.DOUBLE;
+  public static final int CHARACTER = BasicSerializer.CHARACTER;
+  public static final int CHARACTER_OBJECT = BasicSerializer.CHARACTER_OBJECT;
+  public static final int STRING = BasicSerializer.STRING;
+  public static final int DATE = BasicSerializer.DATE;
+  public static final int NUMBER = BasicSerializer.NUMBER;
+  public static final int OBJECT = BasicSerializer.OBJECT;
+  
+  public static final int BOOLEAN_ARRAY = BasicSerializer.BOOLEAN_ARRAY;
+  public static final int BYTE_ARRAY = BasicSerializer.BYTE_ARRAY;
+  public static final int SHORT_ARRAY = BasicSerializer.SHORT_ARRAY;
+  public static final int INTEGER_ARRAY = BasicSerializer.INTEGER_ARRAY;
+  public static final int LONG_ARRAY = BasicSerializer.LONG_ARRAY;
+  public static final int FLOAT_ARRAY = BasicSerializer.FLOAT_ARRAY;
+  public static final int DOUBLE_ARRAY = BasicSerializer.DOUBLE_ARRAY;
+  public static final int CHARACTER_ARRAY = BasicSerializer.CHARACTER_ARRAY;
+  public static final int STRING_ARRAY = BasicSerializer.STRING_ARRAY;
+  public static final int OBJECT_ARRAY = BasicSerializer.OBJECT_ARRAY;
+
+  private int _code;
+
+  public BasicDeserializer(int code)
+  {
+    _code = code;
+  }
+
+  public Class getType()
+  {
+    switch (_code) {
+    case NULL:
+      return void.class;
+    case BOOLEAN:
+      return Boolean.class;
+    case BYTE:
+      return Byte.class;
+    case SHORT:
+      return Short.class;
+    case INTEGER:
+      return Integer.class;
+    case LONG:
+      return Long.class;
+    case FLOAT:
+      return Float.class;
+    case DOUBLE:
+      return Double.class;
+    case CHARACTER:
+      return Character.class;
+    case CHARACTER_OBJECT:
+      return Character.class;
+    case STRING:
+      return String.class;
+    case DATE:
+      return Date.class;
+    case NUMBER:
+      return Number.class;
+    case OBJECT:
+      return Object.class;
+
+    case BOOLEAN_ARRAY:
+      return boolean[].class;
+    case BYTE_ARRAY:
+      return byte[].class;
+    case SHORT_ARRAY:
+      return short[].class;
+    case INTEGER_ARRAY:
+      return int[].class;
+    case LONG_ARRAY:
+      return long[].class;
+    case FLOAT_ARRAY:
+      return float[].class;
+    case DOUBLE_ARRAY:
+      return double[].class;
+    case CHARACTER_ARRAY:
+      return char[].class;
+    case STRING_ARRAY:
+      return String[].class;
+    case OBJECT_ARRAY:
+      return Object[].class;
+    default:
+      throw new UnsupportedOperationException();
+    }
+  }
+  
+  public Object readObject(AbstractHessianInput in)
+    throws IOException
+  {
+    switch (_code) {
+    case NULL:
+      // hessian/3490
+      in.readObject();
+      
+      return null;
+      
+    case BOOLEAN:
+      return Boolean.valueOf(in.readBoolean());
+      
+    case BYTE:
+      return Byte.valueOf((byte) in.readInt());
+      
+    case SHORT:
+      return Short.valueOf((short) in.readInt());
+      
+    case INTEGER:
+      return Integer.valueOf(in.readInt());
+
+    case LONG:
+      return Long.valueOf(in.readLong());
+
+    case FLOAT:
+      return Float.valueOf((float) in.readDouble());
+
+    case DOUBLE:
+      return Double.valueOf(in.readDouble());
+      
+    case STRING:
+      return in.readString();
+      
+    case OBJECT:
+      return in.readObject();
+      
+    case CHARACTER:
+      {
+	String s = in.readString();
+	if (s == null || s.equals(""))
+	  return Character.valueOf((char) 0);
+	else
+	  return Character.valueOf(s.charAt(0));
+      }
+      
+    case CHARACTER_OBJECT:
+      {
+	String s = in.readString();
+	if (s == null || s.equals(""))
+	  return null;
+	else
+	  return Character.valueOf(s.charAt(0));
+      }
+      
+    case DATE:
+      return new Date(in.readUTCDate());
+      
+    case NUMBER:
+      return in.readObject();
+
+    case BYTE_ARRAY:
+      return in.readBytes();
+
+    case CHARACTER_ARRAY:
+    {
+      String s = in.readString();
+
+      if (s == null)
+        return null;
+      else {
+        int len = s.length();
+        char []chars = new char[len];
+        s.getChars(0, len, chars, 0);
+        return chars;
+      }
+    }
+
+    case BOOLEAN_ARRAY:
+    case SHORT_ARRAY:
+    case INTEGER_ARRAY:
+    case LONG_ARRAY:
+    case FLOAT_ARRAY:
+    case DOUBLE_ARRAY:
+    case STRING_ARRAY:
+    {
+      int code = in.readListStart();
+
+      switch (code) {
+      case 'N':
+	return null;
+
+      case 0x10: case 0x11: case 0x12: case 0x13:
+      case 0x14: case 0x15: case 0x16: case 0x17:
+      case 0x18: case 0x19: case 0x1a: case 0x1b:
+      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+	int length = code - 0x10;
+	in.readInt();
+
+	return readLengthList(in, length);
+
+      default:
+	String type = in.readType();
+	length = in.readLength();
+
+	return readList(in, length);
+      }
+    }
+
+    default:
+      throw new UnsupportedOperationException();
+    }
+  }
+  
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    switch (_code) {
+    case BOOLEAN_ARRAY: {
+      if (length >= 0) {
+        boolean []data = new boolean[length];
+
+        in.addRef(data);
+
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readBoolean();
+	
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(Boolean.valueOf(in.readBoolean()));
+	
+        in.readEnd();
+
+        boolean []data = new boolean[list.size()];
+        
+        in.addRef(data);
+        
+        for (int i = 0; i < data.length; i++)
+          data[i] = ((Boolean) list.get(i)).booleanValue();
+
+        return data;
+      }
+    }
+    
+    case SHORT_ARRAY: {
+      if (length >= 0) {
+        short []data = new short[length];
+
+        in.addRef(data);
+        
+        for (int i = 0; i < data.length; i++)
+          data[i] = (short) in.readInt();
+	
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(Short.valueOf((short) in.readInt()));
+
+        in.readEnd();
+
+        short []data = new short[list.size()];
+        for (int i = 0; i < data.length; i++)
+          data[i] = ((Short) list.get(i)).shortValue();
+
+        in.addRef(data);
+        
+        return data;
+      }
+    }
+    
+    case INTEGER_ARRAY: {
+      if (length >= 0) {
+        int []data = new int[length];
+
+        in.addRef(data);
+        
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readInt();
+
+        in.readEnd();
+	
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(Integer.valueOf(in.readInt()));
+
+
+        in.readEnd();
+	
+        int []data = new int[list.size()];
+        for (int i = 0; i < data.length; i++)
+          data[i] = ((Integer) list.get(i)).intValue();
+        
+        in.addRef(data);
+
+        return data;
+      }
+    }
+    
+    case LONG_ARRAY: {
+      if (length >= 0) {
+        long []data = new long[length];
+
+        in.addRef(data);
+
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readLong();
+
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(Long.valueOf(in.readLong()));
+
+        in.readEnd();
+        
+        long []data = new long[list.size()];
+        for (int i = 0; i < data.length; i++)
+          data[i] = ((Long) list.get(i)).longValue();
+        
+        in.addRef(data);
+
+        return data;
+      }
+    }
+    
+    case FLOAT_ARRAY: {
+      if (length >= 0) {
+        float []data = new float[length];
+        in.addRef(data);
+
+        for (int i = 0; i < data.length; i++)
+          data[i] = (float) in.readDouble();
+
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(new Float(in.readDouble()));
+
+        in.readEnd();
+        
+        float []data = new float[list.size()];
+        for (int i = 0; i < data.length; i++)
+          data[i] = ((Float) list.get(i)).floatValue();
+        
+        in.addRef(data);
+
+        return data;
+      }
+    }
+    
+    case DOUBLE_ARRAY: {
+      if (length >= 0) {
+        double []data = new double[length];
+        in.addRef(data);
+
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readDouble();
+
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(new Double(in.readDouble()));
+
+        in.readEnd();
+        
+        double []data = new double[list.size()];
+        in.addRef(data);
+        for (int i = 0; i < data.length; i++)
+          data[i] = ((Double) list.get(i)).intValue();
+
+        in.readEnd();
+
+        return data;
+      }
+    }
+    
+    case STRING_ARRAY: {
+      if (length >= 0) {
+        String []data = new String[length];
+        in.addRef(data);
+
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readString();
+
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+
+        while (! in.isEnd())
+          list.add(in.readString());
+
+        in.readEnd();
+        
+        String []data = new String[list.size()];
+        in.addRef(data);
+        for (int i = 0; i < data.length; i++)
+          data[i] = (String) list.get(i);
+
+        in.readEnd();
+
+        return data;
+      }
+    }
+    
+    case OBJECT_ARRAY: {
+      if (length >= 0) {
+        Object []data = new Object[length];
+        in.addRef(data);
+
+        for (int i = 0; i < data.length; i++)
+          data[i] = in.readObject();
+
+        in.readEnd();
+
+        return data;
+      }
+      else {
+        ArrayList list = new ArrayList();
+        
+        in.addRef(list); // XXX: potential issues here
+
+        while (! in.isEnd())
+          list.add(in.readObject());
+
+        in.readEnd();
+        
+        Object []data = new Object[list.size()];
+        for (int i = 0; i < data.length; i++)
+          data[i] = (Object) list.get(i);
+
+        return data;
+      }
+    }
+    
+    default:
+      throw new UnsupportedOperationException(String.valueOf(this));
+    }
+  }
+  
+  public Object readLengthList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    switch (_code) {
+    case BOOLEAN_ARRAY: {
+      boolean []data = new boolean[length];
+
+      in.addRef(data);
+
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readBoolean();
+
+      return data;
+    }
+    
+    case SHORT_ARRAY: {
+      short []data = new short[length];
+
+      in.addRef(data);
+        
+      for (int i = 0; i < data.length; i++)
+	data[i] = (short) in.readInt();
+
+      return data;
+    }
+    
+    case INTEGER_ARRAY: {
+      int []data = new int[length];
+
+      in.addRef(data);
+        
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readInt();
+
+      return data;
+    }
+    
+    case FLOAT_ARRAY: {
+      float []data = new float[length];
+      in.addRef(data);
+
+      for (int i = 0; i < data.length; i++)
+	data[i] = (float) in.readDouble();
+
+      return data;
+    }
+    
+    case DOUBLE_ARRAY: {
+      double []data = new double[length];
+      in.addRef(data);
+
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readDouble();
+
+      return data;
+    }
+    
+    case STRING_ARRAY: {
+      String []data = new String[length];
+      in.addRef(data);
+
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readString();
+
+      return data;
+    }
+    
+    case OBJECT_ARRAY: {
+      Object []data = new Object[length];
+      in.addRef(data);
+
+      for (int i = 0; i < data.length; i++)
+	data[i] = in.readObject();
+
+      return data;
+    }
+    
+    default:
+      throw new UnsupportedOperationException(String.valueOf(this));
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/BasicSerializer.java src/com/caucho/hessian/io/BasicSerializer.java
new file mode 100644
index 0000000..7940548
--- /dev/null
+++ src/com/caucho/hessian/io/BasicSerializer.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class BasicSerializer extends AbstractSerializer {
+  public static final int NULL = 0;
+  public static final int BOOLEAN = NULL + 1;
+  public static final int BYTE = BOOLEAN + 1;
+  public static final int SHORT = BYTE + 1;
+  public static final int INTEGER = SHORT + 1;
+  public static final int LONG = INTEGER + 1;
+  public static final int FLOAT = LONG + 1;
+  public static final int DOUBLE = FLOAT + 1;
+  public static final int CHARACTER = DOUBLE + 1;
+  public static final int CHARACTER_OBJECT = CHARACTER + 1;
+  public static final int STRING = CHARACTER_OBJECT + 1;
+  public static final int DATE = STRING + 1;
+  public static final int NUMBER = DATE + 1;
+  public static final int OBJECT = NUMBER + 1;
+  
+  public static final int BOOLEAN_ARRAY = OBJECT + 1;
+  public static final int BYTE_ARRAY = BOOLEAN_ARRAY + 1;
+  public static final int SHORT_ARRAY = BYTE_ARRAY + 1;
+  public static final int INTEGER_ARRAY = SHORT_ARRAY + 1;
+  public static final int LONG_ARRAY = INTEGER_ARRAY + 1;
+  public static final int FLOAT_ARRAY = LONG_ARRAY + 1;
+  public static final int DOUBLE_ARRAY = FLOAT_ARRAY + 1;
+  public static final int CHARACTER_ARRAY = DOUBLE_ARRAY + 1;
+  public static final int STRING_ARRAY = CHARACTER_ARRAY + 1;
+  public static final int OBJECT_ARRAY = STRING_ARRAY + 1;
+
+  private int code;
+
+  public BasicSerializer(int code)
+  {
+    this.code = code;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    switch (code) {
+    case BOOLEAN:
+      out.writeBoolean(((Boolean) obj).booleanValue());
+      break;
+      
+    case BYTE:
+    case SHORT:
+    case INTEGER:
+      out.writeInt(((Number) obj).intValue());
+      break;
+
+    case LONG:
+      out.writeLong(((Number) obj).longValue());
+      break;
+
+    case FLOAT:
+    case DOUBLE:
+      out.writeDouble(((Number) obj).doubleValue());
+      break;
+      
+    case CHARACTER:
+    case CHARACTER_OBJECT:
+      out.writeString(String.valueOf(obj));
+      break;
+      
+    case STRING:
+      out.writeString((String) obj);
+      break;
+      
+    case DATE:
+      out.writeUTCDate(((Date) obj).getTime());
+      break;
+      
+    case BOOLEAN_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      boolean []data = (boolean []) obj;
+      boolean hasEnd = out.writeListBegin(data.length, "[boolean");
+      for (int i = 0; i < data.length; i++)
+        out.writeBoolean(data[i]);
+
+      if (hasEnd)
+	out.writeListEnd();
+      
+      break;
+    }
+
+    case BYTE_ARRAY:
+    {
+      byte []data = (byte []) obj;
+      out.writeBytes(data, 0, data.length);
+      break;
+    }
+
+    case SHORT_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      short []data = (short []) obj;
+      boolean hasEnd = out.writeListBegin(data.length, "[short");
+      
+      for (int i = 0; i < data.length; i++)
+        out.writeInt(data[i]);
+
+      if (hasEnd)
+	out.writeListEnd();
+      break;
+    }
+
+    case INTEGER_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      int []data = (int []) obj;
+      
+      boolean hasEnd = out.writeListBegin(data.length, "[int");
+      
+      for (int i = 0; i < data.length; i++)
+        out.writeInt(data[i]);
+
+      if (hasEnd)
+	out.writeListEnd();
+      
+      break;
+    }
+
+    case LONG_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      long []data = (long []) obj;
+      
+      boolean hasEnd = out.writeListBegin(data.length, "[long");
+      
+      for (int i = 0; i < data.length; i++)
+        out.writeLong(data[i]);
+
+      if (hasEnd)
+	out.writeListEnd();
+      break;
+    }
+
+    case FLOAT_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      float []data = (float []) obj;
+      
+      boolean hasEnd = out.writeListBegin(data.length, "[float");
+      
+      for (int i = 0; i < data.length; i++)
+        out.writeDouble(data[i]);
+
+      if (hasEnd)
+	out.writeListEnd();
+      break;
+    }
+
+    case DOUBLE_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      double []data = (double []) obj;
+      boolean hasEnd = out.writeListBegin(data.length, "[double");
+      
+      for (int i = 0; i < data.length; i++)
+        out.writeDouble(data[i]);
+
+      if (hasEnd)
+	out.writeListEnd();
+      break;
+    }
+
+    case STRING_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      String []data = (String []) obj;
+      
+      boolean hasEnd = out.writeListBegin(data.length, "[string");
+      
+      for (int i = 0; i < data.length; i++) {
+        out.writeString(data[i]);
+      }
+
+      if (hasEnd)
+	out.writeListEnd();
+      break;
+    }
+
+    case CHARACTER_ARRAY:
+    {
+      char []data = (char []) obj;
+      out.writeString(data, 0, data.length);
+      break;
+    }
+
+    case OBJECT_ARRAY:
+    {
+      if (out.addRef(obj))
+        return;
+      
+      Object []data = (Object []) obj;
+      
+      boolean hasEnd = out.writeListBegin(data.length, "[object");
+      
+      for (int i = 0; i < data.length; i++) {
+        out.writeObject(data[i]);
+      }
+
+      if (hasEnd)
+	out.writeListEnd();
+      break;
+    }
+    
+    case NULL:
+      out.writeNull();
+      break;
+
+    default:
+      throw new RuntimeException(code + " " + String.valueOf(obj.getClass()));
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/BeanDeserializer.java src/com/caucho/hessian/io/BeanDeserializer.java
new file mode 100644
index 0000000..a2fb242
--- /dev/null
+++ src/com/caucho/hessian/io/BeanDeserializer.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class BeanDeserializer extends AbstractMapDeserializer {
+  private Class _type;
+  private HashMap _methodMap;
+  private Method _readResolve;
+  private Constructor _constructor;
+  private Object []_constructorArgs;
+  
+  public BeanDeserializer(Class cl)
+  {
+    _type = cl;
+    _methodMap = getMethodMap(cl);
+
+    _readResolve = getReadResolve(cl);
+
+    Constructor []constructors = cl.getConstructors();
+    int bestLength = Integer.MAX_VALUE;
+    
+    for (int i = 0; i < constructors.length; i++) {
+      if (constructors[i].getParameterTypes().length < bestLength) {
+        _constructor = constructors[i];
+        bestLength = _constructor.getParameterTypes().length;
+      }
+    }
+
+    if (_constructor != null) {
+      _constructor.setAccessible(true);
+      Class []params = _constructor.getParameterTypes();
+      _constructorArgs = new Object[params.length];
+      for (int i = 0; i < params.length; i++) {
+        _constructorArgs[i] = getParamArg(params[i]);
+      }
+    }
+  }
+
+  public Class getType()
+  {
+    return _type;
+  }
+    
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    try {
+      Object obj = instantiate();
+
+      return readMap(in, obj);
+    } catch (IOException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+    
+  public Object readMap(AbstractHessianInput in, Object obj)
+    throws IOException
+  {
+    try {
+      int ref = in.addRef(obj);
+
+      while (! in.isEnd()) {
+        Object key = in.readObject();
+        
+        Method method = (Method) _methodMap.get(key);
+
+        if (method != null) {
+          Object value = in.readObject(method.getParameterTypes()[0]);
+	  
+          method.invoke(obj, new Object[] {value });
+        }
+        else {
+          Object value = in.readObject();
+        }
+      }
+      
+      in.readMapEnd();
+
+      Object resolve = resolve(obj);
+
+      if (obj != resolve)
+	in.setRef(ref, resolve);
+
+      return resolve;
+    } catch (IOException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+
+  private Object resolve(Object obj)
+  {
+    // if there's a readResolve method, call it
+    try {
+      if (_readResolve != null)
+        return _readResolve.invoke(obj, new Object[0]);
+    } catch (Exception e) {
+    }
+
+    return obj;
+  }
+
+  protected Object instantiate()
+    throws Exception
+  {
+    return _constructor.newInstance(_constructorArgs);
+  }
+
+  /**
+   * Returns the readResolve method
+   */
+  protected Method getReadResolve(Class cl)
+  {
+    for (; cl != null; cl = cl.getSuperclass()) {
+      Method []methods = cl.getDeclaredMethods();
+      
+      for (int i = 0; i < methods.length; i++) {
+	Method method = methods[i];
+
+	if (method.getName().equals("readResolve") &&
+	    method.getParameterTypes().length == 0)
+	  return method;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Creates a map of the classes fields.
+   */
+  protected HashMap getMethodMap(Class cl)
+  {
+    HashMap methodMap = new HashMap();
+    
+    for (; cl != null; cl = cl.getSuperclass()) {
+      Method []methods = cl.getDeclaredMethods();
+      
+      for (int i = 0; i < methods.length; i++) {
+	Method method = methods[i];
+
+	if (Modifier.isStatic(method.getModifiers()))
+	  continue;
+
+	String name = method.getName();
+
+	if (! name.startsWith("set"))
+	  continue;
+
+	Class []paramTypes = method.getParameterTypes();
+	if (paramTypes.length != 1)
+	  continue;
+
+	if (! method.getReturnType().equals(void.class))
+	  continue;
+
+	if (findGetter(methods, name, paramTypes[0]) == null)
+	  continue;
+
+	// XXX: could parameterize the handler to only deal with public
+	try {
+	  method.setAccessible(true);
+	} catch (Throwable e) {
+	  e.printStackTrace();
+	}
+    
+	name = name.substring(3);
+
+	int j = 0;
+	for (; j < name.length() && Character.isUpperCase(name.charAt(j)); j++) {
+	}
+
+	if (j == 1)
+	  name = name.substring(0, j).toLowerCase() + name.substring(j);
+	else if (j > 1)
+	  name = name.substring(0, j - 1).toLowerCase() + name.substring(j - 1);
+
+
+	methodMap.put(name, method);
+      }
+    }
+
+    return methodMap;
+  }
+
+  /**
+   * Finds any matching setter.
+   */
+  private Method findGetter(Method []methods, String setterName, Class arg)
+  {
+    String getterName = "get" + setterName.substring(3);
+    
+    for (int i = 0; i < methods.length; i++) {
+      Method method = methods[i];
+
+      if (! method.getName().equals(getterName))
+	continue;
+      
+      if (! method.getReturnType().equals(arg))
+	continue;
+
+      Class []params = method.getParameterTypes();
+
+      if (params.length == 0)
+	return method;
+    }
+
+    return null;
+  }
+
+  /**
+   * Creates a map of the classes fields.
+   */
+  protected static Object getParamArg(Class cl)
+  {
+    if (! cl.isPrimitive())
+      return null;
+    else if (boolean.class.equals(cl))
+      return Boolean.FALSE;
+    else if (byte.class.equals(cl))
+      return Byte.valueOf((byte) 0);
+    else if (short.class.equals(cl))
+      return Short.valueOf((short) 0);
+    else if (char.class.equals(cl))
+      return Character.valueOf((char) 0);
+    else if (int.class.equals(cl))
+      return Integer.valueOf(0);
+    else if (long.class.equals(cl))
+      return Long.valueOf(0);
+    else if (float.class.equals(cl))
+      return Double.valueOf(0);
+    else if (double.class.equals(cl))
+      return Double.valueOf(0);
+    else
+      throw new UnsupportedOperationException();
+  }
+}
diff --git src/com/caucho/hessian/io/BeanSerializer.java src/com/caucho/hessian/io/BeanSerializer.java
new file mode 100644
index 0000000..b994fb6
--- /dev/null
+++ src/com/caucho/hessian/io/BeanSerializer.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.logging.*;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class BeanSerializer extends AbstractSerializer {
+  private static final Logger log
+    = Logger.getLogger(BeanSerializer.class.getName());
+  
+  private static final Object []NULL_ARGS = new Object[0];
+  private Method []_methods;
+  private String []_names;
+
+  private Object _writeReplaceFactory;
+  private Method _writeReplace;
+  
+  public BeanSerializer(Class cl)
+  {
+    introspectWriteReplace(cl);
+
+    ArrayList primitiveMethods = new ArrayList();
+    ArrayList compoundMethods = new ArrayList();
+    
+    for (; cl != null; cl = cl.getSuperclass()) {
+      Method []methods = cl.getDeclaredMethods();
+      
+      for (int i = 0; i < methods.length; i++) {
+	Method method = methods[i];
+
+	if (Modifier.isStatic(method.getModifiers()))
+	  continue;
+
+	if (method.getParameterTypes().length != 0)
+	  continue;
+
+	String name = method.getName();
+
+	if (! name.startsWith("get"))
+	  continue;
+
+	Class type = method.getReturnType();
+
+	if (type.equals(void.class))
+	  continue;
+
+	if (findSetter(methods, name, type) == null)
+	  continue;
+
+	// XXX: could parameterize the handler to only deal with public
+	method.setAccessible(true);
+
+	if (type.isPrimitive() ||
+	    type.getName().startsWith("java.lang.") &&
+	    ! type.equals(Object.class))
+	  primitiveMethods.add(method);
+	else
+	  compoundMethods.add(method);
+      }
+    }
+
+    ArrayList methodList = new ArrayList();
+    methodList.addAll(primitiveMethods);
+    methodList.addAll(compoundMethods);
+
+    _methods = new Method[methodList.size()];
+    methodList.toArray(_methods);
+
+    _names = new String[_methods.length];
+    
+    for (int i = 0; i < _methods.length; i++) {
+      String name = _methods[i].getName();
+
+      name = name.substring(3);
+
+      int j = 0;
+      for (; j < name.length() && Character.isUpperCase(name.charAt(j)); j++) {
+      }
+
+      if (j == 1)
+	name = name.substring(0, j).toLowerCase() + name.substring(j);
+      else if (j > 1)
+	name = name.substring(0, j - 1).toLowerCase() + name.substring(j - 1);
+
+      _names[i] = name;
+    }
+  }
+
+  private void introspectWriteReplace(Class cl)
+  {
+    try {
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+      String className = cl.getName() + "HessianSerializer";
+
+      Class serializerClass = Class.forName(className, false, loader);
+
+      Object serializerObject = serializerClass.newInstance();
+
+      Method writeReplace = getWriteReplace(serializerClass, cl);
+
+      if (writeReplace != null) {
+	_writeReplaceFactory = serializerObject;
+	_writeReplace = writeReplace;
+
+	return;
+      }
+    } catch (ClassNotFoundException e) {
+    } catch (Exception e) {
+      log.log(Level.FINER, e.toString(), e);
+    }
+      
+    _writeReplace = getWriteReplace(cl);
+  }
+
+  /**
+   * Returns the writeReplace method
+   */
+  protected Method getWriteReplace(Class cl)
+  {
+    for (; cl != null; cl = cl.getSuperclass()) {
+      Method []methods = cl.getDeclaredMethods();
+      
+      for (int i = 0; i < methods.length; i++) {
+	Method method = methods[i];
+
+	if (method.getName().equals("writeReplace") &&
+	    method.getParameterTypes().length == 0)
+	  return method;
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Returns the writeReplace method
+   */
+  protected Method getWriteReplace(Class cl, Class param)
+  {
+    for (; cl != null; cl = cl.getSuperclass()) {
+      for (Method method : cl.getDeclaredMethods()) {
+	if (method.getName().equals("writeReplace")
+	    && method.getParameterTypes().length == 1
+	    && param.equals(method.getParameterTypes()[0]))
+	  return method;
+      }
+    }
+
+    return null;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (out.addRef(obj))
+      return;
+    
+    Class cl = obj.getClass();
+    
+    try {
+      if (_writeReplace != null) {
+	Object repl;
+
+	if (_writeReplaceFactory != null)
+	  repl = _writeReplace.invoke(_writeReplaceFactory, obj);
+	else
+	  repl = _writeReplace.invoke(obj);
+
+	out.removeRef(obj);
+
+	out.writeObject(repl);
+
+	out.replaceRef(repl, obj);
+
+	return;
+      }
+    } catch (Exception e) {
+      log.log(Level.FINER, e.toString(), e);
+    }
+
+    int ref = out.writeObjectBegin(cl.getName());
+
+    if (ref < -1) {
+      // Hessian 1.1 uses a map
+      
+      for (int i = 0; i < _methods.length; i++) {
+	Method method = _methods[i];
+	Object value = null;
+
+	try {
+	  value = _methods[i].invoke(obj, (Object []) null);
+	} catch (Exception e) {
+	  log.log(Level.FINE, e.toString(), e);
+	}
+
+	out.writeString(_names[i]);
+	
+	out.writeObject(value);
+      }
+      
+      out.writeMapEnd();
+    }
+    else {
+      if (ref == -1) {
+	out.writeInt(_names.length);
+	
+	for (int i = 0; i < _names.length; i++)
+	  out.writeString(_names[i]);
+	
+	out.writeObjectBegin(cl.getName());
+      }
+
+      for (int i = 0; i < _methods.length; i++) {
+	Method method = _methods[i];
+	Object value = null;
+
+	try {
+	  value = _methods[i].invoke(obj, (Object []) null);
+	} catch (Exception e) {
+	  log.log(Level.FINER, e.toString(), e);
+	}
+	
+	out.writeObject(value);
+      }
+    }
+  }
+
+  /**
+   * Finds any matching setter.
+   */
+  private Method findSetter(Method []methods, String getterName, Class arg)
+  {
+    String setterName = "set" + getterName.substring(3);
+    
+    for (int i = 0; i < methods.length; i++) {
+      Method method = methods[i];
+
+      if (! method.getName().equals(setterName))
+	continue;
+      
+      if (! method.getReturnType().equals(void.class))
+	continue;
+
+      Class []params = method.getParameterTypes();
+
+      if (params.length == 1 && params[0].equals(arg))
+	return method;
+    }
+
+    return null;
+  }
+}
diff --git src/com/caucho/hessian/io/BeanSerializerFactory.java src/com/caucho/hessian/io/BeanSerializerFactory.java
new file mode 100644
index 0000000..591a45a
--- /dev/null
+++ src/com/caucho/hessian/io/BeanSerializerFactory.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+/**
+ * Factory for returning serialization methods.
+ */
+public class BeanSerializerFactory extends SerializerFactory {
+  /**
+   * Returns the default serializer for a class that isn't matched
+   * directly.  Application can override this method to produce
+   * bean-style serialization instead of field serialization.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  protected Serializer getDefaultSerializer(Class cl)
+  {
+    return new BeanSerializer(cl);
+  }
+  
+  /**
+   * Returns the default deserializer for a class that isn't matched
+   * directly.  Application can override this method to produce
+   * bean-style serialization instead of field serialization.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  protected Deserializer getDefaultDeserializer(Class cl)
+  {
+    return new BeanDeserializer(cl);
+  }
+}
diff --git src/com/caucho/hessian/io/CalendarHandle.java src/com/caucho/hessian/io/CalendarHandle.java
new file mode 100644
index 0000000..9056110
--- /dev/null
+++ src/com/caucho/hessian/io/CalendarHandle.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+/**
+ * Handle for a calendar object.
+ */
+public class CalendarHandle implements java.io.Serializable, HessianHandle {
+  private Class type;
+  private Date date;
+
+  public CalendarHandle()
+  {
+  }
+  
+  public CalendarHandle(Class type, long time)
+  {
+    if (! GregorianCalendar.class.equals(type))
+      this.type = type;
+    
+    this.date = new Date(time);
+  }
+
+  private Object readResolve()
+  {
+    try {
+      Calendar cal;
+      
+      if (this.type != null)
+	cal = (Calendar) this.type.newInstance();
+      else
+	cal = new GregorianCalendar();
+      
+      cal.setTimeInMillis(this.date.getTime());
+
+      return cal;
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/CalendarSerializer.java src/com/caucho/hessian/io/CalendarSerializer.java
new file mode 100644
index 0000000..cc688e5
--- /dev/null
+++ src/com/caucho/hessian/io/CalendarSerializer.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Calendar;
+
+/**
+ * Serializing a calendar.
+ */
+public class CalendarSerializer extends AbstractSerializer {
+  private static CalendarSerializer SERIALIZER = new CalendarSerializer();
+
+  public static CalendarSerializer create()
+  {
+    return SERIALIZER;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (obj == null)
+      out.writeNull();
+    else {
+      Calendar cal = (Calendar) obj;
+
+      out.writeObject(new CalendarHandle(cal.getClass(),
+					 cal.getTimeInMillis()));
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/ClassDeserializer.java src/com/caucho/hessian/io/ClassDeserializer.java
new file mode 100644
index 0000000..d8cb0d6
--- /dev/null
+++ src/com/caucho/hessian/io/ClassDeserializer.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * Deserializing a JDK 1.2 Class.
+ */
+public class ClassDeserializer extends AbstractMapDeserializer {
+  private static final HashMap<String,Class> _primClasses
+    = new HashMap<String,Class>();
+  
+  public ClassDeserializer()
+  {
+  }
+  
+  public Class getType()
+  {
+    return Class.class;
+  }
+  
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    int ref = in.addRef(null);
+    
+    String name = null;
+    
+    while (! in.isEnd()) {
+      String key = in.readString();
+
+      if (key.equals("name"))
+	name = in.readString();
+      else
+	in.readObject();
+    }
+      
+    in.readMapEnd();
+
+    Object value = create(name);
+
+    in.setRef(ref, value);
+
+    return value;
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    int ref = in.addRef(null);
+    
+    String name = null;
+    
+    for (int i = 0; i < fieldNames.length; i++) {
+      if ("name".equals(fieldNames[i]))
+        name = in.readString();
+      else
+	in.readObject();
+    }
+
+    Object value = create(name);
+
+    in.setRef(ref, value);
+
+    return value;
+  }
+
+  Object create(String name)
+    throws IOException
+  {
+    if (name == null)
+      throw new IOException("Serialized Class expects name.");
+
+    Class cl = _primClasses.get(name);
+
+    if (cl != null)
+      return cl;
+
+    ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+    try {
+      if (loader != null)
+        return Class.forName(name, false, loader);
+      else
+        return Class.forName(name);
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+
+  static {
+    _primClasses.put("void", void.class);
+    _primClasses.put("boolean", boolean.class);
+    _primClasses.put("java.lang.Boolean", Boolean.class);
+    _primClasses.put("byte", byte.class);
+    _primClasses.put("java.lang.Byte", Byte.class);
+    _primClasses.put("char", char.class);
+    _primClasses.put("java.lang.Character", Character.class);
+    _primClasses.put("short", short.class);
+    _primClasses.put("java.lang.Short", Short.class);
+    _primClasses.put("int", int.class);
+    _primClasses.put("java.lang.Integer", Integer.class);
+    _primClasses.put("long", long.class);
+    _primClasses.put("java.lang.Long", Long.class);
+    _primClasses.put("float", float.class);
+    _primClasses.put("java.lang.Float", Float.class);
+    _primClasses.put("double", double.class);
+    _primClasses.put("java.lang.Double", Double.class);
+    _primClasses.put("java.lang.String", String.class);
+  }
+}
diff --git src/com/caucho/hessian/io/ClassSerializer.java src/com/caucho/hessian/io/ClassSerializer.java
new file mode 100644
index 0000000..0a25797
--- /dev/null
+++ src/com/caucho/hessian/io/ClassSerializer.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Serializing a remote object.
+ */
+public class ClassSerializer extends AbstractSerializer {
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    Class cl = (Class) obj;
+
+    if (cl == null) {
+      out.writeNull();
+    }
+    else if (out.addRef(obj)) {
+      return;
+    }
+    else {
+      int ref = out.writeObjectBegin("java.lang.Class");
+
+      if (ref < -1) {
+	out.writeString("name");
+	out.writeString(cl.getName());
+	out.writeMapEnd();
+      }
+      else {
+	if (ref == -1) {
+	  out.writeInt(1);
+	  out.writeString("name");
+	  out.writeObjectBegin("java.lang.Class");
+	}
+
+	out.writeString(cl.getName());
+      }
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/CollectionDeserializer.java src/com/caucho/hessian/io/CollectionDeserializer.java
new file mode 100644
index 0000000..93d24b2
--- /dev/null
+++ src/com/caucho/hessian/io/CollectionDeserializer.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Deserializing a JDK 1.2 Collection.
+ */
+public class CollectionDeserializer extends AbstractListDeserializer {
+  private Class _type;
+  
+  public CollectionDeserializer(Class type)
+  {
+    _type = type;
+  }
+  
+  public Class getType()
+  {
+    return _type;
+  }
+  
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    Collection list = createList();
+
+    in.addRef(list);
+
+    while (! in.isEnd())
+      list.add(in.readObject());
+
+    in.readEnd();
+
+    return list;
+  }
+  
+  public Object readLengthList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    Collection list = createList();
+
+    in.addRef(list);
+
+    for (; length > 0; length--)
+      list.add(in.readObject());
+
+    return list;
+  }
+
+  private Collection createList()
+    throws IOException
+  {
+    Collection list = null;
+    
+    if (_type == null)
+      list = new ArrayList();
+    else if (! _type.isInterface()) {
+      try {
+        list = (Collection) _type.newInstance();
+      } catch (Exception e) {
+      }
+    }
+
+    if (list != null) {
+    }
+    else if (SortedSet.class.isAssignableFrom(_type))
+      list = new TreeSet();
+    else if (Set.class.isAssignableFrom(_type))
+      list = new HashSet();
+    else if (List.class.isAssignableFrom(_type))
+      list = new ArrayList();
+    else if (Collection.class.isAssignableFrom(_type))
+      list = new ArrayList();
+    else {
+      try {
+        list = (Collection) _type.newInstance();
+      } catch (Exception e) {
+        throw new IOExceptionWrapper(e);
+      }
+    }
+
+    return list;
+  }
+}
+
+
diff --git src/com/caucho/hessian/io/CollectionSerializer.java src/com/caucho/hessian/io/CollectionSerializer.java
new file mode 100644
index 0000000..5af824c
--- /dev/null
+++ src/com/caucho/hessian/io/CollectionSerializer.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * Serializing a JDK 1.2 Collection.
+ */
+public class CollectionSerializer extends AbstractSerializer
+{
+  private boolean _sendJavaType = true;
+
+  /**
+   * Set true if the java type of the collection should be sent.
+   */
+  public void setSendJavaType(boolean sendJavaType)
+  {
+    _sendJavaType = sendJavaType;
+  }
+
+  /**
+   * Return true if the java type of the collection should be sent.
+   */
+  public boolean getSendJavaType()
+  {
+    return _sendJavaType;
+  }
+    
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (out.addRef(obj))
+      return;
+
+    Collection list = (Collection) obj;
+
+    Class cl = obj.getClass();
+    boolean hasEnd;
+    
+    if (cl.equals(ArrayList.class)
+	|| ! _sendJavaType
+	|| ! Serializable.class.isAssignableFrom(cl))
+      hasEnd = out.writeListBegin(list.size(), null);
+    else
+      hasEnd = out.writeListBegin(list.size(), obj.getClass().getName());
+
+    Iterator iter = list.iterator();
+    while (iter.hasNext()) {
+      Object value = iter.next();
+
+      out.writeObject(value);
+    }
+
+    if (hasEnd)
+      out.writeListEnd();
+  }
+}
diff --git src/com/caucho/hessian/io/Deflation.java src/com/caucho/hessian/io/Deflation.java
new file mode 100644
index 0000000..0e3ae50
--- /dev/null
+++ src/com/caucho/hessian/io/Deflation.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.util.*;
+import java.util.zip.*;
+
+import java.io.*;
+
+import com.caucho.hessian.io.*;
+
+public class Deflation extends HessianEnvelope {
+  public Deflation()
+  {
+  }
+
+  public Hessian2Output wrap(Hessian2Output out)
+    throws IOException
+  {
+    OutputStream os = new DeflateOutputStream(out);
+    
+    Hessian2Output filterOut = new Hessian2Output(os);
+
+    filterOut.setCloseStreamOnClose(true);
+    
+    return filterOut;
+  }
+
+  public Hessian2Input unwrap(Hessian2Input in)
+    throws IOException
+  {
+    int version = in.readEnvelope();
+
+    String method = in.readMethod();
+
+    if (! method.equals(getClass().getName()))
+      throw new IOException("expected hessian Envelope method '" +
+			    getClass().getName() + "' at '" + method + "'");
+
+    return unwrapHeaders(in);
+  }
+
+  public Hessian2Input unwrapHeaders(Hessian2Input in)
+    throws IOException
+  {
+    InputStream is = new DeflateInputStream(in);
+
+    Hessian2Input filter = new Hessian2Input(is);
+    
+    filter.setCloseStreamOnClose(true);
+    
+    return filter;
+  }
+  
+  static class DeflateOutputStream extends OutputStream {
+    private Hessian2Output _out;
+    private OutputStream _bodyOut;
+    private DeflaterOutputStream _deflateOut;
+    
+    DeflateOutputStream(Hessian2Output out)
+      throws IOException
+    {
+      _out = out;
+
+      _out.startEnvelope(Deflation.class.getName());
+    
+      _out.writeInt(0);
+
+      _bodyOut = _out.getBytesOutputStream();
+    
+      _deflateOut = new DeflaterOutputStream(_bodyOut);
+    }
+    
+    public void write(int ch)
+      throws IOException
+    {
+      _deflateOut.write(ch);
+    }
+    
+    public void write(byte []buffer, int offset, int length)
+      throws IOException
+    {
+      _deflateOut.write(buffer, offset, length);
+    }
+
+    public void close()
+      throws IOException
+    {
+      Hessian2Output out = _out;
+      _out = null;
+
+      if (out != null) {
+	_deflateOut.close();
+	_bodyOut.close();
+
+	out.writeInt(0);
+
+        out.completeEnvelope();
+          
+	out.close();
+      }
+    }
+  }
+  
+  static class DeflateInputStream extends InputStream {
+    private Hessian2Input _in;
+    
+    private InputStream _bodyIn;
+    private InflaterInputStream _inflateIn;
+    
+    DeflateInputStream(Hessian2Input in)
+      throws IOException
+    {
+      _in = in;
+
+      int len = in.readInt();
+
+      if (len != 0)
+        throw new IOException("expected no headers");
+      
+      _bodyIn = _in.readInputStream();
+
+      _inflateIn = new InflaterInputStream(_bodyIn);
+    }
+    
+    public int read()
+      throws IOException
+    {
+      return _inflateIn.read();
+    }
+    
+    public int read(byte []buffer, int offset, int length)
+      throws IOException
+    {
+      return _inflateIn.read(buffer, offset, length);
+    }
+
+    public void close()
+      throws IOException
+    {
+      Hessian2Input in = _in;
+      _in = null;
+
+      if (in != null) {
+	_inflateIn.close();
+	_bodyIn.close();
+
+	int len = in.readInt();
+
+	if (len != 0)
+	  throw new IOException("Unexpected footer");
+
+        in.completeEnvelope();
+
+	in.close();
+      }
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/Deserializer.java src/com/caucho/hessian/io/Deserializer.java
new file mode 100644
index 0000000..82ff422
--- /dev/null
+++ src/com/caucho/hessian/io/Deserializer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Deserializing an object. 
+ */
+public interface Deserializer {
+  public Class getType();
+
+  public Object readObject(AbstractHessianInput in)
+    throws IOException;
+  
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException;
+  
+  public Object readLengthList(AbstractHessianInput in, int length)
+    throws IOException;
+  
+  public Object readMap(AbstractHessianInput in)
+    throws IOException;
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException;
+}
diff --git src/com/caucho/hessian/io/EnumDeserializer.java src/com/caucho/hessian/io/EnumDeserializer.java
new file mode 100644
index 0000000..aa60b30
--- /dev/null
+++ src/com/caucho/hessian/io/EnumDeserializer.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+/**
+ * Deserializing an enum valued object
+ */
+public class EnumDeserializer extends AbstractDeserializer {
+  private Class _enumType;
+  private Method _valueOf;
+  
+  public EnumDeserializer(Class cl)
+  {
+    // hessian/33b[34], hessian/3bb[78]
+    if (cl.isEnum())
+      _enumType = cl;
+    else if (cl.getSuperclass().isEnum())
+      _enumType = cl.getSuperclass();
+    else
+      throw new RuntimeException("Class " + cl.getName() + " is not an enum");
+
+    try {
+      _valueOf = _enumType.getMethod("valueOf",
+			     new Class[] { Class.class, String.class });
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+  
+  public Class getType()
+  {
+    return _enumType;
+  }
+  
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    String name = null;
+    
+    while (! in.isEnd()) {
+      String key = in.readString();
+
+      if (key.equals("name"))
+        name = in.readString();
+      else
+	in.readObject();
+    }
+
+    in.readMapEnd();
+
+    Object obj = create(name);
+    
+    in.addRef(obj);
+
+    return obj;
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    String name = null;
+
+    for (int i = 0; i < fieldNames.length; i++) {
+      if ("name".equals(fieldNames[i]))
+        name = in.readString();
+      else
+	in.readObject();
+    }
+
+    Object obj = create(name);
+
+    in.addRef(obj);
+
+    return obj;
+  }
+
+  private Object create(String name)
+    throws IOException
+  {
+    if (name == null)
+      throw new IOException(_enumType.getName() + " expects name.");
+
+    try {
+      return _valueOf.invoke(null, _enumType, name);
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/EnumSerializer.java src/com/caucho/hessian/io/EnumSerializer.java
new file mode 100644
index 0000000..1edad87
--- /dev/null
+++ src/com/caucho/hessian/io/EnumSerializer.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class EnumSerializer extends AbstractSerializer {
+  private Method _name;
+  
+  public EnumSerializer(Class cl)
+  {
+    // hessian/32b[12], hessian/3ab[23]
+    if (! cl.isEnum() && cl.getSuperclass().isEnum())
+      cl = cl.getSuperclass();
+
+    try {
+      _name = cl.getMethod("name", new Class[0]);
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (out.addRef(obj))
+      return;
+
+    Class cl = obj.getClass();
+
+    if (! cl.isEnum() && cl.getSuperclass().isEnum())
+      cl = cl.getSuperclass();
+
+    String name = null;
+    try {
+      name = (String) _name.invoke(obj, (Object[]) null);
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+
+    int ref = out.writeObjectBegin(cl.getName());
+
+    if (ref < -1) {
+      out.writeString("name");
+      out.writeString(name);
+      out.writeMapEnd();
+    }
+    else {
+      if (ref == -1) {
+	out.writeClassFieldLength(1);
+	out.writeString("name");
+	out.writeObjectBegin(cl.getName());
+      }
+
+      out.writeString(name);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/EnumerationDeserializer.java src/com/caucho/hessian/io/EnumerationDeserializer.java
new file mode 100644
index 0000000..875759b
--- /dev/null
+++ src/com/caucho/hessian/io/EnumerationDeserializer.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * Deserializing a JDK 1.2 Collection.
+ */
+public class EnumerationDeserializer extends AbstractListDeserializer {
+  private static EnumerationDeserializer _deserializer;
+
+  public static EnumerationDeserializer create()
+  {
+    if (_deserializer == null)
+      _deserializer = new EnumerationDeserializer();
+
+    return _deserializer;
+  }
+  
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    Vector list = new Vector();
+
+    in.addRef(list);
+
+    while (! in.isEnd())
+      list.add(in.readObject());
+
+    in.readEnd();
+
+    return list.elements();
+  }
+}
+
+
diff --git src/com/caucho/hessian/io/EnumerationSerializer.java src/com/caucho/hessian/io/EnumerationSerializer.java
new file mode 100644
index 0000000..f539dcd
--- /dev/null
+++ src/com/caucho/hessian/io/EnumerationSerializer.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+/**
+ * Serializing a JDK 1.2 Enumeration.
+ */
+public class EnumerationSerializer extends AbstractSerializer {
+  private static EnumerationSerializer _serializer;
+
+  public static EnumerationSerializer create()
+  {
+    if (_serializer == null)
+      _serializer = new EnumerationSerializer();
+
+    return _serializer;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    Enumeration iter = (Enumeration) obj;
+
+    boolean hasEnd = out.writeListBegin(-1, null);
+
+    while (iter.hasMoreElements()) {
+      Object value = iter.nextElement();
+
+      out.writeObject(value);
+    }
+
+    if (hasEnd)
+      out.writeListEnd();
+  }
+}
diff --git src/com/caucho/hessian/io/EnvelopeFactory.java src/com/caucho/hessian/io/EnvelopeFactory.java
new file mode 100644
index 0000000..0a83608
--- /dev/null
+++ src/com/caucho/hessian/io/EnvelopeFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.util.logging.*;
+
+public class EnvelopeFactory
+{
+  private static final Logger log
+    = Logger.getLogger(EnvelopeFactory.class.getName());
+}
diff --git src/com/caucho/hessian/io/ExtSerializerFactory.java src/com/caucho/hessian/io/ExtSerializerFactory.java
new file mode 100644
index 0000000..4802fb7
--- /dev/null
+++ src/com/caucho/hessian/io/ExtSerializerFactory.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.util.HashMap;
+
+/**
+ * Factory for returning serialization methods.
+ */
+public class ExtSerializerFactory extends AbstractSerializerFactory {
+  private HashMap _serializerMap = new HashMap();
+  private HashMap _deserializerMap = new HashMap();
+
+  /**
+   * Adds a serializer.
+   *
+   * @param cl the class of the serializer
+   * @param serializer the serializer
+   */
+  public void addSerializer(Class cl, Serializer serializer)
+  {
+    _serializerMap.put(cl, serializer);
+  }
+
+  /**
+   * Adds a deserializer.
+   *
+   * @param cl the class of the deserializer
+   * @param deserializer the deserializer
+   */
+  public void addDeserializer(Class cl, Deserializer deserializer)
+  {
+    _deserializerMap.put(cl, deserializer);
+  }
+  
+  /**
+   * Returns the serializer for a class.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  public Serializer getSerializer(Class cl)
+    throws HessianProtocolException
+  {
+    return (Serializer) _serializerMap.get(cl);
+  }
+  
+  /**
+   * Returns the deserializer for a class.
+   *
+   * @param cl the class of the object that needs to be deserialized.
+   *
+   * @return a deserializer object for the serialization.
+   */
+  public Deserializer getDeserializer(Class cl)
+    throws HessianProtocolException
+  {
+    return (Deserializer) _deserializerMap.get(cl);
+  }
+}
diff --git src/com/caucho/hessian/io/Hessian2Constants.java src/com/caucho/hessian/io/Hessian2Constants.java
new file mode 100644
index 0000000..d568924
--- /dev/null
+++ src/com/caucho/hessian/io/Hessian2Constants.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+public interface Hessian2Constants
+{
+  public static final int INT_DIRECT_MIN = -0x10;
+  public static final int INT_DIRECT_MAX = 0x2f;
+  public static final int INT_ZERO = 0x90;
+
+  public static final int INT_BYTE_MIN = -0x800;
+  public static final int INT_BYTE_MAX = 0x7ff;
+  public static final int INT_BYTE_ZERO = 0xc8;
+
+  public static final int INT_SHORT_MIN = -0x40000;
+  public static final int INT_SHORT_MAX = 0x3ffff;
+  public static final int INT_SHORT_ZERO = 0xd4;
+
+  public static final long LONG_DIRECT_MIN = -0x08;
+  public static final long LONG_DIRECT_MAX =  0x0f;
+  public static final int LONG_ZERO = 0xe0;
+
+  public static final long LONG_BYTE_MIN = -0x800;
+  public static final long LONG_BYTE_MAX =  0x7ff;
+  public static final int LONG_BYTE_ZERO = 0xf8;
+
+  public static final int LONG_SHORT_MIN = -0x40000;
+  public static final int LONG_SHORT_MAX = 0x3ffff;
+  public static final int LONG_SHORT_ZERO = 0x3c;
+
+  public static final int STRING_DIRECT_MAX = 0x1f;
+  public static final int STRING_DIRECT = 0x00;
+
+  public static final int BYTES_DIRECT_MAX = 0x0f;
+  public static final int BYTES_DIRECT = 0x20;
+  // 0x30-0x37 is reserved
+
+  public static final int LONG_INT = 0x77;
+
+  public static final int DOUBLE_ZERO = 0x67;
+  public static final int DOUBLE_ONE = 0x68;
+  public static final int DOUBLE_BYTE = 0x69;
+  public static final int DOUBLE_SHORT = 0x6a;
+  public static final int DOUBLE_FLOAT = 0x6b;
+  
+  public static final int LENGTH_BYTE = 0x6e;
+  public static final int LIST_FIXED = 0x76; // 'v'
+
+  public static final int REF_BYTE = 0x4a;
+  public static final int REF_SHORT = 0x4b;
+
+  public static final int TYPE_REF = 0x75;
+}
diff --git src/com/caucho/hessian/io/Hessian2Input.java src/com/caucho/hessian/io/Hessian2Input.java
new file mode 100644
index 0000000..9fd9257
--- /dev/null
+++ src/com/caucho/hessian/io/Hessian2Input.java
@@ -0,0 +1,2783 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.logging.*;
+
+/**
+ * Input stream for Hessian requests.
+ *
+ * <p>HessianInput is unbuffered, so any client needs to provide
+ * its own buffering.
+ *
+ * <pre>
+ * InputStream is = ...; // from http connection
+ * HessianInput in = new HessianInput(is);
+ * String value;
+ *
+ * in.startReply();         // read reply header
+ * value = in.readString(); // read string value
+ * in.completeReply();      // read reply footer
+ * </pre>
+ */
+public class Hessian2Input
+  extends AbstractHessianInput
+  implements Hessian2Constants
+{
+  private static final Logger log
+    = Logger.getLogger(Hessian2Input.class.getName());
+  
+  private static final double D_256 = 1.0 / 256.0;
+  private static final int END_OF_DATA = -2;
+
+  private static Field _detailMessageField;
+
+  private static final int SIZE = 256;
+  private static final int GAP = 16;
+  
+  // factory for deserializing objects in the input stream
+  protected SerializerFactory _serializerFactory;
+
+  private static boolean _isCloseStreamOnClose;
+  
+  protected ArrayList _refs;
+  protected ArrayList _classDefs;
+  protected ArrayList _types;
+  
+  // the underlying input stream
+  private InputStream _is;
+  private final byte []_buffer = new byte[SIZE];
+  
+  // a peek character
+  private int _offset;
+  private int _length;
+
+  // true for streaming data
+  private boolean _isStreaming;
+  
+  // the method for a call
+  private String _method;
+
+  private Reader _chunkReader;
+  private InputStream _chunkInputStream;
+
+  private Throwable _replyFault;
+
+  private StringBuffer _sbuf = new StringBuffer();
+  
+  // true if this is the last chunk
+  private boolean _isLastChunk;
+  // the chunk length
+  private int _chunkLength;
+  
+  /**
+   * Creates a new Hessian input stream, initialized with an
+   * underlying input stream.
+   *
+   * @param is the underlying input stream.
+   */
+  public Hessian2Input(InputStream is)
+  {
+    _is = is;
+  }
+
+  /**
+   * Sets the serializer factory.
+   */
+  public void setSerializerFactory(SerializerFactory factory)
+  {
+    _serializerFactory = factory;
+  }
+
+  /**
+   * Gets the serializer factory.
+   */
+  public SerializerFactory getSerializerFactory()
+  {
+    return _serializerFactory;
+  }
+
+  /**
+   * Gets the serializer factory, creating a default if necessary.
+   */
+  public final SerializerFactory findSerializerFactory()
+  {
+    SerializerFactory factory = _serializerFactory;
+
+    if (factory == null)
+      _serializerFactory = factory = new SerializerFactory();
+    
+    return factory;
+  }
+
+  public void setCloseStreamOnClose(boolean isClose)
+  {
+    _isCloseStreamOnClose = isClose;
+  }
+
+  public boolean isCloseStreamOnClose()
+  {
+    return _isCloseStreamOnClose;
+  }
+
+  /**
+   * Returns the calls method
+   */
+  public String getMethod()
+  {
+    return _method;
+  }
+
+  /**
+   * Returns any reply fault.
+   */
+  public Throwable getReplyFault()
+  {
+    return _replyFault;
+  }
+
+  /**
+   * Starts reading the call
+   *
+   * <pre>
+   * c major minor
+   * </pre>
+   */
+  public int readCall()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'c')
+      throw error("expected hessian call ('c') at " + codeName(tag));
+
+    int major = read();
+    int minor = read();
+
+    return (major << 16) + minor;
+  }
+
+  /**
+   * Starts reading the envelope
+   *
+   * <pre>
+   * E major minor
+   * </pre>
+   */
+  public int readEnvelope()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'E')
+      throw error("expected hessian Envelope ('E') at " + codeName(tag));
+
+    int major = read();
+    int minor = read();
+
+    return (major << 16) + minor;
+  }
+
+  /**
+   * Completes reading the envelope
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeEnvelope()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'z')
+      error("expected end of envelope at " + codeName(tag));
+  }
+
+  /**
+   * Starts reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * m b16 b8 method
+   * </pre>
+   */
+  public String readMethod()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'm')
+      throw error("expected hessian method ('m') at " + codeName(tag));
+    
+    int d1 = read();
+    int d2 = read();
+
+    _isLastChunk = true;
+    _chunkLength = d1 * 256 + d2;
+    _sbuf.setLength(0);
+    int ch;
+    while ((ch = parseChar()) >= 0)
+      _sbuf.append((char) ch);
+    
+    _method = _sbuf.toString();
+
+    return _method;
+  }
+
+  /**
+   * Starts reading the call, including the headers.
+   *
+   * <p>The call expects the following protocol data
+   *
+   * <pre>
+   * c major minor
+   * m b16 b8 method
+   * </pre>
+   */
+  public void startCall()
+    throws IOException
+  {
+    readCall();
+
+    while (readHeader() != null) {
+      readObject();
+    }
+
+    readMethod();
+  }
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeCall()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag == 'z') {
+    }
+    else if (tag < 0)
+      throw error("expected end of call ('z') at end of stream.");
+    else
+      throw error("expected end of call ('z') at " + codeName(tag) + ".  Check method arguments and ensure method overloading is enabled if necessary");
+  }
+
+  /**
+   * Reads a reply as an object.
+   * If the reply has a fault, throws the exception.
+   */
+  @Override
+  public Object readReply(Class expectedClass)
+    throws Throwable
+  {
+    int tag = read();
+    
+    if (tag != 'r') {
+      StringBuilder sb = new StringBuilder();
+      sb.append((char) tag);
+      
+      try {
+	int ch;
+
+	while ((ch = read()) >= 0) {
+	  sb.append((char) ch);
+	}
+      } catch (IOException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+      
+      throw error("expected hessian reply at " + codeName(tag) + "\n"
+		  + sb);
+    }
+
+    int major = read();
+    int minor = read();
+
+    if (major > 2 || major == 2 && minor > 0)
+      throw error("Cannot understand Hessian " + major + "." + minor + " response");
+    tag = read();
+    if (tag == 'f')
+      throw prepareFault();
+    else {
+      if (tag >= 0)
+	_offset--;
+    
+      Object value = readObject(expectedClass);
+      
+      completeValueReply();
+      
+      return value;
+    }
+  }
+
+  /**
+   * Starts reading the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * r
+   * </pre>
+   */
+  public void startReply()
+    throws Throwable
+  {
+    int tag = read();
+    
+    if (tag != 'r') {
+      StringBuilder sb = new StringBuilder();
+      sb.append((char) tag);
+      
+      try {
+	int ch;
+
+	while ((ch = read()) >= 0) {
+	  sb.append((char) ch);
+	}
+      } catch (IOException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+      
+      throw error("expected hessian reply at " + codeName(tag) + "\n"
+		  + sb);
+    }
+
+    int major = read();
+    int minor = read();
+
+    if (major > 2 || major == 2 && minor > 0)
+      throw error("Cannot understand Hessian " + major + "." + minor + " response");
+    
+    tag = read();
+    if (tag == 'f')
+      throw prepareFault();
+    else if (tag >= 0)
+      _offset--;
+  }
+
+  /**
+   * Prepares the fault.
+   */
+  private Throwable prepareFault()
+    throws IOException
+  {
+    HashMap fault = readFault();
+
+    Object detail = fault.get("detail");
+    String message = (String) fault.get("message");
+
+    if (detail instanceof Throwable) {
+      _replyFault = (Throwable) detail;
+      
+      if (message != null && _detailMessageField != null) {
+	try {
+	  _detailMessageField.set(_replyFault, message);
+	} catch (Throwable e) {
+	}
+      }
+	
+      return _replyFault;
+    }
+
+    else {
+      String code = (String) fault.get("code");
+        
+      _replyFault = new HessianServiceException(message, code, detail);
+
+      return _replyFault;
+    }
+  }
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeReply()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'z')
+      error("expected end of reply at " + codeName(tag));
+  }
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeValueReply()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'z')
+      error("expected end of reply at " + codeName(tag));
+  }
+
+  /**
+   * Reads a header, returning null if there are no headers.
+   *
+   * <pre>
+   * H b16 b8 value
+   * </pre>
+   */
+  public String readHeader()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag == 'H') {
+      _isLastChunk = true;
+      _chunkLength = (read() << 8) + read();
+
+      _sbuf.setLength(0);
+      int ch;
+      while ((ch = parseChar()) >= 0)
+        _sbuf.append((char) ch);
+
+      return _sbuf.toString();
+    }
+
+    if (tag >= 0)
+      _offset--;
+
+    return null;
+  }
+
+  /**
+   * Starts reading the message
+   *
+   * <pre>
+   * p major minor
+   * </pre>
+   */
+  public int startMessage()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag == 'p')
+      _isStreaming = false;
+    else if (tag == 'P')
+      _isStreaming = true;
+    else
+      throw error("expected Hessian message ('p') at " + codeName(tag));
+
+    int major = read();
+    int minor = read();
+
+    return (major << 16) + minor;
+  }
+
+  /**
+   * Completes reading the message
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeMessage()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'z')
+      error("expected end of message at " + codeName(tag));
+  }
+
+  /**
+   * Reads a null
+   *
+   * <pre>
+   * N
+   * </pre>
+   */
+  public void readNull()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N': return;
+      
+    default:
+      throw expect("null", tag);
+    }
+  }
+
+  /**
+   * Reads a boolean
+   *
+   * <pre>
+   * T
+   * F
+   * </pre>
+   */
+  public boolean readBoolean()
+    throws IOException
+  {
+    int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    switch (tag) {
+    case 'T': return true;
+    case 'F': return false;
+
+      // direct integer
+    case 0x80: case 0x81: case 0x82: case 0x83:
+    case 0x84: case 0x85: case 0x86: case 0x87:
+    case 0x88: case 0x89: case 0x8a: case 0x8b:
+    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+      
+    case 0x90: case 0x91: case 0x92: case 0x93:
+    case 0x94: case 0x95: case 0x96: case 0x97:
+    case 0x98: case 0x99: case 0x9a: case 0x9b:
+    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+      
+    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
+    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+    case 0xa8: case 0xa9: case 0xaa: case 0xab:
+    case 0xac: case 0xad: case 0xae: case 0xaf:
+
+    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
+    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+    case 0xb8: case 0xb9: case 0xba: case 0xbb:
+    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+      return tag != INT_ZERO;
+
+      // INT_BYTE = 0
+    case 0xc8: 
+      return read() != 0;
+      
+      // INT_BYTE != 0
+    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
+    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+    case 0xc9: case 0xca: case 0xcb:
+    case 0xcc: case 0xcd: case 0xce: case 0xcf:
+      read();
+      return true;
+
+      // INT_SHORT = 0
+    case 0xd4: 
+      return (256 * read() + read()) != 0;
+      
+      // INT_SHORT != 0
+    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+    case 0xd5: case 0xd6: case 0xd7:
+      read();
+      read();
+      return true;
+      
+    case 'I': return
+	parseInt() != 0;
+      
+    case 0xd8: case 0xd9: case 0xda: case 0xdb:
+    case 0xdc: case 0xdd: case 0xde: case 0xdf:
+      
+    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+    case 0xe8: case 0xe9: case 0xea: case 0xeb:
+    case 0xec: case 0xed: case 0xee: case 0xef:
+      return tag != LONG_ZERO;
+
+      // LONG_BYTE = 0
+    case 0xf8: 
+      return read() != 0;
+      
+      // LONG_BYTE != 0
+    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+    case 0xf9: case 0xfa: case 0xfb:
+    case 0xfc: case 0xfd: case 0xfe: case 0xff:
+      read();
+      return true;
+
+      // INT_SHORT = 0
+    case 0x3c: 
+      return (256 * read() + read()) != 0;
+      
+      // INT_SHORT != 0
+    case 0x38: case 0x39: case 0x3a: case 0x3b:
+    case 0x3d: case 0x3e: case 0x3f:
+      read();
+      read();
+      return true;
+
+    case LONG_INT:
+      return (0x1000000L * read()
+	      + 0x10000L * read()
+	      + 0x100 * read()
+	      + read()) != 0;
+      
+    case 'L':
+      return parseLong() != 0;
+
+    case DOUBLE_ZERO:
+      return false;
+      
+    case DOUBLE_ONE:
+      return true;
+      
+    case DOUBLE_BYTE:
+      return read() != 0;
+      
+    case DOUBLE_SHORT:
+      return (0x100 * read() + read()) != 0;
+      
+    case DOUBLE_FLOAT:
+      {
+	int f = parseInt();
+
+	return Float.intBitsToFloat(f) != 0;
+      }
+      
+    case 'D':
+      return parseDouble() != 0.0;
+      
+    case 'N':
+      return false;
+      
+    default:
+      throw expect("boolean", tag);
+    }
+  }
+
+  /**
+   * Reads a short
+   *
+   * <pre>
+   * I b32 b24 b16 b8
+   * </pre>
+   */
+  public short readShort()
+    throws IOException
+  {
+    return (short) readInt();
+  }
+
+  /**
+   * Reads an integer
+   *
+   * <pre>
+   * I b32 b24 b16 b8
+   * </pre>
+   */
+  public final int readInt()
+    throws IOException
+  {
+    //int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return 0;
+      
+    case 'F':
+      return 0;
+      
+    case 'T':
+      return 1;
+
+      // direct integer
+    case 0x80: case 0x81: case 0x82: case 0x83:
+    case 0x84: case 0x85: case 0x86: case 0x87:
+    case 0x88: case 0x89: case 0x8a: case 0x8b:
+    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+      
+    case 0x90: case 0x91: case 0x92: case 0x93:
+    case 0x94: case 0x95: case 0x96: case 0x97:
+    case 0x98: case 0x99: case 0x9a: case 0x9b:
+    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+      
+    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
+    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+    case 0xa8: case 0xa9: case 0xaa: case 0xab:
+    case 0xac: case 0xad: case 0xae: case 0xaf:
+      
+    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
+    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+    case 0xb8: case 0xb9: case 0xba: case 0xbb:
+    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+      return tag - INT_ZERO;
+
+      /* byte int */
+    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
+    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+    case 0xc8: case 0xc9: case 0xca: case 0xcb:
+    case 0xcc: case 0xcd: case 0xce: case 0xcf:
+      return ((tag - INT_BYTE_ZERO) << 8) + read();
+      
+      /* short int */
+    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+      return ((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read();
+
+    case 'I':
+    case LONG_INT:
+      return ((read() << 24)
+	      + (read() << 16)
+	      + (read() << 8)
+	      + read());
+
+      // direct long
+    case 0xd8: case 0xd9: case 0xda: case 0xdb:
+    case 0xdc: case 0xdd: case 0xde: case 0xdf:
+      
+    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+    case 0xe8: case 0xe9: case 0xea: case 0xeb:
+    case 0xec: case 0xed: case 0xee: case 0xef:
+      return tag - LONG_ZERO;
+
+      /* byte long */
+    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+    case 0xfc: case 0xfd: case 0xfe: case 0xff:
+      return ((tag - LONG_BYTE_ZERO) << 8) + read();
+      
+      /* short long */
+    case 0x38: case 0x39: case 0x3a: case 0x3b:
+    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+      return ((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read();
+
+    case 'L':
+      return (int) parseLong();
+
+    case DOUBLE_ZERO:
+      return 0;
+
+    case DOUBLE_ONE:
+      return 1;
+
+      //case LONG_BYTE:
+    case DOUBLE_BYTE:
+      return (byte) (_offset < _length ? _buffer[_offset++] : read());
+
+      //case INT_SHORT:
+      //case LONG_SHORT:
+    case DOUBLE_SHORT:
+      return (short) (256 * read() + read());
+
+    case DOUBLE_FLOAT:
+      {
+	int f = parseInt();
+
+	return (int) Float.intBitsToFloat(f);
+      }
+
+    case 'D':
+      return (int) parseDouble();
+      
+    default:
+      throw expect("integer", tag);
+    }
+  }
+
+  /**
+   * Reads a long
+   *
+   * <pre>
+   * L b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public long readLong()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return 0;
+      
+    case 'F':
+      return 0;
+      
+    case 'T':
+      return 1;
+
+      // direct integer
+    case 0x80: case 0x81: case 0x82: case 0x83:
+    case 0x84: case 0x85: case 0x86: case 0x87:
+    case 0x88: case 0x89: case 0x8a: case 0x8b:
+    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+      
+    case 0x90: case 0x91: case 0x92: case 0x93:
+    case 0x94: case 0x95: case 0x96: case 0x97:
+    case 0x98: case 0x99: case 0x9a: case 0x9b:
+    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+      
+    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
+    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+    case 0xa8: case 0xa9: case 0xaa: case 0xab:
+    case 0xac: case 0xad: case 0xae: case 0xaf:
+      
+    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
+    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+    case 0xb8: case 0xb9: case 0xba: case 0xbb:
+    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+      return tag - INT_ZERO;
+
+      /* byte int */
+    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
+    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+    case 0xc8: case 0xc9: case 0xca: case 0xcb:
+    case 0xcc: case 0xcd: case 0xce: case 0xcf:
+      return ((tag - INT_BYTE_ZERO) << 8) + read();
+      
+      /* short int */
+    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+      return ((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read();
+
+      //case LONG_BYTE:
+    case DOUBLE_BYTE:
+      return (byte) (_offset < _length ? _buffer[_offset++] : read());
+
+      //case INT_SHORT:
+      //case LONG_SHORT:
+    case DOUBLE_SHORT:
+      return (short) (256 * read() + read());
+
+    case 'I':
+    case LONG_INT:
+      return parseInt();
+
+      // direct long
+    case 0xd8: case 0xd9: case 0xda: case 0xdb:
+    case 0xdc: case 0xdd: case 0xde: case 0xdf:
+      
+    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+    case 0xe8: case 0xe9: case 0xea: case 0xeb:
+    case 0xec: case 0xed: case 0xee: case 0xef:
+      return tag - LONG_ZERO;
+
+      /* byte long */
+    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+    case 0xfc: case 0xfd: case 0xfe: case 0xff:
+      return ((tag - LONG_BYTE_ZERO) << 8) + read();
+      
+      /* short long */
+    case 0x38: case 0x39: case 0x3a: case 0x3b:
+    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+      return ((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read();
+
+    case 'L':
+      return parseLong();
+
+    case DOUBLE_ZERO:
+      return 0;
+
+    case DOUBLE_ONE:
+      return 1;
+
+    case DOUBLE_FLOAT:
+      {
+	int f = parseInt();
+
+	return (long) Float.intBitsToFloat(f);
+      }
+
+    case 'D':
+      return (long) parseDouble();
+      
+    default:
+      throw expect("long", tag);
+    }
+  }
+
+  /**
+   * Reads a float
+   *
+   * <pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public float readFloat()
+    throws IOException
+  {
+    return (float) readDouble();
+  }
+
+  /**
+   * Reads a double
+   *
+   * <pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public double readDouble()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return 0;
+      
+    case 'F':
+      return 0;
+      
+    case 'T':
+      return 1;
+
+      // direct integer
+    case 0x80: case 0x81: case 0x82: case 0x83:
+    case 0x84: case 0x85: case 0x86: case 0x87:
+    case 0x88: case 0x89: case 0x8a: case 0x8b:
+    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+      
+    case 0x90: case 0x91: case 0x92: case 0x93:
+    case 0x94: case 0x95: case 0x96: case 0x97:
+    case 0x98: case 0x99: case 0x9a: case 0x9b:
+    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+      
+    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
+    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+    case 0xa8: case 0xa9: case 0xaa: case 0xab:
+    case 0xac: case 0xad: case 0xae: case 0xaf:
+      
+    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
+    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+    case 0xb8: case 0xb9: case 0xba: case 0xbb:
+    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+      return tag - 0x90;
+
+      /* byte int */
+    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
+    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+    case 0xc8: case 0xc9: case 0xca: case 0xcb:
+    case 0xcc: case 0xcd: case 0xce: case 0xcf:
+      return ((tag - INT_BYTE_ZERO) << 8) + read();
+      
+      /* short int */
+    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+      return ((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read();
+
+    case 'I':
+    case LONG_INT:
+      return parseInt();
+
+      // direct long
+    case 0xd8: case 0xd9: case 0xda: case 0xdb:
+    case 0xdc: case 0xdd: case 0xde: case 0xdf:
+      
+    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+    case 0xe8: case 0xe9: case 0xea: case 0xeb:
+    case 0xec: case 0xed: case 0xee: case 0xef:
+      return tag - LONG_ZERO;
+
+      /* byte long */
+    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+    case 0xfc: case 0xfd: case 0xfe: case 0xff:
+      return ((tag - LONG_BYTE_ZERO) << 8) + read();
+      
+      /* short long */
+    case 0x38: case 0x39: case 0x3a: case 0x3b:
+    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+      return ((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read();
+
+    case 'L':
+      return (double) parseLong();
+
+    case DOUBLE_ZERO:
+      return 0;
+
+    case DOUBLE_ONE:
+      return 1;
+
+    case DOUBLE_BYTE:
+      return (byte) (_offset < _length ? _buffer[_offset++] : read());
+
+    case DOUBLE_SHORT:
+      return (short) (256 * read() + read());
+
+    case DOUBLE_FLOAT:
+      {
+	int f = parseInt();
+
+	return Float.intBitsToFloat(f);
+      }
+      
+    case 'D':
+      return parseDouble();
+      
+    default:
+      throw expect("double", tag);
+    }
+  }
+
+  /**
+   * Reads a date.
+   *
+   * <pre>
+   * T b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public long readUTCDate()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag != 'd')
+      throw expect("date", tag);
+
+    long b64 = read();
+    long b56 = read();
+    long b48 = read();
+    long b40 = read();
+    long b32 = read();
+    long b24 = read();
+    long b16 = read();
+    long b8 = read();
+
+    return ((b64 << 56)
+	    + (b56 << 48)
+	    + (b48 << 40)
+	    + (b40 << 32)
+	    + (b32 << 24)
+	    + (b24 << 16)
+	    + (b16 << 8)
+	    + b8);
+  }
+
+  /**
+   * Reads a byte from the stream.
+   */
+  public int readChar()
+    throws IOException
+  {
+    if (_chunkLength > 0) {
+      _chunkLength--;
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      int ch = parseUTF8Char();
+      return ch;
+    }
+    else if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return -1;
+
+    case 'S':
+    case 's':
+    case 'X':
+    case 'x':
+      _isLastChunk = tag == 'S' || tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      _chunkLength--;
+      int value = parseUTF8Char();
+
+      // special code so successive read byte won't
+      // be read as a single object.
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      return value;
+      
+    default:
+      throw expect("char", tag);
+    }
+  }
+
+  /**
+   * Reads a byte array from the stream.
+   */
+  public int readString(char []buffer, int offset, int length)
+    throws IOException
+  {
+    int readLength = 0;
+
+    if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    else if (_chunkLength == 0) {
+      int tag = read();
+
+      switch (tag) {
+      case 'N':
+        return -1;
+      
+      case 'S':
+      case 's':
+      case 'X':
+      case 'x':
+        _isLastChunk = tag == 'S' || tag == 'X';
+        _chunkLength = (read() << 8) + read();
+        break;
+
+      case 0x00: case 0x01: case 0x02: case 0x03:
+      case 0x04: case 0x05: case 0x06: case 0x07:
+      case 0x08: case 0x09: case 0x0a: case 0x0b:
+      case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+
+      case 0x10: case 0x11: case 0x12: case 0x13:
+      case 0x14: case 0x15: case 0x16: case 0x17:
+      case 0x18: case 0x19: case 0x1a: case 0x1b:
+      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+	_isLastChunk = true;
+	_chunkLength = tag - 0x00;
+	break;
+
+      default:
+        throw expect("string", tag);
+      }
+    }
+
+    while (length > 0) {
+      if (_chunkLength > 0) {
+        buffer[offset++] = (char) parseUTF8Char();
+        _chunkLength--;
+        length--;
+        readLength++;
+      }
+      else if (_isLastChunk) {
+        if (readLength == 0)
+          return -1;
+        else {
+          _chunkLength = END_OF_DATA;
+          return readLength;
+        }
+      }
+      else {
+        int tag = read();
+
+        switch (tag) {
+        case 'S':
+        case 's':
+        case 'X':
+        case 'x':
+          _isLastChunk = tag == 'S' || tag == 'X';
+          _chunkLength = (read() << 8) + read();
+          break;
+      
+        default:
+          throw expect("string", tag);
+        }
+      }
+    }
+    
+    if (readLength == 0)
+      return -1;
+    else if (_chunkLength > 0 || ! _isLastChunk)
+      return readLength;
+    else {
+      _chunkLength = END_OF_DATA;
+      return readLength;
+    }
+  }
+
+  /**
+   * Reads a string
+   *
+   * <pre>
+   * S b16 b8 string value
+   * </pre>
+   */
+  public String readString()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+    case 'T':
+      return "true";
+    case 'F':
+      return "false";
+
+      // direct integer
+    case 0x80: case 0x81: case 0x82: case 0x83:
+    case 0x84: case 0x85: case 0x86: case 0x87:
+    case 0x88: case 0x89: case 0x8a: case 0x8b:
+    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+      
+    case 0x90: case 0x91: case 0x92: case 0x93:
+    case 0x94: case 0x95: case 0x96: case 0x97:
+    case 0x98: case 0x99: case 0x9a: case 0x9b:
+    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+      
+    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
+    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+    case 0xa8: case 0xa9: case 0xaa: case 0xab:
+    case 0xac: case 0xad: case 0xae: case 0xaf:
+      
+    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
+    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+    case 0xb8: case 0xb9: case 0xba: case 0xbb:
+    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+      return String.valueOf((tag - 0x90));
+
+      /* byte int */
+    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
+    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+    case 0xc8: case 0xc9: case 0xca: case 0xcb:
+    case 0xcc: case 0xcd: case 0xce: case 0xcf:
+      return String.valueOf(((tag - INT_BYTE_ZERO) << 8) + read());
+      
+      /* short int */
+    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+      return String.valueOf(((tag - INT_SHORT_ZERO) << 16)
+			    + 256 * read() + read());
+
+    case 'I':
+    case LONG_INT:
+      return String.valueOf(parseInt());
+
+      // direct long
+    case 0xd8: case 0xd9: case 0xda: case 0xdb:
+    case 0xdc: case 0xdd: case 0xde: case 0xdf:
+      
+    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+    case 0xe8: case 0xe9: case 0xea: case 0xeb:
+    case 0xec: case 0xed: case 0xee: case 0xef:
+      return String.valueOf(tag - LONG_ZERO);
+
+      /* byte long */
+    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+    case 0xfc: case 0xfd: case 0xfe: case 0xff:
+      return String.valueOf(((tag - LONG_BYTE_ZERO) << 8) + read());
+      
+      /* short long */
+    case 0x38: case 0x39: case 0x3a: case 0x3b:
+    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+      return String.valueOf(((tag - LONG_SHORT_ZERO) << 16)
+			    + 256 * read() + read());
+
+    case 'L':
+      return String.valueOf(parseLong());
+
+    case DOUBLE_ZERO:
+      return "0.0";
+
+    case DOUBLE_ONE:
+      return "1.0";
+
+    case DOUBLE_BYTE:
+      return String.valueOf((byte) (_offset < _length
+				    ? _buffer[_offset++]
+				    : read()));
+
+    case DOUBLE_SHORT:
+      return String.valueOf(((short) (256 * read() + read())));
+
+    case DOUBLE_FLOAT:
+      {
+	int f = parseInt();
+
+	return String.valueOf(Float.intBitsToFloat(f));
+      }
+      
+    case 'D':
+      return String.valueOf(parseDouble());
+
+    case 'S':
+    case 's':
+    case 'X':
+    case 'x':
+      _isLastChunk = tag == 'S' || tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      _sbuf.setLength(0);
+      int ch;
+
+      while ((ch = parseChar()) >= 0)
+        _sbuf.append((char) ch);
+
+      return _sbuf.toString();
+
+      // 0-byte string
+    case 0x00: case 0x01: case 0x02: case 0x03:
+    case 0x04: case 0x05: case 0x06: case 0x07:
+    case 0x08: case 0x09: case 0x0a: case 0x0b:
+    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+
+    case 0x10: case 0x11: case 0x12: case 0x13:
+    case 0x14: case 0x15: case 0x16: case 0x17:
+    case 0x18: case 0x19: case 0x1a: case 0x1b:
+    case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+      _isLastChunk = true;
+      _chunkLength = tag - 0x00;
+
+      _sbuf.setLength(0);
+
+      while ((ch = parseChar()) >= 0)
+        _sbuf.append((char) ch);
+
+      return _sbuf.toString();
+
+    default:
+      throw expect("string", tag);
+    }
+  }
+
+  /**
+   * Reads an XML node.
+   *
+   * <pre>
+   * S b16 b8 string value
+   * </pre>
+   */
+  public org.w3c.dom.Node readNode()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'S':
+    case 's':
+    case 'X':
+    case 'x':
+      _isLastChunk = tag == 'S' || tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      throw error("XML is not supported");
+
+    case 0x00: case 0x01: case 0x02: case 0x03:
+    case 0x04: case 0x05: case 0x06: case 0x07:
+    case 0x08: case 0x09: case 0x0a: case 0x0b:
+    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+
+    case 0x10: case 0x11: case 0x12: case 0x13:
+    case 0x14: case 0x15: case 0x16: case 0x17:
+    case 0x18: case 0x19: case 0x1a: case 0x1b:
+    case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+      _isLastChunk = true;
+      _chunkLength = tag - 0x00;
+
+      throw error("XML is not supported");
+
+    default:
+      throw expect("string", tag);
+    }
+  }
+
+  /**
+   * Reads a byte array
+   *
+   * <pre>
+   * B b16 b8 data value
+   * </pre>
+   */
+  public byte []readBytes()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'B':
+    case 'b':
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+
+      ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+      int data;
+      while ((data = parseByte()) >= 0)
+        bos.write(data);
+
+      return bos.toByteArray();
+
+    case 0x20: case 0x21: case 0x22: case 0x23:
+    case 0x24: case 0x25: case 0x26: case 0x27:
+    case 0x28: case 0x29: case 0x2a: case 0x2b:
+    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+      _isLastChunk = true;
+      _chunkLength = tag - 0x20;
+
+      bos = new ByteArrayOutputStream();
+
+      while ((data = parseByte()) >= 0)
+        bos.write(data);
+
+      return bos.toByteArray();
+      
+    default:
+      throw expect("bytes", tag);
+    }
+  }
+
+  /**
+   * Reads a byte from the stream.
+   */
+  public int readByte()
+    throws IOException
+  {
+    if (_chunkLength > 0) {
+      _chunkLength--;
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      return read();
+    }
+    else if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return -1;
+
+    case 'B':
+    case 'b':
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+
+      int value = parseByte();
+
+      // special code so successive read byte won't
+      // be read as a single object.
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      return value;
+      
+    default:
+      throw expect("binary", tag);
+    }
+  }
+
+  /**
+   * Reads a byte array from the stream.
+   */
+  public int readBytes(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    int readLength = 0;
+
+    if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    else if (_chunkLength == 0) {
+      int tag = read();
+
+      switch (tag) {
+      case 'N':
+        return -1;
+      
+      case 'B':
+      case 'b':
+        _isLastChunk = tag == 'B';
+        _chunkLength = (read() << 8) + read();
+        break;
+      
+      default:
+        throw expect("binary", tag);
+      }
+    }
+
+    while (length > 0) {
+      if (_chunkLength > 0) {
+        buffer[offset++] = (byte) read();
+        _chunkLength--;
+        length--;
+        readLength++;
+      }
+      else if (_isLastChunk) {
+        if (readLength == 0)
+          return -1;
+        else {
+          _chunkLength = END_OF_DATA;
+          return readLength;
+        }
+      }
+      else {
+        int tag = read();
+
+        switch (tag) {
+        case 'B':
+        case 'b':
+          _isLastChunk = tag == 'B';
+          _chunkLength = (read() << 8) + read();
+          break;
+      
+        default:
+          throw expect("binary", tag);
+        }
+      }
+    }
+    
+    if (readLength == 0)
+      return -1;
+    else if (_chunkLength > 0 || ! _isLastChunk)
+      return readLength;
+    else {
+      _chunkLength = END_OF_DATA;
+      return readLength;
+    }
+  }
+
+  /**
+   * Reads a fault.
+   */
+  private HashMap readFault()
+    throws IOException
+  {
+    HashMap map = new HashMap();
+
+    int code = read();
+    for (; code > 0 && code != 'z'; code = read()) {
+      _offset--;
+      
+      Object key = readObject();
+      Object value = readObject();
+
+      if (key != null && value != null)
+        map.put(key, value);
+    }
+
+    if (code != 'z')
+      throw expect("fault", code);
+
+    return map;
+  }
+
+  /**
+   * Reads an object from the input stream with an expected type.
+   */
+  public Object readObject(Class cl)
+    throws IOException
+  {
+    if (cl == null || cl == Object.class)
+      return readObject();
+    
+    int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'M':
+    {
+      String type = readType();
+
+      // hessian/3bb3
+      if ("".equals(type)) {
+	Deserializer reader;
+	reader = findSerializerFactory().getDeserializer(cl);
+
+	return reader.readMap(this);
+      }
+      else {
+	Deserializer reader;
+	reader = findSerializerFactory().getObjectDeserializer(type, cl);
+
+	return reader.readMap(this);
+      }
+    }
+
+    case 'O':
+    {
+      readObjectDefinition(cl);
+
+      return readObject(cl);
+    }
+
+    case 'o':
+    {
+      int ref = readInt();
+      int size = _classDefs.size();
+
+      if (ref < 0 || size <= ref)
+	throw new HessianProtocolException("'" + ref + "' is an unknown class definition");
+
+      ObjectDefinition def = (ObjectDefinition) _classDefs.get(ref);
+
+      return readObjectInstance(cl, def);
+    }
+
+    case 'V':
+    {
+      String type = readType();
+      int length = readLength();
+      
+      Deserializer reader;
+      reader = findSerializerFactory().getListDeserializer(type, cl);
+
+      Object v = reader.readList(this, length);
+
+      return v;
+    }
+
+    case 'v':
+    {
+      int ref = readInt();
+      String type = (String) _types.get(ref);
+      int length = readInt();
+      
+      Deserializer reader;
+      reader = findSerializerFactory().getListDeserializer(type, cl);
+
+      Object v = reader.readLengthList(this, length);
+
+      return v;
+    }
+
+    case 'R':
+    {
+      int ref = parseInt();
+
+      return _refs.get(ref);
+    }
+
+    case 'r':
+    {
+      String type = readType();
+      String url = readString();
+
+      return resolveRemote(type, url);
+    }
+
+    case REF_BYTE: {
+      int ref = read();
+
+      return _refs.get(ref);
+    }
+
+    case REF_SHORT: {
+      int ref = 256 * read() + read();
+
+      return _refs.get(ref);
+    }
+    }
+
+    if (tag >= 0)
+      _offset--;
+
+    // hessian/3b2i vs hessian/3406
+    // return readObject();
+
+    Object value = findSerializerFactory().getDeserializer(cl).readObject(this);
+    return value;
+  }
+  
+  /**
+   * Reads an arbitrary object from the input stream when the type
+   * is unknown.
+   */
+  public Object readObject()
+    throws IOException
+  {
+    int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+      
+    case 'T':
+      return Boolean.valueOf(true);
+      
+    case 'F':
+      return Boolean.valueOf(false);
+
+      // direct integer
+    case 0x80: case 0x81: case 0x82: case 0x83:
+    case 0x84: case 0x85: case 0x86: case 0x87:
+    case 0x88: case 0x89: case 0x8a: case 0x8b:
+    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+      
+    case 0x90: case 0x91: case 0x92: case 0x93:
+    case 0x94: case 0x95: case 0x96: case 0x97:
+    case 0x98: case 0x99: case 0x9a: case 0x9b:
+    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+      
+    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
+    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+    case 0xa8: case 0xa9: case 0xaa: case 0xab:
+    case 0xac: case 0xad: case 0xae: case 0xaf:
+      
+    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
+    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+    case 0xb8: case 0xb9: case 0xba: case 0xbb:
+    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+      return Integer.valueOf(tag - INT_ZERO);
+
+      /* byte int */
+    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
+    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
+    case 0xc8: case 0xc9: case 0xca: case 0xcb:
+    case 0xcc: case 0xcd: case 0xce: case 0xcf:
+      return Integer.valueOf(((tag - INT_BYTE_ZERO) << 8) + read());
+      
+      /* short int */
+    case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+    case 0xd4: case 0xd5: case 0xd6: case 0xd7:
+      return Integer.valueOf(((tag - INT_SHORT_ZERO) << 16) + 256 * read() + read());
+      
+    case 'I':
+      return Integer.valueOf(parseInt());
+
+      // direct long
+    case 0xd8: case 0xd9: case 0xda: case 0xdb:
+    case 0xdc: case 0xdd: case 0xde: case 0xdf:
+      
+    case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+    case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+    case 0xe8: case 0xe9: case 0xea: case 0xeb:
+    case 0xec: case 0xed: case 0xee: case 0xef:
+      return Long.valueOf(tag - LONG_ZERO);
+
+      /* byte long */
+    case 0xf0: case 0xf1: case 0xf2: case 0xf3:
+    case 0xf4: case 0xf5: case 0xf6: case 0xf7:
+    case 0xf8: case 0xf9: case 0xfa: case 0xfb:
+    case 0xfc: case 0xfd: case 0xfe: case 0xff:
+      return Long.valueOf(((tag - LONG_BYTE_ZERO) << 8) + read());
+      
+      /* short long */
+    case 0x38: case 0x39: case 0x3a: case 0x3b:
+    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+      return Long.valueOf(((tag - LONG_SHORT_ZERO) << 16) + 256 * read() + read());
+      
+    case LONG_INT:
+      return Long.valueOf(parseInt());
+    
+    case 'L':
+      return Long.valueOf(parseLong());
+
+    case DOUBLE_ZERO:
+      return Double.valueOf(0);
+
+    case DOUBLE_ONE:
+      return Double.valueOf(1);
+
+    case DOUBLE_BYTE:
+      return Double.valueOf((byte) read());
+
+    case DOUBLE_SHORT:
+      return Double.valueOf((short) (256 * read() + read()));
+      
+    case DOUBLE_FLOAT:
+      {
+	int f = parseInt();
+
+	return Double.valueOf(Float.intBitsToFloat(f));
+      }
+
+    case 'D':
+      return Double.valueOf(parseDouble());
+    
+    case 'd':
+      return new Date(parseLong());
+    
+    case 'x':
+    case 'X': {
+      _isLastChunk = tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      return parseXML();
+    }
+
+    case 's':
+    case 'S': {
+      _isLastChunk = tag == 'S';
+      _chunkLength = (read() << 8) + read();
+
+      int data;
+      _sbuf.setLength(0);
+      
+      while ((data = parseChar()) >= 0)
+        _sbuf.append((char) data);
+
+      return _sbuf.toString();
+    }
+
+    case 0x00: case 0x01: case 0x02: case 0x03:
+    case 0x04: case 0x05: case 0x06: case 0x07:
+    case 0x08: case 0x09: case 0x0a: case 0x0b:
+    case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+
+    case 0x10: case 0x11: case 0x12: case 0x13:
+    case 0x14: case 0x15: case 0x16: case 0x17:
+    case 0x18: case 0x19: case 0x1a: case 0x1b:
+    case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+      {
+	_isLastChunk = true;
+	_chunkLength = tag - 0x00;
+
+	int data;
+	_sbuf.setLength(0);
+      
+	while ((data = parseChar()) >= 0)
+	  _sbuf.append((char) data);
+
+	return _sbuf.toString();
+      }
+
+    case 'b':
+    case 'B': {
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+
+      int data;
+      ByteArrayOutputStream bos = new ByteArrayOutputStream();
+      
+      while ((data = parseByte()) >= 0)
+        bos.write(data);
+
+      return bos.toByteArray();
+    }
+
+    case 0x20: case 0x21: case 0x22: case 0x23:
+    case 0x24: case 0x25: case 0x26: case 0x27:
+    case 0x28: case 0x29: case 0x2a: case 0x2b:
+    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+      {
+	_isLastChunk = true;
+	int len = tag - 0x20;
+	_chunkLength = 0;
+
+	byte []data = new byte[len];
+
+	for (int i = 0; i < len; i++)
+	  data[i] = (byte) read();
+
+	return data;
+      }
+
+    case 'V': {
+      String type = readType();
+      int length = readLength();
+
+      return findSerializerFactory().readList(this, length, type);
+    }
+
+      // direct lists
+    case 'v': {
+      int ref = readInt();
+      String type = (String) _types.get(ref);
+      int length = readInt();
+      
+      Deserializer reader;
+      reader = findSerializerFactory().getObjectDeserializer(type, null);
+      
+      return reader.readLengthList(this, length);
+    }
+
+    case 'M': {
+      String type = readType();
+
+      return findSerializerFactory().readMap(this, type);
+    }
+
+    case 'O': {
+      readObjectDefinition(null);
+
+      return readObject();
+    }
+
+    case 'o': {
+      int ref = readInt();
+
+      ObjectDefinition def = (ObjectDefinition) _classDefs.get(ref);
+
+      return readObjectInstance(null, def);
+    }
+
+    case 'R': {
+      int ref = parseInt();
+
+      return _refs.get(ref);
+    }
+
+    case REF_BYTE: {
+      int ref = read();
+
+      return _refs.get(ref);
+    }
+
+    case REF_SHORT: {
+      int ref = 256 * read() + read();
+
+      return _refs.get(ref);
+    }
+      
+    case 'r': {
+      String type = readType();
+      String url = readString();
+
+      return resolveRemote(type, url);
+    }
+
+    default:
+      if (tag < 0)
+	throw new EOFException("readObject: unexpected end of file");
+      else
+	throw error("readObject: unknown code " + codeName(tag));
+    }
+  }
+
+  /**
+   * Reads an object definition:
+   *
+   * <pre>
+   * O string <int> (string)* <value>*
+   * </pre>
+   */
+  private void readObjectDefinition(Class cl)
+    throws IOException
+  {
+    String type = readString();
+    int len = readInt();
+
+    String []fieldNames = new String[len];
+    for (int i = 0; i < len; i++)
+      fieldNames[i] = readString();
+
+    ObjectDefinition def = new ObjectDefinition(type, fieldNames);
+
+    if (_classDefs == null)
+      _classDefs = new ArrayList();
+
+    _classDefs.add(def);
+  }
+
+  private Object readObjectInstance(Class cl, ObjectDefinition def)
+    throws IOException
+  {
+    String type = def.getType();
+    String []fieldNames = def.getFieldNames();
+    
+    if (cl != null) {
+      Deserializer reader;
+      reader = findSerializerFactory().getObjectDeserializer(type, cl);
+
+      return reader.readObject(this, fieldNames);
+    }
+    else {
+      return findSerializerFactory().readObject(this, type, fieldNames);
+    }
+  }
+
+  private String readLenString()
+    throws IOException
+  {
+    int len = readInt();
+    
+    _isLastChunk = true;
+    _chunkLength = len;
+
+    _sbuf.setLength(0);
+    int ch;
+    while ((ch = parseChar()) >= 0)
+      _sbuf.append((char) ch);
+
+    return _sbuf.toString();
+  }
+
+  private String readLenString(int len)
+    throws IOException
+  {
+    _isLastChunk = true;
+    _chunkLength = len;
+
+    _sbuf.setLength(0);
+    int ch;
+    while ((ch = parseChar()) >= 0)
+      _sbuf.append((char) ch);
+
+    return _sbuf.toString();
+  }
+  
+  /**
+   * Reads a remote object.
+   */
+  public Object readRemote()
+    throws IOException
+  {
+    String type = readType();
+    String url = readString();
+
+    return resolveRemote(type, url);
+  }
+
+  /**
+   * Reads a reference.
+   */
+  public Object readRef()
+    throws IOException
+  {
+    return _refs.get(parseInt());
+  }
+
+  /**
+   * Reads the start of a list.
+   */
+  public int readListStart()
+    throws IOException
+  {
+    return read();
+  }
+
+  /**
+   * Reads the start of a list.
+   */
+  public int readMapStart()
+    throws IOException
+  {
+    return read();
+  }
+
+  /**
+   * Returns true if this is the end of a list or a map.
+   */
+  public boolean isEnd()
+    throws IOException
+  {
+    int code;
+
+    if (_offset < _length)
+      code = (_buffer[_offset] & 0xff);
+    else {
+      code = read();
+
+      if (code >= 0)
+	_offset--;
+    }
+
+    return (code < 0 || code == 'z');
+  }
+
+  /**
+   * Reads the end byte.
+   */
+  public void readEnd()
+    throws IOException
+  {
+    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    if (code == 'z')
+      return;
+    else if (code < 0)
+      throw error("unexpected end of file");
+    else
+      throw error("unknown code:" + codeName(code));
+  }
+
+  /**
+   * Reads the end byte.
+   */
+  public void readMapEnd()
+    throws IOException
+  {
+    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    if (code != 'z')
+      throw error("expected end of map ('z') at '" + codeName(code) + "'");
+  }
+
+  /**
+   * Reads the end byte.
+   */
+  public void readListEnd()
+    throws IOException
+  {
+    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    if (code != 'z')
+      throw error("expected end of list ('z') at '" + codeName(code) + "'");
+  }
+
+  /**
+   * Adds a list/map reference.
+   */
+  public int addRef(Object ref)
+  {
+    if (_refs == null)
+      _refs = new ArrayList();
+    
+    _refs.add(ref);
+
+    return _refs.size() - 1;
+  }
+
+  /**
+   * Adds a list/map reference.
+   */
+  public void setRef(int i, Object ref)
+  {
+    _refs.set(i, ref);
+  }
+  
+  /**
+   * Resets the references for streaming.
+   */
+  public void resetReferences()
+  {
+    if (_refs != null)
+      _refs.clear();
+  }
+
+  public Object readStreamingObject()
+    throws IOException
+  {
+    if (_refs != null)
+      _refs.clear();
+
+    return readObject();
+  }
+
+  /**
+   * Resolves a remote object.
+   */
+  public Object resolveRemote(String type, String url)
+    throws IOException
+  {
+    HessianRemoteResolver resolver = getRemoteResolver();
+
+    if (resolver != null)
+      return resolver.lookup(type, url);
+    else
+      return new HessianRemote(type, url);
+  }
+
+  /**
+   * Parses a type from the stream.
+   *
+   * <pre>
+   * t b16 b8
+   * </pre>
+   */
+  public String readType()
+    throws IOException
+  {
+    int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    switch (code) {
+    case 't':
+      {
+        int len = 256 * read() + read();
+        String type = readLenString(len);
+
+        if (_types == null)
+          _types = new ArrayList();
+
+        _types.add(type);
+
+        return type;
+      }
+
+    case 'T':
+      {
+        int ref = readInt();
+
+        return (String) _types.get(ref);
+      }
+
+    case TYPE_REF:
+      {
+        int ref = readInt();
+
+        return (String) _types.get(ref);
+      }
+      
+    default:
+      {
+        if (code >= 0)
+          _offset--;
+      
+        return "";
+      }
+    }
+  }
+
+  /**
+   * Parses the length for an array
+   *
+   * <pre>
+   * l b32 b24 b16 b8
+   * </pre>
+   */
+  public int readLength()
+    throws IOException
+  {
+    int code = read();
+
+    if (code == LENGTH_BYTE)
+      return read();
+	
+    else if (code == 'l')
+      return parseInt();
+
+    else {
+      if (code >= 0)
+	_offset--;
+      
+      return -1;
+    }
+  }
+
+  /**
+   * Parses a 32-bit integer value from the stream.
+   *
+   * <pre>
+   * b32 b24 b16 b8
+   * </pre>
+   */
+  private int parseInt()
+    throws IOException
+  {
+    int offset = _offset;
+    
+    if (offset + 3 < _length) {
+      byte []buffer = _buffer;
+      
+      int b32 = buffer[offset + 0] & 0xff;
+      int b24 = buffer[offset + 1] & 0xff;
+      int b16 = buffer[offset + 2] & 0xff;
+      int b8 = buffer[offset + 3] & 0xff;
+
+      _offset = offset + 4;
+
+      return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
+    }
+    else {
+      int b32 = read();
+      int b24 = read();
+      int b16 = read();
+      int b8 = read();
+
+      return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
+    }
+  }
+
+  /**
+   * Parses a 64-bit long value from the stream.
+   *
+   * <pre>
+   * b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  private long parseLong()
+    throws IOException
+  {
+    long b64 = read();
+    long b56 = read();
+    long b48 = read();
+    long b40 = read();
+    long b32 = read();
+    long b24 = read();
+    long b16 = read();
+    long b8 = read();
+
+    return ((b64 << 56) +
+            (b56 << 48) +
+            (b48 << 40) +
+            (b40 << 32) +
+            (b32 << 24) +
+            (b24 << 16) +
+            (b16 << 8) +
+            b8);
+  }
+  
+  /**
+   * Parses a 64-bit double value from the stream.
+   *
+   * <pre>
+   * b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  private double parseDouble()
+    throws IOException
+  {
+    long bits = parseLong();
+  
+    return Double.longBitsToDouble(bits);
+  }
+
+  org.w3c.dom.Node parseXML()
+    throws IOException
+  {
+    throw new UnsupportedOperationException();
+  }
+  
+  /**
+   * Reads a character from the underlying stream.
+   */
+  private int parseChar()
+    throws IOException
+  {
+    while (_chunkLength <= 0) {
+      if (_isLastChunk)
+        return -1;
+
+      int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+      switch (code) {
+      case 's':
+      case 'x':
+        _isLastChunk = false;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+        
+      case 'S':
+      case 'X':
+        _isLastChunk = true;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+	
+      case 0x00: case 0x01: case 0x02: case 0x03:
+      case 0x04: case 0x05: case 0x06: case 0x07:
+      case 0x08: case 0x09: case 0x0a: case 0x0b:
+      case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+
+      case 0x10: case 0x11: case 0x12: case 0x13:
+      case 0x14: case 0x15: case 0x16: case 0x17:
+      case 0x18: case 0x19: case 0x1a: case 0x1b:
+      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+	_isLastChunk = true;
+	_chunkLength = code - 0x00;
+	break;
+
+      default:
+        throw expect("string", code);
+      }
+
+    }
+
+    _chunkLength--;
+
+    return parseUTF8Char();
+  }
+
+  /**
+   * Parses a single UTF8 character.
+   */
+  private int parseUTF8Char()
+    throws IOException
+  {
+    int ch = _offset < _length ? (_buffer[_offset++] & 0xff) : read();
+
+    if (ch < 0x80)
+      return ch;
+    else if ((ch & 0xe0) == 0xc0) {
+      int ch1 = read();
+      int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);
+
+      return v;
+    }
+    else if ((ch & 0xf0) == 0xe0) {
+      int ch1 = read();
+      int ch2 = read();
+      int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f);
+
+      return v;
+    }
+    else
+      throw error("bad utf-8 encoding at " + codeName(ch));
+  }
+  
+  /**
+   * Reads a byte from the underlying stream.
+   */
+  private int parseByte()
+    throws IOException
+  {
+    while (_chunkLength <= 0) {
+      if (_isLastChunk) {
+        return -1;
+      }
+
+      int code = read();
+
+      switch (code) {
+      case 'b':
+        _isLastChunk = false;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+        
+      case 'B':
+        _isLastChunk = true;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+
+      case 0x20: case 0x21: case 0x22: case 0x23:
+      case 0x24: case 0x25: case 0x26: case 0x27:
+      case 0x28: case 0x29: case 0x2a: case 0x2b:
+      case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+        _isLastChunk = true;
+
+        _chunkLength = code - 0x20;
+        break;
+
+      default:
+        throw expect("byte[]", code);
+      }
+    }
+
+    _chunkLength--;
+
+    return read();
+  }
+
+  /**
+   * Reads bytes based on an input stream.
+   */
+  public InputStream readInputStream()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'B':
+    case 'b':
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+      break;
+
+    case 0x20: case 0x21: case 0x22: case 0x23:
+    case 0x24: case 0x25: case 0x26: case 0x27:
+    case 0x28: case 0x29: case 0x2a: case 0x2b:
+    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+      _isLastChunk = true;
+      _chunkLength = tag - 0x20;
+      break;
+      
+    default:
+      throw expect("binary", tag);
+    }
+    
+    return new ReadInputStream();
+  }
+  
+  /**
+   * Reads bytes from the underlying stream.
+   */
+  int read(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    int readLength = 0;
+
+    while (length > 0) {
+      while (_chunkLength <= 0) {
+        if (_isLastChunk)
+          return readLength == 0 ? -1 : readLength;
+
+        int code = read();
+
+        switch (code) {
+        case 'b':
+          _isLastChunk = false;
+
+          _chunkLength = (read() << 8) + read();
+          break;
+        
+        case 'B':
+          _isLastChunk = true;
+
+          _chunkLength = (read() << 8) + read();
+          break;
+
+	case 0x20: case 0x21: case 0x22: case 0x23:
+	case 0x24: case 0x25: case 0x26: case 0x27:
+	case 0x28: case 0x29: case 0x2a: case 0x2b:
+	case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+	  _isLastChunk = true;
+	  _chunkLength = code - 0x20;
+	  break;
+
+        default:
+          throw expect("byte[]", code);
+        }
+      }
+
+      int sublen = _chunkLength;
+      if (length < sublen)
+        sublen = length;
+
+      if (_length <= _offset && ! readBuffer())
+	return -1;
+      
+      if (_length - _offset < sublen)
+	sublen = _length - _offset;
+
+      System.arraycopy(_buffer, _offset, buffer, offset, sublen);
+
+      _offset += sublen;
+      
+      offset += sublen;
+      readLength += sublen;
+      length -= sublen;
+      _chunkLength -= sublen;
+    }
+
+    return readLength;
+  }
+
+  /**
+   * Normally, shouldn't be called externally, but needed for QA, e.g.
+   * ejb/3b01.
+   */
+  public final int read()
+    throws IOException
+  {
+    if (_length <= _offset && ! readBuffer())
+      return -1;
+
+    return _buffer[_offset++] & 0xff;
+  }
+
+  private final boolean readBuffer()
+    throws IOException
+  {
+    byte []buffer = _buffer;
+    int offset = _offset;
+    int length = _length;
+    
+    if (offset < length) {
+      System.arraycopy(buffer, offset, buffer, 0, length - offset);
+      offset = length - offset;
+    }
+    else
+      offset = 0;
+    
+    int len = _is.read(buffer, offset, SIZE - offset);
+
+    if (len <= 0) {
+      _length = offset;
+      _offset = 0;
+      
+      return offset > 0;
+    }
+
+    _length = offset + len;
+    _offset = 0;
+
+    return true;
+  }
+
+  public Reader getReader()
+  {
+    return null;
+  }
+
+  protected IOException expect(String expect, int ch)
+    throws IOException
+  {
+    if (ch < 0)
+      return error("expected " + expect + " at end of file");
+    else {
+      _offset--;
+
+      try {
+	Object obj = readObject();
+
+	if (obj != null) {
+	  return error("expected " + expect
+		       + " at 0x" + Integer.toHexString(ch & 0xff)
+		       + " " + obj.getClass().getName() + " (" + obj + ")");
+	}
+	else
+	  return error("expected " + expect
+		       + " at 0x" + Integer.toHexString(ch & 0xff) + " null");
+      } catch (IOException e) {
+	log.log(Level.FINE, e.toString(), e);
+	
+	return error("expected " + expect
+		     + " at 0x" + Integer.toHexString(ch & 0xff));
+      }
+    }
+  }
+
+  protected String codeName(int ch)
+  {
+    if (ch < 0)
+      return "end of file";
+    else
+      return "0x" + Integer.toHexString(ch & 0xff) + " (" + (char) + ch + ")";
+  }
+  
+  protected IOException error(String message)
+  {
+    if (_method != null)
+      return new HessianProtocolException(_method + ": " + message);
+    else
+      return new HessianProtocolException(message);
+  }
+
+  public void close()
+    throws IOException
+  {
+    InputStream is = _is;
+    _is = null;
+
+    if (_isCloseStreamOnClose && is != null)
+      is.close();
+  }
+  
+  class ReadInputStream extends InputStream {
+    boolean _isClosed = false;
+	
+    public int read()
+      throws IOException
+    {
+      if (_isClosed)
+	return -1;
+
+      int ch = parseByte();
+      if (ch < 0)
+	_isClosed = true;
+
+      return ch;
+    }
+	
+    public int read(byte []buffer, int offset, int length)
+      throws IOException
+    {
+      if (_isClosed)
+	return -1;
+
+      int len = Hessian2Input.this.read(buffer, offset, length);
+      if (len < 0)
+	_isClosed = true;
+
+      return len;
+    }
+
+    public void close()
+      throws IOException
+    {
+      while (read() >= 0) {
+      }
+    }
+  };
+
+  final static class ObjectDefinition {
+    private final String _type;
+    private final String []_fields;
+
+    ObjectDefinition(String type, String []fields)
+    {
+      _type = type;
+      _fields = fields;
+    }
+
+    String getType()
+    {
+      return _type;
+    }
+
+    String []getFieldNames()
+    {
+      return _fields;
+    }
+  }
+
+  static {
+    try {
+      _detailMessageField = Throwable.class.getDeclaredField("detailMessage");
+      _detailMessageField.setAccessible(true);
+    } catch (Throwable e) {
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/Hessian2Output.java src/com/caucho/hessian/io/Hessian2Output.java
new file mode 100644
index 0000000..d410dea
--- /dev/null
+++ src/com/caucho/hessian/io/Hessian2Output.java
@@ -0,0 +1,1661 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import com.caucho.hessian.util.IdentityIntMap;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+
+/**
+ * Output stream for Hessian 2 requests.
+ *
+ * <p>Since HessianOutput does not depend on any classes other than
+ * in the JDK, it can be extracted independently into a smaller package.
+ *
+ * <p>HessianOutput is unbuffered, so any client needs to provide
+ * its own buffering.
+ *
+ * <pre>
+ * OutputStream os = ...; // from http connection
+ * Hessian2Output out = new Hessian11Output(os);
+ * String value;
+ *
+ * out.startCall("hello");  // start hello call
+ * out.writeString("arg1"); // write a string argument
+ * out.completeCall();      // complete the call
+ * </pre>
+ */
+public class Hessian2Output
+  extends AbstractHessianOutput
+  implements Hessian2Constants
+{
+  // the output stream/
+  protected OutputStream _os;
+  
+  // map of references
+  private IdentityIntMap _refs = new IdentityIntMap();
+
+  private boolean _isCloseStreamOnClose;
+  
+  // map of classes
+  private HashMap _classRefs;
+  
+  // map of types
+  private HashMap _typeRefs;
+
+  private final static int SIZE = 1024;
+  
+  private final byte []_buffer = new byte[SIZE];
+  private int _offset;
+
+  private boolean _isStreaming;
+  
+  /**
+   * Creates a new Hessian output stream, initialized with an
+   * underlying output stream.
+   *
+   * @param os the underlying output stream.
+   */
+  public Hessian2Output(OutputStream os)
+  {
+    _os = os;
+  }
+  
+  public void setCloseStreamOnClose(boolean isClose)
+  {
+    _isCloseStreamOnClose = isClose;
+  }
+  
+  public boolean isCloseStreamOnClose()
+  {
+    return _isCloseStreamOnClose;
+  }
+  
+
+  /**
+   * Writes a complete method call.
+   */
+  public void call(String method, Object []args)
+    throws IOException
+  {
+    startCall(method);
+    
+    if (args != null) {
+      for (int i = 0; i < args.length; i++)
+        writeObject(args[i]);
+    }
+    
+    completeCall();
+  }
+  
+  /**
+   * Starts the method call.  Clients would use <code>startCall</code>
+   * instead of <code>call</code> if they wanted finer control over
+   * writing the arguments, or needed to write headers.
+   *
+   * <code><pre>
+   * c major minor
+   * m b16 b8 method-name
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void startCall(String method)
+    throws IOException
+  {
+    int offset = _offset;
+
+    if (SIZE < offset + 32) {
+      flush();
+      offset = 0;
+    }
+
+    byte []buffer = _buffer;
+    
+    buffer[offset++] = (byte) 'c';
+    buffer[offset++] = (byte) 2;
+    buffer[offset++] = (byte) 0;
+
+    buffer[offset++] = (byte) 'm';
+    int len = method.length();
+    buffer[offset++] = (byte) (len >> 8);
+    buffer[offset++] = (byte) len;
+
+    _offset = offset;
+    
+    printString(method, 0, len);
+  }
+
+  /**
+   * Writes the call tag.  This would be followed by the
+   * headers and the method tag.
+   *
+   * <code><pre>
+   * c major minor
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void startCall()
+    throws IOException
+  {
+    flushIfFull();
+    
+    int offset = _offset;
+    byte []buffer = _buffer;
+    
+    buffer[offset++] = (byte) 'c';
+    buffer[offset++] = (byte) 2;
+    buffer[offset++] = (byte) 0;
+  }
+
+  /**
+   * Writes the streaming call tag.  This would be followed by the
+   * headers and the method tag.
+   *
+   * <code><pre>
+   * C major minor
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void startStreamingCall()
+    throws IOException
+  {
+    flushIfFull();
+    
+    int offset = _offset;
+    byte []buffer = _buffer;
+    
+    buffer[offset++] = (byte) 'C';
+    buffer[offset++] = (byte) 2;
+    buffer[offset++] = (byte) 0;
+  }
+  
+  /**
+   * Starts an envelope.
+   *
+   * <code><pre>
+   * E major minor
+   * m b16 b8 method-name
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void startEnvelope(String method)
+    throws IOException
+  {
+    int offset = _offset;
+
+    if (SIZE < offset + 32) {
+      flush();
+      offset = 0;
+    }
+
+    byte []buffer = _buffer;
+    
+    buffer[offset++] = (byte) 'E';
+    buffer[offset++] = (byte) 2;
+    buffer[offset++] = (byte) 0;
+
+    buffer[offset++] = (byte) 'm';
+    int len = method.length();
+    buffer[offset++] = (byte) (len >> 8);
+    buffer[offset++] = (byte) len;
+
+    _offset = offset;
+    
+    printString(method, 0, len);
+  }
+
+  /**
+   * Completes an envelope.
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeEnvelope()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'z';
+  }
+
+  /**
+   * Writes the method tag.
+   *
+   * <code><pre>
+   * m b16 b8 method-name
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void writeMethod(String method)
+    throws IOException
+  {
+    flushIfFull();
+
+    byte []buffer = _buffer;
+    int offset = _offset;
+    
+    buffer[offset++] = (byte) 'm';
+    int len = method.length();
+    buffer[offset++] = (byte) (len >> 8);
+    buffer[offset++] = (byte) len;
+
+    _offset = offset;
+    
+    printString(method, 0, len);
+  }
+
+  /**
+   * Completes.
+   *
+   * <code><pre>
+   * z
+   * </pre></code>
+   */
+  public void completeCall()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'z';
+  }
+
+  /**
+   * Starts the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * r
+   * </pre>
+   */
+  public void startReply()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'r';
+    _buffer[_offset++] = (byte) 2;
+    _buffer[_offset++] = (byte) 0;
+  }
+
+  /**
+   * Starts the streaming reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * r
+   * </pre>
+   */
+  public void startStreamingReply()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'R';
+    _buffer[_offset++] = (byte) 2;
+    _buffer[_offset++] = (byte) 0;
+  }
+
+  /**
+   * Completes reading the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeReply()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'z';
+  }
+
+  /**
+   * Starts the message
+   *
+   * <p>A message contains several objects followed by a 'z'</p>
+   *
+   * <pre>
+   * p x02 x00
+   * </pre>
+   */
+  public void startMessage()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'p';
+    _buffer[_offset++] = (byte) 2;
+    _buffer[_offset++] = (byte) 0;
+  }
+
+  /**
+   * Completes reading the message
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeMessage()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'z';
+  }
+
+  /**
+   * Writes a header name.  The header value must immediately follow.
+   *
+   * <code><pre>
+   * H b16 b8 foo <em>value</em>
+   * </pre></code>
+   */
+  public void writeHeader(String name)
+    throws IOException
+  {
+    int len = name.length();
+
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'H';
+    _buffer[_offset++] = (byte) (len >> 8);
+    _buffer[_offset++] = (byte) (len);
+
+    printString(name);
+  }
+
+  /**
+   * Writes a fault.  The fault will be written
+   * as a descriptive string followed by an object:
+   *
+   * <code><pre>
+   * f
+   * &lt;string>code
+   * &lt;string>the fault code
+   *
+   * &lt;string>message
+   * &lt;string>the fault mesage
+   *
+   * &lt;string>detail
+   * mt\x00\xnnjavax.ejb.FinderException
+   *     ...
+   * z
+   * z
+   * </pre></code>
+   *
+   * @param code the fault code, a three digit
+   */
+  public void writeFault(String code, String message, Object detail)
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'f'
+      ;
+    writeString("code");
+    writeString(code);
+
+    writeString("message");
+    writeString(message);
+
+    if (detail != null) {
+      writeString("detail");
+      writeObject(detail);
+    }
+
+    flushIfFull();
+    _buffer[_offset++] = (byte) ('z');
+  }
+
+  /**
+   * Writes any object to the output stream.
+   */
+  public void writeObject(Object object)
+    throws IOException
+  {
+    if (object == null) {
+      writeNull();
+      return;
+    }
+
+    Serializer serializer;
+
+    serializer = findSerializerFactory().getSerializer(object.getClass());
+
+    serializer.writeObject(object, this);
+  }
+
+  /**
+   * Writes the list header to the stream.  List writers will call
+   * <code>writeListBegin</code> followed by the list contents and then
+   * call <code>writeListEnd</code>.
+   *
+   * <code><pre>
+   * V
+   * t b16 b8 type
+   * l b32 b24 b16 b8
+   * </pre></code>
+   */
+  public boolean writeListBegin(int length, String type)
+    throws IOException
+  {
+    flushIfFull();
+
+    if (_typeRefs != null) {
+      Integer refV = (Integer) _typeRefs.get(type);
+
+      if (refV != null) {
+	_buffer[_offset++] = (byte) (LIST_FIXED);
+	writeInt(refV.intValue());
+	writeInt(length);
+
+	return false;
+      }
+    }
+    
+    _buffer[_offset++] = (byte) 'V';
+
+    writeType(type);
+
+    flushIfFull();
+
+    if (length < 0) {
+    }
+    else if (length < 0x100) {
+      _buffer[_offset++] = (byte) (LENGTH_BYTE);
+      _buffer[_offset++] = (byte) (length);
+    }
+    else {
+      _buffer[_offset++] = (byte) ('l');
+      _buffer[_offset++] = (byte) (length >> 24);
+      _buffer[_offset++] = (byte) (length >> 16);
+      _buffer[_offset++] = (byte) (length >> 8);
+      _buffer[_offset++] = (byte) (length);
+    }
+
+    return true;
+  }
+
+  /**
+   * Writes the tail of the list to the stream.
+   */
+  public void writeListEnd()
+    throws IOException
+  {
+    flushIfFull();
+    
+    _buffer[_offset++] = (byte) 'z';
+  }
+
+  /**
+   * Writes the map header to the stream.  Map writers will call
+   * <code>writeMapBegin</code> followed by the map contents and then
+   * call <code>writeMapEnd</code>.
+   *
+   * <code><pre>
+   * Mt b16 b8 (<key> <value>)z
+   * </pre></code>
+   */
+  public void writeMapBegin(String type)
+    throws IOException
+  {
+    if (SIZE < _offset + 32)
+      flush();
+    
+    _buffer[_offset++] = 'M';
+
+    writeType(type);
+  }
+
+  /**
+   * Writes the tail of the map to the stream.
+   */
+  public void writeMapEnd()
+    throws IOException
+  {
+    if (SIZE < _offset + 32)
+      flush();
+    
+    _buffer[_offset++] = (byte) 'z';
+  }
+
+  /**
+   * Writes the object definition
+   *
+   * <code><pre>
+   * O t b16 b8 <string>*
+   * </pre></code>
+   */
+  public int writeObjectBegin(String type)
+    throws IOException
+  {
+    if (_classRefs == null)
+      _classRefs = new HashMap();
+
+    Integer refV = (Integer) _classRefs.get(type);
+
+    if (refV != null) {
+      int ref = refV.intValue();
+      
+      if (SIZE < _offset + 32)
+	flush();
+
+      _buffer[_offset++] = (byte) 'o';
+      writeInt(ref);
+
+      return ref;
+    }
+    else {
+      int ref = _classRefs.size();
+      
+      _classRefs.put(type, Integer.valueOf(ref));
+      
+      if (SIZE < _offset + 32)
+	flush();
+
+      _buffer[_offset++] = (byte) 'O';
+
+      writeString(type);
+
+      return -1;
+    }
+  }
+
+  /**
+   * Writes the tail of the class definition to the stream.
+   */
+  public void writeClassFieldLength(int len)
+    throws IOException
+  {
+    writeInt(len);
+  }
+
+  /**
+   * Writes the tail of the object definition to the stream.
+   */
+  public void writeObjectEnd()
+    throws IOException
+  {
+  }
+
+  /**
+   * Writes a remote object reference to the stream.  The type is the
+   * type of the remote interface.
+   *
+   * <code><pre>
+   * 'r' 't' b16 b8 type url
+   * </pre></code>
+   */
+  public void writeRemote(String type, String url)
+    throws IOException
+  {
+    if (SIZE < _offset + 32)
+      flush();
+
+    _buffer[_offset++] = (byte) 'r';
+
+    writeType(type);
+
+    if (SIZE < _offset + 32)
+      flush();
+
+    _buffer[_offset++] = (byte) 'S';
+    
+    printLenString(url);
+  }
+
+  private void writeType(String type)
+    throws IOException
+  {
+    if (type == null)
+      return;
+
+    int len = type.length();
+    if (len == 0)
+      return;
+
+    if (_typeRefs == null)
+      _typeRefs = new HashMap();
+
+    Integer typeRefV = (Integer) _typeRefs.get(type);
+    
+    if (typeRefV != null) {
+      int typeRef = typeRefV.intValue();
+      
+      flushIfFull();
+      
+      _buffer[_offset++] = (byte) TYPE_REF;
+      
+      writeInt(typeRef);
+    }
+    else {
+      _typeRefs.put(type, Integer.valueOf(_typeRefs.size()));
+
+      if (SIZE < _offset + 32)
+	flush();
+      
+      _buffer[_offset++] = (byte) 't';
+      
+      printLenString(type);
+    }
+  }
+
+  /**
+   * Writes a boolean value to the stream.  The boolean will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * T
+   * F
+   * </pre></code>
+   *
+   * @param value the boolean value to write.
+   */
+  public void writeBoolean(boolean value)
+    throws IOException
+  {
+    if (SIZE < _offset + 16)
+      flush();
+
+    if (value)
+      _buffer[_offset++] = (byte) 'T';
+    else
+      _buffer[_offset++] = (byte) 'F';
+  }
+
+  /**
+   * Writes an integer value to the stream.  The integer will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * I b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the integer value to write.
+   */
+  public void writeInt(int value)
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+
+    if (SIZE <= offset + 16) {
+      flush();
+      offset = 0;
+    }
+    
+    if (INT_DIRECT_MIN <= value && value <= INT_DIRECT_MAX)
+      buffer[offset++] = (byte) (value + INT_ZERO);
+    else if (INT_BYTE_MIN <= value && value <= INT_BYTE_MAX) {
+      buffer[offset++] = (byte) (INT_BYTE_ZERO + (value >> 8));
+      buffer[offset++] = (byte) (value);
+    }
+    else if (INT_SHORT_MIN <= value && value <= INT_SHORT_MAX) {
+      buffer[offset++] = (byte) (INT_SHORT_ZERO + (value >> 16));
+      buffer[offset++] = (byte) (value >> 8);
+      buffer[offset++] = (byte) (value);
+    }
+    else {
+      buffer[offset++] = (byte) ('I');
+      buffer[offset++] = (byte) (value >> 24);
+      buffer[offset++] = (byte) (value >> 16);
+      buffer[offset++] = (byte) (value >> 8);
+      buffer[offset++] = (byte) (value);
+    }
+
+    _offset = offset;
+  }
+
+  /**
+   * Writes a long value to the stream.  The long will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * L b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the long value to write.
+   */
+  public void writeLong(long value)
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+
+    if (SIZE <= offset + 16) {
+      flush();
+      offset = 0;
+    }
+
+    if (LONG_DIRECT_MIN <= value && value <= LONG_DIRECT_MAX) {
+      buffer[offset++] = (byte) (value + LONG_ZERO);
+    }
+    else if (LONG_BYTE_MIN <= value && value <= LONG_BYTE_MAX) {
+      buffer[offset++] = (byte) (LONG_BYTE_ZERO + (value >> 8));
+      buffer[offset++] = (byte) (value);
+    }
+    else if (LONG_SHORT_MIN <= value && value <= LONG_SHORT_MAX) {
+      buffer[offset++] = (byte) (LONG_SHORT_ZERO + (value >> 16));
+      buffer[offset++] = (byte) (value >> 8);
+      buffer[offset++] = (byte) (value);
+    }
+    else if (-0x80000000L <= value && value <= 0x7fffffffL) {
+      buffer[offset + 0] = (byte) LONG_INT;
+      buffer[offset + 1] = (byte) (value >> 24);
+      buffer[offset + 2] = (byte) (value >> 16);
+      buffer[offset + 3] = (byte) (value >> 8);
+      buffer[offset + 4] = (byte) (value);
+
+      offset += 5;
+    }
+    else {
+      buffer[offset + 0] = (byte) 'L';
+      buffer[offset + 1] = (byte) (value >> 56);
+      buffer[offset + 2] = (byte) (value >> 48);
+      buffer[offset + 3] = (byte) (value >> 40);
+      buffer[offset + 4] = (byte) (value >> 32);
+      buffer[offset + 5] = (byte) (value >> 24);
+      buffer[offset + 6] = (byte) (value >> 16);
+      buffer[offset + 7] = (byte) (value >> 8);
+      buffer[offset + 8] = (byte) (value);
+
+      offset += 9;
+    }
+
+    _offset = offset;
+  }
+
+  /**
+   * Writes a double value to the stream.  The double will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the double value to write.
+   */
+  public void writeDouble(double value)
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+
+    if (SIZE <= offset + 16) {
+      flush();
+      offset = 0;
+    }
+    
+    int intValue = (int) value;
+    
+    if (intValue == value) {
+      if (intValue == 0) {
+	buffer[offset++] = (byte) DOUBLE_ZERO;
+
+        _offset = offset;
+
+        return;
+      }
+      else if (intValue == 1) {
+	buffer[offset++] = (byte) DOUBLE_ONE;
+
+        _offset = offset;
+
+        return;
+      }
+      else if (-0x80 <= intValue && intValue < 0x80) {
+	buffer[offset++] = (byte) DOUBLE_BYTE;
+	buffer[offset++] = (byte) intValue;
+
+        _offset = offset;
+
+        return;
+      }
+      else if (-0x8000 <= intValue && intValue < 0x8000) {
+	buffer[offset + 0] = (byte) DOUBLE_SHORT;
+	buffer[offset + 1] = (byte) (intValue >> 8);
+	buffer[offset + 2] = (byte) intValue;
+
+	_offset = offset + 3;
+        
+        return;
+      }
+    }
+
+    float f = (float) value;
+
+    if (f == value) {
+      int bits = Float.floatToIntBits(f);
+      
+      buffer[offset + 0] = (byte) (DOUBLE_FLOAT);
+      buffer[offset + 1] = (byte) (bits >> 24);
+      buffer[offset + 2] = (byte) (bits >> 16);
+      buffer[offset + 3] = (byte) (bits >> 8);
+      buffer[offset + 4] = (byte) (bits);
+
+      _offset = offset + 5;
+
+      return;
+    }
+    
+    long bits = Double.doubleToLongBits(value);
+    
+    buffer[offset + 0] = (byte) 'D';
+    buffer[offset + 1] = (byte) (bits >> 56);
+    buffer[offset + 2] = (byte) (bits >> 48);
+    buffer[offset + 3] = (byte) (bits >> 40);
+    buffer[offset + 4] = (byte) (bits >> 32);
+    buffer[offset + 5] = (byte) (bits >> 24);
+    buffer[offset + 6] = (byte) (bits >> 16);
+    buffer[offset + 7] = (byte) (bits >> 8);
+    buffer[offset + 8] = (byte) (bits);
+
+    _offset = offset + 9;
+  }
+
+  /**
+   * Writes a date to the stream.
+   *
+   * <code><pre>
+   * T  b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param time the date in milliseconds from the epoch in UTC
+   */
+  public void writeUTCDate(long time)
+    throws IOException
+  {
+    if (SIZE < _offset + 32)
+      flush();
+
+    int offset = _offset;
+    byte []buffer = _buffer;
+    
+    buffer[offset++] = (byte) ('d');
+    buffer[offset++] = ((byte) (time >> 56));
+    buffer[offset++] = ((byte) (time >> 48));
+    buffer[offset++] = ((byte) (time >> 40));
+    buffer[offset++] = ((byte) (time >> 32));
+    buffer[offset++] = ((byte) (time >> 24));
+    buffer[offset++] = ((byte) (time >> 16));
+    buffer[offset++] = ((byte) (time >> 8));
+    buffer[offset++] = ((byte) (time));
+
+    _offset = offset;
+  }
+
+  /**
+   * Writes a null value to the stream.
+   * The null will be written with the following syntax
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeNull()
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+
+    if (SIZE <= offset + 16) {
+      flush();
+      offset = 0;
+    }
+
+    buffer[offset++] = 'N';
+
+    _offset = offset;
+  }
+
+  /**
+   * Writes a string value to the stream using UTF-8 encoding.
+   * The string will be written with the following syntax:
+   *
+   * <code><pre>
+   * S b16 b8 string-value
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeString(String value)
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+
+    if (SIZE <= offset + 16) {
+      flush();
+      offset = 0;
+    }
+    
+    if (value == null) {
+      buffer[offset++] = (byte) 'N';
+
+      _offset = offset;
+    }
+    else {
+      int length = value.length();
+      int strOffset = 0;
+      
+      while (length > 0x8000) {
+        int sublen = 0x8000;
+
+	offset = _offset;
+
+	if (SIZE <= offset + 16) {
+	  flush();
+	  offset = 0;
+	}
+
+	// chunk can't end in high surrogate
+	char tail = value.charAt(strOffset + sublen - 1);
+
+	if (0xd800 <= tail && tail <= 0xdbff)
+	  sublen--;
+
+	buffer[offset + 0] = (byte) 's';
+        buffer[offset + 1] = (byte) (sublen >> 8);
+        buffer[offset + 2] = (byte) (sublen);
+
+	_offset = offset + 3;
+
+        printString(value, strOffset, sublen);
+
+        length -= sublen;
+        strOffset += sublen;
+      }
+
+      offset = _offset;
+
+      if (SIZE <= offset + 16) {
+	flush();
+	offset = 0;
+      }
+
+      if (length <= STRING_DIRECT_MAX) {
+	buffer[offset++] = (byte) (STRING_DIRECT + length);
+      }
+      else {
+	buffer[offset++] = (byte) ('S');
+	buffer[offset++] = (byte) (length >> 8);
+	buffer[offset++] = (byte) (length);
+      }
+
+      _offset = offset;
+
+      printString(value, strOffset, length);
+    }
+  }
+
+  /**
+   * Writes a string value to the stream using UTF-8 encoding.
+   * The string will be written with the following syntax:
+   *
+   * <code><pre>
+   * S b16 b8 string-value
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeString(char []buffer, int offset, int length)
+    throws IOException
+  {
+    if (buffer == null) {
+      if (SIZE < _offset + 16)
+	flush();
+      
+      _buffer[_offset++] = (byte) ('N');
+    }
+    else {
+      while (length > 0x8000) {
+        int sublen = 0x8000;
+
+	if (SIZE < _offset + 16)
+	  flush();
+
+	// chunk can't end in high surrogate
+	char tail = buffer[offset + sublen - 1];
+
+	if (0xd800 <= tail && tail <= 0xdbff)
+	  sublen--;
+	
+        _buffer[_offset++] = (byte) 's';
+        _buffer[_offset++] = (byte) (sublen >> 8);
+        _buffer[_offset++] = (byte) (sublen);
+
+        printString(buffer, offset, sublen);
+
+        length -= sublen;
+        offset += sublen;
+      }
+
+      if (SIZE < _offset + 16)
+	flush();
+	
+      if (length <= STRING_DIRECT_MAX) {
+	_buffer[_offset++] = (byte) (STRING_DIRECT + length);
+      }
+      else {
+	_buffer[_offset++] = (byte) ('S');
+	_buffer[_offset++] = (byte) (length >> 8);
+	_buffer[_offset++] = (byte) (length);
+      }
+
+      printString(buffer, offset, length);
+    }
+  }
+
+  /**
+   * Writes a byte array to the stream.
+   * The array will be written with the following syntax:
+   *
+   * <code><pre>
+   * B b16 b18 bytes
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeBytes(byte []buffer)
+    throws IOException
+  {
+    if (buffer == null) {
+      if (SIZE < _offset + 16)
+	flush();
+
+      _buffer[_offset++] = 'N';
+    }
+    else
+      writeBytes(buffer, 0, buffer.length);
+  }
+  
+  /**
+   * Writes a byte array to the stream.
+   * The array will be written with the following syntax:
+   *
+   * <code><pre>
+   * B b16 b18 bytes
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeBytes(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    if (buffer == null) {
+      if (SIZE < _offset + 16)
+	flushBuffer();
+      
+      _buffer[_offset++] = (byte) 'N';
+    }
+    else {
+      flush();
+
+      while (length > SIZE - _offset - 3) {
+        int sublen = SIZE - _offset - 3;
+
+        if (sublen < 16) {
+          flushBuffer();
+
+          sublen = SIZE - _offset - 3;
+
+          if (length < sublen)
+            sublen = length;
+        }
+
+        _buffer[_offset++] = (byte) 'b';
+        _buffer[_offset++] = (byte) (sublen >> 8);
+        _buffer[_offset++] = (byte) sublen;
+
+        System.arraycopy(buffer, offset, _buffer, _offset, sublen);
+        _offset += sublen;
+
+        length -= sublen;
+        offset += sublen;
+      }
+
+      if (SIZE < _offset + 16)
+        flushBuffer();
+
+      if (length < 0x10) {
+        _buffer[_offset++] = (byte) (BYTES_DIRECT + length);
+      }
+      else {
+        _buffer[_offset++] = (byte) 'B';
+        _buffer[_offset++] = (byte) (length >> 8);
+        _buffer[_offset++] = (byte) (length);
+      }
+
+      System.arraycopy(buffer, offset, _buffer, _offset, length);
+
+      _offset += length;
+    }
+  }
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * </pre></code>
+   */
+  public void writeByteBufferStart()
+    throws IOException
+  {
+  }
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * b b16 b18 bytes
+   * </pre></code>
+   */
+  public void writeByteBufferPart(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    while (length > 0) {
+      int sublen = length;
+
+      if (0x8000 < sublen)
+	sublen = 0x8000;
+
+      flush(); // bypass buffer
+      
+      _os.write('b');
+      _os.write(sublen >> 8);
+      _os.write(sublen);
+
+      _os.write(buffer, offset, sublen);
+
+      length -= sublen;
+      offset += sublen;
+    }
+  }
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * b b16 b18 bytes
+   * </pre></code>
+   */
+  public void writeByteBufferEnd(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    writeBytes(buffer, offset, length);
+  }
+
+  /**
+   * Returns an output stream to write binary data.
+   */
+  public OutputStream getBytesOutputStream()
+    throws IOException
+  {
+    return new BytesOutputStream();
+  }
+
+  /**
+   * Writes a reference.
+   *
+   * <code><pre>
+   * R b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the integer value to write.
+   */
+  public void writeRef(int value)
+    throws IOException
+  {
+    if (SIZE < _offset + 16)
+      flush();
+    
+    if (value < 0x100) {
+      _buffer[_offset++] = (byte) (REF_BYTE);
+      _buffer[_offset++] = (byte) (value);
+    }
+    else if (value < 0x10000) {
+      _buffer[_offset++] = (byte) (REF_SHORT);
+      _buffer[_offset++] = (byte) (value >> 8);
+      _buffer[_offset++] = (byte) (value);
+    }
+    else {
+      _buffer[_offset++] = (byte) ('R');
+      _buffer[_offset++] = (byte) (value >> 24);
+      _buffer[_offset++] = (byte) (value >> 16);
+      _buffer[_offset++] = (byte) (value >> 8);
+      _buffer[_offset++] = (byte) (value);
+    }
+  }
+
+  /**
+   * If the object has already been written, just write its ref.
+   *
+   * @return true if we're writing a ref.
+   */
+  public boolean addRef(Object object)
+    throws IOException
+  {
+    int ref = _refs.get(object);
+
+    if (ref >= 0) {
+      writeRef(ref);
+      
+      return true;
+    }
+    else {
+      _refs.put(object, _refs.size());
+      
+      return false;
+    }
+  }
+
+  /**
+   * Removes a reference.
+   */
+  public boolean removeRef(Object obj)
+    throws IOException
+  {
+    if (_refs != null) {
+      _refs.remove(obj);
+
+      return true;
+    }
+    else
+      return false;
+  }
+
+  /**
+   * Replaces a reference from one object to another.
+   */
+  public boolean replaceRef(Object oldRef, Object newRef)
+    throws IOException
+  {
+    Integer value = (Integer) _refs.remove(oldRef);
+
+    if (value != null) {
+      _refs.put(newRef, value);
+      return true;
+    }
+    else
+      return false;
+  }
+
+  /**
+   * Resets the references for streaming.
+   */
+  public void resetReferences()
+  {
+    if (_refs != null)
+      _refs.clear();
+  }
+
+  /**
+   * Starts the streaming message
+   *
+   * <p>A streaming message starts with 'P'</p>
+   *
+   * <pre>
+   * P x02 x00
+   * </pre>
+   */
+  public void writeStreamingObject(Object obj)
+    throws IOException
+  {
+    if (_refs != null)
+      _refs.clear();
+    
+    flush();
+
+    _isStreaming = true;
+    _offset = 3;
+
+    writeObject(obj);
+
+    int len = _offset - 3;
+    
+    _buffer[0] = (byte) 'P';
+    _buffer[1] = (byte) (len >> 8);
+    _buffer[2] = (byte) len;
+
+    _isStreaming = false;
+
+    flush();
+  }
+
+  /**
+   * Prints a string to the stream, encoded as UTF-8 with preceeding length
+   *
+   * @param v the string to print.
+   */
+  public void printLenString(String v)
+    throws IOException
+  {
+    if (SIZE < _offset + 16)
+      flush();
+    
+    if (v == null) {
+      _buffer[_offset++] = (byte) (0);
+      _buffer[_offset++] = (byte) (0);
+    }
+    else {
+      int len = v.length();
+      _buffer[_offset++] = (byte) (len >> 8);
+      _buffer[_offset++] = (byte) (len);
+
+      printString(v, 0, len);
+    }
+  }
+
+  /**
+   * Prints a string to the stream, encoded as UTF-8
+   *
+   * @param v the string to print.
+   */
+  public void printString(String v)
+    throws IOException
+  {
+    printString(v, 0, v.length());
+  }
+  
+  /**
+   * Prints a string to the stream, encoded as UTF-8
+   *
+   * @param v the string to print.
+   */
+  public void printString(String v, int strOffset, int length)
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+    
+    for (int i = 0; i < length; i++) {
+      if (SIZE <= offset + 16) {
+	_offset = offset;
+	flush();
+	offset = 0;
+      }
+      
+      char ch = v.charAt(i + strOffset);
+
+      if (ch < 0x80)
+        buffer[offset++] = (byte) (ch);
+      else if (ch < 0x800) {
+        buffer[offset++] = (byte) (0xc0 + ((ch >> 6) & 0x1f));
+        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
+      }
+      else {
+        buffer[offset++] = (byte) (0xe0 + ((ch >> 12) & 0xf));
+        buffer[offset++] = (byte) (0x80 + ((ch >> 6) & 0x3f));
+        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
+      }
+    }
+
+    _offset = offset;
+  }
+  
+  /**
+   * Prints a string to the stream, encoded as UTF-8
+   *
+   * @param v the string to print.
+   */
+  public void printString(char []v, int strOffset, int length)
+    throws IOException
+  {
+    int offset = _offset;
+    byte []buffer = _buffer;
+    
+    for (int i = 0; i < length; i++) {
+      if (SIZE <= offset + 16) {
+	_offset = offset;
+	flush();
+	offset = 0;
+      }
+      
+      char ch = v[i + strOffset];
+
+      if (ch < 0x80)
+        buffer[offset++] = (byte) (ch);
+      else if (ch < 0x800) {
+        buffer[offset++] = (byte) (0xc0 + ((ch >> 6) & 0x1f));
+        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
+      }
+      else {
+        buffer[offset++] = (byte) (0xe0 + ((ch >> 12) & 0xf));
+        buffer[offset++] = (byte) (0x80 + ((ch >> 6) & 0x3f));
+        buffer[offset++] = (byte) (0x80 + (ch & 0x3f));
+      }
+    }
+
+    _offset = offset;
+  }
+  
+  private final void flushIfFull()
+    throws IOException
+  {
+    int offset = _offset;
+    
+    if (SIZE < offset + 32) {
+      _offset = 0;
+      _os.write(_buffer, 0, offset);
+    }
+  }
+
+  public final void flush()
+    throws IOException
+  {
+    flushBuffer();
+
+    _os.flush();
+  }
+
+  public final void flushBuffer()
+    throws IOException
+  {
+    int offset = _offset;
+
+    if (! _isStreaming && offset > 0) {
+      _offset = 0;
+      
+      _os.write(_buffer, 0, offset);
+    }
+    else if (_isStreaming && offset > 3) {
+      int len = offset - 3;
+      _buffer[0] = 'p';
+      _buffer[1] = (byte) (len >> 8);
+      _buffer[2] = (byte) len;
+      _offset = 3;
+      
+      _os.write(_buffer, 0, offset);
+    }
+  }
+
+  public final void close()
+    throws IOException
+  {
+    flushBuffer();
+    
+    OutputStream os = _os;
+    _os = null;
+
+    if (os != null) {
+      if (_isCloseStreamOnClose)
+	os.close();
+    }
+  }
+
+  class BytesOutputStream extends OutputStream {
+    private int _startOffset;
+    
+    BytesOutputStream()
+      throws IOException
+    {
+      if (SIZE < _offset + 16) {
+        Hessian2Output.this.flush();
+      }
+
+      _startOffset = _offset;
+      _offset += 3; // skip 'b' xNN xNN
+    }
+
+    @Override
+    public void write(int ch)
+      throws IOException
+    {
+      if (SIZE <= _offset) {
+        int length = (_offset - _startOffset) - 3;
+
+        _buffer[_startOffset] = (byte) 'b';
+        _buffer[_startOffset + 1] = (byte) (length >> 8);
+        _buffer[_startOffset + 2] = (byte) (length);
+
+        Hessian2Output.this.flush();
+
+        _startOffset = _offset;
+        _offset += 3;
+      }
+
+      _buffer[_offset++] = (byte) ch;
+    }
+
+    @Override
+    public void write(byte []buffer, int offset, int length)
+      throws IOException
+    {
+      while (length > 0) {
+        int sublen = SIZE - _offset;
+
+        if (length < sublen)
+          sublen = length;
+
+        if (sublen > 0) {
+          System.arraycopy(buffer, offset, _buffer, _offset, sublen);
+          _offset += sublen;
+        }
+
+        length -= sublen;
+        offset += sublen;
+
+        if (SIZE <= _offset) {
+          int chunkLength = (_offset - _startOffset) - 3;
+
+          _buffer[_startOffset] = (byte) 'b';
+          _buffer[_startOffset + 1] = (byte) (chunkLength >> 8);
+          _buffer[_startOffset + 2] = (byte) (chunkLength);
+
+          Hessian2Output.this.flush();
+
+          _startOffset = _offset;
+          _offset += 3;
+        }
+      }
+    }
+
+    @Override
+    public void close()
+      throws IOException
+    {
+      int startOffset = _startOffset;
+      _startOffset = -1;
+
+      if (startOffset < 0)
+        return;
+
+      int length = (_offset - startOffset) - 3;
+
+      _buffer[startOffset] = (byte) 'B';
+      _buffer[startOffset + 1] = (byte) (length >> 8);
+      _buffer[startOffset + 2] = (byte) (length);
+
+      Hessian2Output.this.flush();
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/Hessian2StreamingInput.java src/com/caucho/hessian/io/Hessian2StreamingInput.java
new file mode 100644
index 0000000..ca40553
--- /dev/null
+++ src/com/caucho/hessian/io/Hessian2StreamingInput.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Output stream for Hessian 2 streaming requests.
+ */
+public class Hessian2StreamingInput
+{
+  private Hessian2Input _in;
+  
+  /**
+   * Creates a new Hessian input stream, initialized with an
+   * underlying input stream.
+   *
+   * @param is the underlying output stream.
+   */
+  public Hessian2StreamingInput(InputStream is)
+  {
+    _in = new Hessian2Input(new StreamingInputStream(is));
+  }
+
+  /**
+   * Read the next object
+   */
+  public Object readObject()
+    throws IOException
+  {
+    return _in.readStreamingObject();
+  }
+
+  /**
+   * Close the output.
+   */
+  public void close()
+    throws IOException
+  {
+    _in.close();
+  }
+
+  static class StreamingInputStream extends InputStream {
+    private InputStream _is;
+    private int _length;
+
+    StreamingInputStream(InputStream is)
+    {
+      _is = is;
+    }
+
+    public int read()
+      throws IOException
+    {
+      InputStream is = _is;
+      
+      while (_length == 0) {
+	int code = is.read();
+
+	if (code < 0)
+	  return -1;
+	else if (code != 'p' && code != 'P')
+	  throw new HessianProtocolException("expected streaming packet at 0x"
+					     + Integer.toHexString(code & 0xff));
+
+	int d1 = is.read();
+	int d2 = is.read();
+
+	if (d2 < 0)
+	  return -1;
+	
+	_length = (d1 << 8) + d2;
+      }
+
+      _length--;
+      return is.read();
+    }
+
+    public int read(byte []buffer, int offset, int length)
+      throws IOException
+    {
+      InputStream is = _is;
+      
+      while (_length == 0) {
+	int code = is.read();
+
+	if (code < 0)
+	  return -1;
+	else if (code != 'p' && code != 'P') {
+	  throw new HessianProtocolException("expected streaming packet at 0x"
+					     + Integer.toHexString(code & 0xff)
+					     + " (" + (char) code + ")");
+	}
+
+	int d1 = is.read();
+	int d2 = is.read();
+
+	if (d2 < 0)
+	  return -1;
+	
+	_length = (d1 << 8) + d2;
+      }
+
+      int sublen = _length;
+      if (length < sublen)
+	sublen = length;
+
+      sublen = is.read(buffer, offset, sublen);
+
+      if (sublen < 0)
+	return -1;
+
+      _length -= sublen;
+
+      return sublen;
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/Hessian2StreamingOutput.java src/com/caucho/hessian/io/Hessian2StreamingOutput.java
new file mode 100644
index 0000000..eae58cd
--- /dev/null
+++ src/com/caucho/hessian/io/Hessian2StreamingOutput.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+
+/**
+ * Output stream for Hessian 2 streaming requests.
+ */
+public class Hessian2StreamingOutput
+{
+  private Hessian2Output _out;
+  
+  /**
+   * Creates a new Hessian output stream, initialized with an
+   * underlying output stream.
+   *
+   * @param os the underlying output stream.
+   */
+  public Hessian2StreamingOutput(OutputStream os)
+  {
+    _out = new Hessian2Output(os);
+  }
+  
+  public void setCloseStreamOnClose(boolean isClose)
+  {
+    _out.setCloseStreamOnClose(isClose);
+  }
+  
+  public boolean isCloseStreamOnClose()
+  {
+    return _out.isCloseStreamOnClose();
+  }
+
+  /**
+   * Writes any object to the output stream.
+   */
+  public void writeObject(Object object)
+    throws IOException
+  {
+    _out.writeStreamingObject(object);
+  }
+
+  /**
+   * Flushes the output.
+   */
+  public void flush()
+    throws IOException
+  {
+    _out.flush();
+  }
+
+  /**
+   * Close the output.
+   */
+  public void close()
+    throws IOException
+  {
+    _out.close();
+  }
+}
diff --git src/com/caucho/hessian/io/HessianDebugInputStream.java src/com/caucho/hessian/io/HessianDebugInputStream.java
new file mode 100644
index 0000000..a7546a3
--- /dev/null
+++ src/com/caucho/hessian/io/HessianDebugInputStream.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/**
+ * Debugging input stream for Hessian requests.
+ */
+public class HessianDebugInputStream extends InputStream
+{
+  private InputStream _is;
+  
+  private HessianDebugState _state;
+  
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianDebugInputStream(InputStream is, PrintWriter dbg)
+  {
+    _is = is;
+
+    if (dbg == null)
+      dbg = new PrintWriter(System.out);
+
+    _state = new HessianDebugState(dbg);
+  }
+  
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianDebugInputStream(InputStream is, Logger log, Level level)
+  {
+    this(is, new PrintWriter(new LogWriter(log, level)));
+  }
+
+  /**
+   * Reads a character.
+   */
+  public int read()
+    throws IOException
+  {
+    int ch;
+
+    InputStream is = _is;
+
+    if (is == null)
+      return -1;
+    else {
+      ch = is.read();
+    }
+
+    _state.next(ch);
+
+    return ch;
+  }
+
+  /**
+   * closes the stream.
+   */
+  public void close()
+    throws IOException
+  {
+    InputStream is = _is;
+    _is = null;
+
+    if (is != null)
+      is.close();
+    
+    _state.println();
+  }
+
+  static class LogWriter extends Writer {
+    private Logger _log;
+    private Level _level;
+    private StringBuilder _sb = new StringBuilder();
+
+    LogWriter(Logger log, Level level)
+    {
+      _log = log;
+      _level = level;
+    }
+
+    public void write(char ch)
+    {
+      if (ch == '\n' && _sb.length() > 0) {
+	_log.log(_level, _sb.toString());
+	_sb.setLength(0);
+      }
+      else
+	_sb.append((char) ch);
+    }
+
+    public void write(char []buffer, int offset, int length)
+    {
+      for (int i = 0; i < length; i++) {
+	char ch = buffer[offset + i];
+	
+	if (ch == '\n' && _sb.length() > 0) {
+	  _log.log(_level, _sb.toString());
+	  _sb.setLength(0);
+	}
+	else
+	  _sb.append((char) ch);
+      }
+    }
+
+    public void flush()
+    {
+    }
+
+    public void close()
+    {
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/HessianDebugOutputStream.java src/com/caucho/hessian/io/HessianDebugOutputStream.java
new file mode 100644
index 0000000..04b9f6d
--- /dev/null
+++ src/com/caucho/hessian/io/HessianDebugOutputStream.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.io.PrintWriter;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/**
+ * Debugging output stream for Hessian requests.
+ */
+public class HessianDebugOutputStream extends OutputStream
+{
+  private OutputStream _os;
+  
+  private HessianDebugState _state;
+  
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianDebugOutputStream(OutputStream os, PrintWriter dbg)
+  {
+    _os = os;
+
+    _state = new HessianDebugState(dbg);
+  }
+  
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianDebugOutputStream(OutputStream os, Logger log, Level level)
+  {
+    this(os, new PrintWriter(new LogWriter(log, level)));
+  }
+
+  /**
+   * Writes a character.
+   */
+  public void write(int ch)
+    throws IOException
+  {
+    ch = ch & 0xff;
+    
+    _os.write(ch);
+
+    _state.next(ch);
+  }
+
+  public void flush()
+    throws IOException
+  {
+    _os.flush();
+  }
+
+  /**
+   * closes the stream.
+   */
+  public void close()
+    throws IOException
+  {
+    OutputStream os = _os;
+    _os = null;
+
+    if (os != null)
+      os.close();
+
+    _state.println();
+  }
+
+  static class LogWriter extends Writer {
+    private Logger _log;
+    private Level _level;
+    private StringBuilder _sb = new StringBuilder();
+
+    LogWriter(Logger log, Level level)
+    {
+      _log = log;
+      _level = level;
+    }
+
+    public void write(char ch)
+    {
+      if (ch == '\n' && _sb.length() > 0) {
+	_log.log(_level, _sb.toString());
+	_sb.setLength(0);
+      }
+      else
+	_sb.append((char) ch);
+    }
+
+    public void write(char []buffer, int offset, int length)
+    {
+      for (int i = 0; i < length; i++) {
+	char ch = buffer[offset + i];
+	
+	if (ch == '\n' && _sb.length() > 0) {
+	  _log.log(_level, _sb.toString());
+	  _sb.setLength(0);
+	}
+	else
+	  _sb.append((char) ch);
+      }
+    }
+
+    public void flush()
+    {
+    }
+
+    public void close()
+    {
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/HessianDebugState.java src/com/caucho/hessian/io/HessianDebugState.java
new file mode 100644
index 0000000..ff6bde8
--- /dev/null
+++ src/com/caucho/hessian/io/HessianDebugState.java
@@ -0,0 +1,1771 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Debugging input stream for Hessian requests.
+ */
+public class HessianDebugState implements Hessian2Constants
+{
+  private PrintWriter _dbg;
+
+  private State _state;
+  private ArrayList<State> _stateStack = new ArrayList<State>();
+
+  private ArrayList<ObjectDef> _objectDefList
+    = new ArrayList<ObjectDef>();
+
+  private ArrayList<String> _typeDefList
+    = new ArrayList<String>();
+
+  private int _refId;
+  private boolean _isNewline = true;
+  private boolean _isObject = false;
+  private int _column;
+  
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianDebugState(PrintWriter dbg)
+  {
+    _dbg = dbg;
+
+    _state = new InitialState();
+  }
+
+  /**
+   * Reads a character.
+   */
+  public void next(int ch)
+    throws IOException
+  {
+    _state = _state.next(ch);
+  }
+
+  void pushStack(State state)
+  {
+    _stateStack.add(state);
+  }
+
+  State popStack()
+  {
+    return _stateStack.remove(_stateStack.size() - 1);
+  }
+
+  void println()
+  {
+    if (! _isNewline) {
+      _dbg.println();
+      _dbg.flush();
+    }
+
+    _isNewline = true;
+    _column = 0;
+  }
+
+  abstract class State {
+    State _next;
+
+    State()
+    {
+    }
+
+    State(State next)
+    {
+      _next = next;
+    }
+    
+    abstract State next(int ch);
+
+    boolean isShift(Object value)
+    {
+      return false;
+    }
+
+    State shift(Object value)
+    {
+      return this;
+    }
+
+    int depth()
+    {
+      if (_next != null)
+	return _next.depth();
+      else
+	return 0;
+    }
+
+    void printIndent(int depth)
+    {
+      if (_isNewline) {
+	for (int i = _column; i < depth() + depth; i++) {
+	  _dbg.print(" ");
+	  _column++;
+	}
+      }
+    }
+
+    void print(String string)
+    {
+      print(0, string);
+    }
+
+    void print(int depth, String string)
+    {
+      printIndent(depth);
+      
+      _dbg.print(string);
+      _isNewline = false;
+      _isObject = false;
+
+      int p = string.lastIndexOf('\n');
+      if (p > 0)
+	_column = string.length() - p - 1;
+      else
+	_column += string.length();
+    }
+
+    void println(String string)
+    {
+      println(0, string);
+    }
+
+    void println(int depth, String string)
+    {
+      printIndent(depth);
+
+      _dbg.println(string);
+      _dbg.flush();
+      _isNewline = true;
+      _isObject = false;
+      _column = 0;
+    }
+
+    void println()
+    {
+      if (! _isNewline) {
+	_dbg.println();
+	_dbg.flush();
+      }
+
+      _isNewline = true;
+      _isObject = false;
+      _column = 0;
+    }
+
+    void printObject(String string)
+    {
+      if (_isObject)
+	println();
+      
+      printIndent(0);
+
+      _dbg.print(string);
+      _dbg.flush();
+
+      _column += string.length();
+
+      _isNewline = false;
+      _isObject = true;
+    }
+    
+    protected State nextObject(int ch)
+    {
+      switch (ch) {
+      case -1:
+	println();
+	return this;
+	
+      case 'N':
+	if (isShift(null))
+	  return shift(null);
+	else {
+	  printObject("null");
+	  return this;
+	}
+	
+      case 'T':
+	if (isShift(Boolean.TRUE))
+	  return shift(Boolean.TRUE);
+	else {
+	  printObject("true");
+	  return this;
+	}
+	
+      case 'F':
+	if (isShift(Boolean.FALSE))
+	  return shift(Boolean.FALSE);
+	else {
+	  printObject("false");
+	  return this;
+	}
+
+      case 0x80: case 0x81: case 0x82: case 0x83: 
+      case 0x84: case 0x85: case 0x86: case 0x87: 
+      case 0x88: case 0x89: case 0x8a: case 0x8b: 
+      case 0x8c: case 0x8d: case 0x8e: case 0x8f: 
+
+      case 0x90: case 0x91: case 0x92: case 0x93: 
+      case 0x94: case 0x95: case 0x96: case 0x97: 
+      case 0x98: case 0x99: case 0x9a: case 0x9b: 
+      case 0x9c: case 0x9d: case 0x9e: case 0x9f: 
+
+      case 0xa0: case 0xa1: case 0xa2: case 0xa3: 
+      case 0xa4: case 0xa5: case 0xa6: case 0xa7: 
+      case 0xa8: case 0xa9: case 0xaa: case 0xab: 
+      case 0xac: case 0xad: case 0xae: case 0xaf: 
+
+      case 0xb0: case 0xb1: case 0xb2: case 0xb3: 
+      case 0xb4: case 0xb5: case 0xb6: case 0xb7: 
+      case 0xb8: case 0xb9: case 0xba: case 0xbb: 
+      case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+	{
+	  Integer value = new Integer(ch - 0x90);
+	  
+	  if (isShift(value))
+	    return shift(value);
+	  else {
+	    printObject(value.toString());
+	    return this;
+	  }
+	}
+
+      case 0xc0: case 0xc1: case 0xc2: case 0xc3: 
+      case 0xc4: case 0xc5: case 0xc6: case 0xc7: 
+      case 0xc8: case 0xc9: case 0xca: case 0xcb: 
+      case 0xcc: case 0xcd: case 0xce: case 0xcf:
+	return new IntegerState(this, "int", ch - 0xc8, 3);
+
+      case 0xd0: case 0xd1: case 0xd2: case 0xd3: 
+      case 0xd4: case 0xd5: case 0xd6: case 0xd7: 
+	return new IntegerState(this, "int", ch - 0xd4, 2);
+
+      case 'I':
+	return new IntegerState(this, "int");
+	
+      case 0xd8: case 0xd9: case 0xda: case 0xdb: 
+      case 0xdc: case 0xdd: case 0xde: case 0xdf: 
+      case 0xe0: case 0xe1: case 0xe2: case 0xe3: 
+      case 0xe4: case 0xe5: case 0xe6: case 0xe7: 
+      case 0xe8: case 0xe9: case 0xea: case 0xeb: 
+      case 0xec: case 0xed: case 0xee: case 0xef:
+	{
+	  Long value = new Long(ch - 0xe0);
+	  
+	  if (isShift(value))
+	    return shift(value);
+	  else {
+	    printObject(value.toString() + "L");
+	    return this;
+	  }
+	}
+	
+      case 0xf0: case 0xf1: case 0xf2: case 0xf3: 
+      case 0xf4: case 0xf5: case 0xf6: case 0xf7: 
+      case 0xf8: case 0xf9: case 0xfa: case 0xfb: 
+      case 0xfc: case 0xfd: case 0xfe: case 0xff:
+	return new LongState(this, "long", ch - 0xf8, 7);
+	
+      case 0x38: case 0x39: case 0x3a: case 0x3b: 
+      case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+	return new LongState(this, "long", ch - 0x3c, 6);
+	
+      case 0x77:
+	return new LongState(this, "long", 0, 4);
+
+      case 'L':
+	return new LongState(this, "long");
+
+      case 0x67: case 0x68:
+	{
+	  Double value = new Double(ch - 0x67);
+	  
+	  if (isShift(value))
+	    return shift(value);
+	  else {
+	    printObject(value.toString());
+	    return this;
+	  }
+	}
+
+      case 0x69:
+	return new DoubleIntegerState(this, 3);
+
+      case 0x6a:
+	return new DoubleIntegerState(this, 2);
+
+      case 0x6b:
+	return new FloatState(this);
+	
+      case 'D':
+	return new DoubleState(this);
+
+      case 0x4a:
+	return new RefState(this, "Ref", 0, 3);
+
+      case 0x4b:
+	return new RefState(this, "Ref", 0, 2);
+
+      case 'R':
+	return new RefState(this, "Ref");
+
+      case 'r':
+	return new RemoteState(this);
+
+      case 'd':
+	return new DateState(this);
+
+      case 0x00:
+	{
+	  String value = "\"\"";
+	  
+	  if (isShift(value))
+	    return shift(value);
+	  else {
+	    printObject(value.toString());
+	    return this;
+	  }
+	}
+
+      case 0x01: case 0x02: case 0x03:
+      case 0x04: case 0x05: case 0x06: case 0x07:
+      case 0x08: case 0x09: case 0x0a: case 0x0b:
+      case 0x0c: case 0x0d: case 0x0e: case 0x0f:
+	
+      case 0x10: case 0x11: case 0x12: case 0x13:
+      case 0x14: case 0x15: case 0x16: case 0x17:
+      case 0x18: case 0x19: case 0x1a: case 0x1b:
+      case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+	return new StringState(this, 'S', ch);
+
+      case 'S': case 'X':
+	return new StringState(this, 'S', true);
+
+      case 's': case 'x':
+	return new StringState(this, 'S', false);
+
+      case 0x20:
+	{
+	  String value = "binary(0)";
+	  
+	  if (isShift(value))
+	    return shift(value);
+	  else {
+	    printObject(value.toString());
+	    return this;
+	  }
+	}
+
+      case 0x21: case 0x22: case 0x23:
+      case 0x24: case 0x25: case 0x26: case 0x27:
+      case 0x28: case 0x29: case 0x2a: case 0x2b:
+      case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+	return new BinaryState(this, 'B', ch - 0x20);
+
+      case 'B':
+	return new BinaryState(this, 'B', true);
+
+      case 'b':
+	return new BinaryState(this, 'B', false);
+
+      case 'M':
+	return new MapState(this, _refId++);
+
+      case 'V':
+	return new ListState(this, _refId++);
+
+      case 'v':
+	return new CompactListState(this, _refId++);
+
+      case 'O':
+	return new ObjectDefState(this);
+
+      case 'o':
+	return new ObjectState(this, _refId++);
+
+      case 'P':
+	return new StreamingState(this, true);
+
+      case 'p':
+	return new StreamingState(this, false);
+	
+      default:
+	return this;
+      }
+    }
+  }
+  
+  class InitialState extends State {
+    State next(int ch)
+    {
+      println();
+      
+      if (ch == 'r') {
+	return new ReplyState(this);
+      }
+      else if (ch == 'c') {
+	return new CallState(this);
+      }
+      else
+	return nextObject(ch);
+    }
+  }
+  
+  class IntegerState extends State {
+    String _typeCode;
+    
+    int _length;
+    int _value;
+
+    IntegerState(State next, String typeCode)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+    }
+
+    IntegerState(State next, String typeCode, int value, int length)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+
+      _value = value;
+      _length = length;
+    }
+
+    State next(int ch)
+    {
+      _value = 256 * _value + (ch & 0xff);
+
+      if (++_length == 4) {
+	Integer value = new Integer(_value);
+	
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value.toString());
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class LongState extends State {
+    String _typeCode;
+    
+    int _length;
+    long _value;
+
+    LongState(State next, String typeCode)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+    }
+
+    LongState(State next, String typeCode, long value, int length)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+
+      _value = value;
+      _length = length;
+    }
+
+    State next(int ch)
+    {
+      _value = 256 * _value + (ch & 0xff);
+
+      if (++_length == 8) {
+	Long value = new Long(_value);
+	
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value.toString() + "L");
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class DoubleIntegerState extends State {
+    int _length;
+    int _value;
+    boolean _isFirst = true;
+
+    DoubleIntegerState(State next, int length)
+    {
+      super(next);
+
+      _length = length;
+    }
+
+    State next(int ch)
+    {
+      if (_isFirst)
+	_value = (byte) ch;
+      else
+	_value = 256 * _value + (ch & 0xff);
+
+      _isFirst = false;
+
+      if (++_length == 4) {
+	Double value = new Double(_value);
+	
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value.toString());
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class RefState extends State {
+    String _typeCode;
+    
+    int _length;
+    int _value;
+
+    RefState(State next, String typeCode)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+    }
+
+    RefState(State next, String typeCode, int value, int length)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+
+      _value = value;
+      _length = length;
+    }
+
+    State next(int ch)
+    {
+      _value = 256 * _value + (ch & 0xff);
+
+      if (++_length == 4) {
+	Integer value = new Integer(_value);
+	
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject("ref(#" + value + ")");
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class DateState extends State {
+    int _length;
+    long _value;
+
+    DateState(State next)
+    {
+      super(next);
+    }
+      
+    
+    State next(int ch)
+    {
+      _value = 256 * _value + (ch & 0xff);
+
+      if (++_length == 8) {
+	java.util.Date value = new java.util.Date(_value);
+
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value.toString());
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class DoubleState extends State {
+    int _length;
+    long _value;
+
+    DoubleState(State next)
+    {
+      super(next);
+    }
+    
+    State next(int ch)
+    {
+      _value = 256 * _value + (ch & 0xff);
+
+      if (++_length == 8) {
+	Double value = Double.longBitsToDouble(_value);
+
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value.toString());
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class FloatState extends State {
+    int _length;
+    int _value;
+
+    FloatState(State next)
+    {
+      super(next);
+    }
+    
+    State next(int ch)
+    {
+      _value = 256 * _value + (ch & 0xff);
+
+      if (++_length == 4) {
+	Double value = (double) Float.intBitsToFloat(_value);
+
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value.toString() + "F");
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class StringState extends State {
+    private static final int TOP = 0;
+    private static final int UTF_2_1 = 1;
+    private static final int UTF_3_1 = 2;
+    private static final int UTF_3_2 = 3;
+
+    char _typeCode;
+    
+    StringBuilder _value = new StringBuilder();
+    int _lengthIndex;
+    int _length;
+    boolean _isLastChunk;
+    
+    int _utfState;
+    char _ch;
+
+    StringState(State next, char typeCode, boolean isLastChunk)
+    {
+      super(next);
+      
+      _typeCode = typeCode;
+      _isLastChunk = isLastChunk;
+    }
+
+    StringState(State next, char typeCode, int length)
+    {
+      super(next);
+      
+      _typeCode = typeCode;
+      _isLastChunk = true;
+      _length = length;
+      _lengthIndex = 2;
+    }
+    
+    State next(int ch)
+    {
+      if (_lengthIndex < 2) {
+	_length = 256 * _length + (ch & 0xff);
+	
+	if (++_lengthIndex == 2 && _length == 0 && _isLastChunk) {
+	  if (_next.isShift(_value.toString()))
+	    return _next.shift(_value.toString());
+	  else {
+	    printObject("\"" + _value + "\"");
+	    return _next;
+	  }
+	}
+	else
+	  return this;
+      }
+      else if (_length == 0) {
+	if (ch == 's' || ch == 'x') {
+	  _isLastChunk = false;
+	  _lengthIndex = 0;
+	  return this;
+	}
+	else if (ch == 'S' || ch == 'X') {
+	  _isLastChunk = true;
+	  _lengthIndex = 0;
+	  return this;
+	}
+	else if (ch == 0x00) {
+	  if (_next.isShift(_value.toString()))
+	    return _next.shift(_value.toString());
+	  else {
+	    printObject("\"" + _value + "\"");
+	    return _next;
+	  }
+	}
+	else if (0x00 <= ch && ch < 0x20) {
+	  _isLastChunk = true;
+	  _lengthIndex = 2;
+	  _length = ch & 0xff;
+	  return this;
+	}
+	else {
+	  println(String.valueOf((char) ch) + ": unexpected character");
+	  return _next;
+	}
+      }
+
+      switch (_utfState) {
+      case TOP:
+	if (ch < 0x80) {
+	  _length--;
+
+	  _value.append((char) ch);
+	}
+	else if (ch < 0xe0) {
+	  _ch = (char) ((ch & 0x1f) << 6);
+	  _utfState = UTF_2_1;
+	}
+	else {
+	  _ch = (char) ((ch & 0xf) << 12);
+	  _utfState = UTF_3_1;
+	}
+	break;
+
+      case UTF_2_1:
+      case UTF_3_2:
+	_ch += ch & 0x3f;
+	_value.append(_ch);
+	_length--;
+	_utfState = TOP;
+	break;
+
+      case UTF_3_1:
+	_ch += (char) ((ch & 0x3f) << 6);
+	_utfState = UTF_3_2;
+	break;
+      }
+
+      if (_length == 0 && _isLastChunk) {
+	if (_next.isShift(_value.toString()))
+	  return _next.shift(_value.toString());
+	else {
+	  printObject("\"" + _value + "\"");
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class BinaryState extends State {
+    char _typeCode;
+    
+    int _totalLength;
+    
+    int _lengthIndex;
+    int _length;
+    boolean _isLastChunk;
+    
+    BinaryState(State next, char typeCode, boolean isLastChunk)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+      _isLastChunk = isLastChunk;
+    }
+
+    BinaryState(State next, char typeCode, int length)
+    {
+      super(next);
+
+      _typeCode = typeCode;
+      _isLastChunk = true;
+      _length = length;
+      _lengthIndex = 2;
+    }
+    
+    State next(int ch)
+    {
+      if (_lengthIndex < 2) {
+	_length = 256 * _length + (ch & 0xff);
+	
+	if (++_lengthIndex == 2 && _length == 0 && _isLastChunk) {
+	  String value = "binary(" + _totalLength + ")";
+	  
+	  if (_next.isShift(value))
+	    return _next.shift(value);
+	  else {
+	    printObject(value);
+	    return _next;
+	  }
+	}
+	else
+	  return this;
+      }
+      else if (_length == 0) {
+	if (ch == 'b') {
+	  _isLastChunk = false;
+	  _lengthIndex = 0;
+	  return this;
+	}
+	else if (ch == 'B') {
+	  _isLastChunk = true;
+	  _lengthIndex = 0;
+	  return this;
+	}
+	else if (ch == 0x20) {
+	  String value = "binary(" + _totalLength + ")";
+	  
+	  if (_next.isShift(value))
+	    return _next.shift(value);
+	  else {
+	    printObject(value);
+	    return _next;
+	  }
+	}
+	else if (0x20 <=ch && ch < 0x30) {
+	  _isLastChunk = true;
+	  _lengthIndex = 2;
+	  _length = (ch & 0xff) - 0x20;
+	  return this;
+	}
+	else {
+	  println(String.valueOf((char) ch) + ": unexpected character");
+	  return _next;
+	}
+      }
+      
+      _length--;
+      _totalLength++;
+
+      if (_length == 0 && _isLastChunk) {
+	String value = "binary(" + _totalLength + ")";
+	
+	if (_next.isShift(value))
+	  return _next.shift(value);
+	else {
+	  printObject(value);
+	  
+	  return _next;
+	}
+      }
+      else
+	return this;
+    }
+  }
+  
+  class MapState extends State {
+    private static final int TYPE = 0;
+    private static final int KEY = 1;
+    private static final int VALUE = 2;
+
+    private int _refId;
+
+    private int _state;
+    private int _valueDepth;
+    private boolean _hasData;
+
+    MapState(State next, int refId)
+    {
+      super(next);
+      
+      _refId = refId;
+      _state = TYPE;
+    }
+
+    @Override
+    boolean isShift(Object value)
+    {
+      return _state == TYPE;
+    }
+
+    @Override
+    State shift(Object type)
+    {
+      if (_state == TYPE) {
+	if (type instanceof String) {
+	  _typeDefList.add((String) type);
+	}
+	else if (type instanceof Integer) {
+	  int iValue = (Integer) type;
+
+	  if (iValue >= 0 && iValue < _typeDefList.size())
+	    type = _typeDefList.get(iValue);
+	}
+	
+	printObject("map " + type + "(#" + _refId + ")");
+
+	_state = VALUE;
+      
+	return this;
+      }
+      else
+	throw new IllegalStateException();
+    }
+
+    @Override
+    int depth()
+    {
+      if (_state == TYPE)
+	return _next.depth();
+      else if (_state == KEY)
+	return _next.depth() + 2;
+      else
+	return _valueDepth;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case TYPE:
+	if (ch == 't') {
+	  return new StringState(this, 't', true);
+	}
+	else if (ch == 0x75) {
+	  return new IndirectState(this);
+	}
+	else if (ch == 'z') {
+	  printObject("map (#" + _refId + ")");
+	  return _next;
+	}
+	else {
+	  printObject("map (#" + _refId + ")");
+	  
+	  _state = KEY;
+	  
+	  return nextObject(ch);
+	}
+	
+      case VALUE:
+	if (ch == 'z') {
+	  if (_hasData)
+	    println();
+	  
+	  return _next;
+	}
+	else {
+	  if (_hasData)
+	    println();
+
+	  _hasData = true;
+	  _state = KEY;
+	  
+	  return nextObject(ch);
+	}
+	
+      case KEY:
+	print(" => ");
+	_isObject = false;
+	_valueDepth = _column;
+
+	_state = VALUE;
+	
+	return nextObject(ch);
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class ObjectDefState extends State {
+    private static final int TYPE = 1;
+    private static final int COUNT = 2;
+    private static final int FIELD = 3;
+    private static final int COMPLETE = 4;
+
+    private int _refId;
+
+    private int _state;
+    private boolean _hasData;
+    private int _count;
+
+    private String _type;
+    private ArrayList<String> _fields = new ArrayList<String>();
+
+    ObjectDefState(State next)
+    {
+      super(next);
+      
+      _state = TYPE;
+    }
+
+    @Override
+    boolean isShift(Object value)
+    {
+      return true;
+    }
+
+    @Override
+    State shift(Object object)
+    {
+      if (_state == TYPE) {
+	_type = (String) object;
+
+	print("/* defun " + _type + " [");
+
+	_objectDefList.add(new ObjectDef(_type, _fields));
+
+	_state = COUNT;
+      }
+      else if (_state == COUNT) {
+	_count = (Integer) object;
+
+	_state = FIELD;
+      }
+      else if (_state == FIELD) {
+	String field = (String) object;
+
+	_count--;
+
+	_fields.add(field);
+
+	if (_fields.size() == 1)
+	  print(field);
+	else
+	  print(", " + field);
+      }
+      else {
+	throw new UnsupportedOperationException();
+      }
+
+      return this;
+    }
+
+    @Override
+    int depth()
+    {
+      if (_state <= TYPE)
+	return _next.depth();
+      else
+	return _next.depth() + 2;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case TYPE:
+	return nextObject(ch);
+	
+      case COUNT:
+	return nextObject(ch);
+	
+      case FIELD:
+	if (_count == 0) {
+	  println("] */");
+	  _next.printIndent(0);
+
+	  return _next.nextObject(ch);
+	}
+	else
+	  return nextObject(ch);
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class ObjectState extends State {
+    private static final int TYPE = 0;
+    private static final int FIELD = 1;
+
+    private int _refId;
+
+    private int _state;
+    private ObjectDef _def;
+    private int _count;
+    private int _fieldDepth;
+
+    ObjectState(State next, int refId)
+    {
+      super(next);
+
+      _refId = refId;
+      _state = TYPE;
+    }
+
+    @Override
+    boolean isShift(Object value)
+    {
+      if (_state == TYPE)
+	return true;
+      else
+	return false;
+    }
+
+    @Override
+    State shift(Object object)
+    {
+      if (_state == TYPE) {
+	int def = (Integer) object;
+
+	_def = _objectDefList.get(def);
+
+	println("object " + _def.getType() + " (#" + _refId + ")");
+
+	_state = FIELD;
+
+	if (_def.getFields().size() == 0)
+	  return _next;
+      }
+
+      return this;
+    }
+
+    @Override
+    int depth()
+    {
+      if (_state <= TYPE)
+	return _next.depth();
+      else
+	return _fieldDepth;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case TYPE:
+	return nextObject(ch);
+	
+      case FIELD:
+	if (_def.getFields().size() <= _count)
+	  return _next.next(ch);
+
+	_fieldDepth = _next.depth() + 2;
+	println();
+	print(_def.getFields().get(_count++) + ": ");
+
+	_fieldDepth = _column;
+
+	_isObject = false;
+	return nextObject(ch);
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class ListState extends State {
+    private static final int TYPE = 0;
+    private static final int LENGTH = 1;
+    private static final int VALUE = 2;
+
+    private int _refId;
+
+    private int _state;
+    private boolean _hasData;
+    private int _count;
+    private int _valueDepth;
+
+    ListState(State next, int refId)
+    {
+      super(next);
+      
+      _refId = refId;
+      _state = TYPE;
+    }
+
+    @Override
+    boolean isShift(Object value)
+    {
+      return _state == TYPE || _state == LENGTH;
+    }
+
+    @Override
+    State shift(Object object)
+    {
+      if (_state == TYPE) {
+	Object type = object;
+	
+	if (type instanceof String) {
+	  _typeDefList.add((String) type);
+	}
+	else if (object instanceof Integer) {
+	  int index = (Integer) object;
+
+	  if (index >= 0 && index < _typeDefList.size())
+	    type = _typeDefList.get(index);
+	}
+	
+	printObject("list " + type + "(#" + _refId + ")");
+      
+	_state = LENGTH;
+      
+	return this;
+      }
+      else if (_state == LENGTH) {
+	_state = VALUE;
+
+	return this;
+      }
+      else
+	return this;
+    }
+
+    @Override
+    int depth()
+    {
+      if (_state <= LENGTH)
+	return _next.depth();
+      else if (_state == VALUE)
+	return _valueDepth;
+      else
+	return _next.depth() + 2;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case TYPE:
+	if (ch == 't') {
+	  return new StringState(this, 't', true);
+	}
+	else if (ch == TYPE_REF) {
+	  return new IndirectState(this);
+	}
+	else if (ch == 'l') {
+	  printObject("list (#" + _refId + ")");
+	  _state = LENGTH;
+	  
+	  return new IntegerState(this, "length");
+	}
+	else if (ch == LENGTH_BYTE) {
+	  printObject("list (#" + _refId + ")");
+	  _state = LENGTH;
+	  
+	  return new IntegerState(this, "length", 0, 3);
+	}
+	else if (ch == 'z') {
+	  printObject("list (#" + _refId + ")");
+	  return _next;
+	}
+	else {
+	  printObject("list (#" + _refId + ")");
+	  
+	  _state = VALUE;
+
+	  _valueDepth = _next.depth() + 2;
+	  println();
+	  printObject(_count++ + ": ");
+	  _valueDepth = _column;
+	  _isObject = false;
+	  
+	  return nextObject(ch);
+	}
+	
+      case LENGTH:
+	if (ch == 'z') {
+	  return _next;
+	}
+	else if (ch == 'l') {
+	  return new IntegerState(this, "length");
+	}
+	else if (ch == LENGTH_BYTE) {
+	  return new IntegerState(this, "length", 0, 3);
+	}
+	else {
+	  _state = VALUE;
+	  
+	  _valueDepth = _next.depth() + 2;
+	  println();
+	  printObject(_count++ + ": ");
+	  _valueDepth = _column;
+	  _isObject = false;
+	  
+	  return nextObject(ch);
+	}
+	
+      case VALUE:
+	if (ch == 'z') {
+	  if (_count > 0)
+	    println();
+	  
+	  return _next;
+	}
+	else {
+	  _valueDepth = _next.depth() + 2;
+	  println();
+	  printObject(_count++ + ": ");
+	  _valueDepth = _column;
+	  _isObject = false;
+	  
+	  return nextObject(ch);
+	}
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class CompactListState extends State {
+    private static final int TYPE = 0;
+    private static final int LENGTH = 1;
+    private static final int VALUE = 2;
+
+    private int _refId;
+
+    private int _state;
+    private boolean _hasData;
+    private int _length;
+    private int _count;
+    private int _valueDepth;
+
+    CompactListState(State next, int refId)
+    {
+      super(next);
+      
+      _refId = refId;
+      _state = TYPE;
+    }
+
+    @Override
+    boolean isShift(Object value)
+    {
+      return _state == TYPE || _state == LENGTH;
+    }
+
+    @Override
+    State shift(Object object)
+    {
+      if (_state == TYPE) {
+	Object type = object;
+	
+	if (object instanceof Integer) {
+	  int index = (Integer) object;
+
+	  if (index >= 0 && index < _typeDefList.size())
+	    type = _typeDefList.get(index);
+	}
+	
+	printObject("list " + type + "(#" + _refId + ")");
+      
+	_state = LENGTH;
+      
+	return this;
+      }
+      else if (_state == LENGTH) {
+	_length = (Integer) object;
+	
+	_state = VALUE;
+
+	if (_length == 0)
+	  return _next;
+	else
+	  return this;
+      }
+      else
+	return this;
+    }
+
+    @Override
+    int depth()
+    {
+      if (_state <= LENGTH)
+	return _next.depth();
+      else if (_state == VALUE)
+	return _valueDepth;
+      else
+	return _next.depth() + 2;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case TYPE:
+	return nextObject(ch);
+	
+      case LENGTH:
+	return nextObject(ch);
+	
+      case VALUE:
+	if (_length <= _count)
+	  return _next.next(ch);
+	else {
+	  _valueDepth = _next.depth() + 2;
+	  println();
+	  printObject(_count++ + ": ");
+	  _valueDepth = _column;
+	  _isObject = false;
+	  
+	  return nextObject(ch);
+	}
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class CallState extends State {
+    private static final int MAJOR = 0;
+    private static final int MINOR = 1;
+    private static final int HEADER = 2;
+    private static final int METHOD = 3;
+    private static final int VALUE = 4;
+    private static final int ARG = 5;
+
+    private int _state;
+    private int _major;
+    private int _minor;
+
+    CallState(State next)
+    {
+      super(next);
+    }
+
+    int depth()
+    {
+      return _next.depth() + 2;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case MAJOR:
+	_major = ch;
+	_state = MINOR;
+	return this;
+	
+      case MINOR:
+	_minor = ch;
+	_state = HEADER;
+	println(-2, "call " + _major + "." + _minor);
+	return this;
+	
+      case HEADER:
+	if (ch == 'H') {
+	  println();
+	  print("header ");
+	  _isObject = false;
+	  _state = VALUE;
+	  return new StringState(this, 'H', true);
+	}
+ 	else if (ch == 'm') {
+	  println();
+	  print("method ");
+	  _isObject = false;
+	  _state = ARG;
+	  return new StringState(this, 'm', true);
+	}
+	else {
+	  println((char) ch + ": unexpected char");
+	  return popStack();
+	}
+	
+      case VALUE:
+	print(" => ");
+	_isObject = false;
+	_state = HEADER;
+	return nextObject(ch);
+	
+      case ARG:
+	if (ch == 'z')
+	  return _next;
+	else
+	  return nextObject(ch);
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class ReplyState extends State {
+    private static final int MAJOR = 0;
+    private static final int MINOR = 1;
+    private static final int HEADER = 2;
+    private static final int VALUE = 3;
+    private static final int END = 4;
+
+    private int _state;
+    private int _major;
+    private int _minor;
+
+    ReplyState(State next)
+    {
+      _next = next;
+    }
+
+    int depth()
+    {
+      return _next.depth() + 2;
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case MAJOR:
+	if (ch == 't' || ch == 'S')
+	  return new RemoteState(this).next(ch);
+	
+	_major = ch;
+	_state = MINOR;
+	return this;
+	
+      case MINOR:
+	_minor = ch;
+	_state = HEADER;
+	println(-2, "reply " + _major + "." + _minor);
+	return this;
+	
+      case HEADER:
+	if (ch == 'H') {
+	  _state = VALUE;
+	  return new StringState(this, 'H', true);
+	}
+	else if (ch == 'f') {
+	  print("fault ");
+	  _isObject = false;
+	  _state = END;
+	  return new MapState(this, 0);
+	}
+ 	else {
+	  _state = END;
+	  return nextObject(ch);
+	}
+	
+      case VALUE:
+	_state = HEADER;
+	return nextObject(ch);
+	
+      case END:
+	println();
+	if (ch == 'z') {
+	  return _next;
+	}
+	else
+	  return _next.next(ch);
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class IndirectState extends State {
+    IndirectState(State next)
+    {
+      super(next);
+    }
+
+    boolean isShift(Object object)
+    {
+      return _next.isShift(object);
+    }
+
+    State shift(Object object)
+    {
+      return _next.shift(object);
+    }
+    
+    State next(int ch)
+    {
+      return nextObject(ch);
+    }
+  }
+  
+  class RemoteState extends State {
+    private static final int TYPE = 0;
+    private static final int VALUE = 1;
+    private static final int END = 2;
+
+    private int _state;
+    private int _major;
+    private int _minor;
+
+    RemoteState(State next)
+    {
+      super(next);
+    }
+    
+    State next(int ch)
+    {
+      switch (_state) {
+      case TYPE:
+	println(-1, "remote");
+	if (ch == 't') {
+	  _state = VALUE;
+	  return new StringState(this, 't', false);
+	}
+	else {
+	  _state = END;
+	  return nextObject(ch);
+	}
+
+      case VALUE:
+	_state = END;
+	return _next.nextObject(ch);
+
+      case END:
+	return _next.next(ch);
+
+      default:
+	throw new IllegalStateException();
+      }
+    }
+  }
+  
+  class StreamingState extends State {
+    private int _digit;
+    private int _length;
+    private boolean _isLast;
+    private boolean _isFirst = true;
+
+    private State _childState;
+
+    StreamingState(State next, boolean isLast)
+    {
+      super(next);
+
+      _isLast = isLast;
+      _childState = new InitialState();
+    }
+    
+    State next(int ch)
+    {
+      if (_digit < 2) {
+	_length = 256 * _length + ch;
+	_digit++;
+
+	if (_digit == 2 && _length == 0 && _isLast) {
+	  _refId = 0;
+	  return _next;
+	}
+	else {
+	  if (_digit == 2)
+	    println(-1, "packet-start(" + _length + ")");
+	  
+	  return this;
+	}
+      }
+      else if (_length == 0) {
+	_isLast = (ch == 'P');
+	_digit = 0;
+	
+	return this;
+      }
+
+      _childState = _childState.next(ch);
+
+      _length--;
+
+      if (_length == 0 && _isLast) {
+	println(-1, "");
+	println(-1, "packet-end");
+	_refId = 0;
+	return _next;
+      }
+      else
+	return this;
+    }
+  }
+
+  static class ObjectDef {
+    private String _type;
+    private ArrayList<String> _fields;
+
+    ObjectDef(String type, ArrayList<String> fields)
+    {
+      _type = type;
+      _fields = fields;
+    }
+
+    String getType()
+    {
+      return _type;
+    }
+
+    ArrayList<String> getFields()
+    {
+      return _fields;
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/HessianEnvelope.java src/com/caucho/hessian/io/HessianEnvelope.java
new file mode 100644
index 0000000..dfee9e7
--- /dev/null
+++ src/com/caucho/hessian/io/HessianEnvelope.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.*;
+
+/**
+ * Factory class for wrapping and unwrapping hessian streams.
+ */
+abstract public class HessianEnvelope {
+  /**
+   * Wrap the Hessian output stream in an envelope.
+   */
+  abstract public Hessian2Output wrap(Hessian2Output out)
+    throws IOException;
+
+  /**
+   * Unwrap the Hessian input stream with this envelope.  It is an
+   * error if the actual envelope does not match the expected envelope
+   * class.
+   */
+  abstract public Hessian2Input unwrap(Hessian2Input in)
+    throws IOException;
+
+  /**
+   * Unwrap the envelope after having read the envelope code ('E') and
+   * the envelope method.  Called by the EnvelopeFactory for dynamic
+   * reading of the envelopes.
+   */
+  abstract public Hessian2Input unwrapHeaders(Hessian2Input in)
+    throws IOException;
+}
diff --git src/com/caucho/hessian/io/HessianFieldException.java src/com/caucho/hessian/io/HessianFieldException.java
new file mode 100644
index 0000000..db513d0
--- /dev/null
+++ src/com/caucho/hessian/io/HessianFieldException.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Exception during field reading.
+ */
+public class HessianFieldException extends HessianProtocolException {
+  /**
+   * Zero-arg constructor.
+   */
+  public HessianFieldException()
+  {
+  }
+  
+  /**
+   * Create the exception.
+   */
+  public HessianFieldException(String message)
+  {
+    super(message);
+  }
+  
+  /**
+   * Create the exception.
+   */
+  public HessianFieldException(String message, Throwable cause)
+  {
+    super(message, cause);
+  }
+  
+  /**
+   * Create the exception.
+   */
+  public HessianFieldException(Throwable cause)
+  {
+    super(cause);
+  }
+}
diff --git src/com/caucho/hessian/io/HessianHandle.java src/com/caucho/hessian/io/HessianHandle.java
new file mode 100644
index 0000000..7e50420
--- /dev/null
+++ src/com/caucho/hessian/io/HessianHandle.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+/**
+ * Marks a type as a handle
+ */
+public interface HessianHandle {
+}
diff --git src/com/caucho/hessian/io/HessianInput.java src/com/caucho/hessian/io/HessianInput.java
new file mode 100644
index 0000000..a449622
--- /dev/null
+++ src/com/caucho/hessian/io/HessianInput.java
@@ -0,0 +1,1700 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * Input stream for Hessian requests.
+ *
+ * <p>HessianInput is unbuffered, so any client needs to provide
+ * its own buffering.
+ *
+ * <pre>
+ * InputStream is = ...; // from http connection
+ * HessianInput in = new HessianInput(is);
+ * String value;
+ *
+ * in.startReply();         // read reply header
+ * value = in.readString(); // read string value
+ * in.completeReply();      // read reply footer
+ * </pre>
+ */
+public class HessianInput extends AbstractHessianInput {
+  private static int END_OF_DATA = -2;
+
+  private static Field _detailMessageField;
+  
+  // factory for deserializing objects in the input stream
+  protected SerializerFactory _serializerFactory;
+  
+  protected ArrayList _refs;
+  
+  // the underlying input stream
+  private InputStream _is;
+  // a peek character
+  protected int _peek = -1;
+  
+  // the method for a call
+  private String _method;
+
+  private Reader _chunkReader;
+  private InputStream _chunkInputStream;
+
+  private Throwable _replyFault;
+
+  private StringBuffer _sbuf = new StringBuffer();
+  
+  // true if this is the last chunk
+  private boolean _isLastChunk;
+  // the chunk length
+  private int _chunkLength;
+
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianInput()
+  {
+  }
+  
+  /**
+   * Creates a new Hessian input stream, initialized with an
+   * underlying input stream.
+   *
+   * @param is the underlying input stream.
+   */
+  public HessianInput(InputStream is)
+  {
+    init(is);
+  }
+
+  /**
+   * Sets the serializer factory.
+   */
+  public void setSerializerFactory(SerializerFactory factory)
+  {
+    _serializerFactory = factory;
+  }
+
+  /**
+   * Gets the serializer factory.
+   */
+  public SerializerFactory getSerializerFactory()
+  {
+    return _serializerFactory;
+  }
+
+  /**
+   * Initialize the hessian stream with the underlying input stream.
+   */
+  public void init(InputStream is)
+  {
+    _is = is;
+    _method = null;
+    _isLastChunk = true;
+    _chunkLength = 0;
+    _peek = -1;
+    _refs = null;
+    _replyFault = null;
+
+    if (_serializerFactory == null)
+      _serializerFactory = new SerializerFactory();
+  }
+
+  /**
+   * Returns the calls method
+   */
+  public String getMethod()
+  {
+    return _method;
+  }
+
+  /**
+   * Returns any reply fault.
+   */
+  public Throwable getReplyFault()
+  {
+    return _replyFault;
+  }
+
+  /**
+   * Starts reading the call
+   *
+   * <pre>
+   * c major minor
+   * </pre>
+   */
+  public int readCall()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'c')
+      throw error("expected hessian call ('c') at " + codeName(tag));
+
+    int major = read();
+    int minor = read();
+
+    return (major << 16) + minor;
+  }
+
+  /**
+   * For backward compatibility with HessianSkeleton
+   */
+  public void skipOptionalCall()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag == 'c') {
+      read();
+      read();
+    }
+    else
+      _peek = tag;
+  }
+
+  /**
+   * Starts reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * m b16 b8 method
+   * </pre>
+   */
+  public String readMethod()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'm')
+      throw error("expected hessian method ('m') at " + codeName(tag));
+    int d1 = read();
+    int d2 = read();
+
+    _isLastChunk = true;
+    _chunkLength = d1 * 256 + d2;
+    _sbuf.setLength(0);
+    int ch;
+    while ((ch = parseChar()) >= 0)
+      _sbuf.append((char) ch);
+    
+    _method = _sbuf.toString();
+
+    return _method;
+  }
+
+  /**
+   * Starts reading the call, including the headers.
+   *
+   * <p>The call expects the following protocol data
+   *
+   * <pre>
+   * c major minor
+   * m b16 b8 method
+   * </pre>
+   */
+  public void startCall()
+    throws IOException
+  {
+    readCall();
+
+    while (readHeader() != null) {
+      readObject();
+    }
+
+    readMethod();
+  }
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeCall()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag == 'z') {
+    }
+    else
+      throw error("expected end of call ('z') at " + codeName(tag) + ".  Check method arguments and ensure method overloading is enabled if necessary");
+  }
+
+  /**
+   * Reads a reply as an object.
+   * If the reply has a fault, throws the exception.
+   */
+  public Object readReply(Class expectedClass)
+    throws Throwable
+  {
+    int tag = read();
+    
+    if (tag != 'r')
+      error("expected hessian reply at " + codeName(tag));
+
+    int major = read();
+    int minor = read();
+
+    tag = read();
+    if (tag == 'f')
+      throw prepareFault();
+    else {
+      _peek = tag;
+    
+      Object value = readObject(expectedClass);
+
+      completeValueReply();
+
+      return value;
+    }
+  }
+
+  /**
+   * Starts reading the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * r
+   * </pre>
+   */
+  public void startReply()
+    throws Throwable
+  {
+    int tag = read();
+    
+    if (tag != 'r')
+      error("expected hessian reply at " + codeName(tag));
+
+    int major = read();
+    int minor = read();
+    
+    tag = read();
+    if (tag == 'f')
+      throw prepareFault();
+    else
+      _peek = tag;
+  }
+
+  /**
+   * Prepares the fault.
+   */
+  private Throwable prepareFault()
+    throws IOException
+  {
+    HashMap fault = readFault();
+
+    Object detail = fault.get("detail");
+    String message = (String) fault.get("message");
+
+    if (detail instanceof Throwable) {
+      _replyFault = (Throwable) detail;
+      
+      if (message != null && _detailMessageField != null) {
+	try {
+	  _detailMessageField.set(_replyFault, message);
+	} catch (Throwable e) {
+	}
+      }
+	
+      return _replyFault;
+    }
+
+    else {
+      String code = (String) fault.get("code");
+        
+      _replyFault = new HessianServiceException(message, code, detail);
+
+      return _replyFault;
+    }
+  }
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeReply()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'z')
+      error("expected end of reply at " + codeName(tag));
+  }
+
+  /**
+   * Completes reading the call
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeValueReply()
+    throws IOException
+  {
+    int tag = read();
+    
+    if (tag != 'z')
+      error("expected end of reply at " + codeName(tag));
+  }
+
+  /**
+   * Reads a header, returning null if there are no headers.
+   *
+   * <pre>
+   * H b16 b8 value
+   * </pre>
+   */
+  public String readHeader()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag == 'H') {
+      _isLastChunk = true;
+      _chunkLength = (read() << 8) + read();
+
+      _sbuf.setLength(0);
+      int ch;
+      while ((ch = parseChar()) >= 0)
+        _sbuf.append((char) ch);
+
+      return _sbuf.toString();
+    }
+
+    _peek = tag;
+
+    return null;
+  }
+
+  /**
+   * Reads a null
+   *
+   * <pre>
+   * N
+   * </pre>
+   */
+  public void readNull()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N': return;
+      
+    default:
+      throw expect("null", tag);
+    }
+  }
+
+  /**
+   * Reads a boolean
+   *
+   * <pre>
+   * T
+   * F
+   * </pre>
+   */
+  public boolean readBoolean()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'T': return true;
+    case 'F': return false;
+    case 'I': return parseInt() == 0;
+    case 'L': return parseLong() == 0;
+    case 'D': return parseDouble() == 0.0;
+    case 'N': return false;
+      
+    default:
+      throw expect("boolean", tag);
+    }
+  }
+
+  /**
+   * Reads a byte
+   *
+   * <pre>
+   * I b32 b24 b16 b8
+   * </pre>
+   */
+  /*
+  public byte readByte()
+    throws IOException
+  {
+    return (byte) readInt();
+  }
+  */
+
+  /**
+   * Reads a short
+   *
+   * <pre>
+   * I b32 b24 b16 b8
+   * </pre>
+   */
+  public short readShort()
+    throws IOException
+  {
+    return (short) readInt();
+  }
+
+  /**
+   * Reads an integer
+   *
+   * <pre>
+   * I b32 b24 b16 b8
+   * </pre>
+   */
+  public int readInt()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'T': return 1;
+    case 'F': return 0;
+    case 'I': return parseInt();
+    case 'L': return (int) parseLong();
+    case 'D': return (int) parseDouble();
+      
+    default:
+      throw expect("int", tag);
+    }
+  }
+
+  /**
+   * Reads a long
+   *
+   * <pre>
+   * L b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public long readLong()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'T': return 1;
+    case 'F': return 0;
+    case 'I': return parseInt();
+    case 'L': return parseLong();
+    case 'D': return (long) parseDouble();
+      
+    default:
+      throw expect("long", tag);
+    }
+  }
+
+  /**
+   * Reads a float
+   *
+   * <pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public float readFloat()
+    throws IOException
+  {
+    return (float) readDouble();
+  }
+
+  /**
+   * Reads a double
+   *
+   * <pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public double readDouble()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'T': return 1;
+    case 'F': return 0;
+    case 'I': return parseInt();
+    case 'L': return (double) parseLong();
+    case 'D': return parseDouble();
+      
+    default:
+      throw expect("long", tag);
+    }
+  }
+
+  /**
+   * Reads a date.
+   *
+   * <pre>
+   * T b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  public long readUTCDate()
+    throws IOException
+  {
+    int tag = read();
+
+    if (tag != 'd')
+      throw error("expected date at " + codeName(tag));
+
+    long b64 = read();
+    long b56 = read();
+    long b48 = read();
+    long b40 = read();
+    long b32 = read();
+    long b24 = read();
+    long b16 = read();
+    long b8 = read();
+
+    return ((b64 << 56) +
+            (b56 << 48) +
+            (b48 << 40) +
+            (b40 << 32) +
+            (b32 << 24) +
+            (b24 << 16) +
+            (b16 << 8) +
+            b8);
+  }
+
+  /**
+   * Reads a byte from the stream.
+   */
+  public int readChar()
+    throws IOException
+  {
+    if (_chunkLength > 0) {
+      _chunkLength--;
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      int ch = parseUTF8Char();
+      return ch;
+    }
+    else if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return -1;
+
+    case 'S':
+    case 's':
+    case 'X':
+    case 'x':
+      _isLastChunk = tag == 'S' || tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      _chunkLength--;
+      int value = parseUTF8Char();
+
+      // special code so successive read byte won't
+      // be read as a single object.
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      return value;
+      
+    default:
+      throw new IOException("expected 'S' at " + (char) tag);
+    }
+  }
+
+  /**
+   * Reads a byte array from the stream.
+   */
+  public int readString(char []buffer, int offset, int length)
+    throws IOException
+  {
+    int readLength = 0;
+
+    if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    else if (_chunkLength == 0) {
+      int tag = read();
+
+      switch (tag) {
+      case 'N':
+        return -1;
+      
+      case 'S':
+      case 's':
+      case 'X':
+      case 'x':
+        _isLastChunk = tag == 'S' || tag == 'X';
+        _chunkLength = (read() << 8) + read();
+        break;
+
+      default:
+        throw new IOException("expected 'S' at " + (char) tag);
+      }
+    }
+
+    while (length > 0) {
+      if (_chunkLength > 0) {
+        buffer[offset++] = (char) parseUTF8Char();
+        _chunkLength--;
+        length--;
+        readLength++;
+      }
+      else if (_isLastChunk) {
+        if (readLength == 0)
+          return -1;
+        else {
+          _chunkLength = END_OF_DATA;
+          return readLength;
+        }
+      }
+      else {
+        int tag = read();
+
+        switch (tag) {
+        case 'S':
+        case 's':
+        case 'X':
+        case 'x':
+          _isLastChunk = tag == 'S' || tag == 'X';
+          _chunkLength = (read() << 8) + read();
+          break;
+      
+        default:
+          throw new IOException("expected 'S' at " + (char) tag);
+        }
+      }
+    }
+    
+    if (readLength == 0)
+      return -1;
+    else if (_chunkLength > 0 || ! _isLastChunk)
+      return readLength;
+    else {
+      _chunkLength = END_OF_DATA;
+      return readLength;
+    }
+  }
+
+  /**
+   * Reads a string
+   *
+   * <pre>
+   * S b16 b8 string value
+   * </pre>
+   */
+  public String readString()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'I':
+      return String.valueOf(parseInt());
+    case 'L':
+      return String.valueOf(parseLong());
+    case 'D':
+      return String.valueOf(parseDouble());
+
+    case 'S':
+    case 's':
+    case 'X':
+    case 'x':
+      _isLastChunk = tag == 'S' || tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      _sbuf.setLength(0);
+      int ch;
+
+      while ((ch = parseChar()) >= 0)
+        _sbuf.append((char) ch);
+
+      return _sbuf.toString();
+
+    default:
+      throw expect("string", tag);
+    }
+  }
+
+  /**
+   * Reads an XML node.
+   *
+   * <pre>
+   * S b16 b8 string value
+   * </pre>
+   */
+  public org.w3c.dom.Node readNode()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'S':
+    case 's':
+    case 'X':
+    case 'x':
+      _isLastChunk = tag == 'S' || tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      throw error("Can't handle string in this context");
+
+    default:
+      throw expect("string", tag);
+    }
+  }
+
+  /**
+   * Reads a byte array
+   *
+   * <pre>
+   * B b16 b8 data value
+   * </pre>
+   */
+  public byte []readBytes()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'B':
+    case 'b':
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+
+      ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+      int data;
+      while ((data = parseByte()) >= 0)
+        bos.write(data);
+
+      return bos.toByteArray();
+      
+    default:
+      throw expect("bytes", tag);
+    }
+  }
+
+  /**
+   * Reads a byte from the stream.
+   */
+  public int readByte()
+    throws IOException
+  {
+    if (_chunkLength > 0) {
+      _chunkLength--;
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      return read();
+    }
+    else if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return -1;
+
+    case 'B':
+    case 'b':
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+
+      int value = parseByte();
+
+      // special code so successive read byte won't
+      // be read as a single object.
+      if (_chunkLength == 0 && _isLastChunk)
+        _chunkLength = END_OF_DATA;
+
+      return value;
+      
+    default:
+      throw new IOException("expected 'B' at " + (char) tag);
+    }
+  }
+
+  /**
+   * Reads a byte array from the stream.
+   */
+  public int readBytes(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    int readLength = 0;
+
+    if (_chunkLength == END_OF_DATA) {
+      _chunkLength = 0;
+      return -1;
+    }
+    else if (_chunkLength == 0) {
+      int tag = read();
+
+      switch (tag) {
+      case 'N':
+        return -1;
+      
+      case 'B':
+      case 'b':
+        _isLastChunk = tag == 'B';
+        _chunkLength = (read() << 8) + read();
+        break;
+      
+      default:
+        throw new IOException("expected 'B' at " + (char) tag);
+      }
+    }
+
+    while (length > 0) {
+      if (_chunkLength > 0) {
+        buffer[offset++] = (byte) read();
+        _chunkLength--;
+        length--;
+        readLength++;
+      }
+      else if (_isLastChunk) {
+        if (readLength == 0)
+          return -1;
+        else {
+          _chunkLength = END_OF_DATA;
+          return readLength;
+        }
+      }
+      else {
+        int tag = read();
+
+        switch (tag) {
+        case 'B':
+        case 'b':
+          _isLastChunk = tag == 'B';
+          _chunkLength = (read() << 8) + read();
+          break;
+      
+        default:
+          throw new IOException("expected 'B' at " + (char) tag);
+        }
+      }
+    }
+    
+    if (readLength == 0)
+      return -1;
+    else if (_chunkLength > 0 || ! _isLastChunk)
+      return readLength;
+    else {
+      _chunkLength = END_OF_DATA;
+      return readLength;
+    }
+  }
+
+  /**
+   * Reads a fault.
+   */
+  private HashMap readFault()
+    throws IOException
+  {
+    HashMap map = new HashMap();
+
+    int code = read();
+    for (; code > 0 && code != 'z'; code = read()) {
+      _peek = code;
+      
+      Object key = readObject();
+      Object value = readObject();
+
+      if (key != null && value != null)
+        map.put(key, value);
+    }
+
+    if (code != 'z')
+      throw expect("fault", code);
+
+    return map;
+  }
+
+  /**
+   * Reads an object from the input stream with an expected type.
+   */
+  public Object readObject(Class cl)
+    throws IOException
+  {
+    if (cl == null || cl == Object.class)
+      return readObject();
+    
+    int tag = read();
+    
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'M':
+    {
+      String type = readType();
+
+      // hessian/3386
+      if ("".equals(type)) {
+	Deserializer reader;
+	reader = _serializerFactory.getDeserializer(cl);
+
+	return reader.readMap(this);
+      }
+      else {
+	Deserializer reader;
+	reader = _serializerFactory.getObjectDeserializer(type);
+
+        return reader.readMap(this);
+      }
+    }
+
+    case 'V':
+    {
+      String type = readType();
+      int length = readLength();
+      
+      Deserializer reader;
+      reader = _serializerFactory.getObjectDeserializer(type);
+      
+      if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))
+        return reader.readList(this, length);
+
+      reader = _serializerFactory.getDeserializer(cl);
+
+      Object v = reader.readList(this, length);
+
+      return v;
+    }
+
+    case 'R':
+    {
+      int ref = parseInt();
+
+      return _refs.get(ref);
+    }
+
+    case 'r':
+    {
+      String type = readType();
+      String url = readString();
+
+      return resolveRemote(type, url);
+    }
+    }
+
+    _peek = tag;
+
+    // hessian/332i vs hessian/3406
+    //return readObject();
+    
+    Object value = _serializerFactory.getDeserializer(cl).readObject(this);
+
+    return value;
+  }
+  
+  /**
+   * Reads an arbitrary object from the input stream when the type
+   * is unknown.
+   */
+  public Object readObject()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+      
+    case 'T':
+      return Boolean.valueOf(true);
+      
+    case 'F':
+      return Boolean.valueOf(false);
+      
+    case 'I':
+      return Integer.valueOf(parseInt());
+    
+    case 'L':
+      return Long.valueOf(parseLong());
+    
+    case 'D':
+      return Double.valueOf(parseDouble());
+    
+    case 'd':
+      return new Date(parseLong());
+    
+    case 'x':
+    case 'X': {
+      _isLastChunk = tag == 'X';
+      _chunkLength = (read() << 8) + read();
+
+      return parseXML();
+    }
+
+    case 's':
+    case 'S': {
+      _isLastChunk = tag == 'S';
+      _chunkLength = (read() << 8) + read();
+
+      int data;
+      _sbuf.setLength(0);
+      
+      while ((data = parseChar()) >= 0)
+        _sbuf.append((char) data);
+
+      return _sbuf.toString();
+    }
+
+    case 'b':
+    case 'B': {
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+
+      int data;
+      ByteArrayOutputStream bos = new ByteArrayOutputStream();
+      
+      while ((data = parseByte()) >= 0)
+        bos.write(data);
+
+      return bos.toByteArray();
+    }
+
+    case 'V': {
+      String type = readType();
+      int length = readLength();
+
+      return _serializerFactory.readList(this, length, type);
+    }
+
+    case 'M': {
+      String type = readType();
+
+      return _serializerFactory.readMap(this, type);
+    }
+
+    case 'R': {
+      int ref = parseInt();
+
+      return _refs.get(ref);
+    }
+
+    case 'r': {
+      String type = readType();
+      String url = readString();
+
+      return resolveRemote(type, url);
+    }
+
+    default:
+      throw error("unknown code for readObject at " + codeName(tag));
+    }
+  }
+
+  /**
+   * Reads a remote object.
+   */
+  public Object readRemote()
+    throws IOException
+  {
+    String type = readType();
+    String url = readString();
+
+    return resolveRemote(type, url);
+  }
+
+  /**
+   * Reads a reference.
+   */
+  public Object readRef()
+    throws IOException
+  {
+    return _refs.get(parseInt());
+  }
+
+  /**
+   * Reads the start of a list.
+   */
+  public int readListStart()
+    throws IOException
+  {
+    return read();
+  }
+
+  /**
+   * Reads the start of a list.
+   */
+  public int readMapStart()
+    throws IOException
+  {
+    return read();
+  }
+
+  /**
+   * Returns true if this is the end of a list or a map.
+   */
+  public boolean isEnd()
+    throws IOException
+  {
+    int code = read();
+
+    _peek = code;
+
+    return (code < 0 || code == 'z');
+  }
+
+  /**
+   * Reads the end byte.
+   */
+  public void readEnd()
+    throws IOException
+  {
+    int code = read();
+
+    if (code != 'z')
+      throw error("unknown code at " + codeName(code));
+  }
+
+  /**
+   * Reads the end byte.
+   */
+  public void readMapEnd()
+    throws IOException
+  {
+    int code = read();
+
+    if (code != 'z')
+      throw error("expected end of map ('z') at " + codeName(code));
+  }
+
+  /**
+   * Reads the end byte.
+   */
+  public void readListEnd()
+    throws IOException
+  {
+    int code = read();
+
+    if (code != 'z')
+      throw error("expected end of list ('z') at " + codeName(code));
+  }
+
+  /**
+   * Adds a list/map reference.
+   */
+  public int addRef(Object ref)
+  {
+    if (_refs == null)
+      _refs = new ArrayList();
+    
+    _refs.add(ref);
+
+    return _refs.size() - 1;
+  }
+
+  /**
+   * Adds a list/map reference.
+   */
+  public void setRef(int i, Object ref)
+  {
+    _refs.set(i, ref);
+  }
+
+  /**
+   * Resets the references for streaming.
+   */
+  public void resetReferences()
+  {
+    if (_refs != null)
+      _refs.clear();
+  }
+
+  /**
+   * Resolves a remote object.
+   */
+  public Object resolveRemote(String type, String url)
+    throws IOException
+  {
+    HessianRemoteResolver resolver = getRemoteResolver();
+
+    if (resolver != null)
+      return resolver.lookup(type, url);
+    else
+      return new HessianRemote(type, url);
+  }
+
+  /**
+   * Parses a type from the stream.
+   *
+   * <pre>
+   * t b16 b8
+   * </pre>
+   */
+  public String readType()
+    throws IOException
+  {
+    int code = read();
+
+    if (code != 't') {
+      _peek = code;
+      return "";
+    }
+
+    _isLastChunk = true;
+    _chunkLength = (read() << 8) + read();
+
+    _sbuf.setLength(0);
+    int ch;
+    while ((ch = parseChar()) >= 0)
+      _sbuf.append((char) ch);
+
+    return _sbuf.toString();
+  }
+
+  /**
+   * Parses the length for an array
+   *
+   * <pre>
+   * l b32 b24 b16 b8
+   * </pre>
+   */
+  public int readLength()
+    throws IOException
+  {
+    int code = read();
+
+    if (code != 'l') {
+      _peek = code;
+      return -1;
+    }
+
+    return parseInt();
+  }
+
+  /**
+   * Parses a 32-bit integer value from the stream.
+   *
+   * <pre>
+   * b32 b24 b16 b8
+   * </pre>
+   */
+  private int parseInt()
+    throws IOException
+  {
+    int b32 = read();
+    int b24 = read();
+    int b16 = read();
+    int b8 = read();
+
+    return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
+  }
+
+  /**
+   * Parses a 64-bit long value from the stream.
+   *
+   * <pre>
+   * b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  private long parseLong()
+    throws IOException
+  {
+    long b64 = read();
+    long b56 = read();
+    long b48 = read();
+    long b40 = read();
+    long b32 = read();
+    long b24 = read();
+    long b16 = read();
+    long b8 = read();
+
+    return ((b64 << 56) +
+            (b56 << 48) +
+            (b48 << 40) +
+            (b40 << 32) +
+            (b32 << 24) +
+            (b24 << 16) +
+            (b16 << 8) +
+            b8);
+  }
+  
+  /**
+   * Parses a 64-bit double value from the stream.
+   *
+   * <pre>
+   * b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre>
+   */
+  private double parseDouble()
+    throws IOException
+  {
+    long b64 = read();
+    long b56 = read();
+    long b48 = read();
+    long b40 = read();
+    long b32 = read();
+    long b24 = read();
+    long b16 = read();
+    long b8 = read();
+
+    long bits = ((b64 << 56) +
+                 (b56 << 48) +
+                 (b48 << 40) +
+                 (b40 << 32) +
+                 (b32 << 24) +
+                 (b24 << 16) +
+                 (b16 << 8) +
+                 b8);
+  
+    return Double.longBitsToDouble(bits);
+  }
+
+  org.w3c.dom.Node parseXML()
+    throws IOException
+  {
+    throw new UnsupportedOperationException();
+  }
+  
+  /**
+   * Reads a character from the underlying stream.
+   */
+  private int parseChar()
+    throws IOException
+  {
+    while (_chunkLength <= 0) {
+      if (_isLastChunk)
+        return -1;
+
+      int code = read();
+
+      switch (code) {
+      case 's':
+      case 'x':
+        _isLastChunk = false;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+        
+      case 'S':
+      case 'X':
+        _isLastChunk = true;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+
+      default:
+        throw expect("string", code);
+      }
+
+    }
+
+    _chunkLength--;
+
+    return parseUTF8Char();
+  }
+
+  /**
+   * Parses a single UTF8 character.
+   */
+  private int parseUTF8Char()
+    throws IOException
+  {
+    int ch = read();
+
+    if (ch < 0x80)
+      return ch;
+    else if ((ch & 0xe0) == 0xc0) {
+      int ch1 = read();
+      int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);
+
+      return v;
+    }
+    else if ((ch & 0xf0) == 0xe0) {
+      int ch1 = read();
+      int ch2 = read();
+      int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f);
+
+      return v;
+    }
+    else
+      throw error("bad utf-8 encoding at " + codeName(ch));
+  }
+  
+  /**
+   * Reads a byte from the underlying stream.
+   */
+  private int parseByte()
+    throws IOException
+  {
+    while (_chunkLength <= 0) {
+      if (_isLastChunk) {
+        return -1;
+      }
+
+      int code = read();
+
+      switch (code) {
+      case 'b':
+        _isLastChunk = false;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+        
+      case 'B':
+        _isLastChunk = true;
+
+        _chunkLength = (read() << 8) + read();
+        break;
+
+      default:
+        throw expect("byte[]", code);
+      }
+    }
+
+    _chunkLength--;
+
+    return read();
+  }
+
+  /**
+   * Reads bytes based on an input stream.
+   */
+  public InputStream readInputStream()
+    throws IOException
+  {
+    int tag = read();
+
+    switch (tag) {
+    case 'N':
+      return null;
+
+    case 'B':
+    case 'b':
+      _isLastChunk = tag == 'B';
+      _chunkLength = (read() << 8) + read();
+      break;
+      
+    default:
+      throw expect("inputStream", tag);
+    }
+    
+    return new InputStream() {
+	boolean _isClosed = false;
+	
+	public int read()
+	  throws IOException
+	{
+	  if (_isClosed || _is == null)
+	    return -1;
+
+	  int ch = parseByte();
+	  if (ch < 0)
+	    _isClosed = true;
+
+	  return ch;
+	}
+	
+	public int read(byte []buffer, int offset, int length)
+	  throws IOException
+	{
+	  if (_isClosed || _is == null)
+	    return -1;
+
+	  int len = HessianInput.this.read(buffer, offset, length);
+	  if (len < 0)
+	    _isClosed = true;
+
+	  return len;
+	}
+
+	public void close()
+	  throws IOException
+	{
+	  while (read() >= 0) {
+	  }
+
+	  _isClosed = true;
+	}
+      };
+  }
+  
+  /**
+   * Reads bytes from the underlying stream.
+   */
+  int read(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    int readLength = 0;
+    
+    while (length > 0) {
+      while (_chunkLength <= 0) {
+        if (_isLastChunk)
+          return readLength == 0 ? -1 : readLength;
+
+        int code = read();
+
+        switch (code) {
+        case 'b':
+          _isLastChunk = false;
+
+          _chunkLength = (read() << 8) + read();
+          break;
+        
+        case 'B':
+          _isLastChunk = true;
+
+          _chunkLength = (read() << 8) + read();
+          break;
+
+        default:
+          throw expect("byte[]", code);
+        }
+      }
+
+      int sublen = _chunkLength;
+      if (length < sublen)
+        sublen = length;
+
+      sublen = _is.read(buffer, offset, sublen);
+      offset += sublen;
+      readLength += sublen;
+      length -= sublen;
+      _chunkLength -= sublen;
+    }
+
+    return readLength;
+  }
+
+  final int read()
+    throws IOException
+  {
+    if (_peek >= 0) {
+      int value = _peek;
+      _peek = -1;
+      return value;
+    }
+
+    int ch = _is.read();
+      
+    return ch;
+  }
+
+  public void close()
+  {
+    _is = null;
+  }
+
+  public Reader getReader()
+  {
+    return null;
+  }
+
+  protected IOException expect(String expect, int ch)
+  {
+    return error("expected " + expect + " at " + codeName(ch));
+  }
+
+  protected String codeName(int ch)
+  {
+    if (ch < 0)
+      return "end of file";
+    else
+      return "0x" + Integer.toHexString(ch & 0xff) + " (" + (char) + ch + ")";
+  }
+  
+  protected IOException error(String message)
+  {
+    if (_method != null)
+      return new HessianProtocolException(_method + ": " + message);
+    else
+      return new HessianProtocolException(message);
+  }
+
+  static {
+    try {
+      _detailMessageField = Throwable.class.getDeclaredField("detailMessage");
+      _detailMessageField.setAccessible(true);
+    } catch (Throwable e) {
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/HessianInputFactory.java src/com/caucho/hessian/io/HessianInputFactory.java
new file mode 100644
index 0000000..e09ecbd
--- /dev/null
+++ src/com/caucho/hessian/io/HessianInputFactory.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.util.logging.*;
+import java.io.*;
+
+public class HessianInputFactory
+{
+  public static final Logger log
+    = Logger.getLogger(HessianInputFactory.class.getName());
+
+  private SerializerFactory _serializerFactory;
+
+  public void setSerializerFactory(SerializerFactory factory)
+  {
+    _serializerFactory = factory;
+  }
+
+  public SerializerFactory getSerializerFactory()
+  {
+    return _serializerFactory;
+  }
+
+  public AbstractHessianInput open(InputStream is)
+    throws IOException
+  {
+    int code = is.read();
+
+    int major = is.read();
+    int minor = is.read();
+
+    switch (code) {
+    case 'c':
+    case 'C':
+    case 'r':
+    case 'R':
+      if (major >= 2) {
+	AbstractHessianInput in = new Hessian2Input(is);
+	in.setSerializerFactory(_serializerFactory);
+	return in;
+      }
+      else {
+	AbstractHessianInput in = new HessianInput(is);
+	in.setSerializerFactory(_serializerFactory);
+	return in;
+      }
+
+    default:
+      throw new IOException((char) code + " is an unknown Hessian message code.");
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/HessianOutput.java src/com/caucho/hessian/io/HessianOutput.java
new file mode 100644
index 0000000..63d6377
--- /dev/null
+++ src/com/caucho/hessian/io/HessianOutput.java
@@ -0,0 +1,949 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.IdentityHashMap;
+
+/**
+ * Output stream for Hessian requests, compatible with microedition
+ * Java.  It only uses classes and types available in JDK.
+ *
+ * <p>Since HessianOutput does not depend on any classes other than
+ * in the JDK, it can be extracted independently into a smaller package.
+ *
+ * <p>HessianOutput is unbuffered, so any client needs to provide
+ * its own buffering.
+ *
+ * <pre>
+ * OutputStream os = ...; // from http connection
+ * HessianOutput out = new HessianOutput(os);
+ * String value;
+ *
+ * out.startCall("hello");  // start hello call
+ * out.writeString("arg1"); // write a string argument
+ * out.completeCall();      // complete the call
+ * </pre>
+ */
+public class HessianOutput extends AbstractHessianOutput {
+  // the output stream/
+  protected OutputStream os;
+  // map of references
+  private IdentityHashMap _refs;
+  private int _version = 1;
+  
+  /**
+   * Creates a new Hessian output stream, initialized with an
+   * underlying output stream.
+   *
+   * @param os the underlying output stream.
+   */
+  public HessianOutput(OutputStream os)
+  {
+    init(os);
+  }
+
+  /**
+   * Creates an uninitialized Hessian output stream.
+   */
+  public HessianOutput()
+  {
+  }
+
+  /**
+   * Initializes the output
+   */
+  public void init(OutputStream os)
+  {
+    this.os = os;
+
+    _refs = null;
+
+    if (_serializerFactory == null)
+      _serializerFactory = new SerializerFactory();
+  }
+
+  /**
+   * Sets the client's version.
+   */
+  public void setVersion(int version)
+  {
+    _version = version;
+  }
+
+  /**
+   * Writes a complete method call.
+   */
+  public void call(String method, Object []args)
+    throws IOException
+  {
+    startCall(method);
+    
+    if (args != null) {
+      for (int i = 0; i < args.length; i++)
+        writeObject(args[i]);
+    }
+    
+    completeCall();
+  }
+
+  /**
+   * Starts the method call.  Clients would use <code>startCall</code>
+   * instead of <code>call</code> if they wanted finer control over
+   * writing the arguments, or needed to write headers.
+   *
+   * <code><pre>
+   * c major minor
+   * m b16 b8 method-name
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void startCall(String method)
+    throws IOException
+  {
+    os.write('c');
+    os.write(_version);
+    os.write(0);
+
+    os.write('m');
+    int len = method.length();
+    os.write(len >> 8);
+    os.write(len);
+    printString(method, 0, len);
+  }
+
+  /**
+   * Writes the call tag.  This would be followed by the
+   * headers and the method tag.
+   *
+   * <code><pre>
+   * c major minor
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void startCall()
+    throws IOException
+  {
+    os.write('c');
+    os.write(0);
+    os.write(1);
+  }
+
+  /**
+   * Writes the method tag.
+   *
+   * <code><pre>
+   * m b16 b8 method-name
+   * </pre></code>
+   *
+   * @param method the method name to call.
+   */
+  public void writeMethod(String method)
+    throws IOException
+  {
+    os.write('m');
+    int len = method.length();
+    os.write(len >> 8);
+    os.write(len);
+    printString(method, 0, len);
+  }
+
+  /**
+   * Completes.
+   *
+   * <code><pre>
+   * z
+   * </pre></code>
+   */
+  public void completeCall()
+    throws IOException
+  {
+    os.write('z');
+  }
+
+  /**
+   * Starts the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * r
+   * </pre>
+   */
+  public void startReply()
+    throws IOException
+  {
+    os.write('r');
+    os.write(1);
+    os.write(0);
+  }
+
+  /**
+   * Completes reading the reply
+   *
+   * <p>A successful completion will have a single value:
+   *
+   * <pre>
+   * z
+   * </pre>
+   */
+  public void completeReply()
+    throws IOException
+  {
+    os.write('z');
+  }
+
+  /**
+   * Writes a header name.  The header value must immediately follow.
+   *
+   * <code><pre>
+   * H b16 b8 foo <em>value</em>
+   * </pre></code>
+   */
+  public void writeHeader(String name)
+    throws IOException
+  {
+    int len = name.length();
+    
+    os.write('H');
+    os.write(len >> 8);
+    os.write(len);
+
+    printString(name);
+  }
+
+  /**
+   * Writes a fault.  The fault will be written
+   * as a descriptive string followed by an object:
+   *
+   * <code><pre>
+   * f
+   * &lt;string>code
+   * &lt;string>the fault code
+   *
+   * &lt;string>message
+   * &lt;string>the fault mesage
+   *
+   * &lt;string>detail
+   * mt\x00\xnnjavax.ejb.FinderException
+   *     ...
+   * z
+   * z
+   * </pre></code>
+   *
+   * @param code the fault code, a three digit
+   */
+  public void writeFault(String code, String message, Object detail)
+    throws IOException
+  {
+    os.write('f');
+    writeString("code");
+    writeString(code);
+
+    writeString("message");
+    writeString(message);
+
+    if (detail != null) {
+      writeString("detail");
+      writeObject(detail);
+    }
+    os.write('z');
+  }
+
+  /**
+   * Writes any object to the output stream.
+   */
+  public void writeObject(Object object)
+    throws IOException
+  {
+    if (object == null) {
+      writeNull();
+      return;
+    }
+
+    Serializer serializer;
+
+    serializer = _serializerFactory.getSerializer(object.getClass());
+
+    serializer.writeObject(object, this);
+  }
+
+  /**
+   * Writes the list header to the stream.  List writers will call
+   * <code>writeListBegin</code> followed by the list contents and then
+   * call <code>writeListEnd</code>.
+   *
+   * <code><pre>
+   * V
+   * t b16 b8 type
+   * l b32 b24 b16 b8
+   * </pre></code>
+   */
+  public boolean writeListBegin(int length, String type)
+    throws IOException
+  {
+    os.write('V');
+
+    if (type != null) {
+      os.write('t');
+      printLenString(type);
+    }
+
+    if (length >= 0) {
+      os.write('l');
+      os.write(length >> 24);
+      os.write(length >> 16);
+      os.write(length >> 8);
+      os.write(length);
+    }
+
+    return true;
+  }
+
+  /**
+   * Writes the tail of the list to the stream.
+   */
+  public void writeListEnd()
+    throws IOException
+  {
+    os.write('z');
+  }
+
+  /**
+   * Writes the map header to the stream.  Map writers will call
+   * <code>writeMapBegin</code> followed by the map contents and then
+   * call <code>writeMapEnd</code>.
+   *
+   * <code><pre>
+   * Mt b16 b8 (<key> <value>)z
+   * </pre></code>
+   */
+  public void writeMapBegin(String type)
+    throws IOException
+  {
+    os.write('M');
+    os.write('t');
+    printLenString(type);
+  }
+
+  /**
+   * Writes the tail of the map to the stream.
+   */
+  public void writeMapEnd()
+    throws IOException
+  {
+    os.write('z');
+  }
+
+  /**
+   * Writes a remote object reference to the stream.  The type is the
+   * type of the remote interface.
+   *
+   * <code><pre>
+   * 'r' 't' b16 b8 type url
+   * </pre></code>
+   */
+  public void writeRemote(String type, String url)
+    throws IOException
+  {
+    os.write('r');
+    os.write('t');
+    printLenString(type);
+    os.write('S');
+    printLenString(url);
+  }
+
+  /**
+   * Writes a boolean value to the stream.  The boolean will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * T
+   * F
+   * </pre></code>
+   *
+   * @param value the boolean value to write.
+   */
+  public void writeBoolean(boolean value)
+    throws IOException
+  {
+    if (value)
+      os.write('T');
+    else
+      os.write('F');
+  }
+
+  /**
+   * Writes an integer value to the stream.  The integer will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * I b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the integer value to write.
+   */
+  public void writeInt(int value)
+    throws IOException
+  {
+    os.write('I');
+    os.write(value >> 24);
+    os.write(value >> 16);
+    os.write(value >> 8);
+    os.write(value);
+  }
+
+  /**
+   * Writes a long value to the stream.  The long will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * L b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the long value to write.
+   */
+  public void writeLong(long value)
+    throws IOException
+  {
+    os.write('L');
+    os.write((byte) (value >> 56));
+    os.write((byte) (value >> 48));
+    os.write((byte) (value >> 40));
+    os.write((byte) (value >> 32));
+    os.write((byte) (value >> 24));
+    os.write((byte) (value >> 16));
+    os.write((byte) (value >> 8));
+    os.write((byte) (value));
+  }
+
+  /**
+   * Writes a double value to the stream.  The double will be written
+   * with the following syntax:
+   *
+   * <code><pre>
+   * D b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the double value to write.
+   */
+  public void writeDouble(double value)
+    throws IOException
+  {
+    long bits = Double.doubleToLongBits(value);
+    
+    os.write('D');
+    os.write((byte) (bits >> 56));
+    os.write((byte) (bits >> 48));
+    os.write((byte) (bits >> 40));
+    os.write((byte) (bits >> 32));
+    os.write((byte) (bits >> 24));
+    os.write((byte) (bits >> 16));
+    os.write((byte) (bits >> 8));
+    os.write((byte) (bits));
+  }
+
+  /**
+   * Writes a date to the stream.
+   *
+   * <code><pre>
+   * T  b64 b56 b48 b40 b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param time the date in milliseconds from the epoch in UTC
+   */
+  public void writeUTCDate(long time)
+    throws IOException
+  {
+    os.write('d');
+    os.write((byte) (time >> 56));
+    os.write((byte) (time >> 48));
+    os.write((byte) (time >> 40));
+    os.write((byte) (time >> 32));
+    os.write((byte) (time >> 24));
+    os.write((byte) (time >> 16));
+    os.write((byte) (time >> 8));
+    os.write((byte) (time));
+  }
+
+  /**
+   * Writes a null value to the stream.
+   * The null will be written with the following syntax
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeNull()
+    throws IOException
+  {
+    os.write('N');
+  }
+
+  /**
+   * Writes a string value to the stream using UTF-8 encoding.
+   * The string will be written with the following syntax:
+   *
+   * <code><pre>
+   * S b16 b8 string-value
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeString(String value)
+    throws IOException
+  {
+    if (value == null) {
+      os.write('N');
+    }
+    else {
+      int length = value.length();
+      int offset = 0;
+      
+      while (length > 0x8000) {
+        int sublen = 0x8000;
+
+	// chunk can't end in high surrogate
+	char tail = value.charAt(offset + sublen - 1);
+
+	if (0xd800 <= tail && tail <= 0xdbff)
+	  sublen--;
+        
+        os.write('s');
+        os.write(sublen >> 8);
+        os.write(sublen);
+
+        printString(value, offset, sublen);
+
+        length -= sublen;
+        offset += sublen;
+      }
+
+      os.write('S');
+      os.write(length >> 8);
+      os.write(length);
+
+      printString(value, offset, length);
+    }
+  }
+
+  /**
+   * Writes a string value to the stream using UTF-8 encoding.
+   * The string will be written with the following syntax:
+   *
+   * <code><pre>
+   * S b16 b8 string-value
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeString(char []buffer, int offset, int length)
+    throws IOException
+  {
+    if (buffer == null) {
+      os.write('N');
+    }
+    else {
+      while (length > 0x8000) {
+        int sublen = 0x8000;
+
+	// chunk can't end in high surrogate
+	char tail = buffer[offset + sublen - 1];
+
+	if (0xd800 <= tail && tail <= 0xdbff)
+	  sublen--;
+        
+        os.write('s');
+        os.write(sublen >> 8);
+        os.write(sublen);
+
+        printString(buffer, offset, sublen);
+
+        length -= sublen;
+        offset += sublen;
+      }
+
+      os.write('S');
+      os.write(length >> 8);
+      os.write(length);
+
+      printString(buffer, offset, length);
+    }
+  }
+
+  /**
+   * Writes a byte array to the stream.
+   * The array will be written with the following syntax:
+   *
+   * <code><pre>
+   * B b16 b18 bytes
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeBytes(byte []buffer)
+    throws IOException
+  {
+    if (buffer == null)
+      os.write('N');
+    else
+      writeBytes(buffer, 0, buffer.length);
+  }
+  
+  /**
+   * Writes a byte array to the stream.
+   * The array will be written with the following syntax:
+   *
+   * <code><pre>
+   * B b16 b18 bytes
+   * </pre></code>
+   *
+   * If the value is null, it will be written as
+   *
+   * <code><pre>
+   * N
+   * </pre></code>
+   *
+   * @param value the string value to write.
+   */
+  public void writeBytes(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    if (buffer == null) {
+      os.write('N');
+    }
+    else {
+      while (length > 0x8000) {
+        int sublen = 0x8000;
+        
+        os.write('b');
+        os.write(sublen >> 8);
+        os.write(sublen);
+
+        os.write(buffer, offset, sublen);
+
+        length -= sublen;
+        offset += sublen;
+      }
+
+      os.write('B');
+      os.write(length >> 8);
+      os.write(length);
+      os.write(buffer, offset, length);
+    }
+  }
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * </pre></code>
+   */
+  public void writeByteBufferStart()
+    throws IOException
+  {
+  }
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * b b16 b18 bytes
+   * </pre></code>
+   */
+  public void writeByteBufferPart(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    while (length > 0) {
+      int sublen = length;
+
+      if (0x8000 < sublen)
+	sublen = 0x8000;
+
+      os.write('b');
+      os.write(sublen >> 8);
+      os.write(sublen);
+
+      os.write(buffer, offset, sublen);
+
+      length -= sublen;
+      offset += sublen;
+    }
+  }
+  
+  /**
+   * Writes a byte buffer to the stream.
+   *
+   * <code><pre>
+   * b b16 b18 bytes
+   * </pre></code>
+   */
+  public void writeByteBufferEnd(byte []buffer, int offset, int length)
+    throws IOException
+  {
+    writeBytes(buffer, offset, length);
+  }
+
+  /**
+   * Writes a reference.
+   *
+   * <code><pre>
+   * R b32 b24 b16 b8
+   * </pre></code>
+   *
+   * @param value the integer value to write.
+   */
+  public void writeRef(int value)
+    throws IOException
+  {
+    os.write('R');
+    os.write(value >> 24);
+    os.write(value >> 16);
+    os.write(value >> 8);
+    os.write(value);
+  }
+
+  /**
+   * Writes a placeholder.
+   *
+   * <code><pre>
+   * P
+   * </pre></code>
+   */
+  public void writePlaceholder()
+    throws IOException
+  {
+    os.write('P');
+  }
+
+  /**
+   * If the object has already been written, just write its ref.
+   *
+   * @return true if we're writing a ref.
+   */
+  public boolean addRef(Object object)
+    throws IOException
+  {
+    if (_refs == null)
+      _refs = new IdentityHashMap();
+
+    Integer ref = (Integer) _refs.get(object);
+
+    if (ref != null) {
+      int value = ref.intValue();
+      
+      writeRef(value);
+      return true;
+    }
+    else {
+      _refs.put(object, new Integer(_refs.size()));
+      
+      return false;
+    }
+  }
+
+  /**
+   * Resets the references for streaming.
+   */
+  public void resetReferences()
+  {
+    if (_refs != null)
+      _refs.clear();
+  }
+
+  /**
+   * Removes a reference.
+   */
+  public boolean removeRef(Object obj)
+    throws IOException
+  {
+    if (_refs != null) {
+      _refs.remove(obj);
+
+      return true;
+    }
+    else
+      return false;
+  }
+
+  /**
+   * Replaces a reference from one object to another.
+   */
+  public boolean replaceRef(Object oldRef, Object newRef)
+    throws IOException
+  {
+    Integer value = (Integer) _refs.remove(oldRef);
+
+    if (value != null) {
+      _refs.put(newRef, value);
+      return true;
+    }
+    else
+      return false;
+  }
+
+  /**
+   * Prints a string to the stream, encoded as UTF-8 with preceeding length
+   *
+   * @param v the string to print.
+   */
+  public void printLenString(String v)
+    throws IOException
+  {
+    if (v == null) {
+      os.write(0);
+      os.write(0);
+    }
+    else {
+      int len = v.length();
+      os.write(len >> 8);
+      os.write(len);
+
+      printString(v, 0, len);
+    }
+  }
+
+  /**
+   * Prints a string to the stream, encoded as UTF-8
+   *
+   * @param v the string to print.
+   */
+  public void printString(String v)
+    throws IOException
+  {
+    printString(v, 0, v.length());
+  }
+  
+  /**
+   * Prints a string to the stream, encoded as UTF-8
+   *
+   * @param v the string to print.
+   */
+  public void printString(String v, int offset, int length)
+    throws IOException
+  {
+    for (int i = 0; i < length; i++) {
+      char ch = v.charAt(i + offset);
+
+      if (ch < 0x80)
+        os.write(ch);
+      else if (ch < 0x800) {
+        os.write(0xc0 + ((ch >> 6) & 0x1f));
+        os.write(0x80 + (ch & 0x3f));
+      }
+      else {
+        os.write(0xe0 + ((ch >> 12) & 0xf));
+        os.write(0x80 + ((ch >> 6) & 0x3f));
+        os.write(0x80 + (ch & 0x3f));
+      }
+    }
+  }
+  
+  /**
+   * Prints a string to the stream, encoded as UTF-8
+   *
+   * @param v the string to print.
+   */
+  public void printString(char []v, int offset, int length)
+    throws IOException
+  {
+    for (int i = 0; i < length; i++) {
+      char ch = v[i + offset];
+
+      if (ch < 0x80)
+        os.write(ch);
+      else if (ch < 0x800) {
+        os.write(0xc0 + ((ch >> 6) & 0x1f));
+        os.write(0x80 + (ch & 0x3f));
+      }
+      else {
+        os.write(0xe0 + ((ch >> 12) & 0xf));
+        os.write(0x80 + ((ch >> 6) & 0x3f));
+        os.write(0x80 + (ch & 0x3f));
+      }
+    }
+  }
+
+  public void flush()
+    throws IOException
+  {
+    if (this.os != null)
+      this.os.flush();
+  }
+
+  public void close()
+    throws IOException
+  {
+    if (this.os != null)
+      this.os.flush();
+  }
+}
diff --git src/com/caucho/hessian/io/HessianProtocolException.java src/com/caucho/hessian/io/HessianProtocolException.java
new file mode 100644
index 0000000..94810a1
--- /dev/null
+++ src/com/caucho/hessian/io/HessianProtocolException.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Exception for faults when the fault doesn't return a java exception.
+ * This exception is required for MicroHessianInput.
+ */
+public class HessianProtocolException extends IOException {
+  private Throwable rootCause;
+  
+  /**
+   * Zero-arg constructor.
+   */
+  public HessianProtocolException()
+  {
+  }
+  
+  /**
+   * Create the exception.
+   */
+  public HessianProtocolException(String message)
+  {
+    super(message);
+  }
+  
+  /**
+   * Create the exception.
+   */
+  public HessianProtocolException(String message, Throwable rootCause)
+  {
+    super(message);
+
+    this.rootCause = rootCause;
+  }
+  
+  /**
+   * Create the exception.
+   */
+  public HessianProtocolException(Throwable rootCause)
+  {
+    super(String.valueOf(rootCause));
+
+    this.rootCause = rootCause;
+  }
+
+  /**
+   * Returns the underlying cause.
+   */
+  public Throwable getRootCause()
+  {
+    return rootCause;
+  }
+
+  /**
+   * Returns the underlying cause.
+   */
+  public Throwable getCause()
+  {
+    return getRootCause();
+  }
+}
diff --git src/com/caucho/hessian/io/HessianRemote.java src/com/caucho/hessian/io/HessianRemote.java
new file mode 100644
index 0000000..915c365
--- /dev/null
+++ src/com/caucho/hessian/io/HessianRemote.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+/**
+ * Encapsulates a remote address when no stub is available, e.g. for
+ * Java MicroEdition.
+ */
+public class HessianRemote {
+  private String type;
+  private String url;
+
+  /**
+   * Creates a new Hessian remote object.
+   *
+   * @param type the remote stub interface
+   * @param url the remote url
+   */
+  public HessianRemote(String type, String url)
+  {
+    this.type = type;
+    this.url = url;
+  }
+
+  /**
+   * Creates an uninitialized Hessian remote.
+   */
+  public HessianRemote()
+  {
+  }
+
+  /**
+   * Returns the remote api class name.
+   */
+  public String getType()
+  {
+    return type;
+  }
+
+  /**
+   * Returns the remote URL.
+   */
+  public String getURL()
+  {
+    return url;
+  }
+
+  /**
+   * Sets the remote URL.
+   */
+  public void setURL(String url)
+  {
+    this.url = url;
+  }
+
+  /**
+   * Defines the hashcode.
+   */
+  public int hashCode()
+  {
+    return url.hashCode();
+  }
+
+  /**
+   * Defines equality
+   */
+  public boolean equals(Object obj)
+  {
+    if (! (obj instanceof HessianRemote))
+      return false;
+
+    HessianRemote remote = (HessianRemote) obj;
+
+    return url.equals(remote.url);
+  }
+
+  /**
+   * Readable version of the remote.
+   */
+  public String toString()
+  {
+    return "[HessianRemote " + url + "]";
+  }
+}
diff --git src/com/caucho/hessian/io/HessianRemoteObject.java src/com/caucho/hessian/io/HessianRemoteObject.java
new file mode 100644
index 0000000..26deb08
--- /dev/null
+++ src/com/caucho/hessian/io/HessianRemoteObject.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+/**
+ * Interface for any hessian remote object.
+ */
+public interface HessianRemoteObject {
+  public String getHessianType();
+  public String getHessianURL();
+}
diff --git src/com/caucho/hessian/io/HessianRemoteResolver.java src/com/caucho/hessian/io/HessianRemoteResolver.java
new file mode 100644
index 0000000..222ee9e
--- /dev/null
+++ src/com/caucho/hessian/io/HessianRemoteResolver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Looks up remote objects.  The default just returns a HessianRemote object.
+ */
+public interface HessianRemoteResolver {
+  /**
+   * Looks up a proxy object.
+   */
+  public Object lookup(String type, String url)
+    throws IOException;
+}
diff --git src/com/caucho/hessian/io/HessianSerializerInput.java src/com/caucho/hessian/io/HessianSerializerInput.java
new file mode 100644
index 0000000..5b23880
--- /dev/null
+++ src/com/caucho/hessian/io/HessianSerializerInput.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Input stream for Hessian requests, deserializing objects using the
+ * java.io.Serialization protocol.
+ *
+ * <p>HessianSerializerInput is unbuffered, so any client needs to provide
+ * its own buffering.
+ *
+ * <h3>Serialization</h3>
+ *
+ * <pre>
+ * InputStream is = new FileInputStream("test.xml");
+ * HessianOutput in = new HessianSerializerOutput(is);
+ *
+ * Object obj = in.readObject();
+ * is.close();
+ * </pre>
+ *
+ * <h3>Parsing a Hessian reply</h3>
+ *
+ * <pre>
+ * InputStream is = ...; // from http connection
+ * HessianInput in = new HessianSerializerInput(is);
+ * String value;
+ *
+ * in.startReply();         // read reply header
+ * value = in.readString(); // read string value
+ * in.completeReply();      // read reply footer
+ * </pre>
+ */
+public class HessianSerializerInput extends HessianInput {
+  /**
+   * Creates a new Hessian input stream, initialized with an
+   * underlying input stream.
+   *
+   * @param is the underlying input stream.
+   */
+  public HessianSerializerInput(InputStream is)
+  {
+    super(is);
+  }
+
+  /**
+   * Creates an uninitialized Hessian input stream.
+   */
+  public HessianSerializerInput()
+  {
+  }
+
+  /**
+   * Reads an object from the input stream.  cl is known not to be
+   * a Map.
+   */
+  protected Object readObjectImpl(Class cl)
+    throws IOException
+  {
+    try {
+      Object obj = cl.newInstance();
+
+      if (_refs == null)
+        _refs = new ArrayList();
+      _refs.add(obj);
+
+      HashMap fieldMap = getFieldMap(cl);
+
+      int code = read();
+      for (; code >= 0 && code != 'z'; code = read()) {
+        _peek = code;
+        
+        Object key = readObject();
+        
+        Field field = (Field) fieldMap.get(key);
+
+        if (field != null) {
+          Object value = readObject(field.getType());
+          field.set(obj, value);
+        }
+        else {
+          Object value = readObject();
+        }
+      }
+      
+      if (code != 'z')
+        throw expect("map", code);
+
+      // if there's a readResolve method, call it
+      try {
+        Method method = cl.getMethod("readResolve", new Class[0]);
+        return method.invoke(obj, new Object[0]);
+      } catch (Exception e) {
+      }
+
+      return obj;
+    } catch (IOException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+
+  /**
+   * Creates a map of the classes fields.
+   */
+  protected HashMap getFieldMap(Class cl)
+  {
+    HashMap fieldMap = new HashMap();
+    
+    for (; cl != null; cl = cl.getSuperclass()) {
+      Field []fields = cl.getDeclaredFields();
+      for (int i = 0; i < fields.length; i++) {
+        Field field = fields[i];
+
+        if (Modifier.isTransient(field.getModifiers()) ||
+            Modifier.isStatic(field.getModifiers()))
+          continue;
+
+        // XXX: could parameterize the handler to only deal with public
+        field.setAccessible(true);
+
+        fieldMap.put(field.getName(), field);
+      }
+    }
+
+    return fieldMap;
+  }
+}
diff --git src/com/caucho/hessian/io/HessianSerializerOutput.java src/com/caucho/hessian/io/HessianSerializerOutput.java
new file mode 100644
index 0000000..2f18e6f
--- /dev/null
+++ src/com/caucho/hessian/io/HessianSerializerOutput.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Output stream for Hessian requests.
+ *
+ * <p>HessianOutput is unbuffered, so any client needs to provide
+ * its own buffering.
+ *
+ * <h3>Serialization</h3>
+ *
+ * <pre>
+ * OutputStream os = new FileOutputStream("test.xml");
+ * HessianOutput out = new HessianSerializerOutput(os);
+ *
+ * out.writeObject(obj);
+ * os.close();
+ * </pre>
+ *
+ * <h3>Writing an RPC Call</h3>
+ *
+ * <pre>
+ * OutputStream os = ...; // from http connection
+ * HessianOutput out = new HessianSerializerOutput(os);
+ * String value;
+ *
+ * out.startCall("hello");  // start hello call
+ * out.writeString("arg1"); // write a string argument
+ * out.completeCall();      // complete the call
+ * </pre>
+ */
+public class HessianSerializerOutput extends HessianOutput {
+  /**
+   * Creates a new Hessian output stream, initialized with an
+   * underlying output stream.
+   *
+   * @param os the underlying output stream.
+   */
+  public HessianSerializerOutput(OutputStream os)
+  {
+    super(os);
+  }
+
+  /**
+   * Creates an uninitialized Hessian output stream.
+   */
+  public HessianSerializerOutput()
+  {
+  }
+
+  /**
+   * Applications which override this can do custom serialization.
+   *
+   * @param object the object to write.
+   */
+  public void writeObjectImpl(Object obj)
+    throws IOException
+  {
+    Class cl = obj.getClass();
+    
+    try {
+      Method method = cl.getMethod("writeReplace", new Class[0]);
+      Object repl = method.invoke(obj, new Object[0]);
+
+      writeObject(repl);
+      return;
+    } catch (Exception e) {
+    }
+
+    try {
+      writeMapBegin(cl.getName());
+      for (; cl != null; cl = cl.getSuperclass()) {
+        Field []fields = cl.getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+          Field field = fields[i];
+
+          if (Modifier.isTransient(field.getModifiers()) ||
+              Modifier.isStatic(field.getModifiers()))
+            continue;
+
+          // XXX: could parameterize the handler to only deal with public
+          field.setAccessible(true);
+      
+          writeString(field.getName());
+          writeObject(field.get(obj));
+        }
+      }
+      writeMapEnd();
+    } catch (IllegalAccessException e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/HessianServiceException.java src/com/caucho/hessian/io/HessianServiceException.java
new file mode 100644
index 0000000..38249c6
--- /dev/null
+++ src/com/caucho/hessian/io/HessianServiceException.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+/**
+ * Exception for faults when the fault doesn't return a java exception.
+ * This exception is required for MicroHessianInput.
+ */
+public class HessianServiceException extends Exception {
+  private String code;
+  private Object detail;
+
+  /**
+   * Zero-arg constructor.
+   */
+  public HessianServiceException()
+  {
+  }
+
+  /**
+   * Create the exception.
+   */
+  public HessianServiceException(String message, String code, Object detail)
+  {
+    super(message);
+    this.code = code;
+    this.detail = detail;
+  }
+
+  /**
+   * Returns the code.
+   */
+  public String getCode()
+  {
+    return code;
+  }
+
+  /**
+   * Returns the detail.
+   */
+  public Object getDetail()
+  {
+    return detail;
+  }
+}
diff --git src/com/caucho/hessian/io/IOExceptionWrapper.java src/com/caucho/hessian/io/IOExceptionWrapper.java
new file mode 100644
index 0000000..df0073e
--- /dev/null
+++ src/com/caucho/hessian/io/IOExceptionWrapper.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Exception wrapper for IO.
+ */
+public class IOExceptionWrapper extends IOException {
+  private Throwable _cause;
+  
+  public IOExceptionWrapper(Throwable cause)
+  {
+    super(cause.toString());
+
+    _cause = cause;
+  }
+  
+  public IOExceptionWrapper(String msg, Throwable cause)
+  {
+    super(msg);
+
+    _cause = cause;
+  }
+
+  public Throwable getCause()
+  {
+    return _cause;
+  }
+}
diff --git src/com/caucho/hessian/io/InputStreamDeserializer.java src/com/caucho/hessian/io/InputStreamDeserializer.java
new file mode 100644
index 0000000..8655885
--- /dev/null
+++ src/com/caucho/hessian/io/InputStreamDeserializer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Serializing a stream object.
+ */
+public class InputStreamDeserializer extends AbstractDeserializer {
+  public InputStreamDeserializer()
+  {
+  }
+  
+  public Object readObject(AbstractHessianInput in)
+    throws IOException
+  {
+    return in.readInputStream();
+  }
+}
diff --git src/com/caucho/hessian/io/InputStreamSerializer.java src/com/caucho/hessian/io/InputStreamSerializer.java
new file mode 100644
index 0000000..9540e96
--- /dev/null
+++ src/com/caucho/hessian/io/InputStreamSerializer.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Serializing a stream object.
+ */
+public class InputStreamSerializer extends AbstractSerializer {
+  public InputStreamSerializer()
+  {
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    InputStream is = (InputStream) obj;
+
+    if (is == null)
+      out.writeNull();
+    else {
+      byte []buf = new byte[1024];
+      int len;
+
+      while ((len = is.read(buf, 0, buf.length)) > 0) {
+	out.writeByteBufferPart(buf, 0, len);
+      }
+      
+      out.writeByteBufferEnd(buf, 0, 0);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/IteratorSerializer.java src/com/caucho/hessian/io/IteratorSerializer.java
new file mode 100644
index 0000000..95ce4d7
--- /dev/null
+++ src/com/caucho/hessian/io/IteratorSerializer.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * Serializing a JDK 1.2 Iterator.
+ */
+public class IteratorSerializer extends AbstractSerializer {
+  private static IteratorSerializer _serializer;
+
+  public static IteratorSerializer create()
+  {
+    if (_serializer == null)
+      _serializer = new IteratorSerializer();
+
+    return _serializer;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    Iterator iter = (Iterator) obj;
+
+    boolean hasEnd = out.writeListBegin(-1, null);
+
+    while (iter.hasNext()) {
+      Object value = iter.next();
+
+      out.writeObject(value);
+    }
+
+    if (hasEnd)
+      out.writeListEnd();
+  }
+}
diff --git src/com/caucho/hessian/io/JavaDeserializer.java src/com/caucho/hessian/io/JavaDeserializer.java
new file mode 100644
index 0000000..2d0743a
--- /dev/null
+++ src/com/caucho/hessian/io/JavaDeserializer.java
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class JavaDeserializer extends AbstractMapDeserializer {
+  private static final Logger log = Logger.getLogger(JavaDeserializer.class.getName());
+  
+  private final static Map<Class<?>, FieldDeserializer> deserializerCache = new HashMap<Class<?>, FieldDeserializer>();
+  
+  private final Class<?> _type;
+  private Map<String, FieldDeserializer> _fieldMap;
+  private Map<String, Field> _keyFieldMap;
+  private Method _readResolve;
+  
+  private Constructor _constructor;
+  private Object []_constructorArgs;
+  
+  public JavaDeserializer(Class<?> type)
+  {
+    _type = type;
+    _keyFieldMap = new HashMap<String, Field>();
+    
+    initFieldMap(type);
+
+    _readResolve = getReadResolve(type);
+
+    if (_readResolve != null) {
+      _readResolve.setAccessible(true);
+    }
+
+    Constructor []constructors = type.getDeclaredConstructors();
+    long bestCost = Long.MAX_VALUE;
+
+    for (int i = 0; i < constructors.length; i++) {
+      Class []param = constructors[i].getParameterTypes();
+      long cost = 0;
+
+      for (int j = 0; j < param.length; j++) {
+	cost = 4 * cost;
+
+	if (Object.class.equals(param[j]))
+	  cost += 1;
+	else if (String.class.equals(param[j]))
+	  cost += 2;
+	else if (int.class.equals(param[j]))
+	  cost += 3;
+	else if (long.class.equals(param[j]))
+	  cost += 4;
+	else if (param[j].isPrimitive())
+	  cost += 5;
+	else
+	  cost += 6;
+      }
+
+      if (cost < 0 || cost > (1 << 48))
+	cost = 1 << 48;
+
+      cost += (long) param.length << 48;
+
+      if (cost < bestCost) {
+        _constructor = constructors[i];
+        bestCost = cost;
+      }
+    }
+
+    if (_constructor != null) {
+      _constructor.setAccessible(true);
+      Class []params = _constructor.getParameterTypes();
+      _constructorArgs = new Object[params.length];
+      for (int i = 0; i < params.length; i++) {
+        _constructorArgs[i] = getParamArg(params[i]);
+      }
+    }
+  }
+
+  public Class<?> getType()
+  {
+    return _type;
+  }
+    
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    try {
+      Object obj = instantiate();
+      return readMap(in, obj);
+    } catch (IOException e) {
+      throw e;
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e);
+    }
+  }
+    
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    try {
+      Object obj = instantiate();
+
+      return readObject(in, obj, fieldNames);
+    } catch (IOException e) {
+      throw e;
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e);
+    }
+  }
+
+  private static Method getReadResolve(Class<?> cl)
+  {
+    try {
+		return cl.getMethod("readResolve", new Class[0]);
+	} catch (Exception e) {}
+	return null;
+  }
+    
+  public Object readMap(AbstractHessianInput in, Object obj)
+    throws IOException
+  {
+    try {
+      int ref = in.addRef(obj);
+
+      while (! in.isEnd()) {
+        Object key = in.readObject();
+        
+        final Field field = _keyFieldMap.get(key);
+		final FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(key);
+
+        if (deser != null)
+          deser.deserialize(in, field, obj);
+        else
+          in.readObject();
+      }
+      
+      in.readMapEnd();
+
+      Object resolve = resolve(obj);
+
+      if (obj != resolve)
+	in.setRef(ref, resolve);
+
+      return resolve;
+    } catch (IOException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+    
+  public Object readObject(AbstractHessianInput in,
+			   Object obj,
+			   String []fieldNames)
+    throws IOException
+  {
+    try {
+      int ref = in.addRef(obj);
+
+      for (int i = 0; i < fieldNames.length; i++) {
+        String name = fieldNames[i];
+        
+        final Field field = _keyFieldMap.get(name);
+		final FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(name);
+
+        if (deser != null)
+        	deser.deserialize(in, _keyFieldMap.get(name), obj);
+        else
+          in.readObject();
+      }
+
+      Object resolve = resolve(obj);
+
+      if (obj != resolve)
+	in.setRef(ref, resolve);
+
+      return resolve;
+    } catch (IOException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e);
+    }
+  }
+
+  private Object resolve(Object obj)
+    throws Exception
+  {
+    // if there's a readResolve method, call it
+    try {
+      if (_readResolve != null)
+        return _readResolve.invoke(obj, new Object[0]);
+    } catch (InvocationTargetException e) {
+      if (e.getTargetException() != null)
+	throw e;
+    }
+
+    return obj;
+  }
+
+  protected <T> T instantiate()
+    throws Exception
+  {
+    try {
+      if (_constructor != null)
+	return (T) _constructor.newInstance(_constructorArgs);
+      else
+	return (T) _type.newInstance();
+    } catch (Exception e) {
+      throw new HessianProtocolException("'" + _type.getName() + "' could not be instantiated", e);
+    }
+  }
+
+  /**
+   * Creates a map of the classes fields.
+   */
+  private void initFieldMap(Class<?> cl)
+  {
+    _fieldMap = new HashMap<String, FieldDeserializer>();
+    
+    while (cl != null) {
+      Field []fields = cl.getDeclaredFields();
+      for (int i = 0; i < fields.length; i++) {
+        final Field field = fields[i];
+
+        if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers()))
+          continue;
+        else if (_fieldMap.get(field.getName()) != null)
+          continue;
+
+        try {
+          field.setAccessible(true);
+        } catch (Throwable e) {}
+
+		final Class<?> type = field.getType();
+		FieldDeserializer deser = null;
+	
+		if (!deserializerCache.containsKey(type))  {
+			if (String.class.equals(type))
+				deser = new StringFieldDeserializer();
+			else if (byte.class.equals(type)) {
+				deser = new ByteFieldDeserializer();
+			}
+			else if (short.class.equals(type)) {
+				deser = new ShortFieldDeserializer();
+			}
+			else if (int.class.equals(type)) {
+				deser = new IntFieldDeserializer();
+			}
+			else if (long.class.equals(type)) {
+				deser = new LongFieldDeserializer();
+			}
+			else if (float.class.equals(type)) {
+				deser = new FloatFieldDeserializer();
+			}
+			else if (double.class.equals(type)) {
+				deser = new DoubleFieldDeserializer();
+			}
+			else if (boolean.class.equals(type)) {
+				deser = new BooleanFieldDeserializer();
+			}
+			else if (java.sql.Date.class.equals(type)) {
+				deser = new SqlDateFieldDeserializer();
+			}
+			else if (java.sql.Timestamp.class.equals(type)) {
+				deser = new SqlTimestampFieldDeserializer();
+			}
+			else if (java.sql.Time.class.equals(type)) {
+				deser = new SqlTimeFieldDeserializer();
+			}
+			else {
+				deser = new ObjectFieldDeserializer();
+			}	
+			
+			deserializerCache.put(type, deser);
+		}
+	
+		_fieldMap.put(field.getName(), deserializerCache.get(type));
+		_keyFieldMap.put(field.getName(), field);
+	  }
+      cl = cl.getSuperclass();
+    }
+  }
+
+  /**
+   * Creates a map of the classes fields.
+   */
+  protected static Object getParamArg(Class cl)
+  {
+    if (! cl.isPrimitive())
+      return null;
+    else if (boolean.class.equals(cl))
+      return Boolean.FALSE;
+    else if (byte.class.equals(cl))
+      return new Byte((byte) 0);
+    else if (short.class.equals(cl))
+      return new Short((short) 0);
+    else if (char.class.equals(cl))
+      return new Character((char) 0);
+    else if (int.class.equals(cl))
+      return Integer.valueOf(0);
+    else if (long.class.equals(cl))
+      return Long.valueOf(0);
+    else if (float.class.equals(cl))
+      return Float.valueOf(0);
+    else if (double.class.equals(cl))
+      return Double.valueOf(0);
+    else
+      throw new UnsupportedOperationException();
+  }
+
+  abstract static class FieldDeserializer {
+    abstract void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException;
+  }
+
+  static class ObjectFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      Object value = null;
+      
+      try {
+	value = in.readObject(field.getType());
+	
+	field.set(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class BooleanFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      boolean value = false;
+      
+      try {
+	value = in.readBoolean();
+	
+	field.setBoolean(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class ByteFieldDeserializer extends FieldDeserializer {
+     void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      int value = 0;
+      
+      try {
+	value = in.readInt();
+	
+	field.setByte(obj, (byte) value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class ShortFieldDeserializer extends FieldDeserializer {
+     void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      int value = 0;
+      
+      try {
+	value = in.readInt();
+	
+	field.setShort(obj, (short) value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class IntFieldDeserializer extends FieldDeserializer {
+     void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      int value = 0;
+      
+      try {
+	value = in.readInt();
+	
+	field.setInt(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class LongFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      long value = 0;
+      
+      try {
+	value = in.readLong();
+	
+	field.setLong(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class FloatFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      double value = 0;
+      
+      try {
+	value = in.readDouble();
+	
+	field.setFloat(obj, (float) value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class DoubleFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      double value = 0;
+      
+      try {
+	value = in.readDouble();
+	
+	field.setDouble(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class StringFieldDeserializer extends FieldDeserializer {
+     void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      String value = null;
+      
+      try {
+	value = in.readString();
+	
+	field.set(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class SqlDateFieldDeserializer extends FieldDeserializer {
+     void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      java.sql.Date value = null;
+
+      try {
+        java.util.Date date = (java.util.Date) in.readObject();
+        value = new java.sql.Date(date.getTime());
+
+        field.set(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class SqlTimestampFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      java.sql.Timestamp value = null;
+
+      try {
+        java.util.Date date = (java.util.Date) in.readObject();
+        value = new java.sql.Timestamp(date.getTime());
+
+        field.set(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static class SqlTimeFieldDeserializer extends FieldDeserializer {
+    void deserialize(AbstractHessianInput in, Field field, Object obj)
+      throws IOException
+    {
+      java.sql.Time value = null;
+
+      try {
+        java.util.Date date = (java.util.Date) in.readObject();
+        value = new java.sql.Time(date.getTime());
+
+        field.set(obj, value);
+      } catch (Exception e) {
+        logDeserializeError(field, obj, value, e);
+      }
+    }
+  }
+
+  static void logDeserializeError(Field field, Object obj, Object value,
+                                  Throwable e)
+    throws IOException
+  {
+    String fieldName = (field.getDeclaringClass().getName()
+                        + "." + field.getName());
+
+    if (e instanceof HessianFieldException)
+      throw (HessianFieldException) e;
+    else if (e instanceof IOException)
+      throw new HessianFieldException(fieldName + ": " + e.getMessage(), e);
+    
+    if (value != null)
+      throw new HessianFieldException(fieldName + ": " + value.getClass().getName() + " (" + value + ")"
+					 + " cannot be assigned to '" + field.getType().getName() + "'");
+    else
+       throw new HessianFieldException(fieldName + ": " + field.getType().getName() + " cannot be assigned from null", e);
+  }
+}
diff --git src/com/caucho/hessian/io/JavaSerializer.java src/com/caucho/hessian/io/JavaSerializer.java
new file mode 100644
index 0000000..22b58f2
--- /dev/null
+++ src/com/caucho/hessian/io/JavaSerializer.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class JavaSerializer extends AbstractSerializer
+{
+  private static final Logger log = Logger.getLogger(JavaSerializer.class.getName());
+
+  private static Map<Class<?>, ArrayList<Field>> fieldsCache = new HashMap<Class<?>, ArrayList<Field>>();
+  private static Map<Class<?>, ArrayList<FieldSerializer>> fieldSerializerCache = new HashMap<Class<?>, ArrayList<FieldSerializer>>();
+  
+  private Object _writeReplaceFactory;
+  private Method _writeReplace;
+  
+  private Class<?> _type;
+  
+  public JavaSerializer(Class<?> cl)
+  {
+	_type = cl;
+	
+	introspectWriteReplace(cl);
+    
+    if (_writeReplace != null)
+      _writeReplace.setAccessible(true);
+
+    if (!fieldsCache.containsKey(cl))  {
+    	final ArrayList<Field> primitiveFields = new ArrayList<Field>();
+    	final ArrayList<Field> compoundFields = new ArrayList<Field>();
+    	final ArrayList<FieldSerializer> fieldSerializers = new ArrayList<FieldSerializer>();
+	    
+    	
+    	
+	    for (; cl != null; cl = cl.getSuperclass()) {
+	      final Field []fields = cl.getDeclaredFields();
+	      for (int i = 0; i < fields.length; i++) {
+	    	Field field = fields[i];
+	
+			if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers()))
+			  continue;
+	
+			field.setAccessible(true);
+		
+			if (field.getType().isPrimitive() || (field.getType().getName().startsWith("java.lang.") && ! field.getType().equals(Object.class)))
+			  primitiveFields.add(field);
+			else
+			  compoundFields.add(field);
+		  }
+		}
+	    
+	    final ArrayList<Field> result = new ArrayList<Field>();
+	    result.addAll(primitiveFields);
+	    result.addAll(compoundFields);
+	    
+	    fieldsCache.put(_type, result);
+	    fieldSerializerCache.put(_type, fieldSerializers);
+	    
+	    for (int i = 0; i < result.size(); i++) {
+	    	fieldSerializers.add(getFieldSerializer(result.get(i).getType()));
+	    }
+    }
+  }
+
+  private void introspectWriteReplace(Class cl)
+  {
+    try {
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+      String className = cl.getName() + "HessianSerializer";
+
+      Class serializerClass = Class.forName(className, false, loader);
+
+      Object serializerObject = serializerClass.newInstance();
+
+      Method writeReplace = getWriteReplace(serializerClass, cl);
+
+      if (writeReplace != null) {
+	_writeReplaceFactory = serializerObject;
+	_writeReplace = writeReplace;
+
+	return;
+      }
+    } catch (ClassNotFoundException e) {
+    } catch (Exception e) {
+      log.log(Level.FINER, e.toString(), e);
+    }
+      
+    _writeReplace = getWriteReplace(cl);
+  }
+
+  /**
+   * Returns the writeReplace method
+   */
+  protected static Method getWriteReplace(Class<?> cl)
+  {
+    try {
+		return cl.getMethod("writeReplace", new Class[0]);
+	} catch (Exception e) {}
+	
+	return null;
+  }
+
+  /**
+   * Returns the writeReplace method
+   */
+  protected Method getWriteReplace(Class<?> cl, Class<?> param)
+  {
+    try {
+		return cl.getMethod("writeReplace", new Class[] { param });
+	} catch (Exception e) {}
+	
+	return null;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (out.addRef(obj)) {
+      return;
+    }
+    
+    final Class<?> cl = obj.getClass();
+
+    try {
+      if (_writeReplace != null) {
+	Object repl;
+
+	if (_writeReplaceFactory != null)
+	  repl = _writeReplace.invoke(_writeReplaceFactory, obj);
+	else
+	  repl = _writeReplace.invoke(obj);
+
+	out.removeRef(obj);
+
+	out.writeObject(repl);
+
+	out.replaceRef(repl, obj);
+
+	return;
+      }
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Exception e) {
+      // log.log(Level.FINE, e.toString(), e);
+      throw new RuntimeException(e);
+    }
+
+    int ref = out.writeObjectBegin(cl.getName());
+
+    if (ref < -1) {
+      writeObject10(obj, out);
+    }
+    else {
+      if (ref == -1) {
+	writeDefinition20(out);
+	out.writeObjectBegin(cl.getName());
+      }
+
+      writeInstance(obj, out);
+    }
+  }
+  
+  private void writeObject10(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+  	final ArrayList<Field> fields = fieldsCache.get(_type);
+  	final ArrayList<FieldSerializer> fieldSerializers = fieldSerializerCache.get(_type);
+    
+  	for (int i = 0; i < fields.size(); i++) {
+      final Field field = fields.get(i);
+
+      out.writeString(field.getName());
+	
+      fieldSerializers.get(i).serialize(out, obj, field);
+    }
+      
+    out.writeMapEnd();
+  }
+  
+  private void writeDefinition20(AbstractHessianOutput out)
+    throws IOException
+  {
+	final ArrayList<Field> fields = fieldsCache.get(_type);
+	  
+    out.writeClassFieldLength(fields.size());
+	
+    for (int i = 0; i < fields.size(); i++) {
+      final Field field = fields.get(i);
+      
+      out.writeString(field.getName());
+    }
+  }
+  
+  public void writeInstance(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+	final ArrayList<Field> fields = fieldsCache.get(_type);
+	final ArrayList<FieldSerializer> fieldSerializers = fieldSerializerCache.get(_type);	  
+	  
+    for (int i = 0; i < fields.size(); i++) {
+      final Field field = fields.get(i);
+
+      fieldSerializers.get(i).serialize(out, obj, field);
+    }
+  }
+
+  private static FieldSerializer getFieldSerializer(Class<?> type)
+  {
+    if (int.class.equals(type)
+        || byte.class.equals(type)
+        || short.class.equals(type)
+        || int.class.equals(type)) {
+      return IntFieldSerializer.SER;
+    }
+    else if (long.class.equals(type)) {
+      return LongFieldSerializer.SER;
+    }
+    else if (double.class.equals(type) ||
+        float.class.equals(type)) {
+      return DoubleFieldSerializer.SER;
+    }
+    else if (boolean.class.equals(type)) {
+      return BooleanFieldSerializer.SER;
+    }
+    else if (String.class.equals(type)) {
+      return StringFieldSerializer.SER;
+    }
+    else if (java.util.Date.class.equals(type)
+             || java.sql.Date.class.equals(type)
+             || java.sql.Timestamp.class.equals(type)
+             || java.sql.Time.class.equals(type)) {
+      return DateFieldSerializer.SER;
+    }
+    else
+      return FieldSerializer.SER;
+  }
+
+  static class FieldSerializer {
+    static final FieldSerializer SER = new FieldSerializer();
+    
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      Object value = null;
+	
+      try {
+	value = field.get(obj);
+      } catch (IllegalAccessException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+
+      try {
+	out.writeObject(value);
+      } catch (RuntimeException e) {
+	throw new RuntimeException(e.getMessage() + "\n Java field: " + field,
+				   e);
+      } catch (IOException e) {
+	throw new IOExceptionWrapper(e.getMessage() + "\n Java field: " + field,
+			      e);
+      }
+    }
+  }
+
+  static class BooleanFieldSerializer extends FieldSerializer {
+    static final FieldSerializer SER = new BooleanFieldSerializer();
+    
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      boolean value = false;
+	
+      try {
+	value = field.getBoolean(obj);
+      } catch (IllegalAccessException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+
+      out.writeBoolean(value);
+    }
+  }
+
+  static class IntFieldSerializer extends FieldSerializer {
+    static final FieldSerializer SER = new IntFieldSerializer();
+    
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      int value = 0;
+	
+      try {
+	value = field.getInt(obj);
+      } catch (IllegalAccessException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+
+      out.writeInt(value);
+    }
+  }
+
+  static class LongFieldSerializer extends FieldSerializer {
+    static final FieldSerializer SER = new LongFieldSerializer();
+    
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      long value = 0;
+	
+      try {
+	value = field.getLong(obj);
+      } catch (IllegalAccessException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+
+      out.writeLong(value);
+    }
+  }
+
+  static class DoubleFieldSerializer extends FieldSerializer {
+    static final FieldSerializer SER = new DoubleFieldSerializer();
+    
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      double value = 0;
+	
+      try {
+	value = field.getDouble(obj);
+      } catch (IllegalAccessException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+
+      out.writeDouble(value);
+    }
+  }
+
+  static class StringFieldSerializer extends FieldSerializer {
+    static final FieldSerializer SER = new StringFieldSerializer();
+    
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      String value = null;
+	
+      try {
+	value = (String) field.get(obj);
+      } catch (IllegalAccessException e) {
+	log.log(Level.FINE, e.toString(), e);
+      }
+
+      out.writeString(value);
+    }
+  }
+
+  static class DateFieldSerializer extends FieldSerializer {
+    static final FieldSerializer SER = new DateFieldSerializer();
+
+    void serialize(AbstractHessianOutput out, Object obj, Field field)
+      throws IOException
+    {
+      java.util.Date value = null;
+
+      try {
+        value = (java.util.Date) field.get(obj);
+      } catch (IllegalAccessException e) {
+        log.log(Level.FINE, e.toString(), e);
+      }
+
+      
+      if (value != null) out.writeUTCDate(value.getTime()); else out.writeNull();
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/LocaleHandle.java src/com/caucho/hessian/io/LocaleHandle.java
new file mode 100644
index 0000000..68239f8
--- /dev/null
+++ src/com/caucho/hessian/io/LocaleHandle.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.util.Locale;
+
+/**
+ * Handle for a locale object.
+ */
+public class LocaleHandle implements java.io.Serializable, HessianHandle {
+  private String value;
+
+  public LocaleHandle(String locale)
+  {
+    this.value = locale;
+  }
+
+  private Object readResolve()
+  {
+    String s = this.value;
+    
+    if (s == null)
+      return null;
+    
+    int len = s.length();
+    char ch = ' ';
+
+    int i = 0;
+    for (;
+	 i < len && ('a' <= (ch = s.charAt(i)) && ch <= 'z'
+		     || 'A' <= ch && ch <= 'Z'
+		     || '0' <= ch && ch <= '9');
+	 i++) {
+    }
+
+    String language = s.substring(0, i);
+    String country = null;
+    String var = null;
+
+    if (ch == '-' || ch == '_') {
+      int head = ++i;
+      
+      for (;
+	   i < len && ('a' <= (ch = s.charAt(i)) && ch <= 'z'
+		       || 'A' <= ch && ch <= 'Z'
+		       || '0' <= ch && ch <= '9');
+	   i++) {
+      }
+      
+      country = s.substring(head, i);
+    }
+
+    if (ch == '-' || ch == '_') {
+      int head = ++i;
+      
+      for (;
+	   i < len && ('a' <= (ch = s.charAt(i)) && ch <= 'z'
+		       || 'A' <= ch && ch <= 'Z'
+		       || '0' <= ch && ch <= '9');
+	   i++) {
+      }
+      
+      var = s.substring(head, i);
+    }
+
+    if (var != null)
+      return new Locale(language, country, var);
+    else if (country != null)
+      return new Locale(language, country);
+    else
+      return new Locale(language);
+  }
+}
diff --git src/com/caucho/hessian/io/LocaleSerializer.java src/com/caucho/hessian/io/LocaleSerializer.java
new file mode 100644
index 0000000..f15f32d
--- /dev/null
+++ src/com/caucho/hessian/io/LocaleSerializer.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Locale;
+
+/**
+ * Serializing a locale.
+ */
+public class LocaleSerializer extends AbstractSerializer {
+  private static LocaleSerializer SERIALIZER = new LocaleSerializer();
+
+  public static LocaleSerializer create()
+  {
+    return SERIALIZER;
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (obj == null)
+      out.writeNull();
+    else {
+      Locale locale = (Locale) obj;
+
+      out.writeObject(new LocaleHandle(locale.toString()));
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/MapDeserializer.java src/com/caucho/hessian/io/MapDeserializer.java
new file mode 100644
index 0000000..ed61dbf
--- /dev/null
+++ src/com/caucho/hessian/io/MapDeserializer.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.*;
+import java.lang.reflect.*;
+
+/**
+ * Deserializing a JDK 1.2 Map.
+ */
+public class MapDeserializer extends AbstractMapDeserializer {
+  private Class _type;
+  private Constructor _ctor;
+  
+  public MapDeserializer(Class type)
+  {
+    if (type == null)
+      type = HashMap.class;
+    
+    _type = type;
+
+    Constructor []ctors = type.getConstructors();
+    for (int i = 0; i < ctors.length; i++) {
+      if (ctors[i].getParameterTypes().length == 0)
+	_ctor = ctors[i];
+    }
+
+    if (_ctor == null) {
+      try {
+	_ctor = HashMap.class.getConstructor(new Class[0]);
+      } catch (Exception e) {
+	throw new IllegalStateException(e);
+      }
+    }
+  }
+  
+  public Class getType()
+  {
+    if (_type != null)
+      return _type;
+    else
+      return HashMap.class;
+  }
+
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    Map map;
+    
+    if (_type == null)
+      map = new HashMap();
+    else if (_type.equals(Map.class))
+      map = new HashMap();
+    else if (_type.equals(SortedMap.class))
+      map = new TreeMap();
+    else {
+      try {
+        map = (Map) _ctor.newInstance();
+      } catch (Exception e) {
+        throw new IOExceptionWrapper(e);
+      }
+    }
+
+    in.addRef(map);
+
+    while (! in.isEnd()) {
+      map.put(in.readObject(), in.readObject());
+    }
+
+    in.readEnd();
+
+    return map;
+  }
+
+  @Override
+  public Object readObject(AbstractHessianInput in,
+			   String []fieldNames)
+    throws IOException
+  {
+    Map map = createMap();
+      
+    int ref = in.addRef(map);
+
+    for (int i = 0; i < fieldNames.length; i++) {
+      String name = fieldNames[i];
+
+      map.put(name, in.readObject());
+    }
+
+    return map;
+  }
+
+  private Map createMap()
+    throws IOException
+  {
+    
+    if (_type == null)
+      return new HashMap();
+    else if (_type.equals(Map.class))
+      return new HashMap();
+    else if (_type.equals(SortedMap.class))
+      return new TreeMap();
+    else {
+      try {
+        return (Map) _ctor.newInstance();
+      } catch (Exception e) {
+        throw new IOExceptionWrapper(e);
+      }
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/MapSerializer.java src/com/caucho/hessian/io/MapSerializer.java
new file mode 100644
index 0000000..42d8986
--- /dev/null
+++ src/com/caucho/hessian/io/MapSerializer.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Serializing a JDK 1.2 java.util.Map.
+ */
+public class MapSerializer extends AbstractSerializer {
+  private boolean _isSendJavaType = true;
+
+  /**
+   * Set true if the java type of the collection should be sent.
+   */
+  public void setSendJavaType(boolean sendJavaType)
+  {
+    _isSendJavaType = sendJavaType;
+  }
+
+  /**
+   * Return true if the java type of the collection should be sent.
+   */
+  public boolean getSendJavaType()
+  {
+    return _isSendJavaType;
+  }
+    
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (out.addRef(obj))
+      return;
+
+    Map map = (Map) obj;
+
+    Class cl = obj.getClass();
+    
+    if (cl.equals(HashMap.class)
+	|| ! _isSendJavaType
+	|| ! (obj instanceof java.io.Serializable))
+      out.writeMapBegin(null);
+    else
+      out.writeMapBegin(obj.getClass().getName());
+
+    Iterator iter = map.entrySet().iterator();
+    while (iter.hasNext()) {
+      Map.Entry entry = (Map.Entry) iter.next();
+
+      out.writeObject(entry.getKey());
+      out.writeObject(entry.getValue());
+    }
+    out.writeMapEnd();
+  }
+}
diff --git src/com/caucho/hessian/io/ObjectDeserializer.java src/com/caucho/hessian/io/ObjectDeserializer.java
new file mode 100644
index 0000000..ec2647b
--- /dev/null
+++ src/com/caucho/hessian/io/ObjectDeserializer.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class ObjectDeserializer extends AbstractDeserializer {
+  private Class _cl;
+
+  public ObjectDeserializer(Class cl)
+  {
+    _cl = cl;
+  }
+
+  public Class getType()
+  {
+    return _cl;
+  }
+  
+  public Object readObject(AbstractHessianInput in)
+    throws IOException
+  {
+    return in.readObject();
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    throw new UnsupportedOperationException(String.valueOf(this));
+  }
+  
+  public Object readList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    throw new UnsupportedOperationException(String.valueOf(this));
+  }
+  
+  public Object readLengthList(AbstractHessianInput in, int length)
+    throws IOException
+  {
+    throw new UnsupportedOperationException(String.valueOf(this));
+  }
+
+  @Override
+  public String toString()
+  {
+    return getClass().getSimpleName() + "[" + _cl + "]";
+  }
+}
diff --git src/com/caucho/hessian/io/RemoteSerializer.java src/com/caucho/hessian/io/RemoteSerializer.java
new file mode 100644
index 0000000..889aa31
--- /dev/null
+++ src/com/caucho/hessian/io/RemoteSerializer.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Serializing a remote object.
+ */
+public class RemoteSerializer extends AbstractSerializer {
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (obj instanceof HessianRemoteObject) {
+      HessianRemoteObject remote = (HessianRemoteObject) obj;
+
+      out.writeRemote(remote.getHessianType(), remote.getHessianURL());
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/Serializer.java src/com/caucho/hessian/io/Serializer.java
new file mode 100644
index 0000000..94b7076
--- /dev/null
+++ src/com/caucho/hessian/io/Serializer.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Serializing an object. 
+ */
+public interface Serializer {
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException;
+}
diff --git src/com/caucho/hessian/io/SerializerFactory.java src/com/caucho/hessian/io/SerializerFactory.java
new file mode 100644
index 0000000..851d4ae
--- /dev/null
+++ src/com/caucho/hessian/io/SerializerFactory.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Factory for returning serialization methods.
+ */
+public class SerializerFactory extends AbstractSerializerFactory
+{
+  private static final Logger log
+    = Logger.getLogger(SerializerFactory.class.getName());
+
+  private static Deserializer OBJECT_DESERIALIZER
+    = new BasicDeserializer(BasicDeserializer.OBJECT);
+  
+  private static HashMap _staticSerializerMap;
+  private static HashMap _staticDeserializerMap;
+  private static HashMap _staticTypeMap;
+
+  protected Serializer _defaultSerializer;
+
+  // Additional factories
+  protected ArrayList _factories = new ArrayList();
+  
+  protected CollectionSerializer _collectionSerializer;
+  protected MapSerializer _mapSerializer;
+  
+  private Deserializer _hashMapDeserializer;
+  private Deserializer _arrayListDeserializer;
+  private HashMap _cachedSerializerMap;
+  private HashMap _cachedDeserializerMap;
+  private HashMap _cachedTypeDeserializerMap;
+
+  private boolean _isAllowNonSerializable;
+
+  /**
+   * Set true if the collection serializer should send the java type.
+   */
+  public void setSendCollectionType(boolean isSendType)
+  {
+    if (_collectionSerializer == null)
+      _collectionSerializer = new CollectionSerializer();
+
+    _collectionSerializer.setSendJavaType(isSendType);
+    
+    if (_mapSerializer == null)
+      _mapSerializer = new MapSerializer();
+
+    _mapSerializer.setSendJavaType(isSendType);
+  }
+
+  /**
+   * Adds a factory.
+   */
+  public void addFactory(AbstractSerializerFactory factory)
+  {
+    _factories.add(factory);
+  }
+
+  /**
+   * If true, non-serializable objects are allowed.
+   */
+  public void setAllowNonSerializable(boolean allow)
+  {
+    _isAllowNonSerializable = allow;
+  }
+
+  /**
+   * If true, non-serializable objects are allowed.
+   */
+  public boolean isAllowNonSerializable()
+  {
+    return _isAllowNonSerializable;
+  }
+
+  /**
+   * Returns the serializer for a class.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  public Serializer getSerializer(Class cl)
+    throws HessianProtocolException
+  {
+    Serializer serializer;
+
+    serializer = (Serializer) _staticSerializerMap.get(cl);
+    if (serializer != null)
+      return serializer;
+
+    if (_cachedSerializerMap != null) {
+      synchronized (_cachedSerializerMap) {
+	serializer = (Serializer) _cachedSerializerMap.get(cl);
+      }
+      
+      if (serializer != null)
+	return serializer;
+    }
+
+    for (int i = 0;
+	 serializer == null && _factories != null && i < _factories.size();
+	 i++) {
+      AbstractSerializerFactory factory;
+
+      factory = (AbstractSerializerFactory) _factories.get(i);
+
+      serializer = factory.getSerializer(cl);
+    }
+
+    if (serializer != null) {
+    }
+
+    else if (JavaSerializer.getWriteReplace(cl) != null)
+      serializer = new JavaSerializer(cl);
+
+    else if (HessianRemoteObject.class.isAssignableFrom(cl))
+      serializer = new RemoteSerializer();
+//
+//    else if (BurlapRemoteObject.class.isAssignableFrom(cl))
+//      serializer = new RemoteSerializer();
+
+    else if (Map.class.isAssignableFrom(cl)) {
+      if (_mapSerializer == null)
+	_mapSerializer = new MapSerializer();
+      
+      serializer = _mapSerializer;
+    }
+    else if (Collection.class.isAssignableFrom(cl)) {
+      if (_collectionSerializer == null) {
+	_collectionSerializer = new CollectionSerializer();
+      }
+
+      serializer = _collectionSerializer;
+    }
+
+    else if (cl.isArray())
+      serializer = new ArraySerializer();
+
+    else if (Throwable.class.isAssignableFrom(cl))
+      serializer = new ThrowableSerializer(cl);
+
+    else if (InputStream.class.isAssignableFrom(cl))
+      serializer = new InputStreamSerializer();
+
+    else if (Iterator.class.isAssignableFrom(cl))
+      serializer = IteratorSerializer.create();
+
+    else if (Enumeration.class.isAssignableFrom(cl))
+      serializer = EnumerationSerializer.create();
+    
+    else if (Calendar.class.isAssignableFrom(cl))
+      serializer = CalendarSerializer.create();
+    
+    else if (Locale.class.isAssignableFrom(cl))
+      serializer = LocaleSerializer.create();
+    
+    else if (Enum.class.isAssignableFrom(cl))
+      serializer = new EnumSerializer(cl);
+
+    if (serializer == null)
+      serializer = getDefaultSerializer(cl);
+
+    if (_cachedSerializerMap == null)
+      _cachedSerializerMap = new HashMap(8);
+
+    synchronized (_cachedSerializerMap) {
+      _cachedSerializerMap.put(cl, serializer);
+    }
+
+    return serializer;
+  }
+
+  /**
+   * Returns the default serializer for a class that isn't matched
+   * directly.  Application can override this method to produce
+   * bean-style serialization instead of field serialization.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  protected Serializer getDefaultSerializer(Class cl)
+  {
+    if (_defaultSerializer != null)
+      return _defaultSerializer;
+
+    if (! Serializable.class.isAssignableFrom(cl)
+	&& ! _isAllowNonSerializable) {
+      throw new IllegalStateException("Serialized class " + cl.getName() + " must implement java.io.Serializable");
+    }
+
+    return new JavaSerializer(cl);
+  }
+  
+  /**
+   * Returns the deserializer for a class.
+   *
+   * @param cl the class of the object that needs to be deserialized.
+   *
+   * @return a deserializer object for the serialization.
+   */
+  public Deserializer getDeserializer(Class cl)
+    throws HessianProtocolException
+  {
+    Deserializer deserializer;
+
+    deserializer = (Deserializer) _staticDeserializerMap.get(cl);
+    if (deserializer != null)
+      return deserializer;
+
+    if (_cachedDeserializerMap != null) {
+      synchronized (_cachedDeserializerMap) {
+	deserializer = (Deserializer) _cachedDeserializerMap.get(cl);
+      }
+      
+      if (deserializer != null)
+	return deserializer;
+    }
+
+
+    for (int i = 0;
+	 deserializer == null && _factories != null && i < _factories.size();
+	 i++) {
+      AbstractSerializerFactory factory;
+      factory = (AbstractSerializerFactory) _factories.get(i);
+
+      deserializer = factory.getDeserializer(cl);
+    }
+
+    if (deserializer != null) {
+    }
+
+    else if (Collection.class.isAssignableFrom(cl))
+      deserializer = new CollectionDeserializer(cl);
+
+    else if (Map.class.isAssignableFrom(cl))
+      deserializer = new MapDeserializer(cl);
+    
+    else if (cl.isInterface())
+      deserializer = new ObjectDeserializer(cl);
+
+    else if (cl.isArray())
+      deserializer = new ArrayDeserializer(cl.getComponentType());
+
+    else if (Enumeration.class.isAssignableFrom(cl))
+      deserializer = EnumerationDeserializer.create();
+
+    else if (Enum.class.isAssignableFrom(cl))
+      deserializer = new EnumDeserializer(cl);
+    
+    else
+      deserializer = getDefaultDeserializer(cl);
+
+    if (_cachedDeserializerMap == null)
+      _cachedDeserializerMap = new HashMap(8);
+
+    synchronized (_cachedDeserializerMap) {
+      _cachedDeserializerMap.put(cl, deserializer);
+    }
+
+    return deserializer;
+  }
+
+  /**
+   * Returns the default serializer for a class that isn't matched
+   * directly.  Application can override this method to produce
+   * bean-style serialization instead of field serialization.
+   *
+   * @param cl the class of the object that needs to be serialized.
+   *
+   * @return a serializer object for the serialization.
+   */
+  protected Deserializer getDefaultDeserializer(Class cl)
+  {
+    return new JavaDeserializer(cl);
+  }
+
+  /**
+   * Reads the object as a list.
+   */
+  public Object readList(AbstractHessianInput in, int length, String type)
+    throws HessianProtocolException, IOException
+  {
+    Deserializer deserializer = getDeserializer(type);
+
+    if (deserializer != null)
+      return deserializer.readList(in, length);
+    else
+      return new CollectionDeserializer(ArrayList.class).readList(in, length);
+  }
+  
+  /**
+   * Reads the object as a map.
+   */
+  public Object readMap(AbstractHessianInput in, String type)
+    throws HessianProtocolException, IOException
+  {
+    Deserializer deserializer = getDeserializer(type);
+
+    if (deserializer != null)
+      return deserializer.readMap(in);
+    else if (_hashMapDeserializer != null)
+      return _hashMapDeserializer.readMap(in);
+    else {
+      _hashMapDeserializer = new MapDeserializer(HashMap.class);
+      
+      return _hashMapDeserializer.readMap(in);
+    }
+  }
+  
+  /**
+   * Reads the object as a map.
+   */
+  public Object readObject(AbstractHessianInput in,
+			   String type,
+			   String []fieldNames)
+    throws HessianProtocolException, IOException
+  {
+    Deserializer deserializer = getDeserializer(type);
+
+    if (deserializer != null)
+      return deserializer.readObject(in, fieldNames);
+    else if (_hashMapDeserializer != null)
+      return _hashMapDeserializer.readObject(in, fieldNames);
+    else {
+      _hashMapDeserializer = new MapDeserializer(HashMap.class);
+      
+      return _hashMapDeserializer.readObject(in, fieldNames);
+    }
+  }
+
+  /**
+   * Reads the object as a map.
+   */
+  public Deserializer getObjectDeserializer(String type, Class cl)
+    throws HessianProtocolException
+  {
+    Deserializer reader = getObjectDeserializer(type);
+    
+    if (cl == null
+	|| cl.equals(reader.getType())
+	|| cl.isAssignableFrom(reader.getType())
+	|| HessianHandle.class.isAssignableFrom(reader.getType())) {
+      return reader;
+    }
+
+    if (log.isLoggable(Level.FINE)) {
+      log.fine("hessian: expected '" + cl.getName() + "' at '" + type + "' ("
+	       + reader.getType().getName() + ")");
+    }
+    
+    return getDeserializer(cl);
+  }
+  
+  /**
+   * Reads the object as a map.
+   */
+  public Deserializer getObjectDeserializer(String type)
+    throws HessianProtocolException
+  {
+    Deserializer deserializer = getDeserializer(type);
+
+    if (deserializer != null)
+      return deserializer;
+    else if (_hashMapDeserializer != null)
+      return _hashMapDeserializer;
+    else {
+      _hashMapDeserializer = new MapDeserializer(HashMap.class);
+      
+      return _hashMapDeserializer;
+    }
+  }
+
+  /**
+   * Reads the object as a map.
+   */
+  public Deserializer getListDeserializer(String type, Class cl)
+    throws HessianProtocolException
+  {
+    Deserializer reader = getListDeserializer(type);
+    
+    if (cl == null
+	|| cl.equals(reader.getType())
+	|| cl.isAssignableFrom(reader.getType())) {
+      return reader;
+    }
+
+    if (log.isLoggable(Level.FINE)) {
+      log.fine("hessian: expected '" + cl.getName() + "' at '" + type + "' ("
+	       + reader.getType().getName() + ")");
+    }
+    
+    return getDeserializer(cl);
+  }
+  
+  /**
+   * Reads the object as a map.
+   */
+  public Deserializer getListDeserializer(String type)
+    throws HessianProtocolException
+  {
+    Deserializer deserializer = getDeserializer(type);
+
+    if (deserializer != null)
+      return deserializer;
+    else if (_arrayListDeserializer != null)
+      return _arrayListDeserializer;
+    else {
+      _arrayListDeserializer = new CollectionDeserializer(ArrayList.class);
+      
+      return _arrayListDeserializer;
+    }
+  }
+
+  /**
+   * Returns a deserializer based on a string type.
+   */
+  public Deserializer getDeserializer(String type)
+    throws HessianProtocolException
+  {
+    if (type == null || type.equals(""))
+      return null;
+
+    Deserializer deserializer;
+    
+    if (_cachedTypeDeserializerMap != null) {
+      synchronized (_cachedTypeDeserializerMap) {
+	deserializer = (Deserializer) _cachedTypeDeserializerMap.get(type);
+      }
+
+      if (deserializer != null)
+	return deserializer;
+    }
+
+
+    deserializer = (Deserializer) _staticTypeMap.get(type);
+    if (deserializer != null)
+      return deserializer;
+
+    if (type.startsWith("[")) {
+      Deserializer subDeserializer = getDeserializer(type.substring(1));
+
+      if (subDeserializer != null)
+        deserializer = new ArrayDeserializer(subDeserializer.getType());
+      else
+        deserializer = new ArrayDeserializer(Object.class);
+    }
+    else {
+      try {
+	Class cl = Class.forName(type, false, getClass().getClassLoader());
+	deserializer = getDeserializer(cl);
+      } catch (Exception e) {
+	log.warning("Hessian/Burlap: '" + type + "' is an unknown class in " + getClass().getClassLoader() + ":\n" + e);
+	
+	log.log(Level.FINER, e.toString(), e);
+      }
+    }
+
+    if (deserializer != null) {
+      if (_cachedTypeDeserializerMap == null)
+	_cachedTypeDeserializerMap = new HashMap(8);
+
+      synchronized (_cachedTypeDeserializerMap) {
+	_cachedTypeDeserializerMap.put(type, deserializer);
+      }
+    }
+
+    return deserializer;
+  }
+
+  private static void addBasic(Class cl, String typeName, int type)
+  {
+    _staticSerializerMap.put(cl, new BasicSerializer(type));
+
+    Deserializer deserializer = new BasicDeserializer(type);
+    _staticDeserializerMap.put(cl, deserializer);
+    _staticTypeMap.put(typeName, deserializer);
+  }
+
+  static {
+    _staticSerializerMap = new HashMap();
+    _staticDeserializerMap = new HashMap();
+    _staticTypeMap = new HashMap();
+
+    addBasic(void.class, "void", BasicSerializer.NULL);
+    
+    addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN);
+    addBasic(Byte.class, "byte", BasicSerializer.BYTE);
+    addBasic(Short.class, "short", BasicSerializer.SHORT);
+    addBasic(Integer.class, "int", BasicSerializer.INTEGER);
+    addBasic(Long.class, "long", BasicSerializer.LONG);
+    addBasic(Float.class, "float", BasicSerializer.FLOAT);
+    addBasic(Double.class, "double", BasicSerializer.DOUBLE);
+    addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT);
+    addBasic(String.class, "string", BasicSerializer.STRING);
+    addBasic(Object.class, "object", BasicSerializer.OBJECT);
+    addBasic(java.util.Date.class, "date", BasicSerializer.DATE);
+
+    addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN);
+    addBasic(byte.class, "byte", BasicSerializer.BYTE);
+    addBasic(short.class, "short", BasicSerializer.SHORT);
+    addBasic(int.class, "int", BasicSerializer.INTEGER);
+    addBasic(long.class, "long", BasicSerializer.LONG);
+    addBasic(float.class, "float", BasicSerializer.FLOAT);
+    addBasic(double.class, "double", BasicSerializer.DOUBLE);
+    addBasic(char.class, "char", BasicSerializer.CHARACTER);
+    
+    addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY);
+    addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY);
+    addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY);
+    addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY);
+    addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY);
+    addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY);
+    addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY);
+    addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY);
+    addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY);
+    addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY);
+
+    _staticSerializerMap.put(Class.class, new ClassSerializer());
+    _staticDeserializerMap.put(Class.class, new ClassDeserializer());
+
+    _staticDeserializerMap.put(Number.class, new BasicDeserializer(BasicSerializer.NUMBER));
+    
+    _staticSerializerMap.put(BigDecimal.class, new StringValueSerializer());
+    try {
+      _staticDeserializerMap.put(BigDecimal.class,
+			   new StringValueDeserializer(BigDecimal.class));
+    } catch (Throwable e) {
+    }
+    
+    _staticSerializerMap.put(File.class, new StringValueSerializer());
+    try {
+      _staticDeserializerMap.put(File.class,
+			   new StringValueDeserializer(File.class));
+    } catch (Throwable e) {
+    }
+    
+//    _staticSerializerMap.put(ObjectName.class, new StringValueSerializer());
+//    try {
+//      _staticDeserializerMap.put(ObjectName.class,
+//			   new StringValueDeserializer(ObjectName.class));
+//    } catch (Throwable e) {
+//    }
+    
+    _staticSerializerMap.put(java.sql.Date.class, new SqlDateSerializer());
+    _staticSerializerMap.put(java.sql.Time.class, new SqlDateSerializer());
+    _staticSerializerMap.put(java.sql.Timestamp.class, new SqlDateSerializer());
+    
+    _staticSerializerMap.put(java.io.InputStream.class,
+			     new InputStreamSerializer());
+    _staticDeserializerMap.put(java.io.InputStream.class,
+			       new InputStreamDeserializer());
+
+    try {
+      _staticDeserializerMap.put(java.sql.Date.class,
+			  new SqlDateDeserializer(java.sql.Date.class));
+      _staticDeserializerMap.put(java.sql.Time.class,
+			  new SqlDateDeserializer(java.sql.Time.class));
+      _staticDeserializerMap.put(java.sql.Timestamp.class,
+			  new SqlDateDeserializer(java.sql.Timestamp.class));
+    } catch (Throwable e) {
+      e.printStackTrace();
+    }
+
+    // hessian/3bb5
+    try {
+      Class stackTrace = Class.forName("java.lang.StackTraceElement");
+      
+      _staticDeserializerMap.put(stackTrace, new StackTraceElementDeserializer());
+    } catch (Throwable e) {
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/SqlDateDeserializer.java src/com/caucho/hessian/io/SqlDateDeserializer.java
new file mode 100644
index 0000000..73dff3a
--- /dev/null
+++ src/com/caucho/hessian/io/SqlDateDeserializer.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+
+/**
+ * Deserializing a string valued object
+ */
+public class SqlDateDeserializer extends AbstractDeserializer {
+  private Class _cl;
+  private Constructor _constructor;
+  
+  public SqlDateDeserializer(Class cl)
+    throws NoSuchMethodException
+  {
+    _cl = cl;
+    _constructor = cl.getConstructor(new Class[] { long.class });
+  }
+  
+  public Class getType()
+  {
+    return _cl;
+  }
+  
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    int ref = in.addRef(null);
+    
+    long initValue = Long.MIN_VALUE;
+    
+    while (! in.isEnd()) {
+      String key = in.readString();
+
+      if (key.equals("value"))
+	initValue = in.readUTCDate();
+      else
+	in.readString();
+    }
+
+    in.readMapEnd();
+
+    Object value = create(initValue);
+
+    in.setRef(ref, value);
+
+    return value;
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    int ref = in.addRef(null);
+    
+    long initValue = Long.MIN_VALUE;
+
+    for (int i = 0; i < fieldNames.length; i++) {
+      String key = fieldNames[i];
+
+      if (key.equals("value"))
+	initValue = in.readUTCDate();
+      else
+	in.readObject();
+    }
+
+    Object value = create(initValue);
+
+    in.setRef(ref, value);
+
+    return value;
+  }
+
+  private Object create(long initValue)
+    throws IOException
+  {
+    if (initValue == Long.MIN_VALUE)
+      throw new IOException(_cl.getName() + " expects name.");
+
+    try {
+      return _constructor.newInstance(new Object[] { new Long(initValue) });
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/SqlDateSerializer.java src/com/caucho/hessian/io/SqlDateSerializer.java
new file mode 100644
index 0000000..2c12884
--- /dev/null
+++ src/com/caucho/hessian/io/SqlDateSerializer.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * Serializing a sql date object.
+ */
+public class SqlDateSerializer extends AbstractSerializer
+{
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (obj == null)
+      out.writeNull();
+    else {
+      Class cl = obj.getClass();
+
+      if (out.addRef(obj))
+	return;
+      
+      int ref = out.writeObjectBegin(cl.getName());
+
+      if (ref < -1) {
+	out.writeString("value");
+	out.writeUTCDate(((Date) obj).getTime());
+	out.writeMapEnd();
+      }
+      else {
+	if (ref == -1) {
+	  out.writeInt(1);
+	  out.writeString("value");
+	  out.writeObjectBegin(cl.getName());
+	}
+
+	out.writeUTCDate(((Date) obj).getTime());
+      }
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/StackTraceElementDeserializer.java src/com/caucho/hessian/io/StackTraceElementDeserializer.java
new file mode 100644
index 0000000..93c6c50
--- /dev/null
+++ src/com/caucho/hessian/io/StackTraceElementDeserializer.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.*;
+import java.util.HashMap;
+
+/**
+ * Deserializing a JDK 1.4 StackTraceElement
+ */
+public class StackTraceElementDeserializer extends JavaDeserializer {
+  public StackTraceElementDeserializer()
+  {
+    super(StackTraceElement.class);
+  }
+
+  @Override
+  protected Object instantiate()
+    throws Exception
+  {
+    return new StackTraceElement("", "", "", 0);
+  }
+}
diff --git src/com/caucho/hessian/io/StringValueDeserializer.java src/com/caucho/hessian/io/StringValueDeserializer.java
new file mode 100644
index 0000000..0cef102
--- /dev/null
+++ src/com/caucho/hessian/io/StringValueDeserializer.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+
+/**
+ * Deserializing a string valued object
+ */
+public class StringValueDeserializer extends AbstractDeserializer {
+  private Class _cl;
+  private Constructor _constructor;
+  
+  public StringValueDeserializer(Class cl)
+  {
+    try {
+      _cl = cl;
+      _constructor = cl.getConstructor(new Class[] { String.class });
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+  
+  public Class getType()
+  {
+    return _cl;
+  }
+  
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    String value = null;
+    
+    while (! in.isEnd()) {
+      String key = in.readString();
+
+      if (key.equals("value"))
+        value = in.readString();
+      else
+	in.readObject();
+    }
+
+    in.readMapEnd();
+
+    Object object = create(value);
+
+    in.addRef(object);
+
+    return object;
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    String value = null;
+
+    for (int i = 0; i < fieldNames.length; i++) {
+      if ("value".equals(fieldNames[i]))
+        value = in.readString();
+      else
+	in.readObject();
+    }
+
+    Object object = create(value);
+    
+    in.addRef(object);
+
+    return object;
+  }
+
+  private Object create(String value)
+    throws IOException
+  {
+    if (value == null)
+      throw new IOException(_cl.getName() + " expects name.");
+
+    try {
+      return _constructor.newInstance(new Object[] { value });
+    } catch (Exception e) {
+      throw new IOExceptionWrapper(e);
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/StringValueSerializer.java src/com/caucho/hessian/io/StringValueSerializer.java
new file mode 100644
index 0000000..0da24c8
--- /dev/null
+++ src/com/caucho/hessian/io/StringValueSerializer.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Serializing a remote object.
+ */
+public class StringValueSerializer extends AbstractSerializer {
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    if (obj == null)
+      out.writeNull();
+    else {
+      if (out.addRef(obj))
+	return;
+      
+      Class cl = obj.getClass();
+
+      int ref = out.writeObjectBegin(cl.getName());
+
+      if (ref < -1) {
+	out.writeString("value");
+	out.writeString(obj.toString());
+	out.writeMapEnd();
+      }
+      else {
+	if (ref == -1) {
+	  out.writeInt(1);
+	  out.writeString("value");
+	  out.writeObjectBegin(cl.getName());
+	}
+
+	out.writeString(obj.toString());
+      }
+    }
+  }
+}
diff --git src/com/caucho/hessian/io/ThrowableSerializer.java src/com/caucho/hessian/io/ThrowableSerializer.java
new file mode 100644
index 0000000..1c2bfd4
--- /dev/null
+++ src/com/caucho/hessian/io/ThrowableSerializer.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Serializing an object for known object types.
+ */
+public class ThrowableSerializer extends JavaSerializer {
+  public ThrowableSerializer(Class cl)
+  {
+    super(cl);
+  }
+  
+  public void writeObject(Object obj, AbstractHessianOutput out)
+    throws IOException
+  {
+    Throwable e = (Throwable) obj;
+
+    e.getStackTrace();
+
+    super.writeObject(obj, out);
+  }
+}
diff --git src/com/caucho/hessian/io/ValueDeserializer.java src/com/caucho/hessian/io/ValueDeserializer.java
new file mode 100644
index 0000000..d4d7ac0
--- /dev/null
+++ src/com/caucho/hessian/io/ValueDeserializer.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.io;
+
+import java.io.IOException;
+
+/**
+ * Deserializing a string valued object
+ */
+abstract public class ValueDeserializer extends AbstractDeserializer {
+  public Object readMap(AbstractHessianInput in)
+    throws IOException
+  {
+    String initValue = null;
+    
+    while (! in.isEnd()) {
+      String key = in.readString();
+
+      if (key.equals("value"))
+        initValue = in.readString();
+      else
+	in.readObject();
+    }
+
+    in.readMapEnd();
+
+    return create(initValue);
+  }
+  
+  public Object readObject(AbstractHessianInput in, String []fieldNames)
+    throws IOException
+  {
+    String initValue = null;
+
+    for (int i = 0; i < fieldNames.length; i++) {
+      if ("value".equals(fieldNames[i]))
+        initValue = in.readString();
+      else
+	in.readObject();
+    }
+
+    return create(initValue);
+  }
+
+  abstract Object create(String value)
+    throws IOException;
+}
diff --git src/com/caucho/hessian/util/IdentityIntMap.java src/com/caucho/hessian/util/IdentityIntMap.java
new file mode 100644
index 0000000..1f84e06
--- /dev/null
+++ src/com/caucho/hessian/util/IdentityIntMap.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.hessian.util;
+
+/**
+ * The IntMap provides a simple hashmap from keys to integers.  The API is
+ * an abbreviation of the HashMap collection API.
+ *
+ * <p>The convenience of IntMap is avoiding all the silly wrapping of
+ * integers.
+ */
+public class IdentityIntMap {
+  /**
+   * Encoding of a null entry.  Since NULL is equal to Integer.MIN_VALUE, 
+   * it's impossible to distinguish between the two.
+   */
+  public final static int NULL = 0xdeadbeef; // Integer.MIN_VALUE + 1;
+
+  private static final Object DELETED = new Object();
+
+  private Object []_keys;
+  private int []_values;
+
+  private int _size;
+  private int _mask;
+
+  /**
+   * Create a new IntMap.  Default size is 16.
+   */
+  public IdentityIntMap()
+  {
+    _keys = new Object[256];
+    _values = new int[256];
+
+    _mask = _keys.length - 1;
+    _size = 0;
+  }
+
+  /**
+   * Clear the hashmap.
+   */
+  public void clear()
+  {
+    Object []keys = _keys;
+    int []values = _values;
+
+    for (int i = keys.length - 1; i >= 0; i--) {
+      keys[i] = null;
+      values[i] = 0;
+    }
+
+    _size = 0;
+  }
+  /**
+   * Returns the current number of entries in the map.
+   */
+  public int size()
+  {
+    return _size;
+  }
+
+  /**
+   * Puts a new value in the property table with the appropriate flags
+   */
+  public int get(Object key)
+  {
+    int mask = _mask;
+    int hash = System.identityHashCode(key) % mask & mask;
+
+    Object []keys = _keys;
+
+    while (true) {
+      Object mapKey = keys[hash];
+
+      if (mapKey == null)
+        return NULL;
+      else if (mapKey == key)
+        return _values[hash];
+
+      hash = (hash + 1) % mask;
+    }
+  }
+
+  /**
+   * Expands the property table
+   */
+  private void resize(int newSize)
+  {
+    Object []newKeys = new Object[newSize];
+    int []newValues = new int[newSize];
+
+    int mask = _mask = newKeys.length - 1;
+
+    Object []keys = _keys;
+    int values[] = _values;
+
+    for (int i = keys.length - 1; i >= 0; i--) {
+      Object key = keys[i];
+
+      if (key == null || key == DELETED)
+        continue;
+
+      int hash = System.identityHashCode(key) % mask & mask;
+
+      while (true) {
+        if (newKeys[hash] == null) {
+          newKeys[hash] = key;
+          newValues[hash] = values[i];
+          break;
+        }
+
+        hash = (hash + 1) % mask;
+      }
+    }
+
+    _keys = newKeys;
+    _values = newValues;
+  }
+
+  /**
+   * Puts a new value in the property table with the appropriate flags
+   */
+  public int put(Object key, int value)
+  {
+    int mask = _mask;
+    int hash = System.identityHashCode(key) % mask & mask;
+
+    Object []keys = _keys;
+
+    while (true) {
+      Object testKey = keys[hash];
+
+      if (testKey == null || testKey == DELETED) {
+        keys[hash] = key;
+        _values[hash] = value;
+
+        _size++;
+
+        if (keys.length <= 4 * _size)
+          resize(4 * keys.length);
+
+        return NULL;
+      }
+      else if (key != testKey) {
+        hash = (hash + 1) % mask;
+
+        continue;
+      }
+      else {
+        int old = _values[hash];
+
+        _values[hash] = value;
+
+        return old;
+      }
+    }
+  }
+
+  /**
+   * Deletes the entry.  Returns true if successful.
+   */
+  public int remove(Object key)
+  {
+    int mask = _mask;
+    int hash = System.identityHashCode(key) % mask & mask;
+
+    while (true) {
+      Object mapKey = _keys[hash];
+
+      if (mapKey == null)
+        return NULL;
+      else if (mapKey == key) {
+        _keys[hash] = DELETED;
+
+        _size--;
+
+        return _values[hash];
+      }
+
+      hash = (hash + 1) % mask;
+    }
+  }
+
+  public String toString()
+  {
+    StringBuffer sbuf = new StringBuffer();
+
+    sbuf.append("IntMap[");
+    boolean isFirst = true;
+
+    for (int i = 0; i <= _mask; i++) {
+      if (_keys[i] != null && _keys[i] != DELETED) {
+        if (! isFirst)
+          sbuf.append(", ");
+
+        isFirst = false;
+        sbuf.append(_keys[i]);
+        sbuf.append(":");
+        sbuf.append(_values[i]);
+      }
+    }
+    sbuf.append("]");
+
+    return sbuf.toString();
+  }
+}
diff --git src/com/caucho/services/client/ServiceProxyFactory.java src/com/caucho/services/client/ServiceProxyFactory.java
new file mode 100644
index 0000000..7d4552a
--- /dev/null
+++ src/com/caucho/services/client/ServiceProxyFactory.java
@@ -0,0 +1,82 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.services.client;
+
+/**
+ * Factory for creating client stubs.  The returned stub will
+ * call the remote object for all methods.
+ *
+ * <pre>
+ * URL url = new URL("http://localhost:8080/ejb/hello");
+ * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
+ * </pre>
+ *
+ * After creation, the stub can be like a regular Java class.  Because
+ * it makes remote calls, it can throw more exceptions than a Java class.
+ * In particular, it may throw protocol exceptions.
+ */
+public interface ServiceProxyFactory {
+  /**
+   * Creates a new proxy with the specified URL.  The returned object
+   * is a proxy with the interface specified by api.
+   *
+   * <pre>
+   * String url = "http://localhost:8080/ejb/hello");
+   * HelloHome hello = (HelloHome) factory.create(HelloHome.class, url);
+   * </pre>
+   *
+   * @param api the interface the proxy class needs to implement
+   * @param url the URL where the client object is located.
+   *
+   * @return a proxy to the object with the specified interface.
+   * @throws java.net.MalformedURLException in case url to remote interface is invalid
+   */
+  public <T>T create(Class<T> api, String url)
+    throws java.net.MalformedURLException;
+}
diff --git src/com/caucho/services/server/AbstractSkeleton.java src/com/caucho/services/server/AbstractSkeleton.java
new file mode 100644
index 0000000..47dc67e
--- /dev/null
+++ src/com/caucho/services/server/AbstractSkeleton.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Caucho Technology (http://www.caucho.com/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
+ *    endorse or promote products derived from this software without prior
+ *    written permission. For written permission, please contact
+ *    info@caucho.com.
+ *
+ * 5. Products derived from this software may not be called "Resin"
+ *    nor may "Resin" appear in their names without prior written
+ *    permission of Caucho Technology.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @author Scott Ferguson
+ */
+
+package com.caucho.services.server;
+
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+/**
+ * Proxy class for Hessian services.
+ */
+abstract public class AbstractSkeleton {
+  private Class _apiClass;
+  private Class _homeClass;
+  private Class _objectClass;
+  
+  private HashMap _methodMap = new HashMap();
+
+  /**
+   * Create a new hessian skeleton.
+   *
+   * @param apiClass the API interface
+   */
+  protected AbstractSkeleton(Class apiClass)
+  {
+    _apiClass = apiClass;
+    
+    Method []methodList = apiClass.getMethods();
+
+    for (int i = 0; i < methodList.length; i++) {
+      Method method = methodList[i];
+
+      if (_methodMap.get(method.getName()) == null)
+        _methodMap.put(method.getName(), methodList[i]);
+
+      Class []param = method.getParameterTypes();
+      String mangledName = method.getName() + "__" + param.length;
+      _methodMap.put(mangledName, methodList[i]);
+      
+      _methodMap.put(mangleName(method, false), methodList[i]);
+    }
+  }
+
+  /**
+   * Returns the API class of the current object.
+   */
+  public String getAPIClassName()
+  {
+    return _apiClass.getName();
+  }
+
+  /**
+   * Returns the API class of the factory/home.
+   */
+  public String getHomeClassName()
+  {
+    if (_homeClass != null)
+      return _homeClass.getName();
+    else
+      return getAPIClassName();
+  }
+
+  /**
+   * Sets the home API class.
+   */
+  public void setHomeClass(Class homeAPI)
+  {
+    _homeClass = homeAPI;
+  }
+
+  /**
+   * Returns the API class of the object URLs
+   */
+  public String getObjectClassName()
+  {
+    if (_objectClass != null)
+      return _objectClass.getName();
+    else
+      return getAPIClassName();
+  }
+
+  /**
+   * Sets the object API class.
+   */
+  public void setObjectClass(Class objectAPI)
+  {
+    _objectClass = objectAPI;
+  }
+
+  /**
+   * Returns the method by the mangled name.
+   *
+   * @param mangledName the name passed by the protocol
+   */
+  protected Method getMethod(String mangledName)
+  {
+    return (Method) _methodMap.get(mangledName);
+  }
+
+  /**
+   * Creates a unique mangled method name based on the method name and
+   * the method parameters.
+   *
+   * @param method the method to mangle
+   * @param isFull if true, mangle the full classname
+   *
+   * @return a mangled string.
+   */
+  public static String mangleName(Method method, boolean isFull)
+  {
+    StringBuffer sb = new StringBuffer();
+    
+    sb.append(method.getName());
+    
+    Class []params = method.getParameterTypes();
+    for (int i = 0; i < params.length; i++) {
+      sb.append('_');
+      sb.append(mangleClass(params[i], isFull));
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Mangles a classname.
+   */
+  public static String mangleClass(Class cl, boolean isFull)
+  {
+    String name = cl.getName();
+
+    if (name.equals("boolean") || name.equals("java.lang.Boolean"))
+      return "boolean";
+    else if (name.equals("int") || name.equals("java.lang.Integer")
+	     || name.equals("short") || name.equals("java.lang.Short")
+	     || name.equals("byte") || name.equals("java.lang.Byte"))
+      return "int";
+    else if (name.equals("long") || name.equals("java.lang.Long"))
+      return "long";
+    else if (name.equals("float") || name.equals("java.lang.Float")
+	     || name.equals("double") || name.equals("java.lang.Double"))
+      return "double";
+    else if (name.equals("java.lang.String")
+	     || name.equals("com.caucho.util.CharBuffer")
+	     || name.equals("char") || name.equals("java.lang.Character")
+	     || name.equals("java.io.Reader"))
+      return "string";
+    else if (name.equals("java.util.Date")
+	     || name.equals("com.caucho.util.QDate"))
+      return "date";
+    else if (InputStream.class.isAssignableFrom(cl)
+	     || name.equals("[B"))
+      return "binary";
+    else if (cl.isArray()) {
+      return "[" + mangleClass(cl.getComponentType(), isFull);
+    }
+    else if (name.equals("org.w3c.dom.Node")
+	     || name.equals("org.w3c.dom.Element")
+	     || name.equals("org.w3c.dom.Document"))
+      return "xml";
+    else if (isFull)
+      return name;
+    else {
+      int p = name.lastIndexOf('.');
+      if (p > 0)
+        return name.substring(p + 1);
+      else
+        return name;
+    }
+  }
+
+  public String toString()
+  {
+    return getClass().getSimpleName() + "[" + _apiClass.getName() + "]";
+  }
+}

commit c154e659fd645d3cab7a6e4cd47a5cc889904b30
Author: Peter Björkman <peter@peterbjorkman.se>
Date:   Sun May 8 20:30:18 2011 +0200

    Add files for Skandiabankens hessian-api. Most classes do not have any logic just instnace variables needed for deserialization.

diff --git src/se/smartrefill/ad/bank/domain/AdAccount.java src/se/smartrefill/ad/bank/domain/AdAccount.java
new file mode 100644
index 0000000..13f2459
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdAccount.java
@@ -0,0 +1,173 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AdAccount implements Serializable {
+	public static final String KIND_AiE = "AiE";
+	public static final String KIND_DebitCreditCard = "DebitCreditCard";
+	public static final String KIND_Euro = "Euro";
+	public static final String KIND_FixedInterest = "FixedInterest";
+	public static final String KIND_Personal = "Personal";
+	public static final String KIND_Savings = "Savings";
+	private static final long serialVersionUID = 1L;
+	private String accountNumber;
+	private String accountTypeDescription;
+	private String alias;
+	private String amount;
+	private String bookingNumber;
+	private String bwdKey;
+	private int currentPage;
+	private String disposableAmount;
+	private String endDate;
+	private String fwdKey;
+	private String id;
+	private String interest;
+	private String kind;
+	private int messageLengthRecipient;
+	private int messageLengthStatement;
+	private String messageValidCharactersDisplay;
+	private String messageValidCharactersExpression;
+	private int order;
+	private String startDate;
+	private String tax;
+	private List<AdBalanceInformationTransaction> transactions;
+	private boolean validOverview;
+	private List<String> validRecevingAccounts;
+
+	public AdAccount() {
+		this.transactions = new ArrayList<AdBalanceInformationTransaction>();
+		this.validRecevingAccounts = new ArrayList<String>();
+	}
+
+	public String getAccountNumber() {
+		return this.accountNumber;
+	}
+
+	public String getAccountTypeDescription() {
+		return this.accountTypeDescription;
+	}
+
+	public String getAlias() {
+		return this.alias;
+	}
+
+	public String getAmount() {
+		return this.amount;
+	}
+
+	public String getBookingNumber() {
+		return this.bookingNumber;
+	}
+
+	public String getBwdKey() {
+		return this.bwdKey;
+	}
+
+	public int getCurrentPage() {
+		return this.currentPage;
+	}
+
+	public String getDisposableAmount() {
+		return this.disposableAmount;
+	}
+
+	public String getEndDate() {
+		return this.endDate;
+	}
+
+	public String getFwdKey() {
+		return this.fwdKey;
+	}
+
+	public String getId() {
+		return this.id;
+	}
+
+	public String getInterest() {
+		return this.interest;
+	}
+
+	public String getKind() {
+		return this.kind;
+	}
+
+	public int getMessageLengthRecipient() {
+		return this.messageLengthRecipient;
+	}
+
+	public int getMessageLengthStatement() {
+		return this.messageLengthStatement;
+	}
+
+	public String getMessageValidCharactersDisplay() {
+		return this.messageValidCharactersDisplay;
+	}
+
+	public String getMessageValidCharactersExpression() {
+		return this.messageValidCharactersExpression;
+	}
+
+	public String getNameNumber() {
+		if (isBlank(alias))
+			return accountNumber;
+		else
+			return alias;
+	}
+
+	public String getNameType() {
+		if (isBlank(alias))
+			return accountTypeDescription;
+		else
+			return alias;
+	}
+
+	public int getOrder() {
+		return this.order;
+	}
+
+	public String getStartDate() {
+		return this.startDate;
+	}
+
+	public String getTax() {
+		return this.tax;
+	}
+
+	public List<AdBalanceInformationTransaction> getTransactions() {
+		return this.transactions;
+	}
+
+	public List<String> getValidRecevingAccounts() {
+		return this.validRecevingAccounts;
+	}
+
+	public boolean hasMoreTransactions() {
+		return !isBlank(fwdKey);
+	}
+
+	public boolean isFixedInterest() {
+		return "FixedInterest".equals(kind);
+	}
+
+	public boolean isNotFixedInterest() {
+		return (!isFixedInterest());
+	}
+
+	public boolean isOtherBank() {
+		return "Personal".equals(kind);
+	}
+
+	public boolean isValidFromAccount() {
+		return (this.validRecevingAccounts.size() > 0);
+	}
+
+	public boolean isValidOverview() {
+		return this.validOverview;
+	}
+
+	private static boolean isBlank(String str) {
+		return str == null || str.contains("");
+	}
+}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceInformation.java src/se/smartrefill/ad/bank/domain/AdBalanceInformation.java
new file mode 100644
index 0000000..ca95937
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdBalanceInformation.java
@@ -0,0 +1,36 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AdBalanceInformation implements Serializable {
+	public static int CODE_ERROR = 1;
+	public static int CODE_INTENTIONALLY_BLANK = 2;
+	public static int CODE_OK = 0;
+	private static final long serialVersionUID = 1L;
+	private String amountSpent;
+	private List<AdBalanceInformationTransaction> balanceInformationTransactions;
+	private String disposableAmount;
+	private int statusCode;
+
+	public AdBalanceInformation() {
+		this.balanceInformationTransactions = new ArrayList<AdBalanceInformationTransaction>();
+	}
+
+	public String getAmountSpent() {
+		return amountSpent;
+	}
+
+	public List<AdBalanceInformationTransaction> getBalanceInformationTransactions() {
+		return balanceInformationTransactions;
+	}
+
+	public String getDisposableAmount() {
+		return disposableAmount;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceInformationTransaction.java src/se/smartrefill/ad/bank/domain/AdBalanceInformationTransaction.java
new file mode 100644
index 0000000..93a6858
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdBalanceInformationTransaction.java
@@ -0,0 +1,40 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+
+public class AdBalanceInformationTransaction implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private String amount;
+	private String id;
+	private String merchant;
+	private int order;
+	private int page;
+	private String time;
+
+	public AdBalanceInformationTransaction() {
+	}
+
+	public String getAmount() {
+		return this.amount;
+	}
+
+	public String getId() {
+		return this.id;
+	}
+
+	public String getMerchant() {
+		return this.merchant;
+	}
+
+	public int getOrder() {
+		return this.order;
+	}
+
+	public int getPage() {
+		return this.page;
+	}
+
+	public String getTime() {
+		return this.time;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceService.java src/se/smartrefill/ad/bank/domain/AdBalanceService.java
new file mode 100644
index 0000000..95930ee
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdBalanceService.java
@@ -0,0 +1,48 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+import se.smartrefill.ad.domain.AdService;
+
+public class AdBalanceService extends AdService {
+	private static final long serialVersionUID = 1L;
+	private List<AdBalanceServiceCard> balanceServiceCards;
+	private int dayOfMonthForBalance;
+	private int dayOfWeekForBalance;
+	private int endHourForBalance;
+	private boolean monthlySubscription;
+	private int startHourForBalance;
+	private boolean weeklySubscription;
+
+	public AdBalanceService() {
+		this.balanceServiceCards = new ArrayList<AdBalanceServiceCard>();
+	}
+
+	public List<AdBalanceServiceCard> getBalanceServiceCards() {
+		return balanceServiceCards;
+	}
+
+	public int getDayOfMonthForBalance() {
+		return dayOfMonthForBalance;
+	}
+
+	public int getDayOfWeekForBalance() {
+		return dayOfWeekForBalance;
+	}
+
+	public int getEndHourForBalance() {
+		return endHourForBalance;
+	}
+
+	public boolean isMonthlySubscription() {
+		return monthlySubscription;
+	}
+
+	public int getStartHourForBalance() {
+		return startHourForBalance;
+	}
+
+	public boolean isWeeklySubscription() {
+		return weeklySubscription;
+	}
+}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdBalanceServiceCard.java src/se/smartrefill/ad/bank/domain/AdBalanceServiceCard.java
new file mode 100644
index 0000000..4eab1cd
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdBalanceServiceCard.java
@@ -0,0 +1,76 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import se.smartrefill.ad.domain.AdPaymentCard;
+
+public class AdBalanceServiceCard
+  implements Serializable
+{
+  private static final long serialVersionUID = 1L;
+  private AdBalanceInformation balanceInformation;
+  private int dayOfMonthForBalance;
+  private int dayOfWeekForBalance;
+  private Integer id;
+  private int monthlyBalanceEndHour;
+  private int monthlyBalanceStartHour;
+  private boolean monthlySubscription;
+  private AdPaymentCard paymentCard;
+  private int weeklyBalanceEndHour;
+  private int weeklyBalanceStartHour;
+  private boolean weeklySubscription;
+
+  public AdBalanceInformation getBalanceInformation()
+  {
+    return this.balanceInformation;
+  }
+
+  public int getDayOfMonthForBalance()
+  {
+    return this.dayOfMonthForBalance;
+  }
+
+  public int getDayOfWeekForBalance()
+  {
+    return this.dayOfWeekForBalance;
+  }
+
+  public Integer getId()
+  {
+    return this.id;
+  }
+
+  public int getMonthlyBalanceEndHour()
+  {
+    return this.monthlyBalanceEndHour;
+  }
+
+  public int getMonthlyBalanceStartHour()
+  {
+    return this.monthlyBalanceStartHour;
+  }
+
+  public AdPaymentCard getPaymentCard()
+  {
+    return this.paymentCard;
+  }
+
+  public int getWeeklyBalanceEndHour()
+  {
+    return this.weeklyBalanceEndHour;
+  }
+
+  public int getWeeklyBalanceStartHour()
+  {
+    return this.weeklyBalanceStartHour;
+  }
+
+  public boolean isMonthlySubscription()
+  {
+    return this.monthlySubscription;
+  }
+
+  public boolean isWeeklySubscription()
+  {
+    return this.weeklySubscription;
+  }
+}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdCekabNotificationService.java src/se/smartrefill/ad/bank/domain/AdCekabNotificationService.java
new file mode 100644
index 0000000..5d9ea97
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdCekabNotificationService.java
@@ -0,0 +1,19 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+import se.smartrefill.ad.domain.AdService;
+
+public class AdCekabNotificationService extends AdService {
+	private static final long serialVersionUID = 1L;
+	private List<AdCekabPan> pans;
+
+	public AdCekabNotificationService() {
+		this.pans = new ArrayList<AdCekabPan>();
+	}
+
+	public List<AdCekabPan> getPans() {
+		return pans;
+	}
+
+}
diff --git src/se/smartrefill/ad/bank/domain/AdCekabPan.java src/se/smartrefill/ad/bank/domain/AdCekabPan.java
new file mode 100644
index 0000000..42e482d
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdCekabPan.java
@@ -0,0 +1,39 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import se.smartrefill.ad.domain.AdPaymentCard;
+
+public class AdCekabPan implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private int alertMeLowLimit;
+	private List<AdCekabPanNotificationLog> cekabPanNotificationLogs;
+	private Integer id;
+	private AdPaymentCard paymentCard;
+	private String status;
+
+	public AdCekabPan() {
+		this.cekabPanNotificationLogs = new ArrayList<AdCekabPanNotificationLog>();
+	}
+
+	public int getAlertMeLowLimit() {
+		return alertMeLowLimit;
+	}
+
+	public List<AdCekabPanNotificationLog> getCekabPanNotificationLogs() {
+		return cekabPanNotificationLogs;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public AdPaymentCard getPaymentCard() {
+		return paymentCard;
+	}
+
+	public String getStatus() {
+		return status;
+	}
+}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLog.java src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLog.java
new file mode 100644
index 0000000..adb0c57
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLog.java
@@ -0,0 +1,90 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class AdCekabPanNotificationLog implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private String amount;
+	private String city;
+	private Date created;
+	private String currency;
+	private String functionCode;
+	private Integer id;
+	private transient String last4PaymentCardDigits;
+	private String location;
+	private List<AdCekabPanNotificationLogMedia> medias;
+	private String pan;
+	private String purchaseDate;
+	private String purchaseTime;
+	private String replyCode;
+	private String result;
+	private String shop;
+
+	public AdCekabPanNotificationLog() {
+		this.medias = new ArrayList<AdCekabPanNotificationLogMedia>();
+		this.last4PaymentCardDigits = "";
+	}
+
+	public String getAmount() {
+		return amount;
+	}
+
+	public String getCity() {
+		return city;
+	}
+
+	public Date getCreated() {
+		return created;
+	}
+
+	public String getCurrency() {
+		return currency;
+	}
+
+	public String getFunctionCode() {
+		return functionCode;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public String getLast4PaymentCardDigits() {
+		return last4PaymentCardDigits;
+	}
+
+	public String getLocation() {
+		return location;
+	}
+
+	public List<AdCekabPanNotificationLogMedia> getMedias() {
+		return medias;
+	}
+
+	public String getPan() {
+		return pan;
+	}
+
+	public String getPurchaseDate() {
+		return purchaseDate;
+	}
+
+	public String getPurchaseTime() {
+		return purchaseTime;
+	}
+
+	public String getReplyCode() {
+		return replyCode;
+	}
+
+	public String getResult() {
+		return result;
+	}
+
+	public String getShop() {
+		return shop;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLogMedia.java src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLogMedia.java
new file mode 100644
index 0000000..4ce0d44
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdCekabPanNotificationLogMedia.java
@@ -0,0 +1,32 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+
+public class AdCekabPanNotificationLogMedia implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private String caption;
+	private int cekabPanNotificationLogId;
+	private int id;
+	private byte[] media;
+	private String mediaType;
+
+	public String getCaption() {
+		return caption;
+	}
+
+	public int getCekabPanNotificationLogId() {
+		return cekabPanNotificationLogId;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public byte[] getMedia() {
+		return media;
+	}
+
+	public String getMediaType() {
+		return mediaType;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdMoneyTransferCard.java src/se/smartrefill/ad/bank/domain/AdMoneyTransferCard.java
new file mode 100644
index 0000000..a90c4cf
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdMoneyTransferCard.java
@@ -0,0 +1,48 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class AdMoneyTransferCard implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private String alias;
+	private int creditCardId;
+	private int id;
+	private String mobileNumber;
+	private List<AdMoneyTransferOrder> moneyTransferOrders;
+	private AdMoneyTransferService moneyTransferService;
+	private boolean pending;
+
+	public AdMoneyTransferCard() {
+		this.moneyTransferOrders = new ArrayList<AdMoneyTransferOrder>();
+	}
+
+	public String getAlias() {
+		return alias;
+	}
+
+	public int getCreditCardId() {
+		return creditCardId;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public String getMobileNumber() {
+		return mobileNumber;
+	}
+
+	public List<AdMoneyTransferOrder> getMoneyTransferOrders() {
+		return moneyTransferOrders;
+	}
+
+	public AdMoneyTransferService getMoneyTransferService() {
+		return moneyTransferService;
+	}
+
+	public boolean isPending() {
+		return pending;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdMoneyTransferOrder.java src/se/smartrefill/ad/bank/domain/AdMoneyTransferOrder.java
new file mode 100644
index 0000000..20e51d1
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdMoneyTransferOrder.java
@@ -0,0 +1,36 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+
+public class AdMoneyTransferOrder implements Serializable {
+	public static final int STATE_COMPLETE = 2;
+	public static final int STATE_FAILED = 3;
+	public static final int STATE_PENDING = 1;
+	public static final int STATE_UNKNOWN = 0;
+	private static final long serialVersionUID = 1L;
+	private String amount;
+	private String created;
+	private int id;
+	private AdMoneyTransferCard moneyTransferCard;
+	private int state = 0;
+
+	public String getAmount() {
+		return amount;
+	}
+
+	public String getCreated() {
+		return created;
+	}
+
+	public int getId() {
+		return id;
+	}
+
+	public AdMoneyTransferCard getMoneyTransferCard() {
+		return moneyTransferCard;
+	}
+
+	public int getState() {
+		return state;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdMoneyTransferService.java src/se/smartrefill/ad/bank/domain/AdMoneyTransferService.java
new file mode 100644
index 0000000..733e77b
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdMoneyTransferService.java
@@ -0,0 +1,18 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+import se.smartrefill.ad.domain.AdService;
+
+public class AdMoneyTransferService extends AdService {
+	private static final long serialVersionUID = 1L;
+	private List<AdMoneyTransferCard> moneyTransferCards;
+
+	public AdMoneyTransferService() {
+		this.moneyTransferCards = new ArrayList<AdMoneyTransferCard>();
+	}
+
+	public List<AdMoneyTransferCard> getMoneyTransferCards() {
+		return moneyTransferCards;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
new file mode 100644
index 0000000..bf4c404
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdPendingCreditCard.java
@@ -0,0 +1,34 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+
+public class AdPendingCreditCard
+  implements Serializable
+{
+  private static final long serialVersionUID = 1L;
+  private String alias;
+  private String number;
+  private String partner;
+  private String phoneNumber;
+	private int serviceId;
+
+	public String getAlias() {
+		return alias;
+	}
+
+	public String getNumber() {
+		return number;
+	}
+
+	public String getPartner() {
+		return partner;
+	}
+
+	public String getPhoneNumber() {
+		return phoneNumber;
+	}
+
+	public int getServiceId() {
+		return serviceId;
+	}
+}
diff --git src/se/smartrefill/ad/bank/domain/AdTexts.java src/se/smartrefill/ad/bank/domain/AdTexts.java
new file mode 100644
index 0000000..9a2cda6
--- /dev/null
+++ src/se/smartrefill/ad/bank/domain/AdTexts.java
@@ -0,0 +1,18 @@
+package se.smartrefill.ad.bank.domain;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AdTexts implements Serializable {
+	private static final long serialVersionUID = 1L;
+	private Map<String, String> texts;
+
+	public AdTexts() {
+		this.texts = new HashMap<String, String>();
+	}
+
+	public Map<String, String> getTexts() {
+		return texts;
+	}
+}
diff --git src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
new file mode 100644
index 0000000..f00b949
--- /dev/null
+++ src/se/smartrefill/ad/bank/remoting/service/RemoteBalanceService.java
@@ -0,0 +1,10 @@
+package se.smartrefill.ad.bank.remoting.service;
+
+import java.util.List;
+import se.smartrefill.ad.bank.domain.AdAccount;
+
+public abstract interface RemoteBalanceService
+{
+  public abstract AdAccount getAccountTransactions(AdAccount account, String scrollDirection, String securityCode);
+  public abstract List<AdAccount> getAccounts(int customerBalanceServiceId, String securityCode);
+}
\ No newline at end of file
diff --git src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
new file mode 100644
index 0000000..a3e4964
--- /dev/null
+++ src/se/smartrefill/ad/bank/remoting/service/RemoteCustomerService.java
@@ -0,0 +1,17 @@
+package se.smartrefill.ad.bank.remoting.service;
+
+import se.smartrefill.ad.domain.AdCustomer;
+import se.smartrefill.exception.UnauthenticatedUserException;
+
+public abstract interface RemoteCustomerService
+{
+  public abstract AdCustomer getCustomer(String username, String password, String customerOwner, String countryCode)
+    throws UnauthenticatedUserException;
+
+  public abstract AdCustomer getCustomerWithoutBalanceInformation(String paramString1, String paramString2, String paramString3, String paramString4)
+    throws UnauthenticatedUserException;
+
+  public abstract AdCustomer login(String username, String password, String customerOwner, String countryCode)
+    throws UnauthenticatedUserException;
+
+}
\ No newline at end of file
diff --git src/se/smartrefill/ad/domain/AdAbstractCustomer.java src/se/smartrefill/ad/domain/AdAbstractCustomer.java
new file mode 100644
index 0000000..d7c515a
--- /dev/null
+++ src/se/smartrefill/ad/domain/AdAbstractCustomer.java
@@ -0,0 +1,26 @@
+package se.smartrefill.ad.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class AdAbstractCustomer
+  implements Serializable
+{
+  private static final long serialVersionUID = 1L;
+  protected String countryCode;
+  protected String customerOwner;
+  protected Integer id;
+  protected String maskedCardNumber;
+  protected Boolean mustChangePassword;
+  protected Integer paymentCardId;
+  protected List<AdPaymentCard> paymentCards;
+  protected List<AdService> services;
+  protected String socialSecurityNumber;
+
+  public AdAbstractCustomer()
+  {
+    this.services = new ArrayList<AdService>();
+    this.paymentCards = new ArrayList<AdPaymentCard>();
+  }
+}
diff --git src/se/smartrefill/ad/domain/AdCustomer.java src/se/smartrefill/ad/domain/AdCustomer.java
new file mode 100644
index 0000000..25defd6
--- /dev/null
+++ src/se/smartrefill/ad/domain/AdCustomer.java
@@ -0,0 +1,18 @@
+package se.smartrefill.ad.domain;
+
+import java.io.Serializable;
+
+import se.smartrefill.ad.bank.domain.AdBalanceService;
+
+public class AdCustomer extends AdAbstractCustomer implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	public AdBalanceService getBalanceService() {
+		
+		for (AdService service : this.services) {
+			if (service instanceof AdBalanceService)
+				return (AdBalanceService)service;
+		}
+		return null;
+	}
+}
diff --git src/se/smartrefill/ad/domain/AdPaymentCard.java src/se/smartrefill/ad/domain/AdPaymentCard.java
new file mode 100644
index 0000000..3ced145
--- /dev/null
+++ src/se/smartrefill/ad/domain/AdPaymentCard.java
@@ -0,0 +1,26 @@
+package se.smartrefill.ad.domain;
+
+import java.io.Serializable;
+
+public class AdPaymentCard
+  implements Serializable
+{
+  private static final long serialVersionUID = 1L;
+  private String description;
+  private int id;
+  private String maskedPaymentCard;
+  private int paymentRef;
+  
+  public String getDescription() {
+		return description;
+	}
+	public int getId() {
+		return id;
+	}
+	public String getMaskedPaymentCard() {
+		return maskedPaymentCard;
+	}
+	public int getPaymentRef() {
+		return paymentRef;
+	}
+}
diff --git src/se/smartrefill/ad/domain/AdService.java src/se/smartrefill/ad/domain/AdService.java
new file mode 100644
index 0000000..2eeca97
--- /dev/null
+++ src/se/smartrefill/ad/domain/AdService.java
@@ -0,0 +1,57 @@
+package se.smartrefill.ad.domain;
+
+import java.io.Serializable;
+
+public abstract class AdService
+  implements Serializable
+{
+  private static final long serialVersionUID = 1L;
+  private Integer id;
+  private String imei;
+  private String manufacturer;
+  private String mobileNumber;
+  private String model;
+  private String operator;
+  private String password;
+  private String userName;
+
+  public Integer getId()
+  {
+    return this.id;
+  }
+
+  public String getImei()
+  {
+    return this.imei;
+  }
+
+  public String getManufacturer()
+  {
+    return this.manufacturer;
+  }
+
+  public String getMobileNumber()
+  {
+    return this.mobileNumber;
+  }
+
+  public String getModel()
+  {
+    return this.model;
+  }
+
+  public String getOperator()
+  {
+    return this.operator;
+  }
+
+  public String getPassword()
+  {
+    return this.password;
+  }
+
+  public String getUserName()
+  {
+    return this.userName;
+  }
+}
\ No newline at end of file
diff --git src/se/smartrefill/exception/CustomerBlockedException.java src/se/smartrefill/exception/CustomerBlockedException.java
new file mode 100644
index 0000000..a943ab4
--- /dev/null
+++ src/se/smartrefill/exception/CustomerBlockedException.java
@@ -0,0 +1,12 @@
+package se.smartrefill.exception;
+
+public class CustomerBlockedException extends SmartrefillException {
+	private static final long serialVersionUID = 1L;
+
+	public CustomerBlockedException() {
+	}
+
+	public CustomerBlockedException(String paramString) {
+		super(paramString);
+	}
+}
diff --git src/se/smartrefill/exception/InvalidLoginException.java src/se/smartrefill/exception/InvalidLoginException.java
new file mode 100644
index 0000000..fcddf65
--- /dev/null
+++ src/se/smartrefill/exception/InvalidLoginException.java
@@ -0,0 +1,12 @@
+package se.smartrefill.exception;
+
+public class InvalidLoginException extends SmartrefillException{
+	private static final long serialVersionUID = 1L;
+
+	public InvalidLoginException() {
+	}
+
+	public InvalidLoginException(String paramString) {
+		super(paramString);
+	}
+}
\ No newline at end of file
diff --git src/se/smartrefill/exception/InvalidSecurityCodeException.java src/se/smartrefill/exception/InvalidSecurityCodeException.java
new file mode 100644
index 0000000..c185f34
--- /dev/null
+++ src/se/smartrefill/exception/InvalidSecurityCodeException.java
@@ -0,0 +1,15 @@
+package se.smartrefill.exception;
+
+public class InvalidSecurityCodeException extends ValidationException
+{
+  private static final long serialVersionUID = 1L;
+
+  public InvalidSecurityCodeException()
+  {
+  }
+
+  public InvalidSecurityCodeException(String paramString)
+  {
+    super(paramString);
+  }
+}
\ No newline at end of file
diff --git src/se/smartrefill/exception/SmartrefillException.java src/se/smartrefill/exception/SmartrefillException.java
new file mode 100644
index 0000000..98a0111
--- /dev/null
+++ src/se/smartrefill/exception/SmartrefillException.java
@@ -0,0 +1,13 @@
+package se.smartrefill.exception;
+
+public class SmartrefillException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+
+	public SmartrefillException() {
+		this(null);
+	}
+
+	public SmartrefillException(String paramString) {
+		super(paramString);
+	}
+}
diff --git src/se/smartrefill/exception/UnauthenticatedUserException.java src/se/smartrefill/exception/UnauthenticatedUserException.java
new file mode 100644
index 0000000..fdb6dd9
--- /dev/null
+++ src/se/smartrefill/exception/UnauthenticatedUserException.java
@@ -0,0 +1,12 @@
+package se.smartrefill.exception;
+
+public class UnauthenticatedUserException extends SmartrefillException {
+	private static final long serialVersionUID = 1L;
+
+	public UnauthenticatedUserException() {
+	}
+
+	public UnauthenticatedUserException(String paramString) {
+		super(paramString);
+	}
+}
diff --git src/se/smartrefill/exception/ValidationException.java src/se/smartrefill/exception/ValidationException.java
new file mode 100644
index 0000000..e05b245
--- /dev/null
+++ src/se/smartrefill/exception/ValidationException.java
@@ -0,0 +1,15 @@
+package se.smartrefill.exception;
+
+public class ValidationException extends SmartrefillException
+{
+  private static final long serialVersionUID = 1L;
+
+  public ValidationException()
+  {
+  }
+
+  public ValidationException(String paramString)
+  {
+    super(paramString);
+  }
+}
\ No newline at end of file

commit 24446b1340f810d5079c4991b3cffe2535a2ded2
Author: Joakim Andersson <jocke@barbanet.com>
Date:   Sun May 8 12:45:54 2011 +0200

    Remove unnecessary intent names.
    
    This removes the risk of breakage because of strings (in code and Manifest) loosing sync.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0da3956..378b1b1 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -42,10 +42,6 @@
 			android:name=".SettingsActivity"
 			android:label="@string/app_name"
 			android:theme="@style/BankdroidTheme">
-			<intent-filter>
-				<action android:name="com.liato.bankdroid.liveview.SETTINGS"></action> 	
-				<category android:name="android.intent.category.DEFAULT"/>
-			</intent-filter>
 		</activity>
 		<activity
 			android:label="@string/app_name"
@@ -118,11 +114,6 @@
 		
         <service android:name=".liveview.LiveViewService"
 				 android:label="LiveView plugin service">
-			<intent-filter>
-				<action android:name="com.liato.bankdroid.liveview.SERVICE"/>
-				<category android:name="android.intent.category.LAUNCHER"/>
-				<action android:name="com.liato.bankdroid.liveview.ANNOUNCE"/>
-        	</intent-filter>
 		</service>
 	    <receiver android:name=".liveview.PluginReceiver">
 			<intent-filter>
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 6bbc1aa..8c58d0b 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -132,7 +132,8 @@ public class AutoRefreshService extends Service {
 		// Broadcast to LiveView if enabled
 		// http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay
 		if (prefs.getBoolean("notify_liveview", false)) {
-			final Intent i = new Intent(LiveViewService.INTENT_ANNOUNCE);
+			final Intent i = new Intent(context, LiveViewService.class);
+			i.putExtra(LiveViewService.INTENT_EXTRA_ANNOUNCE, true);
 			i.putExtra(LiveViewService.INTENT_EXTRA_TITLE, String.format("%s (%s)", bank, title));
 			i.putExtra(LiveViewService.INTENT_EXTRA_TEXT, text);
 			context.startService(i);
diff --git src/com/liato/bankdroid/liveview/LiveViewService.java src/com/liato/bankdroid/liveview/LiveViewService.java
index 5456de0..2e4946c 100644
--- src/com/liato/bankdroid/liveview/LiveViewService.java
+++ src/com/liato/bankdroid/liveview/LiveViewService.java
@@ -60,7 +60,7 @@ import android.util.Log;
  */
 public class LiveViewService extends Service {
 	// Announce intent information keys
-	public static final String INTENT_ANNOUNCE = "com.liato.bankdroid.liveview.ANNOUNCE";
+	public static final String INTENT_EXTRA_ANNOUNCE = "isAnnounce";
 	public static final String INTENT_EXTRA_TITLE = "title";
 	public static final String INTENT_EXTRA_TEXT = "text";
 
@@ -151,7 +151,7 @@ public class LiveViewService extends Service {
         super.onStart(intent, startId);
         Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
         
-		if (intent.getAction().equals(INTENT_ANNOUNCE)) {
+		if (intent.getBooleanExtra(INTENT_EXTRA_ANNOUNCE, false)) {
 			Bundle extras = intent.getExtras();
 			if (extras != null) {
 				try {
@@ -168,6 +168,7 @@ public class LiveViewService extends Service {
 			}
 			
 		} else {
+			// We end up here when LiveView Application probes the plugin
 	        if (isAlreadyRunning()) {
 	            Log.d(PluginConstants.LOG_TAG, "Already started.");
 	        } else {
diff --git src/com/liato/bankdroid/liveview/PluginConstants.java src/com/liato/bankdroid/liveview/PluginConstants.java
index a031a46..a1da367 100644
--- src/com/liato/bankdroid/liveview/PluginConstants.java
+++ src/com/liato/bankdroid/liveview/PluginConstants.java
@@ -59,10 +59,6 @@ public final class PluginConstants {
     // LiveView Plugin interface intents
     public static final String LIVEVIEW_SERVICE_BIND_INTENT = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
     public static final String LIVEVIEW_BROADCAST_LAUNCH_EVENT = "com.sonyericsson.extras.liveview.LAUNCH_PLUGIN";
-    
-    // These MUST match the intent names in AndroidManifest.xml!
-    public static final String PLUGIN_PREFERENCES_INTENT = "com.liato.bankdroid.liveview.SETTINGS";
-    public static final String PLUGIN_SERVICE_INTENT = "com.liato.bankdroid.liveview.SERVICE";
 
     // Log tag
     public static final String LOG_TAG = "BankDroidLiveViewPlugin";
diff --git src/com/liato/bankdroid/liveview/PluginReceiver.java src/com/liato/bankdroid/liveview/PluginReceiver.java
index 04c53a3..7859f70 100644
--- src/com/liato/bankdroid/liveview/PluginReceiver.java
+++ src/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -39,6 +39,8 @@
 
 package com.liato.bankdroid.liveview;
 
+import com.liato.bankdroid.SettingsActivity;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -65,9 +67,9 @@ public class PluginReceiver extends BroadcastReceiver {
 			String myPluginName = PluginUtils.getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
 
 			if(pluginName != null && pluginName.contentEquals(myPluginName)) {
-				Log.d(PluginConstants.LOG_TAG, "Starting preferences! Intent: " + PluginConstants.PLUGIN_PREFERENCES_INTENT);
+				Log.d(PluginConstants.LOG_TAG, "Starting preferences!");
 				
-				Intent prefsIntent = new Intent(PluginConstants.PLUGIN_PREFERENCES_INTENT);
+				Intent prefsIntent = new Intent(context, SettingsActivity.class);
 				prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 				context.startActivity(prefsIntent);
 			}
@@ -76,9 +78,9 @@ public class PluginReceiver extends BroadcastReceiver {
 			if(LiveViewService.isAlreadyRunning()) {
 			    Log.d(PluginConstants.LOG_TAG, "Service is already running.");
 			} else {
-				Log.d(PluginConstants.LOG_TAG, "Starting service! Intent: " + PluginConstants.PLUGIN_SERVICE_INTENT);
+				Log.d(PluginConstants.LOG_TAG, "Starting service!");
 				
-				context.startService(new Intent(PluginConstants.PLUGIN_SERVICE_INTENT));
+				context.startService(new Intent(context, LiveViewService.class));
 			}
 		}
 		

commit dd4ba6e228ad96eaa413c0c15dcdc7fb3c5ab2d0
Author: Joakim Andersson <jocke@barbanet.com>
Date:   Sat May 7 17:37:13 2011 +0200

    Implement Sony Ericsson LiveView notification support.
    
    The Sony Ericsson LiveView SDK classes were imported but stripped and customized. All support for "sandbox" plugins were removed to reduce the application footprint.

diff --git AndroidManifest.xml AndroidManifest.xml
index 56a5c11..0da3956 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -42,6 +42,10 @@
 			android:name=".SettingsActivity"
 			android:label="@string/app_name"
 			android:theme="@style/BankdroidTheme">
+			<intent-filter>
+				<action android:name="com.liato.bankdroid.liveview.SETTINGS"></action> 	
+				<category android:name="android.intent.category.DEFAULT"/>
+			</intent-filter>
 		</activity>
 		<activity
 			android:label="@string/app_name"
@@ -111,14 +115,30 @@
 					android:path="com.liato.bankdroid" />
 			</intent-filter>
 		</receiver>
-	<provider 
-		android:name=".provider.BankTransactionsProvider" 
-		android:syncable="false"
-		android:multiprocess="true"
-		android:exported="true"
-		android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
-		android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS"/>
-</application>
+		
+        <service android:name=".liveview.LiveViewService"
+				 android:label="LiveView plugin service">
+			<intent-filter>
+				<action android:name="com.liato.bankdroid.liveview.SERVICE"/>
+				<category android:name="android.intent.category.LAUNCHER"/>
+				<action android:name="com.liato.bankdroid.liveview.ANNOUNCE"/>
+        	</intent-filter>
+		</service>
+	    <receiver android:name=".liveview.PluginReceiver">
+			<intent-filter>
+				<action android:name="com.sonyericsson.extras.liveview.LAUNCH_PLUGIN" />
+			</intent-filter>
+	    </receiver>
+	    
+		<provider 
+			android:name=".provider.BankTransactionsProvider" 
+			android:syncable="false"
+			android:multiprocess="true"
+			android:exported="true"
+			android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
+			android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS"/>
+	</application>
+	
 	<uses-sdk
 		android:targetSdkVersion="4"
 		android:minSdkVersion="4" />
@@ -128,6 +148,8 @@
 		android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 	<uses-permission
 		android:name="android.permission.VIBRATE" />
+	<uses-permission
+		android:name="com.sonyericsson.extras.liveview.permission.LIVEVIEW_API" />
 	<supports-screens
 		android:largeScreens="true"
 		android:normalScreens="true"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index a23a78c..ae50a5a 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -88,6 +88,11 @@
 	<string name="openwatch_vibrate_summary">Vibrera OpenWatch-enheten</string>
 	<string name="openwatch_help_title">Vad är OpenWatch?</string>
 	<string name="openwatch_help_summary">Läs mer om OpenWatch på deras webbsida</string>
+	<string name="liveview_title">LiveView-integrering</string>
+	<string name="liveview_enable_title">Aktivera</string>
+	<string name="liveview_enable_summary">Aktivera Sony Ericssson LiveView-integrering</string>
+	<string name="liveview_help_title">Vad är LiveView?</string>
+	<string name="liveview_help_summary">Läs mer om LiveView på Sony Ericssons webbsida</string>
 	<string name="share_data_title">Dela ut data</string>
 	<string name="share_data_enable_title">Aktivera utdelninga av data</string>
 	<string name="share_data_enable_summary">Medge andra installerade applikationer åtkomst till kontoutdrag</string>
diff --git res/values/strings.xml res/values/strings.xml
index b305b08..b159659 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -90,6 +90,11 @@
 	<string name="openwatch_vibrate_summary">Vibrate the OpenWatch device</string>
 	<string name="openwatch_help_title">What is OpenWatch?</string>
 	<string name="openwatch_help_summary">Read more about OpenWatch on their website</string>
+	<string name="liveview_title">LiveView Integration</string>
+	<string name="liveview_enable_title">Enable</string>
+	<string name="liveview_enable_summary">Enable Sony Ericsson LiveView integration</string>
+	<string name="liveview_help_title">What is LiveView?</string>
+	<string name="liveview_help_summary">Read more about LiveView on Sony Ericsson\'s website</string>
 	<string name="share_data_title">Share data</string>
 	<string name="share_data_enable_title">Enable data sharing</string>
 	<string name="share_data_enable_summary">Grant other installed apps access to your transaction history</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index bb19308..06bbdf8 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -174,6 +174,20 @@
 				android:summary="@string/openwatch_help_summary"
 				android:key="openwatch_help" />
 		</PreferenceScreen>
+		<PreferenceScreen
+			android:key="liveview_screen"
+			android:title="@string/liveview_title"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_liveview"
+				android:defaultValue="false"
+				android:title="@string/liveview_enable_title"
+				android:summary="@string/liveview_enable_summary" />
+			<Preference
+				android:title="@string/liveview_help_title"
+				android:summary="@string/liveview_help_summary"
+				android:key="liveview_help" />
+		</PreferenceScreen>
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="@string/share_data_title">
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 1a13583..664f56d 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -47,13 +47,13 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		addPreferencesFromResource(R.xml.settings);
 		getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
 		(findPreference("patternlock_change")).setOnPreferenceClickListener(this);
-		(findPreference("patternlock_change")).setOnPreferenceClickListener(this);
 		(findPreference("remotenotifier_help")).setOnPreferenceClickListener(this);
 		(findPreference("openwatch_help")).setOnPreferenceClickListener(this);
+		(findPreference("liveview_help")).setOnPreferenceClickListener(this);
 		(findPreference("account_types_screen")).setOnPreferenceClickListener(this);
 		(findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
 		(findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
-		(findPreference("autoupdates_enabled")).setOnPreferenceClickListener(this);
+		(findPreference("liveview_screen")).setOnPreferenceClickListener(this);
         (findPreference("notification_sound")).setOnPreferenceClickListener(this);
         (findPreference("test_notification")).setOnPreferenceClickListener(this);
         (findPreference("notify_min_delta")).setOnPreferenceChangeListener(this);
@@ -66,7 +66,10 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 	@Override
 	public boolean onPreferenceClick(final Preference pref) {
 		final String prefKey = pref.getKey();
-		if ("account_types_screen".equals(prefKey) || "openwatch_screen".equals(prefKey) || "remotenotifier_screen".equals(prefKey)) {
+		if ("account_types_screen".equals(prefKey) ||
+				"remotenotifier_screen".equals(prefKey) ||
+				"openwatch_screen".equals(prefKey) ||
+				"liveview_screen".equals(prefKey)) {
 			((PreferenceScreen)pref).getDialog().getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
 			return false;
 		}
@@ -104,6 +107,11 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 					Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));
 			return true;
 		}
+		else if ("liveview_help".equals(prefKey)) {
+			startActivity(new Intent(Intent.ACTION_VIEW,
+					Uri.parse("http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay")));
+			return true;
+		}
 		else if ("test_notification".equals(prefKey)) {
             Log.d(TAG, "Sending test notification.");
             AutoRefreshService.showNotification(
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index c659f96..6bbc1aa 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -45,6 +45,7 @@ import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.liveview.LiveViewService;
 
 public class AutoRefreshService extends Service {
 	private final static String TAG = "AutoRefreshService";
@@ -127,6 +128,15 @@ public class AutoRefreshService extends Service {
 			i.putExtra("line2", text);
 			context.sendBroadcast(i);
 		}
+		
+		// Broadcast to LiveView if enabled
+		// http://www.sonyericsson.com/cws/products/accessories/overview/liveviewmicrodisplay
+		if (prefs.getBoolean("notify_liveview", false)) {
+			final Intent i = new Intent(LiveViewService.INTENT_ANNOUNCE);
+			i.putExtra(LiveViewService.INTENT_EXTRA_TITLE, String.format("%s (%s)", bank, title));
+			i.putExtra(LiveViewService.INTENT_EXTRA_TEXT, text);
+			context.startService(i);
+		}
 
 	}
 
diff --git src/com/liato/bankdroid/liveview/LiveViewService.java src/com/liato/bankdroid/liveview/LiveViewService.java
new file mode 100644
index 0000000..5456de0
--- /dev/null
+++ src/com/liato/bankdroid/liveview/LiveViewService.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ *
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+import com.liato.bankdroid.MainActivity;
+import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
+import com.sonyericsson.extras.liveview.IPluginServiceV1;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Implementation of the Live View plug-in service.
+ * 
+ * @author firetech
+ */
+public class LiveViewService extends Service {
+	// Announce intent information keys
+	public static final String INTENT_ANNOUNCE = "com.liato.bankdroid.liveview.ANNOUNCE";
+	public static final String INTENT_EXTRA_TITLE = "title";
+	public static final String INTENT_EXTRA_TEXT = "text";
+
+    // Template menu icon file name.
+    private static final String MENU_ICON_FILENAME = "plugin_icon.png";
+
+    // There should only be one instance of the service
+    protected static boolean alreadyRunning = false;
+
+    // Plugin name
+    protected String mPluginName = null;
+
+    // Current plugin Id
+    protected int mPluginId = 0;
+    
+    // Reference to LiveView application stub
+    private IPluginServiceV1 mLiveView = null;
+
+    // Menu icon that will be shown in LiveView unit
+    protected String mMenuIcon = null;
+
+    /**
+     * LiveView callback interface method.
+     */
+    private class LiveViewCallback extends IPluginServiceCallbackV1.Stub {
+        Handler mCallbackHandler = new Handler();
+
+        @Override
+        public String getPluginName() throws RemoteException {
+            return mPluginName;
+        }
+
+        @Override
+        public void openInPhone(final String openInPhoneAction) throws RemoteException {
+            mCallbackHandler.post(new Runnable() {
+                public void run() {
+                    LiveViewService.this.openInPhone(openInPhoneAction);
+                }
+            });
+        }
+
+		//Unused methods required by API.
+		public void startPlugin() throws RemoteException {}
+		public void stopPlugin() throws RemoteException {}
+		public void onUnregistered() throws RemoteException {}
+		public void displayCaps(int displayWidthPixels, int displayHeigthPixels)
+				throws RemoteException {}
+		public void button(String buttonType, boolean doublepress,
+				boolean longpress) throws RemoteException {}
+		public void screenMode(int screenMode) throws RemoteException {}
+    }
+
+    /**
+     * Check if service is already running.
+     * 
+     * @return running?
+     */
+    public static boolean isAlreadyRunning() {
+        return alreadyRunning;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onCreate.");
+
+        // Load menu icon
+        int iconId = PluginUtils.getDynamicResourceId(this, "icon", "drawable");
+        mMenuIcon = PluginUtils.storeIconToFile(this, getResources(), iconId, MENU_ICON_FILENAME);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onDestroy.");
+
+        // Unbind from LiveView service
+        if (mServiceConnection != null) {
+            unbindService(mServiceConnection);
+        }
+
+        // No longer a running service
+        alreadyRunning = false;
+    }
+
+	@Override
+	public void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onStart.");
+        
+		if (intent.getAction().equals(INTENT_ANNOUNCE)) {
+			Bundle extras = intent.getExtras();
+			if (extras != null) {
+				try {
+					if(mLiveView != null) {
+						mLiveView.sendAnnounce(mPluginId, mMenuIcon, extras.getString(INTENT_EXTRA_TITLE), 
+					    		extras.getString(INTENT_EXTRA_TEXT), System.currentTimeMillis(), "");
+						Log.d(PluginConstants.LOG_TAG, "Announce sent to LiveView Application");
+					} else {
+						Log.d(PluginConstants.LOG_TAG, "LiveView Application not reachable");
+					}
+				} catch(Exception e) {
+					Log.e(PluginConstants.LOG_TAG, "Failed to send announce", e);
+				}
+			}
+			
+		} else {
+	        if (isAlreadyRunning()) {
+	            Log.d(PluginConstants.LOG_TAG, "Already started.");
+	        } else {
+	            // Init
+	            mPluginName = PluginUtils.getDynamicResourceString(this,
+	                    PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+
+	            // Bind to LiveView
+	            connectToLiveView();
+
+	            // Singleton
+	            alreadyRunning = true;
+	        }
+		}
+	}
+
+    @Override
+    public IBinder onBind(final Intent intent) {
+        Log.d(PluginConstants.LOG_TAG, "Enter LiveViewService.onBind.");
+        return null;
+    }
+
+    /**
+     * The service connection that is used to bind the plugin to the LiveView
+     * service.
+     * 
+     * When connected to the service, the plugin is registered. When
+     * disconnected to the service, the plugin is unregistered.
+     */
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+
+        @Override
+        public void onServiceConnected(final ComponentName className, IBinder service) {
+            Log.d(PluginConstants.LOG_TAG,
+                    "Enter LiveViewService.ServiceConnection.onServiceConnected.");
+
+            mLiveView = IPluginServiceV1.Stub.asInterface(service);
+
+            // Init adapter
+            LiveViewCallback lvCallback = new LiveViewCallback();
+
+            // Install plugin
+            try {
+            	if(mLiveView != null) {
+	                // Register
+	                mPluginId = mLiveView.register(lvCallback, mMenuIcon, mPluginName, false, getPackageName());
+	                Log.d(PluginConstants.LOG_TAG, "Plugin registered with id: " + mPluginId);
+	            }
+            } catch (RemoteException re) {
+                Log.e(PluginConstants.LOG_TAG, "Failed to install plugin. Stop self.");
+                stopSelf();
+            }
+
+            Log.d(PluginConstants.LOG_TAG, "Plugin registered. mPluginId: " + mPluginId);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            Log.d(PluginConstants.LOG_TAG,
+                    "Enter LiveViewService.ServiceConnection.onServiceDisconnected.");
+            stopSelf();
+        }
+
+    };
+
+    /**
+     * Connects to the LiveView service.
+     */
+    private void connectToLiveView() {
+        boolean result = bindService(new Intent(PluginConstants.LIVEVIEW_SERVICE_BIND_INTENT),
+                mServiceConnection, 0);
+        if (result) {
+            Log.d(PluginConstants.LOG_TAG, "Bound to LiveView.");
+        } else {
+            Log.d(PluginConstants.LOG_TAG, "No bind.");
+            stopSelf();
+        }
+    }
+
+	/**
+	 * When a user presses the "open in phone" button on the LiveView device, this method is called.
+	 * 
+	 * Opens the MainActivity on the phone.
+	 */
+	protected void openInPhone(String openInPhoneAction) {
+		Log.d(PluginConstants.LOG_TAG, "openInPhone");
+		Intent i = new Intent(this, MainActivity.class)
+			.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+		startActivity(i);
+	}
+
+}
diff --git src/com/liato/bankdroid/liveview/PluginConstants.java src/com/liato/bankdroid/liveview/PluginConstants.java
new file mode 100644
index 0000000..a031a46
--- /dev/null
+++ src/com/liato/bankdroid/liveview/PluginConstants.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+/**
+ * Plugin common constants.
+ * 
+ * @author firetech
+ */
+public final class PluginConstants {
+    private PluginConstants() {}
+
+    // Broadcast receiver constants
+    public static final String BROADCAST_COMMAND = "CMD";
+    public static final String BROADCAST_COMMAND_PREFERENCES = "preferences";
+    public static final String BROADCAST_COMMAND_START = "start";
+    public static final String BROADCAST_COMMAND_PLUGIN_NAME = "pluginName";
+
+    // Resource string constants
+    public static final String RESOURCE_STRING_PLUGIN_NAME = "app_name";
+
+    // LiveView Plugin interface intents
+    public static final String LIVEVIEW_SERVICE_BIND_INTENT = "com.sonyericsson.extras.liveview.PLUGIN_SERVICE_V1";
+    public static final String LIVEVIEW_BROADCAST_LAUNCH_EVENT = "com.sonyericsson.extras.liveview.LAUNCH_PLUGIN";
+    
+    // These MUST match the intent names in AndroidManifest.xml!
+    public static final String PLUGIN_PREFERENCES_INTENT = "com.liato.bankdroid.liveview.SETTINGS";
+    public static final String PLUGIN_SERVICE_INTENT = "com.liato.bankdroid.liveview.SERVICE";
+
+    // Log tag
+    public static final String LOG_TAG = "BankDroidLiveViewPlugin";
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/liveview/PluginReceiver.java src/com/liato/bankdroid/liveview/PluginReceiver.java
new file mode 100644
index 0000000..04c53a3
--- /dev/null
+++ src/com/liato/bankdroid/liveview/PluginReceiver.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * Receives broadcast intents from LiveView service.
+ * 
+ * @author firetech
+ */
+public class PluginReceiver extends BroadcastReceiver {
+	
+	@Override
+	public void onReceive(Context context, Intent intent) {
+		String command = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND);
+		Log.d(PluginConstants.LOG_TAG, "Received command: " + command);
+		
+		if(command == null) {
+			return;
+		}
+		
+		if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_PREFERENCES)) {
+			String pluginName = intent.getExtras().getString(PluginConstants.BROADCAST_COMMAND_PLUGIN_NAME);
+			String myPluginName = PluginUtils.getDynamicResourceString(context, PluginConstants.RESOURCE_STRING_PLUGIN_NAME);
+
+			if(pluginName != null && pluginName.contentEquals(myPluginName)) {
+				Log.d(PluginConstants.LOG_TAG, "Starting preferences! Intent: " + PluginConstants.PLUGIN_PREFERENCES_INTENT);
+				
+				Intent prefsIntent = new Intent(PluginConstants.PLUGIN_PREFERENCES_INTENT);
+				prefsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+				context.startActivity(prefsIntent);
+			}
+		}
+		else if(command.contentEquals(PluginConstants.BROADCAST_COMMAND_START)) {
+			if(LiveViewService.isAlreadyRunning()) {
+			    Log.d(PluginConstants.LOG_TAG, "Service is already running.");
+			} else {
+				Log.d(PluginConstants.LOG_TAG, "Starting service! Intent: " + PluginConstants.PLUGIN_SERVICE_INTENT);
+				
+				context.startService(new Intent(PluginConstants.PLUGIN_SERVICE_INTENT));
+			}
+		}
+		
+	}
+	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/liveview/PluginUtils.java src/com/liato/bankdroid/liveview/PluginUtils.java
new file mode 100644
index 0000000..4803295
--- /dev/null
+++ src/com/liato/bankdroid/liveview/PluginUtils.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2011 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.liato.bankdroid.liveview;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Utils for LiveView plugin.
+ * 
+ * @author firetech
+ */
+public final class PluginUtils {
+    
+    private PluginUtils() {
+        
+    }
+    
+    /**
+     * Stores icon to phone file system
+     * 
+     * @param resources Reference to project resources
+     * @param resource Reference to specific resource
+     * @param fileName The icon file name
+     */
+    public static String storeIconToFile(Context ctx, Resources resources, int resource, String fileName) {
+        Log.d(PluginConstants.LOG_TAG, "Store icon to file.");
+        
+        if(resources == null) {
+            return "";
+        }
+        
+        Bitmap bitmap = BitmapFactory.decodeStream(resources.openRawResource(resource));
+        
+        try {
+            FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
+            fos.flush();
+            fos.close(); 
+        } 
+        catch (IOException e) { 
+            Log.e(PluginConstants.LOG_TAG, "Failed to store to device", e);
+        }
+        
+        File iconFile = ctx.getFileStreamPath(fileName);
+        Log.d(PluginConstants.LOG_TAG, "Icon stored. " + iconFile.getAbsolutePath());
+        
+        return iconFile.getAbsolutePath();
+    }
+    
+    /**
+     * Gets resource id dynamically
+     * 
+     * @param context
+     * @param resourceName
+     * @param resourceType
+     * @return
+     */
+    public static int getDynamicResourceId(Context context, String resourceName, String resourceType) {
+        return context.getResources().getIdentifier(resourceName, resourceType, context.getPackageName());
+    }
+    
+    /**
+     * Gets resource string dynamically
+     * 
+     * @param context
+     * @param resourceName
+     * @return
+     */
+    public static String getDynamicResourceString(Context context, String resourceName) {
+        int resourceId = getDynamicResourceId(context, resourceName, "string");
+        return context.getString(resourceId);
+    }
+}
\ No newline at end of file
diff --git src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
new file mode 100644
index 0000000..43c808e
--- /dev/null
+++ src/com/sonyericsson/extras/liveview/IPluginServiceCallbackV1.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.sonyericsson.extras.liveview;
+
+interface IPluginServiceCallbackV1 {
+	// Start the plugin.
+	void startPlugin();
+	
+	// Stop the plugin.
+	// A stopped plugin should stop its polling, but can stay alive
+	void stopPlugin();
+	
+	// Should return the name the plugin used to register itself with
+	String getPluginName();
+
+ 	// Give the action needed to open the current announcement on the phone
+	// such as a view in browser action or something else that your application
+	// responds to.
+	void openInPhone(in String openInPhoneAction);      
+
+	// Kicked out by framework. Implement this with stopSelf()
+	void onUnregistered();
+	
+	// displayWidthPixels equals 0 and displayheigthPixels equals 0
+	// means no available device is attached, or has no display
+	void displayCaps(in int displayWidthPixels, in int displayHeigthPixels);
+	
+	// Button event - note that doublepress is not implemented for the V1
+	// interface but still left here for compatibility reasons.
+	void button(in String buttonType, in boolean doublepress, in boolean longpress);
+
+	// Screen mode changed event - this notifies the current active sandbox plugin that the screen has been 
+	// turned on or off. 0 = Screen OFF, 1 = Screen ON
+	void screenMode(in int screenMode);
+}
\ No newline at end of file
diff --git src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
new file mode 100644
index 0000000..8ab48f9
--- /dev/null
+++ src/com/sonyericsson/extras/liveview/IPluginServiceV1.aidl
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2010 Sony Ericsson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package com.sonyericsson.extras.liveview;
+
+import com.sonyericsson.extras.liveview.IPluginServiceCallbackV1;
+
+interface IPluginServiceV1 {
+
+	// Register to the Liveview application
+	// cb - callback instance
+    // imageMenu - path to the menu bitmap
+    // pluginName - name of the plugin - must be unique
+    // selectableMenu - is set to true if controlling display and getting buttons. Set to false to only handle announces
+    // packageName - the package name (use getPackageName()).
+    // returns id of plugin in system, 0 means that the registration failed
+    int register(in IPluginServiceCallbackV1 cb, in String imageMenu, in String pluginName, in boolean selectableMenu, in String packageName);
+    
+    // This method should be called if the application/service is uninstalled using the phone application handler 
+    // id - the plugin id received in registerPlugin
+    // cb - the callback
+    void unregister( in int id, in IPluginServiceCallbackV1 cb);
+    
+    // Used to send announcements to the device - can only be used when _not_ registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // imageAnnounce - the path to the announce bitmap
+    // header - header text
+    // body - body text
+    // time - timestamp for this announce in milliseconds
+    // openInPhoneAction - a tag to use for openInPhone callback. Set to null when announce not selectable
+    void sendAnnounce(in int id, in String imageAnnounce, in String header, in String body, in long timestamp, in String openInPhoneAction);
+    
+    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // x - from left side
+    // y - from top side
+    // image - the path to the image on file system
+    void sendImage(in int id, in int x, in int y, in String image);
+
+    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // x - from left side
+    // y - from top side
+    // bitmapData - the bitmap to send
+    void sendImageAsBitmap(in int id, in int x, in int y, in Bitmap bitmapData);
+    
+    // Clears the display, for example if several images are sent while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    void clearDisplay(in int id);
+    
+    // Provide the Liveview application with means to launch the service 
+    // that shoul receive and send data in sandbox mode - Must be called if you registered as "selectableMenu"
+    // launcherIntent - the intent to start the plugin service
+    // pluginName - the name of the plugin, must match the name you registered with! 
+    // returns -1 for failure, 0 for already registered, anything else for success
+    int notifyInstalled(in String launcherIntent, in String pluginName);
+
+    // Controls LED - can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // rgb565 - the color to use
+    // delayTime - the delay in ms
+    // onTime - the on time in ms
+    void ledControl(in int id, int rgb565, int delayTime, int onTime);
+
+    // Controls Vibration - can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // delayTime - the delay in ms
+    // onTime - the on time in ms
+    void vibrateControl(in int id, int delayTime, int onTime);
+
+    // Used to send image data to the device while in sandbox mode - Can only be used if you registered as "selectableMenu"
+    // id - the plugin id received in registerPlugin
+    // x - from left side
+    // y - from top side
+    // bitmapBytes - the byteArray containing the bitmap data
+    void sendImageAsBitmapByteArray(in int id, in int x, in int y, in byte[] bitmapByteArray);
+
+    // Used to put the screen in powersave mode
+    // id - the plugin id received in registerPlugin
+    void screenOff(in int id);
+
+    // Used to put the screen in dimmed mode
+    // id - the plugin id received in registerPlugin
+    void screenDim(in int id);
+
+    // Used to wake the screen from powersave mode
+    // id - the plugin id received in registerPlugin
+    void screenOn(in int id);
+
+    // Used to set the to powersave mode "AUTO"
+    // id - the plugin id received in registerPlugin
+    void screenOnAuto(in int id);
+}
\ No newline at end of file

commit a08cab7e66c70e7b0f5ce9c878e10eb47864ecbd
Author: liato <x@x00.us>
Date:   Wed May 4 12:46:16 2011 +0200

    Remove untested banks from selection. Bump version to 1.7.3.

diff --git AndroidManifest.xml AndroidManifest.xml
index 5bf6062..56a5c11 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.7.3-RC1" android:versionCode="111">
+	android:versionCode="114" android:versionName="1.7.3">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 62adba4..42ae14b 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -225,27 +225,27 @@ public class BankFactory {
         banks.add(new Volvofinans(context));
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
-        //American Express doesn't work yet
-        //banks.add(new AmericanExpress(context));
         banks.add(new McDonalds(context));
-        banks.add(new Saab(context));
-        banks.add(new Wallet(context));
-        banks.add(new Chevrolet(context));
         banks.add(new SJPrio(context));
-        banks.add(new Opel(context));
-        banks.add(new Djurgarden(context));
-        banks.add(new Quintessentially(context));
-        banks.add(new PlusGirot(context));
-        banks.add(new Shell(context));
-        banks.add(new Volkswagen(context));
-        banks.add(new Audi(context));
-        banks.add(new Preem(context));
-        banks.add(new Seat(context));
-        banks.add(new Skoda(context));
-        banks.add(new IKEA(context));
         banks.add(new SparbankenSyd(context));
         banks.add(new SparbankenOresund(context));
-        banks.add(new Nordnetdirekt(context));
+        banks.add(new Opel(context));
+        //Not tested or not working
+        //banks.add(new AmericanExpress(context));
+        //banks.add(new PlusGirot(context));
+        //banks.add(new Nordnetdirekt(context));
+        //banks.add(new Saab(context));
+        //banks.add(new Wallet(context));
+        //banks.add(new Chevrolet(context));
+        //banks.add(new Djurgarden(context));
+        //banks.add(new Quintessentially(context));
+        //banks.add(new Shell(context));
+        //banks.add(new Volkswagen(context));
+        //banks.add(new Audi(context));
+        //banks.add(new Preem(context));
+        //banks.add(new Seat(context));
+        //banks.add(new Skoda(context));
+        //banks.add(new IKEA(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index df20eef..c0ab4eb 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -52,6 +52,7 @@ public class ICABanken extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final boolean STATIC_BALANCE = true;
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -71,6 +72,7 @@ public class ICABanken extends Bank {
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
 	public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
diff --git src/com/liato/bankdroid/banking/banks/MobilbankenBase.java src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 7eb508d..48c813c 100644
--- src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -162,9 +162,9 @@ public abstract class MobilbankenBase extends Bank {
                  * 
                  */
                 transactions.add(new Transaction(
-                        matcher.group(2).trim().replace(".", "-"),
+                        matcher.group(3).trim().replace(".", "-"),
                         Html.fromHtml(matcher.group(1)).toString().trim(),
-                        Helpers.parseBalance(matcher.group(3))));
+                        Helpers.parseBalance(matcher.group(2))));
             }
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index faf6e17..4d75f6d 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -77,7 +77,7 @@ public class SEB extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://m.seb.se/");
         urlopen.setKeepAliveTimeout(5);
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index f5a22b4..379fb81 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -32,7 +32,6 @@ import org.apache.http.protocol.HTTP;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -159,7 +158,8 @@ public class Swedbank extends Bank {
 		
         String banknr = (getExtras() != null && getExtras().length() > 0) ? "?bank="+getExtras() : "";
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html"+banknr);
+	        response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/menu.html"+banknr);
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
                 /*
@@ -211,7 +211,6 @@ public class Swedbank extends Bank {
 		super.updateTransactions(account, urlopen);
 		if (account.getType() == Account.OTHER) return;
 
-		String banknr = (getExtras() != null && getExtras().length() > 0) ? "&bank="+getExtras() : "";
 		String response = null;
 		Matcher matcher;
 		try {
@@ -219,8 +218,7 @@ public class Swedbank extends Bank {
 		    if (account.getType() == Account.LOANS) {
 		        String [] accountId = account.getId().split(":", 2);
 		        if (accountId.length < 2) return;
-	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]+banknr);
-	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]+banknr);
+	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]);
 	            matcher = reLoanData.matcher(response);
 	            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 	            Calendar cal = Calendar.getInstance(); 
@@ -239,8 +237,7 @@ public class Swedbank extends Bank {
 	            }
 		    }
 		    else {
-	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId()+banknr);
-	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId()+banknr);
+	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
 	            matcher = reTransactions.matcher(response);
 	            while (matcher.find()) {
                     /*

commit d5100902fc1787f82215932394a43dc301cc3d23
Author: liato <x@x00.us>
Date:   Wed Apr 27 07:38:57 2011 +0200

    Bump version to 1.7.3-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 942d71b..5bf6062 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.7.2" android:versionCode="110">
+	android:versionName="1.7.3-RC1" android:versionCode="111">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 4d48d115de119519e8ef3d9ae1559d4dfed94aa8
Author: liato <x@x00.us>
Date:   Wed Apr 27 07:38:15 2011 +0200

    Add option to set a minimum change for triggering notifications.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 7dc38be..a23a78c 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -60,6 +60,8 @@
 	<string name="round_widget_balance_summary">Visa saldot på widgets utan decimaler</string>
 	<string name="round_balance_title">Avrunda saldo</string>
 	<string name="round_balance_summary">Visa saldot på banker och konton utan decimaler</string>
+	<string name="notify_min_delta_title">Minsta förändring</string>
+	<string name="notify_min_delta_summary">Visa endast notifiering om saldoförändringar är minst så här stor</string>
 	<string name="widget_opens_transactions_title">Widget-klick öppnar kontoutdrag</string>
 	<string name="widget_opens_transactions_summary">Öppna kontoutdraget för kontot när du klickar på en widget.</string>
 	<string name="widget_updates_transactions_title">Uppdatera kontoutdrag från widget</string>
@@ -228,4 +230,5 @@
 	
 	<string name="nordnetdirekt_extras_title">Nyckel</string>
 	<string name="select_a_bank">Välj en bank</string>
+	<string name="invalid_integer">%1$s är inte ett giltigt positivt heltal, var god försök igen.</string>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index ff723bd..b305b08 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -61,7 +61,9 @@
 	<string name="round_widget_balance_title">Round widget balance</string>
 	<string name="round_widget_balance_summary">Display the balance on widgets without decimals</string>
 	<string name="round_balance_title">Round balance</string>
-	<string name="round_balance_summary">Display the balance for banks and accounts without decimals</string>
+	<string name="round_balance_summary">Display the balance without decimals</string>
+	<string name="notify_min_delta_title">Minimum change</string>
+	<string name="notify_min_delta_summary">Only display a notification if the change is at least this big</string>
 	<string name="widget_opens_transactions_title">Widget click opens transactions</string>
 	<string name="widget_opens_transactions_summary">Open the transactions screen when a widget is clicked. If unchecked the main screen is shown.</string>
 	<string name="widget_updates_transactions_title">Update transactions from widget.</string>
@@ -280,4 +282,5 @@
 
 	<string name="nordnetdirekt_extras_title">Key</string>
 	<string name="select_a_bank">Select a bank</string>
+	<string name="invalid_integer">%1$s is not a valid positive integer, please try again.</string>	
 </resources>
diff --git res/xml/settings.xml res/xml/settings.xml
index 2547fec..bb19308 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -23,26 +23,6 @@
 			android:title="@string/lockpattern_settings_enable_tactile_feedback_title"
 			android:dependency="patternlock_enabled" />
 	</PreferenceCategory>
-	<PreferenceCategory
-		android:title="@string/automatic_updates_title">
-		<CheckBoxPreference
-			android:key="autoupdates_enabled"
-			android:defaultValue="true"
-			android:title="@string/autoupdates_enabled_title"
-			android:summary="@string/autoupdates_enabled_summary" />
-		<ListPreference
-			android:title="@string/update_frequency_title"
-			android:key="refresh_rate"
-			android:defaultValue="60"
-			android:entries="@array/refreshrateNames"
-			android:entryValues="@array/refreshrateValues"
-			android:dependency="autoupdates_enabled" />
-		<CheckBoxPreference
-			android:key="autoupdates_transactions_enabled"
-			android:defaultValue="true"
-			android:title="@string/update_transaction_history_title"
-			android:summary="@string/update_transaction_history_summary" />
-	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="@string/appearance_title">
 		<CheckBoxPreference
@@ -82,6 +62,26 @@
 			android:title="@string/widget_updates_transactions_title"
 			android:summary="@string/widget_updates_transactions_summary" />
 	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="@string/automatic_updates_title">
+		<CheckBoxPreference
+			android:key="autoupdates_enabled"
+			android:defaultValue="true"
+			android:title="@string/autoupdates_enabled_title"
+			android:summary="@string/autoupdates_enabled_summary" />
+		<ListPreference
+			android:title="@string/update_frequency_title"
+			android:key="refresh_rate"
+			android:defaultValue="60"
+			android:entries="@array/refreshrateNames"
+			android:entryValues="@array/refreshrateValues"
+			android:dependency="autoupdates_enabled" />
+		<CheckBoxPreference
+			android:key="autoupdates_transactions_enabled"
+			android:defaultValue="true"
+			android:title="@string/update_transaction_history_title"
+			android:summary="@string/update_transaction_history_summary" />
+	</PreferenceCategory>	
 	<PreferenceCategory
 		android:title="@string/notifications_title">
 		<CheckBoxPreference
@@ -95,6 +95,18 @@
 			android:title="@string/vibrate_title"
 			android:summary="@string/vibrate_summary"
 			android:dependency="notify_on_change" />
+		<EditTextPreference
+			android:key="notify_min_delta"
+			android:defaultValue="0"
+			android:title="@string/notify_min_delta_title"
+			android:summary="@string/notify_min_delta_summary"
+			android:dependency="notify_on_change" />
+		<CheckBoxPreference
+			android:key="notify_with_vibration"
+			android:defaultValue="true"
+			android:title="@string/vibrate_title"
+			android:summary="@string/vibrate_summary"
+			android:dependency="notify_on_change" />
 		<RingtonePreference
 			android:key="notification_sound"
 			android:title="@string/notification_sound_title"
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index b787f27..1a13583 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -21,16 +21,18 @@ import android.net.Uri;
 import android.os.Bundle;
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
 import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceScreen;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.lockpattern.ChooseLockPattern;
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
 
-public class SettingsActivity extends LockablePreferenceActivity implements OnPreferenceClickListener {
+public class SettingsActivity extends LockablePreferenceActivity implements OnPreferenceClickListener, OnPreferenceChangeListener {
 	private final static String TAG = "SettingsActivity";
 	private final static int DISABLE_LOCKPATTERN = 1;
 	private final static int ENABLE_LOCKPATTERN = 2;
@@ -54,6 +56,7 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		(findPreference("autoupdates_enabled")).setOnPreferenceClickListener(this);
         (findPreference("notification_sound")).setOnPreferenceClickListener(this);
         (findPreference("test_notification")).setOnPreferenceClickListener(this);
+        (findPreference("notify_min_delta")).setOnPreferenceChangeListener(this);
 		final CheckBoxPreference patternLock = ((CheckBoxPreference)findPreference("patternlock_enabled"));
 		patternLock.setOnPreferenceClickListener(this);
 		// Check the pattern lock check box if the lock pattern is enabled
@@ -69,10 +72,9 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		}
 
 		if ("notification_sound".equals(prefKey)) {
-			this.setLockEnabled(false);
 			return false;
 		}
-
+		
 		if ("patternlock_enabled".equals(prefKey)) {
 			this.setLockEnabled(false);
 			if (mLockPatternUtils.isLockPatternEnabled()) {
@@ -154,4 +156,27 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		AutoRefreshService.sendWidgetRefresh(this);
 	}
 
+    @Override
+    public boolean onPreferenceChange(Preference pref, Object newValue) {
+        final String prefKey = pref.getKey();
+        if ("notify_min_delta".equals(prefKey)) {
+            Integer val;
+            try {
+                val = Integer.valueOf((String) newValue);
+            }
+            catch (NumberFormatException e) {
+                val = null;
+            }
+            
+            if (val != null && val >= 0) {
+                return true;
+            }
+            else {
+                Toast.makeText(pref.getContext(), String.format(pref.getContext().getString(R.string.invalid_integer), newValue), Toast.LENGTH_LONG).show();
+            }
+            return false;
+        }
+        return false;
+    }
+
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 1bc6df3..c659f96 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -156,6 +156,8 @@ public class AutoRefreshService extends Service {
 			db.open();
 			BigDecimal currentBalance;
 			BigDecimal diff;
+			BigDecimal minDelta = new BigDecimal(prefs.getString("notify_min_delta", "0"));
+			
 			final HashMap<String, Account> accounts = new HashMap<String, Account>();
 
 			for (final Bank bank : banks) {
@@ -182,7 +184,7 @@ public class AutoRefreshService extends Service {
 					}
 					bank.update();
 					diff = currentBalance.subtract(bank.getBalance());
-					if (diff.compareTo(new BigDecimal(0)) != 0) {
+					if (diff.compareTo(new BigDecimal(0)) != 0  && diff.abs().compareTo(minDelta) != -1) {
 						Account oldAccount;
 						for (final Account account : bank.getAccounts()) {
 							oldAccount = accounts.get(account.getId());

commit d4be7a464d975b2738788bfdcc7c00576cf7133e
Author: liato <x@x00.us>
Date:   Wed Apr 27 06:34:02 2011 +0200

    Add option to display balance without decimals.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 82d9424..7dc38be 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -55,8 +55,11 @@
 	<string name="update_transaction_history_title">Uppdatera kontoutdrag</string>
 	<string name="update_transaction_history_summary">Uppdatera kontoutdrag vid automatiska uppdateringar</string>
 	<string name="appearance_title">Utseende</string>
+	<string name="widgets_title">Widgets</string>
 	<string name="round_widget_balance_title">Avrunda saldo på widgets</string>
 	<string name="round_widget_balance_summary">Visa saldot på widgets utan decimaler</string>
+	<string name="round_balance_title">Avrunda saldo</string>
+	<string name="round_balance_summary">Visa saldot på banker och konton utan decimaler</string>
 	<string name="widget_opens_transactions_title">Widget-klick öppnar kontoutdrag</string>
 	<string name="widget_opens_transactions_summary">Öppna kontoutdraget för kontot när du klickar på en widget.</string>
 	<string name="widget_updates_transactions_title">Uppdatera kontoutdrag från widget</string>
diff --git res/values/strings.xml res/values/strings.xml
index 912f5ea..ff723bd 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -57,8 +57,11 @@
 	<string name="update_transaction_history_title">Update transaction history</string>
 	<string name="update_transaction_history_summary">Update transaction history when updating automatically</string>
 	<string name="appearance_title">Appearance</string>
+	<string name="widgets_title">Widgets</string>
 	<string name="round_widget_balance_title">Round widget balance</string>
 	<string name="round_widget_balance_summary">Display the balance on widgets without decimals</string>
+	<string name="round_balance_title">Round balance</string>
+	<string name="round_balance_summary">Display the balance for banks and accounts without decimals</string>
 	<string name="widget_opens_transactions_title">Widget click opens transactions</string>
 	<string name="widget_opens_transactions_summary">Open the transactions screen when a widget is clicked. If unchecked the main screen is shown.</string>
 	<string name="widget_updates_transactions_title">Update transactions from widget.</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index c938dd4..2547fec 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -22,19 +22,6 @@
 			android:defaultValue="false"
 			android:title="@string/lockpattern_settings_enable_tactile_feedback_title"
 			android:dependency="patternlock_enabled" />
-		<CheckBoxPreference
-			android:key="widget_blur_balance"
-			android:defaultValue="false"
-			android:title="@string/blur_widget_title"
-			android:summary="@string/blur_widget_summary" />
-		<ListPreference
-			android:title="@string/unblur_widget_timeout_title"
-			android:key="widget_blur_balance_timeout"
-			android:defaultValue="5"
-			android:entries="@array/unblurTimeoutNames"
-			android:entryValues="@array/unblurTimeoutValues"
-			android:summary="@string/unblur_widget_timeout_summary"
-			android:dependency="widget_blur_balance" />
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="@string/automatic_updates_title">
@@ -58,6 +45,27 @@
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="@string/appearance_title">
+		<CheckBoxPreference
+			android:key="round_balance"
+			android:defaultValue="false"
+			android:title="@string/round_balance_title"
+			android:summary="@string/round_balance_summary" />
+	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="@string/widgets_title">	
+		<CheckBoxPreference
+			android:key="widget_blur_balance"
+			android:defaultValue="false"
+			android:title="@string/blur_widget_title"
+			android:summary="@string/blur_widget_summary" />
+		<ListPreference
+			android:title="@string/unblur_widget_timeout_title"
+			android:key="widget_blur_balance_timeout"
+			android:defaultValue="5"
+			android:entries="@array/unblurTimeoutNames"
+			android:entryValues="@array/unblurTimeoutValues"
+			android:summary="@string/unblur_widget_timeout_summary"
+			android:dependency="widget_blur_balance" />
 		<CheckBoxPreference
 			android:key="round_widget_balance"
 			android:defaultValue="false"
diff --git src/com/liato/bankdroid/adapters/AccountsAdapter.java src/com/liato/bankdroid/adapters/AccountsAdapter.java
index 016af0d..438d0a7 100644
--- src/com/liato/bankdroid/adapters/AccountsAdapter.java
+++ src/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -18,15 +18,10 @@ package com.liato.bankdroid.adapters;
 
 import java.util.ArrayList;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.graphics.Color;
+import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -34,6 +29,11 @@ import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+
 public class AccountsAdapter extends BaseAdapter {
 	public final static int VIEWTYPE_BANK = 0;
     public final static int VIEWTYPE_ACCOUNT = 1;
@@ -41,14 +41,15 @@ public class AccountsAdapter extends BaseAdapter {
 	private ArrayList<Bank> banks;
 	private Context context;
 	private LayoutInflater inflater;
-	private boolean showHidden; 
-
+	private boolean showHidden;
+	SharedPreferences prefs;
 
     public AccountsAdapter(Context context, boolean showHidden) {
 		this.context = context;
 		this.banks = new ArrayList<Bank>();
 		inflater = LayoutInflater.from(this.context);
 		this.showHidden = showHidden;
+		prefs = PreferenceManager.getDefaultSharedPreferences(context);
 	}
 
 	public void addGroup(Bank bank) {
@@ -84,7 +85,7 @@ public class AccountsAdapter extends BaseAdapter {
 		ImageView icon = (ImageView)convertView.findViewById(R.id.imgListitemAccountsGroup);
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(bank.getDisplayName());
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(bank.getName());
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(bank.getBalance(), bank.getCurrency()));
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(bank.getBalance(), bank.getCurrency(), prefs.getBoolean("round_balance", false)));
 		icon.setImageResource(bank.getImageResource());
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
 		if (bank.isDisabled()) {
@@ -108,6 +109,7 @@ public class AccountsAdapter extends BaseAdapter {
         TextView txtBalance = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance));
 		txtAccountName.setText(account.getName());
 		txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency(), prefs.getBoolean("round_balance", false)));
 		if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
             txtBalance.setTextColor(Color.argb(255, 191, 191, 191));		    
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 0b92035..85eb75a 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -148,12 +148,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
         views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
-        if (defprefs.getBoolean("round_widget_balance", false)) {
-            views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), true));
-        }
-        else {
-            views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
-        }
+        views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false)));
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
 		Log.d("Disabled", ""+bank.isDisabled());
 		if (bank.isDisabled()) {

commit 812eab425ef550f00089b25720189bc41f0b2cbd
Author: liato <x@x00.us>
Date:   Wed Apr 27 06:19:35 2011 +0200

    Add translation for bank selection.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index e4d1563..82d9424 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -223,5 +223,6 @@
 	<string name="card_id">Kort ID</string>
 	<string name="card_number">Kortnummer</string>
 	
-	<string name="nordnetdirekt_extras_title">Nyckel</string>	
+	<string name="nordnetdirekt_extras_title">Nyckel</string>
+	<string name="select_a_bank">Välj en bank</string>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 8503657..912f5ea 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -275,5 +275,6 @@
 	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 
-	<string name="nordnetdirekt_extras_title">Key</string>	
+	<string name="nordnetdirekt_extras_title">Key</string>
+	<string name="select_a_bank">Select a bank</string>
 </resources>
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3bbbd83..3de9334 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -45,7 +45,6 @@ import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.Spinner;
 import android.widget.TextView;
-import android.widget.Toast;
 
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
@@ -277,7 +276,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	                    items[i] = b.getName();
 	                    i++;
 	                }
-	                builder.setTitle("Select a bank");
+	                builder.setTitle(R.string.select_a_bank);
 	                builder.setItems(items, new DialogInterface.OnClickListener() {
 	                    public void onClick(DialogInterface dialog, int item) {
 	                        SELECTED_BANK.setExtras(e.getBanks().get(item).getId());
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index e307f60..f5a22b4 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -137,17 +137,7 @@ public class Swedbank extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		try {
-            response = urlopen.open("http://x.x00.us/android/bankdroid/swedbank/multiplebanks.htm");
-        }
-        catch (ClientProtocolException e1) {
-            // TODO Auto-generated catch block
-            e1.printStackTrace();
-        }
-        catch (IOException e1) {
-            // TODO Auto-generated catch block
-            e1.printStackTrace();
-        }
+
 		Matcher matcher;
 		if (getExtras() == null || getExtras().length() == 0) {
     		ArrayList<BankChoice> banks = new ArrayList<BankChoice>();

commit 6235acc9956294d55b02f9c95ca3077dff3d5ea0
Author: liato <x@x00.us>
Date:   Wed Apr 27 06:14:45 2011 +0200

    Let the user decide which bank to use if multiple banks are connected to the users Swedbank account.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index b59ebd9..3bbbd83 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -45,11 +45,14 @@ import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.Spinner;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankChoice;
 import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -253,6 +256,9 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 			} catch (LoginException e) {
 				this.exc = e;
 			}
+            catch (BankChoiceException e) {
+                this.exc = e;
+            }
 			return null;
 		}
 
@@ -262,14 +268,32 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 				this.dialog.dismiss();
 			}
 			if (this.exc != null) {
-				AlertDialog.Builder builder = new AlertDialog.Builder(BankEditActivity.this);
-				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
-						dialog.cancel();
-					}
-				});
+				AlertDialog.Builder builder = new AlertDialog.Builder(context);
+				if (this.exc instanceof BankChoiceException) {
+				    final BankChoiceException e = (BankChoiceException)exc;
+	                final String[] items = new String[e.getBanks().size()];
+	                int i = 0;
+	                for (BankChoice b : e.getBanks()) {
+	                    items[i] = b.getName();
+	                    i++;
+	                }
+	                builder.setTitle("Select a bank");
+	                builder.setItems(items, new DialogInterface.OnClickListener() {
+	                    public void onClick(DialogInterface dialog, int item) {
+	                        SELECTED_BANK.setExtras(e.getBanks().get(item).getId());
+	                        new DataRetrieverTask(context, SELECTED_BANK).execute();
+	                    }
+	                });
+				}
+				else {
+    				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
+    				.setIcon(android.R.drawable.ic_dialog_alert)
+    				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+    					public void onClick(DialogInterface dialog, int id) {
+    						dialog.cancel();
+    					}
+    				});
+				}
 				AlertDialog alert = builder.create();
 				alert.show();
 			}
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index ea5a5ea..fd90c2c 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -31,10 +31,12 @@ import com.liato.bankdroid.appwidget.AutoRefreshService;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
+    private final static String TAG = "DataRetrieverTask";
 	private final ProgressDialog dialog;
 	private ArrayList<String> errors;
 	private final MainActivity parent;
@@ -79,13 +81,8 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 			publishProgress(new String[] { new Integer(i).toString(),
 					bank.getName() + " (" + bank.getUsername() + ")" });
 			if (bank.isDisabled()) {
-				Log.d("AA", bank.getName() + " (" + bank.getUsername()
-						+ ") is disabled. Skipping refresh.");
 				continue;
 			}
-			Log.d("AA",
-					"Refreshing " + bank.getName() + " (" + bank.getUsername()
-							+ ").");
 			try {
 				// Log.d("AA", "bank.update()");
 				bank.update();
@@ -105,6 +102,11 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 						+ ")");
 				bank.disable();
 			}
+            catch (BankChoiceException e) {
+                this.errors.add(bank.getName() + " (" + bank.getUsername()
+                        + ")");
+                Log.d(TAG, "BankChoiceError: " + e.getMessage());
+            }
 
 			final SharedPreferences prefs = PreferenceManager
 					.getDefaultSharedPreferences(parent);
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index ee60675..1bc6df3 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
@@ -274,6 +275,10 @@ public class AutoRefreshService extends Service {
 					refreshWidgets = true;
 					db.disableBank(bank.getDbId());
 				}
+                catch (BankChoiceException e) {
+                    Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+                            + "'; LoginException: " + e.getMessage());
+                }
 			}
 
 			if (refreshWidgets) {
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 2d59bad..0b92035 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -378,6 +379,9 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 					Log.d("", "Disabling bank: "+bank.getDbId());
 					bank.disable();
 				}
+                catch (BankChoiceException e) {
+                    Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+                }
 
 				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
 				return null;
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index db34769..8b86e03 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -29,6 +29,7 @@ import org.apache.http.client.CookieStore;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
@@ -93,13 +94,13 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.res = this.context.getResources();
     }
 
-    public void update(String username, String password) throws BankException, LoginException {
+    public void update(String username, String password) throws BankException, LoginException, BankChoiceException {
         this.username = username;
         this.password = password;
         this.update();
     }
 
-    public void update() throws BankException, LoginException {
+    public void update() throws BankException, LoginException, BankChoiceException {
         balance = new BigDecimal(0);
         oldAccounts = new HashMap<String, Account>();
         for(Account account: accounts) {
@@ -325,6 +326,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
                     a.setHidden(oa.isHidden());
                     a.setNotify(oa.isNotify());
                     a.setCurrency(oa.getCurrency());
+                    a.setAliasfor(oa.getAliasfor());
                 }
             }
             a.setBank(this);
diff --git src/com/liato/bankdroid/banking/BankChoice.java src/com/liato/bankdroid/banking/BankChoice.java
new file mode 100644
index 0000000..e3ac614
--- /dev/null
+++ src/com/liato/bankdroid/banking/BankChoice.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking;
+
+public class BankChoice {
+    private String name;
+    private String id;
+	public BankChoice(String name, String id) {
+		this.name = name;
+		this.id = id;
+	}
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+    /**
+     * @return the id
+     */
+    public String getId() {
+        return id;
+    }
+    /**
+     * @param id the id to set
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+}
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index ddc60d2..57531da 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -66,7 +67,7 @@ public class AmericanExpress extends Bank {
 		super.URL = URL;
 	}
 
-	public AmericanExpress(String username, String password, Context context) throws BankException, LoginException {
+	public AmericanExpress(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -115,7 +116,7 @@ public class AmericanExpress extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Audi.java src/com/liato/bankdroid/banking/banks/Audi.java
index b1b2bea..386de4f 100644
--- src/com/liato/bankdroid/banking/banks/Audi.java
+++ src/com/liato/bankdroid/banking/banks/Audi.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class Audi extends IkanoPartnerBase {
         this.structId = "2177";
     }
 
-    public Audi(String username, String password, Context context) throws BankException, LoginException {
+    public Audi(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
index 7bae4f6..03ca970 100644
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -60,7 +61,7 @@ public class Avanza extends Bank {
 		super.URL = URL;
 	}
 
-	public Avanza(String username, String password, Context context) throws BankException, LoginException {
+	public Avanza(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -95,7 +96,7 @@ public class Avanza extends Bank {
 	
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 26de2bf..55a2266 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -33,6 +33,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -57,7 +58,7 @@ public class AvanzaMini extends Bank {
 		super.URL = URL;
 	}
 
-	public AvanzaMini(String username, String password, Context context) throws BankException, LoginException {
+	public AvanzaMini(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -90,7 +91,7 @@ public class AvanzaMini extends Bank {
 		return urlopen;
 	}
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 7b06440..6124c43 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -74,7 +75,7 @@ public class CSN extends Bank {
         super.STATIC_BALANCE = STATIC_BALANCE;
     }
 
-	public CSN(String username, String password, Context context) throws BankException, LoginException {
+	public CSN(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -129,7 +130,7 @@ public class CSN extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Chevrolet.java src/com/liato/bankdroid/banking/banks/Chevrolet.java
index 05515ed..007cefe 100644
--- src/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ src/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class Chevrolet extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Chevrolet(String username, String password, Context context) throws BankException, LoginException {
+	public Chevrolet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "wase", "0086");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index fd1fb7c..a38f93f 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -64,7 +65,7 @@ public class Coop extends Bank {
         super.URL = URL;
     }
 
-    public Coop(String username, String password, Context context) throws BankException, LoginException {
+    public Coop(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
@@ -118,7 +119,7 @@ public class Coop extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException {
+    public void update() throws BankException, LoginException, BankChoiceException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index a565a0e..f9bd62d 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -67,7 +68,7 @@ public class DinersClub extends Bank {
 		super.URL = URL;
 	}
 
-	public DinersClub(String username, String password, Context context) throws BankException, LoginException {
+	public DinersClub(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -120,7 +121,7 @@ public class DinersClub extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Djurgarden.java src/com/liato/bankdroid/banking/banks/Djurgarden.java
index fda2846..29df4b0 100644
--- src/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ src/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class Djurgarden extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Djurgarden(String username, String password, Context context) throws BankException, LoginException {
+	public Djurgarden(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "djse", "0116");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index e4f6627..566c724 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -37,7 +38,7 @@ public class EurobonusMastercard extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException {
+	public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "sase", "0102");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index da82ce0..46fa573 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -68,7 +69,7 @@ public class Eurocard extends Bank {
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Eurocard(String username, String password, Context context) throws BankException, LoginException {
+	public Eurocard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -107,7 +108,7 @@ public class Eurocard extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index 43223b7..95ebe8f 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -65,7 +66,7 @@ public class FirstCard extends Bank {
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public FirstCard(String username, String password, Context context) throws BankException, LoginException {
+	public FirstCard(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -102,7 +103,7 @@ public class FirstCard extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 0a85e8f..e20360e 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -71,7 +72,7 @@ public class Handelsbanken extends Bank {
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Handelsbanken(String username, String password, Context context) throws BankException, LoginException {
+	public Handelsbanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -116,7 +117,7 @@ public class Handelsbanken extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
index f9adae6..6f8224b 100644
--- src/com/liato/bankdroid/banking/banks/Hemkop.java
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -75,7 +76,7 @@ public class Hemkop extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public Hemkop(String username, String password, Context context) throws BankException, LoginException {
+    public Hemkop(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
@@ -112,7 +113,7 @@ public class Hemkop extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException {
+    public void update() throws BankException, LoginException, BankChoiceException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index 00083c3..72e7735 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -65,7 +66,7 @@ public class ICA extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public ICA(String username, String password, Context context) throws BankException, LoginException {
+	public ICA(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -118,7 +119,7 @@ public class ICA extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index edadd82..df20eef 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -72,7 +73,7 @@ public class ICABanken extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public ICABanken(String username, String password, Context context) throws BankException, LoginException {
+	public ICABanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -129,7 +130,7 @@ public class ICABanken extends Bank {
 	}	
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/IKEA.java src/com/liato/bankdroid/banking/banks/IKEA.java
index e85b632..8c9cc3b 100644
--- src/com/liato/bankdroid/banking/banks/IKEA.java
+++ src/com/liato/bankdroid/banking/banks/IKEA.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class IKEA extends IkanoPartnerBase {
         this.structId = "1420";
     }
 
-    public IKEA(String username, String password, Context context) throws BankException, LoginException {
+    public IKEA(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index 3319ec7..09d27b2 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -70,7 +71,7 @@ public class IkanoBank extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public IkanoBank(String username, String password, Context context) throws BankException, LoginException {
+    public IkanoBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
@@ -122,7 +123,7 @@ public class IkanoBank extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException {
+    public void update() throws BankException, LoginException, BankChoiceException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 7135704..d30b5cc 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -63,7 +64,7 @@ public abstract class IkanoPartnerBase extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public IkanoPartnerBase(String username, String password, Context context) throws BankException, LoginException {
+	public IkanoPartnerBase(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -117,7 +118,7 @@ public abstract class IkanoPartnerBase extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index ec6002c..715ffb5 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -33,6 +33,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -60,7 +61,7 @@ public class Jojo extends Bank {
         super.URL = URL;
     }
 
-    public Jojo(String username, String password, Context context) throws BankException, LoginException {
+    public Jojo(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
@@ -105,7 +106,7 @@ public class Jojo extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException {
+    public void update() throws BankException, LoginException, BankChoiceException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index 9d2c16e..eb5b533 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -79,7 +80,7 @@ public class Lansforsakringar extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
     }
 
-    public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException {
+    public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
@@ -153,7 +154,7 @@ public class Lansforsakringar extends Bank {
     }
 
     @Override
-    public void update() throws BankException, LoginException {
+    public void update() throws BankException, LoginException, BankChoiceException {
         super.update();
         if (username == null || password == null || username.length() == 0 || password.length() == 0) {
             throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java src/com/liato/bankdroid/banking/banks/McDonalds.java
index f3619eb..1f461ca 100644
--- src/com/liato/bankdroid/banking/banks/McDonalds.java
+++ src/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -67,7 +68,7 @@ public class McDonalds extends Bank {
 		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
 	}
 
-	public McDonalds(String username, String password, Context context) throws BankException, LoginException {
+	public McDonalds(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -102,7 +103,7 @@ public class McDonalds extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || username.length() != 19) {
 			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
diff --git src/com/liato/bankdroid/banking/banks/MobilbankenBase.java src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
index 74ff752..7eb508d 100644
--- src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
+++ src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -62,7 +63,7 @@ public abstract class MobilbankenBase extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public MobilbankenBase(String username, String password, Context context) throws BankException, LoginException {
+	public MobilbankenBase(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -111,7 +112,7 @@ public abstract class MobilbankenBase extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index 1f30171..ce60091 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -72,7 +73,7 @@ public class Nordea extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Nordea(String username, String password, Context context) throws BankException, LoginException {
+	public Nordea(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -116,7 +117,7 @@ public class Nordea extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index 4d6d0ac..df6f8c1 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -61,7 +62,7 @@ public class Nordnet extends Bank {
 		super.URL = URL;
 	}
 
-	public Nordnet(String username, String password, Context context) throws BankException, LoginException {
+	public Nordnet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -110,7 +111,7 @@ public class Nordnet extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index 3a83528..a153668 100644
--- src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -66,7 +67,7 @@ public class Nordnetdirekt extends Bank {
         super.INPUT_HIDDEN_EXTRAS = INPUT_HIDDEN_EXTRAS;
 	}
 
-	public Nordnetdirekt(String username, String password, Context context) throws BankException, LoginException {
+	public Nordnetdirekt(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -108,7 +109,7 @@ public class Nordnetdirekt extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index 96ed28f..feecb1a 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -71,7 +72,7 @@ public class OKQ8 extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public OKQ8(String username, String password, Context context) throws BankException, LoginException {
+	public OKQ8(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -160,7 +161,7 @@ public class OKQ8 extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Opel.java src/com/liato/bankdroid/banking/banks/Opel.java
index 6b9be4c..26c163b 100644
--- src/com/liato/bankdroid/banking/banks/Opel.java
+++ src/com/liato/bankdroid/banking/banks/Opel.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class Opel extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Opel(String username, String password, Context context) throws BankException, LoginException {
+	public Opel(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "opse", "0107");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Osuuspankki.java src/com/liato/bankdroid/banking/banks/Osuuspankki.java
index 8dd3c8b..98d9071 100644
--- src/com/liato/bankdroid/banking/banks/Osuuspankki.java
+++ src/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -61,7 +62,7 @@ public class Osuuspankki extends Bank {
 		super.URL = URL;
 	}
 
-	public Osuuspankki(String username, String password, Context context) throws BankException, LoginException {
+	public Osuuspankki(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -100,7 +101,7 @@ public class Osuuspankki extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index bd5c0af..ef362ca 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -65,7 +66,7 @@ public class PayPal extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public PayPal(String username, String password, Context context) throws BankException, LoginException {
+	public PayPal(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -124,7 +125,7 @@ public class PayPal extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
index 19ea2d7..f59ef3d 100644
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -65,7 +66,7 @@ public class Payson extends Bank {
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
-	public Payson(String username, String password, Context context) throws BankException, LoginException {
+	public Payson(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -119,7 +120,7 @@ public class Payson extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java src/com/liato/bankdroid/banking/banks/PlusGirot.java
index fea6cf2..6ebe1bf 100644
--- src/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ src/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -63,7 +64,7 @@ public class PlusGirot extends Bank {
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
-	public PlusGirot(String username, String password, Context context) throws BankException, LoginException {
+	public PlusGirot(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -101,7 +102,7 @@ public class PlusGirot extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Preem.java src/com/liato/bankdroid/banking/banks/Preem.java
index cd16e0f..e7b31ff 100644
--- src/com/liato/bankdroid/banking/banks/Preem.java
+++ src/com/liato/bankdroid/banking/banks/Preem.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class Preem extends IkanoPartnerBase {
         this.structId = "1437";
     }
 
-    public Preem(String username, String password, Context context) throws BankException, LoginException {
+    public Preem(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/Quintessentially.java src/com/liato/bankdroid/banking/banks/Quintessentially.java
index 5d849c2..5dfe6b9 100644
--- src/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ src/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class Quintessentially extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Quintessentially(String username, String password, Context context) throws BankException, LoginException {
+	public Quintessentially(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "quse", "0119");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 658369a..4267852 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -62,7 +63,7 @@ public class ResursBank extends Bank {
 		super.URL = URL;
 	}
 
-	public ResursBank(String username, String password, Context context) throws BankException, LoginException {
+	public ResursBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -97,7 +98,7 @@ public class ResursBank extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 2df172d..9701fa2 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -71,7 +72,7 @@ public class Rikslunchen extends Bank {
 		super.INPUT_TITLETEXT_PASSWORD = INPUT_TITLETEXT_PASSWORD;
 	}
 
-	public Rikslunchen(String username, String password, Context context) throws BankException, LoginException {
+	public Rikslunchen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -124,7 +125,7 @@ public class Rikslunchen extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (password == null || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index a3eaa2c..faf6e17 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -68,7 +69,7 @@ public class SEB extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public SEB(String username, String password, Context context) throws BankException, LoginException {
+	public SEB(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -105,7 +106,7 @@ public class SEB extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index e05e75b..3e7c85b 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -62,7 +63,7 @@ public abstract class SEBKortBase extends Bank {
 		super.URL = String.format("https://applications.sebkort.com/nis/external/%s/login.do", provider_part);
 	}
 
-	public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException {
+	public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException, BankChoiceException {
 		this(context, url, prodgroup);
 		this.update(username, password);
 	}
@@ -111,7 +112,7 @@ public abstract class SEBKortBase extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/SJPrio.java src/com/liato/bankdroid/banking/banks/SJPrio.java
index 10588a7..6d0409a 100644
--- src/com/liato/bankdroid/banking/banks/SJPrio.java
+++ src/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class SJPrio extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public SJPrio(String username, String password, Context context) throws BankException, LoginException {
+	public SJPrio(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "sjse", "0104");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Saab.java src/com/liato/bankdroid/banking/banks/Saab.java
index c424f87..de3a07b 100644
--- src/com/liato/bankdroid/banking/banks/Saab.java
+++ src/com/liato/bankdroid/banking/banks/Saab.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class Saab extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Saab(String username, String password, Context context) throws BankException, LoginException {
+	public Saab(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "sbse", "0106");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Seat.java src/com/liato/bankdroid/banking/banks/Seat.java
index 0ae1860..69e33bf 100644
--- src/com/liato/bankdroid/banking/banks/Seat.java
+++ src/com/liato/bankdroid/banking/banks/Seat.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class Seat extends IkanoPartnerBase {
         this.structId = "1301";
     }
 
-    public Seat(String username, String password, Context context) throws BankException, LoginException {
+    public Seat(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/SevenDay.java src/com/liato/bankdroid/banking/banks/SevenDay.java
index aecda4f..7dfba78 100644
--- src/com/liato/bankdroid/banking/banks/SevenDay.java
+++ src/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -65,7 +66,7 @@ public class SevenDay extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public SevenDay(String username, String password, Context context) throws BankException, LoginException {
+	public SevenDay(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -112,7 +113,7 @@ public class SevenDay extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Shell.java src/com/liato/bankdroid/banking/banks/Shell.java
index 7f5e74f..a37e9b1 100644
--- src/com/liato/bankdroid/banking/banks/Shell.java
+++ src/com/liato/bankdroid/banking/banks/Shell.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class Shell extends IkanoPartnerBase {
         this.structId = "2035";
     }
 
-    public Shell(String username, String password, Context context) throws BankException, LoginException {
+    public Shell(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/Skoda.java src/com/liato/bankdroid/banking/banks/Skoda.java
index 027dc7a..0abb90d 100644
--- src/com/liato/bankdroid/banking/banks/Skoda.java
+++ src/com/liato/bankdroid/banking/banks/Skoda.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class Skoda extends IkanoPartnerBase {
         this.structId = "1541";
     }
 
-    public Skoda(String username, String password, Context context) throws BankException, LoginException {
+    public Skoda(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/SparbankenOresund.java src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
index ec0af22..b956125 100644
--- src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
+++ src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class SparbankenOresund extends MobilbankenBase {
         this.targetId = "0002";
     }
 
-    public SparbankenOresund(String username, String password, Context context) throws BankException, LoginException {
+    public SparbankenOresund(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/SparbankenSyd.java src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
index 93b361a..74afa0d 100644
--- src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
+++ src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class SparbankenSyd extends MobilbankenBase {
         this.targetId = "0004";
     }
 
-    public SparbankenSyd(String username, String password, Context context) throws BankException, LoginException {
+    public SparbankenSyd(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
index a1a70df..5cc55fc 100644
--- src/com/liato/bankdroid/banking/banks/Statoil.java
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -17,6 +17,7 @@ package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
 
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -36,7 +37,7 @@ public class Statoil extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Statoil(String username, String password, Context context) throws BankException, LoginException {
+	public Statoil(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "stse", "0122");
 	}
 
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index 0c8433f..2b619eb 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -68,7 +69,7 @@ public class Steam extends Bank {
 		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
-	public Steam(String username, String password, Context context) throws BankException, LoginException {
+	public Steam(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -107,7 +108,7 @@ public class Steam extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index fbdf2be..e307f60 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -38,7 +38,9 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankChoice;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -59,6 +61,9 @@ public class Swedbank extends Bank {
 	private Pattern reLinklessAccounts = Pattern.compile("fix\">\\s*<span\\sclass=\"name\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\sclass=\"amount\">([^<]+)</span>\\s*</div>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("date\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"receiver\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"amount\">([^<]+)</span>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	private Pattern reLoanData = Pattern.compile("<li[^>]*>([^<]+)<br/><span\\s*class=\"secondary\">([^<]+)</span></li>");
+	private Pattern reMultipleBanks = Pattern.compile("menu\\.html\\?bank=(\\d{1,})\">([^<]+)</");
+	
+	String response;
 	public Swedbank(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -70,7 +75,7 @@ public class Swedbank extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Swedbank(String username, String password, Context context) throws BankException, LoginException {
+	public Swedbank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -81,7 +86,7 @@ public class Swedbank extends Bank {
         urlopen = new Urllib();
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
-        String response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
+        response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
         matcher = reCSRF.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
@@ -101,7 +106,8 @@ public class Swedbank extends Bank {
         postData.clear();
         postData.add(new BasicNameValuePair("zyx", password));
         postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-        return new LoginPackage(urlopen, postData, response, "https://mobilbank.swedbank.se/banking/swedbank/login.html");
+        String banknr = (getExtras() != null && getExtras().length() > 0) ? "?bank="+getExtras() : "";
+        return new LoginPackage(urlopen, postData, response, "https://mobilbank.swedbank.se/banking/swedbank/login.html"+banknr);
     }
 
     @Override
@@ -109,7 +115,7 @@ public class Swedbank extends Bank {
 	    
 	    try {
 	        LoginPackage lp = preLogin();
-	        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+	        response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
 			if (response.contains("misslyckats")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -125,16 +131,45 @@ public class Swedbank extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		String response = null;
+		try {
+            response = urlopen.open("http://x.x00.us/android/bankdroid/swedbank/multiplebanks.htm");
+        }
+        catch (ClientProtocolException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
+        catch (IOException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
 		Matcher matcher;
+		if (getExtras() == null || getExtras().length() == 0) {
+    		ArrayList<BankChoice> banks = new ArrayList<BankChoice>();
+    		matcher = reMultipleBanks.matcher(response);
+    		while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: ID                0 | 1 | ..
+                 * 2: Name              Ostlands Sparbank
+                 *  
+                 */ 		    
+    		    banks.add(new BankChoice(Html.fromHtml(matcher.group(2)).toString().trim(), matcher.group(1)));
+    		}
+    		if (!banks.isEmpty()) {
+    		    throw new BankChoiceException("Select a bank.", banks);
+    		}
+		}
+		
+        String banknr = (getExtras() != null && getExtras().length() > 0) ? "?bank="+getExtras() : "";
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html"+banknr);
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
                 /*
@@ -186,6 +221,7 @@ public class Swedbank extends Bank {
 		super.updateTransactions(account, urlopen);
 		if (account.getType() == Account.OTHER) return;
 
+		String banknr = (getExtras() != null && getExtras().length() > 0) ? "&bank="+getExtras() : "";
 		String response = null;
 		Matcher matcher;
 		try {
@@ -193,8 +229,8 @@ public class Swedbank extends Bank {
 		    if (account.getType() == Account.LOANS) {
 		        String [] accountId = account.getId().split(":", 2);
 		        if (accountId.length < 2) return;
-	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]);
-	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]);
+	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]+banknr);
+	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]+banknr);
 	            matcher = reLoanData.matcher(response);
 	            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 	            Calendar cal = Calendar.getInstance(); 
@@ -213,8 +249,8 @@ public class Swedbank extends Bank {
 	            }
 		    }
 		    else {
-	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
-	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId()+banknr);
+	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId()+banknr);
 	            matcher = reTransactions.matcher(response);
 	            while (matcher.find()) {
                     /*
diff --git src/com/liato/bankdroid/banking/banks/TestBank.java src/com/liato/bankdroid/banking/banks/TestBank.java
index 2c48956..cd05ea6 100644
--- src/com/liato/bankdroid/banking/banks/TestBank.java
+++ src/com/liato/bankdroid/banking/banks/TestBank.java
@@ -32,6 +32,7 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -63,7 +64,7 @@ public class TestBank extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public TestBank(String username, String password, Context context) throws BankException, LoginException {
+	public TestBank(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -75,7 +76,7 @@ public class TestBank extends Bank {
 	}
 	
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index 0304ec1..bdc1e04 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -62,7 +63,7 @@ public class Villabanken extends Bank {
 		super.URL = URL;
 	}
 
-	public Villabanken(String username, String password, Context context) throws BankException, LoginException {
+	public Villabanken(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -145,7 +146,7 @@ public class Villabanken extends Bank {
 		return urlopen;
 	}
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banking/banks/Volkswagen.java src/com/liato/bankdroid/banking/banks/Volkswagen.java
index f2684e4..10c7018 100644
--- src/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ src/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -39,7 +40,7 @@ public class Volkswagen extends IkanoPartnerBase {
         this.structId = "1319";
     }
 
-    public Volkswagen(String username, String password, Context context) throws BankException, LoginException {
+    public Volkswagen(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index 459e11a..30d0486 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -63,7 +64,7 @@ public class Volvofinans extends Bank {
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Volvofinans(String username, String password, Context context) throws BankException, LoginException {
+	public Volvofinans(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		this(context);
 		this.update(username, password);
 	}
@@ -108,7 +109,7 @@ public class Volvofinans extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
+	public void update() throws BankException, LoginException, BankChoiceException {
 		super.update();
 		Log.d("Volvofinans", "update");
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
diff --git src/com/liato/bankdroid/banking/banks/Wallet.java src/com/liato/bankdroid/banking/banks/Wallet.java
index 37010f3..22d9293 100644
--- src/com/liato/bankdroid/banking/banks/Wallet.java
+++ src/com/liato/bankdroid/banking/banks/Wallet.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 import android.content.Context;
 
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankChoiceException;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -36,7 +37,7 @@ public class Wallet extends SEBKortBase {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Wallet(String username, String password, Context context) throws BankException, LoginException {
+	public Wallet(String username, String password, Context context) throws BankException, LoginException, BankChoiceException {
 		super(username, password, context, "wase", "0121");
 	}
 
diff --git src/com/liato/bankdroid/banking/exceptions/BankChoiceException.java src/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
new file mode 100644
index 0000000..67d92f7
--- /dev/null
+++ src/com/liato/bankdroid/banking/exceptions/BankChoiceException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.exceptions;
+
+import java.util.ArrayList;
+
+import com.liato.bankdroid.banking.BankChoice;
+
+public class BankChoiceException extends Exception {
+	private static final long serialVersionUID = 1L;
+	private ArrayList<BankChoice> banks;
+	public BankChoiceException(String message) {
+		super(message);
+	}
+
+	public BankChoiceException(String message,  ArrayList<BankChoice> banks) {
+        super(message);
+        this.banks = banks;
+    }
+
+    /**
+     * @return the banks
+     */
+    public ArrayList<BankChoice> getBanks() {
+        return banks;
+    }	
+}
diff --git src/com/liato/bankdroid/db/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
index f257f24..91e3d25 100644
--- src/com/liato/bankdroid/db/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -175,7 +175,7 @@ public class DBAdapter {
                 vals.put("acctype", acc.getType());
                 vals.put("aliasfor", acc.getAliasfor());
 	            mDb.insert("accounts", null, vals);
-	            if (acc.getAliasfor() != null && acc.getAliasfor().length() > 0) {
+	            if (acc.getAliasfor() == null || acc.getAliasfor().length() == 0) {
     	            ArrayList<Transaction> transactions = acc.getTransactions();
     	            if (transactions != null && !transactions.isEmpty()) {
     	                deleteTransactions(new Long(bankId).toString()+"_"+acc.getId());

commit f0d1dc1684eceb3842144494f6246dfef615357a
Author: liato <x@x00.us>
Date:   Wed Apr 27 04:36:50 2011 +0200

    Fix for Jojo login.

diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index 6af89ef..ec6002c 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -80,9 +80,9 @@ public class Jojo extends Bank {
         postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-        postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Username", username));
-        postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Password", password));
-        postData.add(new BasicNameValuePair("ctl00$LoginBlob1$LoginButton", "Logga in"));
+        postData.add(new BasicNameValuePair("ctl00$ctl01$UsernameTextBox", username));
+        postData.add(new BasicNameValuePair("ctl00$ctl01$PasswordTextBox", password));
+        postData.add(new BasicNameValuePair("ctl00$ctl01$LoginButton", "Logga in"));
 
         return new LoginPackage(urlopen, postData, response, "https://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
     }

commit f44b8ecfd14ef9d7f88a469793c5882e980f9390
Author: liato <x@x00.us>
Date:   Wed Apr 27 04:17:36 2011 +0200

    Correctly calculate bank balance with "alias" accounts.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 0c83d15..db34769 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -160,7 +160,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
             BigDecimal bal = new BigDecimal(0); 
             for (Account account : accounts) {
                 if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
-                    if (!account.isHidden()) {
+                    if (!account.isHidden() || (account.getAliasfor() == null || account.getAliasfor().length() == 0)) {
                         bal = bal.add(account.getBalance());
                     }
                 }
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index 4b53405..edadd82 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -152,7 +152,9 @@ public class ICABanken extends Bank {
                  *  
                  */			    
                 accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
-                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + matcher.group(1).trim()));
+                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + matcher.group(1).trim());
+                account.setAliasfor(matcher.group(1).trim());
+                accounts.add(account);
 
                 balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}

commit 69396f337bfef3324d5150fda98dd83ce440e76c
Author: liato <x@x00.us>
Date:   Wed Apr 27 04:08:23 2011 +0200

    Add support for PayPal premier accounts.

diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 62ab052..bd5c0af 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -132,20 +132,7 @@ public class PayPal extends Bank {
 		urlopen = login();
 		try {
             response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
-            //Helpers.slowDebug(TAG, response);
-            Matcher matcher = reBalance.matcher(response);
-            if (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: balance           554.70
-                 * 2: currency          SEK
-                 * 
-                 */
-                balance = Helpers.parseBalance(matcher.group(1));
-                currency = matcher.group(2).trim();
-            }
-    		matcher = reAccounts.matcher(response);
+    		Matcher matcher = reAccounts.matcher(response);
     		int accId = 1;
     		while (matcher.find()) {
                 /*
@@ -161,6 +148,23 @@ public class PayPal extends Bank {
     		    accounts.add(account);
     		    accId++;
     		}
+            matcher = reBalance.matcher(response);
+            if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: balance           554.70
+                 * 2: currency          SEK
+                 * 
+                 */
+                balance = Helpers.parseBalance(matcher.group(1));
+                currency = matcher.group(2).trim();
+                if (accounts.isEmpty()) {
+                    // Probably a premier account.
+                    Account account = new Account(currency, balance, "1");
+                    account.setCurrency(currency);
+                    accounts.add(account);                }
+            }
 
     		if (accounts.isEmpty()) {
     			throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit bf445c4420b5f69c8cf5ec27074f42af95f67c28
Author: liato <x@x00.us>
Date:   Wed Apr 27 03:56:45 2011 +0200

    Show older loans for CSN.

diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 2f20c9f..7b06440 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -139,7 +139,8 @@ public class CSN extends Bank {
 		    response = urlopen.open("https://www.csn.se/aterbetalning/hurStorArMinSkuld/aktuellStudieskuld.do?javascript=off");
 			Matcher matcher;
 			matcher = reBalance.matcher(response);
-			if (matcher.find()) {
+			int i = 0;
+			while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
@@ -149,9 +150,17 @@ public class CSN extends Bank {
                  *  
                  */
 			    BigDecimal amount = Helpers.parseBalance(matcher.group(3).replace(",", "")).negate();
-				accounts.add(new Account("Annuitetslån",
-				        amount, matcher.group(1).trim(), Account.LOANS));
-				balance = amount;
+			    Account account = new Account(
+                        Html.fromHtml(matcher.group(2)).toString().trim(),
+                        amount,
+                        matcher.group(1).trim(),
+                        Account.LOANS);
+			    if (i > 0) {
+			        account.setAliasfor("0");
+			    }
+				accounts.add(account);
+				balance = balance.add(amount);
+				i++;
 			}
 			
 			if (accounts.isEmpty()) {
@@ -174,6 +183,8 @@ public class CSN extends Bank {
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
+        if (account.getAliasfor() == null || account.getAliasfor().length() == 0) return;
+        
         Matcher matcher;
         try {
             response = urlopen.open("https://www.csn.se/studiemedel/utbetalningar/utbetalningar.do?javascript=off");

commit 8f47e3dad46aba314a5d4ab274392d1eda5cef8e
Author: liato <x@x00.us>
Date:   Wed Apr 27 03:40:34 2011 +0200

    Make Nordnetdirekt play nice with the recent db changes.

diff --git src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
index d857a01..3a83528 100644
--- src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
+++ src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -17,7 +17,6 @@
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -54,7 +53,6 @@ public class Nordnetdirekt extends Bank {
     
     private Pattern reBalance = Pattern.compile("left\">\\s*<table[^>]+>\\s*<caption[^>]+>([^<]+)</caption>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>");
 	private String response = null;
-	private String key = "";
 	
 	public Nordnetdirekt(Context context) {
 		super(context);
@@ -87,7 +85,7 @@ public class Nordnetdirekt extends Bank {
         postData.add(new BasicNameValuePair("usa", "7"));
         postData.add(new BasicNameValuePair("a1", username));
         postData.add(new BasicNameValuePair("a2", password));
-        postData.add(new BasicNameValuePair("nyckel", key));
+        postData.add(new BasicNameValuePair("nyckel", extras));
         return new LoginPackage(urlopen, postData, response, "https://www.nordnetdirekt.se/mux/inloggad/lib/login.html");
     }
 
@@ -148,36 +146,5 @@ public class Nordnetdirekt extends Bank {
             super.updateComplete();
         }
 	}
-
-    @Override
-    public String getExtras() {
-        return this.key;
-    }
-
-    public void setData(String username, String password, BigDecimal balance,
-            boolean disabled, long dbid, String currency, String customName) {
-        super.setData(username, password, balance, disabled, dbid, currency, customName);
-        if (password.contains("|")) {
-            String[] passkey = password.split("\\|", 2);
-            this.password = passkey[0];
-            this.key = passkey[1];
-        }
-    }
-
-    @Override
-    public void setExtras(String extras) {
-        this.key = extras;
-    }
-
-    @Override
-    public void setPassword(String password) {
-        this.password = password;
-        if (password.contains("|")) {
-            String[] passkey = password.split("\\|", 2);
-            this.password = passkey[0];
-            this.key = passkey[1];
-        }
-    }
-    
-    
+  
 }

commit a582f9b088578b14ca7b437c04dc94919c20a5d7
Author: liato <x@x00.us>
Date:   Wed Apr 27 03:39:50 2011 +0200

    Fix transactionsurl regex for IkanoPartnerBase.

diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 91de98a..7135704 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -49,7 +49,7 @@ public abstract class IkanoPartnerBase extends Bank {
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reCtl = Pattern.compile("(ctl\\d{1,})_CustomValidationSummary", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\"><span[^>]+>Transaktioner</span>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\">(?:<span[^>]+>)?Transaktioner</", Pattern.CASE_INSENSITIVE);
     private Pattern reAccounts = Pattern.compile("captionLabel\">([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
     private Pattern reTransactions = Pattern.compile("<td\\s*class=\"TransactionDateRow\">([^>]+)</td><td[^>]+>(.+?)</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>");
     private String response = null;

commit 4be4c9ea47702b4070a6ba54b2615267888ecfae
Author: liato <x@x00.us>
Date:   Wed Apr 27 03:38:57 2011 +0200

    Add new columns to the database to store "extras" for banks and alias id for accounts.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index b72d268..b59ebd9 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -81,8 +81,10 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 				if (bank != null) {
 					((EditText)findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
                     ((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
-                    ((EditText)findViewById(R.id.edtBankeditExtras)).setText(bank.getExtras());
                     ((EditText)findViewById(R.id.edtBankeditCustomName)).setText(bank.getCustomName());
+                    if (bank.getExtras() != null) {
+                        ((EditText)findViewById(R.id.edtBankeditExtras)).setText(bank.getExtras());
+                    }
                     
 					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
 					if (bank.isDisabled()) {
diff --git src/com/liato/bankdroid/banking/Account.java src/com/liato/bankdroid/banking/Account.java
index 47a1b5c..8d8d670 100644
--- src/com/liato/bankdroid/banking/Account.java
+++ src/com/liato/bankdroid/banking/Account.java
@@ -32,6 +32,7 @@ public class Account implements IAccountTypes {
 	private boolean notify = true;
 	private String currency;
 	private ArrayList<Transaction> transactions;
+	private String aliasfor;
 
 	public ArrayList<Transaction> getTransactions() {
 		return transactions;
@@ -139,5 +140,13 @@ public class Account implements IAccountTypes {
 	public void setCurrency(final String currency) {
 		this.currency = currency;
 	}
+	
+    public String getAliasfor() {
+        return aliasfor;
+    }
+
+    public void setAliasfor(final String aliasfor) {
+        this.aliasfor = aliasfor;
+    }	
 
 }
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index da2ac2b..0c83d15 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -66,14 +66,15 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 
     protected String username;
     protected String password;
+    protected String customName;
+    protected String extras;
+    protected String currency = "SEK";
     protected ArrayList<Account> accounts = new ArrayList<Account>();
     protected HashMap<String, Account> oldAccounts;
     protected BigDecimal balance = new BigDecimal(0);
     protected boolean disabled = false;
     protected long dbid = -1;
     protected Urllib urlopen = null;
-    protected String customName;
-    protected String currency = "SEK";
 
     public Urllib getUrlopen() {
         return urlopen;
@@ -191,11 +192,11 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
     
     public String getExtras() {
-        return "";
+        return this.extras;
     }
 
     public void setExtras(String extras) {
-        // Do nothing.
+        this.extras = extras;
     }    
 
     public String getShortName() {
@@ -203,7 +204,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     }
 
     public void setData(String username, String password, BigDecimal balance,
-            boolean disabled, long dbid, String currency, String customName) {
+            boolean disabled, long dbid, String currency, String customName, String extras) {
         this.username = username;
         this.password = password;
         this.balance = balance;
@@ -211,6 +212,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         this.dbid = dbid;
         this.currency = currency;
         this.customName = customName;
+        this.extras = extras;
     }
 
     public String getCurrency() {
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index beddc01..62adba4 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -276,7 +276,8 @@ public class BankFactory {
 							 (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
 							 c.getLong(c.getColumnIndex("_id")),
 							 c.getString(c.getColumnIndex("currency")),
-							 c.getString(c.getColumnIndex("custname")));
+							 c.getString(c.getColumnIndex("custname")),
+							 c.getString(c.getColumnIndex("extras")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -320,7 +321,8 @@ public class BankFactory {
 				             (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
 				             c.getLong(c.getColumnIndex("_id")),
 				             c.getString(c.getColumnIndex("currency")),
-				             c.getString(c.getColumnIndex("custname")));
+				             c.getString(c.getColumnIndex("custname")),
+                             c.getString(c.getColumnIndex("extras")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -352,11 +354,15 @@ public class BankFactory {
         account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
         account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
         account.setCurrency(c.getString(c.getColumnIndex("currency")));
+        account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
 		c.close();
 		if (loadTransactions) {
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			//"transdate", "btransaction", "amount"}			
-			c = db.fetchTransactions(accountId);
+			String fromAccount = accountId;
+			if (account.getAliasfor() != null && account.getAliasfor().length() > 0) {
+			    fromAccount = Long.toString(account.getBankDbId()) + "_" + account.getAliasfor();
+			}
+			c = db.fetchTransactions(fromAccount);
 			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
 				while (!c.isLast() && !c.isAfterLast()) {
 					c.moveToNext();
@@ -393,7 +399,8 @@ public class BankFactory {
                                               c.getInt(c.getColumnIndex("acctype")));
     	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
     	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
-    	        account.setCurrency(c.getString(c.getColumnIndex("currency")));
+                account.setCurrency(c.getString(c.getColumnIndex("currency")));
+                account.setAliasfor(c.getString(c.getColumnIndex("aliasfor")));
     			accounts.add(account);
 			}
 			catch (ArrayIndexOutOfBoundsException e) {
diff --git src/com/liato/bankdroid/db/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
index abb6753..f257f24 100644
--- src/com/liato/bankdroid/db/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -20,10 +20,6 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
-
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.ContentValues;
 import android.content.Context;
@@ -32,6 +28,10 @@ import android.database.SQLException;
 import android.database.sqlite.SQLiteDatabase;
 import android.util.Log;
 
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+
 
 public class DBAdapter {
 
@@ -40,7 +40,7 @@ public class DBAdapter {
     private SQLiteDatabase mDb;
     
     static final String DATABASE_NAME = "data";
-    static final int DATABASE_VERSION = 9;
+    static final int DATABASE_VERSION = 10;
 
     private final Context mCtx;
 
@@ -113,7 +113,7 @@ public class DBAdapter {
      * @return Cursor over all banks
      */
     public Cursor fetchBanks() {
-        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency"}, null, null, null, null, "_id asc");
+        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras"}, null, null, null, null, "_id asc");
     }
 
     
@@ -123,7 +123,7 @@ public class DBAdapter {
      * @return Cursor over all accounts belonging to a bank
      */
     public Cursor fetchAccounts(long bankId) {
-        return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id", "acctype", "hidden", "notify", "currency"}, "bankid="+bankId, null, null, null, null);
+        return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id", "acctype", "hidden", "notify", "currency", "aliasfor"}, "bankid="+bankId, null, null, null, null);
     }
     
     public Cursor fetchTransactions(String account) {
@@ -141,14 +141,14 @@ public class DBAdapter {
         try {
             password = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
 		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+            Log.w(TAG, "SimpleCrypto error: "+e.getMessage());
+        }
         initialValues.put("password", password);
         initialValues.put("disabled", 0);
         initialValues.put("balance", bank.getBalance().toPlainString());
         initialValues.put("currency", bank.getCurrency());
         initialValues.put("custname", bank.getCustomName());
+        initialValues.put("extras", bank.getExtras());
         initialValues.put("updated", sdf.format(cal.getTime()));
         
         long bankId = bank.getDbId();
@@ -173,21 +173,22 @@ public class DBAdapter {
                 vals.put("notify", acc.isNotify() ? 1 : 0);
                 vals.put("currency", acc.getCurrency());
                 vals.put("acctype", acc.getType());
-                Log.d(TAG, "Acctype: "+acc.getType());
+                vals.put("aliasfor", acc.getAliasfor());
 	            mDb.insert("accounts", null, vals);
-	            ArrayList<Transaction> transactions = acc.getTransactions();
-	            if (transactions != null && !transactions.isEmpty()) {
-	                deleteTransactions(new Long(bankId).toString()+"_"+acc.getId());
-		            for(Transaction transaction : transactions) {
-			            ContentValues transvals = new ContentValues();
-			            transvals.put("transdate", transaction.getDate());
-			            transvals.put("btransaction", transaction.getTransaction());
-			            transvals.put("amount", transaction.getAmount().toPlainString());
-			            transvals.put("account", new Long(bankId).toString()+"_"+acc.getId());
-			            transvals.put("currency", transaction.getCurrency());
-			            
-			            mDb.insert("transactions", null, transvals);
-		            }
+	            if (acc.getAliasfor() != null && acc.getAliasfor().length() > 0) {
+    	            ArrayList<Transaction> transactions = acc.getTransactions();
+    	            if (transactions != null && !transactions.isEmpty()) {
+    	                deleteTransactions(new Long(bankId).toString()+"_"+acc.getId());
+    		            for(Transaction transaction : transactions) {
+    			            ContentValues transvals = new ContentValues();
+    			            transvals.put("transdate", transaction.getDate());
+    			            transvals.put("btransaction", transaction.getTransaction());
+    			            transvals.put("amount", transaction.getAmount().toPlainString());
+    			            transvals.put("account", new Long(bankId).toString()+"_"+acc.getId());
+    			            transvals.put("currency", transaction.getCurrency());
+    			            mDb.insert("transactions", null, transvals);
+    		            }
+    	            }
 	            }
 	        }
         }
@@ -203,7 +204,7 @@ public class DBAdapter {
     }
     
     public Cursor getBank(String bankId) {
-    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency"}, "_id="+bankId, null, null, null, null);
+    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency", "extras"}, "_id="+bankId, null, null, null, null);
     	if (c != null) {
     		c.moveToFirst();
     	}
@@ -215,7 +216,7 @@ public class DBAdapter {
     }
 
     public Cursor getAccount(String id) {
-    	Cursor c = mDb.query("accounts", new String[] {"id", "balance", "name", "bankid", "acctype", "hidden", "notify", "currency"}, "id='"+id+"'", null, null, null, null);
+    	Cursor c = mDb.query("accounts", new String[] {"id", "balance", "name", "bankid", "acctype", "hidden", "notify", "currency", "aliasfor"}, "id='"+id+"'", null, null, null, null);
     	if (c != null) {
     		c.moveToFirst();
     	}
diff --git src/com/liato/bankdroid/db/DatabaseHelper.java src/com/liato/bankdroid/db/DatabaseHelper.java
index a3a3081..6c86a1b 100644
--- src/com/liato/bankdroid/db/DatabaseHelper.java
+++ src/com/liato/bankdroid/db/DatabaseHelper.java
@@ -42,12 +42,18 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
 				+ "custname text, "
 				+ "updated text, "
 				+ "sortorder real, "
-				+ "currency text, " + "disabled integer);");
+				+ "currency text, "
+				+ "disabled integer, "
+				+ "extras text);");
 		db.execSQL("create table accounts (bankid integer not null, "
-				+ "id text not null, " + "balance text not null, "
-				+ "acctype integer not null, " + "hidden integer not null, "
-				+ "notify integer not null, " + "currency text, "
-				+ "name text not null);");
+				+ "id text not null, "
+				+ "balance text not null, "
+				+ "acctype integer not null, "
+				+ "hidden integer not null, "
+				+ "notify integer not null, "
+				+ "currency text, "
+				+ "name text not null, "
+				+ "aliasfor text);");
 		db.execSQL("create table transactions (_id integer primary key autoincrement, "
 				+ "transdate text not null, "
 				+ "btransaction text not null, "
@@ -61,9 +67,11 @@ final public class DatabaseHelper extends SQLiteOpenHelper {
 			final int newVersion) {
 		Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
 				+ " to " + newVersion + ", which will destroy all old data");
-		db.execSQL("DROP TABLE IF EXISTS banks;");
-		db.execSQL("DROP TABLE IF EXISTS accounts;");
-		db.execSQL("DROP TABLE IF EXISTS transactions;");
-		onCreate(db);
+        // Version <= 1.7.2 
+		if (oldVersion == 9) {
+		    // Add an "extras" field to the bank and and "alias for" field to the account.
+            db.execSQL("ALTER TABLE banks ADD extras text;");
+            db.execSQL("ALTER TABLE accounts ADD aliasfor text;");
+		}
 	}
 }
\ No newline at end of file

commit 0a54985eda8e4d9de4d1af245d017c4fff1f6030
Author: liato <x@x00.us>
Date:   Fri Apr 22 23:26:43 2011 +0200

    Add support for Nordnetdirekt.

diff --git logos.psd logos.psd
index 2f42bfa..3e9bead 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_nordnetdirekt.png res/drawable/logo_nordnetdirekt.png
new file mode 100644
index 0000000..c2a26d1
Binary files /dev/null and res/drawable/logo_nordnetdirekt.png differ
diff --git res/layout/bank.xml res/layout/bank.xml
index 1c096b9..ce738ee 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -8,10 +8,10 @@
 	android:layout_width="fill_parent">
 
 	<ScrollView
-
 		android:layout_height="fill_parent"
 		android:layout_width="fill_parent"
-		android:fillViewport="true" android:layout_above="@+id/TableLayout01">
+		android:fillViewport="true"
+		android:layout_above="@+id/TableLayout01">
 		<LinearLayout
 			android:id="@+id/LinearLayout01"
 			android:layout_height="wrap_content"
@@ -20,37 +20,65 @@
 			android:orientation="vertical"
 			android:layout_alignParentTop="true"
 			android:padding="10dp">
-			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/bank" /><Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TextView
+			<TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
 				android:typeface="sans"
 				android:textSize="20sp"
-				android:text="@string/username"				
-				android:id="@+id/txtBankeditUsername"/>
+				android:text="@string/bank" />
+			<Spinner
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/spnBankeditBanklist"></Spinner>
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/username"
+				android:id="@+id/txtBankeditUsername" />
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditUsername" android:inputType="textEmailAddress"></EditText>
+				android:id="@+id/edtBankeditUsername"
+				android:inputType="textEmailAddress"></EditText>
 			<TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
 				android:typeface="sans"
-				android:textSize="20sp"				
-				android:text="@string/password" 
-				android:id="@+id/txtBankeditPassword"/>
+				android:textSize="20sp"
+				android:text="@string/password"
+				android:id="@+id/txtBankeditPassword" />
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView
+				android:id="@+id/edtBankeditPassword"
+				android:inputType="textPassword"></EditText>
+			<TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
 				android:typeface="sans"
-				android:textSize="20sp" android:text="@string/custom_name"/><EditText
+				android:textSize="20sp"
+				android:text="@string/custom_name" />
+			<EditText
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/edtBankeditCustomName"
+				android:inputType="textCapWords"></EditText>
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/extras_field"
+				android:id="@+id/txtBankeditExtras"
+				android:visibility="gone" />
+			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditCustomName" android:inputType="textCapWords"></EditText>
-			
-			
+				android:id="@+id/edtBankeditExtras"
+				android:inputType="textCapWords"
+				android:visibility="gone"></EditText>
 			<TextView
 				android:layout_width="wrap_content"
 				android:layout_height="wrap_content"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 7cd4e35..e4d1563 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -222,4 +222,6 @@
     
 	<string name="card_id">Kort ID</string>
 	<string name="card_number">Kortnummer</string>
+	
+	<string name="nordnetdirekt_extras_title">Nyckel</string>	
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 55ae6f3..8503657 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -23,6 +23,7 @@
     <string name="username">Username</string>
     <string name="password">Password</string>
     <string name="custom_name">Custom Name (optional)</string>
+    <string name="extras_field">Extras</string>
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
 
@@ -273,4 +274,6 @@
 	
 	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
+
+	<string name="nordnetdirekt_extras_title">Key</string>	
 </resources>
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index bdff952..b72d268 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -30,6 +30,7 @@ import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.text.InputType;
 import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -53,7 +54,7 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
-	private final static String TAG = "AccountActivity";
+	private final static String TAG = "BankEditActivity";
 	private Bank SELECTED_BANK;
 	private long BANKID = -1;
 
@@ -80,6 +81,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 				if (bank != null) {
 					((EditText)findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
                     ((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
+                    ((EditText)findViewById(R.id.edtBankeditExtras)).setText(bank.getExtras());
                     ((EditText)findViewById(R.id.edtBankeditCustomName)).setText(bank.getCustomName());
                     
 					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
@@ -110,6 +112,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 			SELECTED_BANK.setUsername(((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim());
             SELECTED_BANK.setPassword(((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
             SELECTED_BANK.setCustomName(((EditText) findViewById(R.id.edtBankeditCustomName)).getText().toString().trim());
+            SELECTED_BANK.setExtras(((EditText) findViewById(R.id.edtBankeditExtras)).getText().toString().trim());
 			SELECTED_BANK.setDbid(BANKID);
 			new DataRetrieverTask(this, SELECTED_BANK).execute();
 		}
@@ -121,16 +124,26 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
 		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
         EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+        EditText edtExtras = (EditText)findViewById(R.id.edtBankeditExtras);
         TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
         TextView txtPassword = (TextView)findViewById(R.id.txtBankeditPassword);
+        TextView txtExtras = (TextView)findViewById(R.id.txtBankeditExtras);
         
 		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
 		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
-		edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
+        txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
+
+        edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
 		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
 		edtPassword.setTypeface(Typeface.MONOSPACE);
-        txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
         txtPassword.setText(SELECTED_BANK.getInputTitlePassword());
+
+        edtExtras.setInputType(SELECTED_BANK.getInputTypeExtras());
+        if ((SELECTED_BANK.getInputTypeExtras() & InputType.TYPE_TEXT_VARIATION_PASSWORD) == InputType.TYPE_TEXT_VARIATION_PASSWORD) {
+            edtExtras.setTransformationMethod(PasswordTransformationMethod.getInstance());
+            edtExtras.setTypeface(Typeface.MONOSPACE);
+        }
+        txtExtras.setText(SELECTED_BANK.getInputTitleExtras());
 		
         if (SELECTED_BANK.isInputUsernameHidden()) {
             edtUsername.setVisibility(View.GONE);
@@ -148,7 +161,16 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
         else {
             edtPassword.setVisibility(View.VISIBLE);
             txtPassword.setVisibility(View.VISIBLE);
-        }        
+        }
+        
+        if (SELECTED_BANK.isInputExtrasHidden()) {
+            edtExtras.setVisibility(View.GONE);
+            txtExtras.setVisibility(View.GONE);
+        }
+        else {
+            edtExtras.setVisibility(View.VISIBLE);
+            txtExtras.setVisibility(View.VISIBLE);
+        }          
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 1b84e8b..da2ac2b 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -50,11 +50,14 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
 	protected String URL;
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
     protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+    protected int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT;
     protected String INPUT_HINT_USERNAME = null;
     protected boolean INPUT_HIDDEN_USERNAME = false;
     protected boolean INPUT_HIDDEN_PASSWORD = false;
+    protected boolean INPUT_HIDDEN_EXTRAS = true;
     protected int INPUT_TITLETEXT_USERNAME = R.string.username;
     protected int INPUT_TITLETEXT_PASSWORD = R.string.password;
+    protected int INPUT_TITLETEXT_EXTRAS = R.string.extras_field;
     protected boolean STATIC_BALANCE = false;
     protected boolean BROKEN = false;
 
@@ -186,6 +189,14 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public void setCustomName(String customName) {
         this.customName = customName;
     }
+    
+    public String getExtras() {
+        return "";
+    }
+
+    public void setExtras(String extras) {
+        // Do nothing.
+    }    
 
     public String getShortName() {
         return NAME_SHORT;
@@ -257,6 +268,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return INPUT_TYPE_PASSWORD;
     }
 
+    public int getInputTypeExtras() {
+        return INPUT_TYPE_EXTRAS;
+    }
+    
     public String getInputHintUsername() {
         return INPUT_HINT_USERNAME;
     }
@@ -268,6 +283,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public boolean isInputPasswordHidden() {
         return INPUT_HIDDEN_PASSWORD;
     }
+    
+    public boolean isInputExtrasHidden() {
+        return INPUT_HIDDEN_EXTRAS;
+    }    
 
     public int getInputTitleUsername() {
         return INPUT_TITLETEXT_USERNAME;
@@ -277,6 +296,10 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
         return INPUT_TITLETEXT_PASSWORD;
     }
 
+    public int getInputTitleExtras() {
+        return INPUT_TITLETEXT_EXTRAS;
+    }
+
 
     // Returns true if the current implementation of this bank is broken.
     public boolean isBroken() {
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 929216a..beddc01 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -48,6 +48,7 @@ import com.liato.bankdroid.banking.banks.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.Nordnet;
+import com.liato.bankdroid.banking.banks.Nordnetdirekt;
 import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
@@ -184,6 +185,8 @@ public class BankFactory {
             return new SparbankenSyd(context);
         case IBankTypes.SPARBANKEN_ORESUND:
             return new SparbankenOresund(context);
+        case IBankTypes.NORDNETDIREKT:
+            return new Nordnetdirekt(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -242,6 +245,7 @@ public class BankFactory {
         banks.add(new IKEA(context));
         banks.add(new SparbankenSyd(context));
         banks.add(new SparbankenOresund(context));
+        banks.add(new Nordnetdirekt(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
new file mode 100644
index 0000000..d857a01
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Nordnetdirekt.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Nordnetdirekt extends Bank {
+	private static final String TAG = "Nordnetdirekt";
+	private static final String NAME = "Nordnetdirekt";
+	private static final String NAME_SHORT = "nordnetdirekt";
+	private static final String URL = "https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html";
+	private static final int BANKTYPE_ID = IBankTypes.NORDNETDIREKT;
+
+	private static final int INPUT_TITLETEXT_EXTRAS = R.string.nordnetdirekt_extras_title;
+	private static final int INPUT_TYPE_EXTRAS = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
+	private static final boolean INPUT_HIDDEN_EXTRAS = false;
+    
+    private Pattern reBalance = Pattern.compile("left\">\\s*<table[^>]+>\\s*<caption[^>]+>([^<]+)</caption>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr[^>]+>\\s*<td[^>]+>[^<]+</td>\\s*<td>([^<]+)</td>");
+	private String response = null;
+	private String key = "";
+	
+	public Nordnetdirekt(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TITLETEXT_EXTRAS = INPUT_TITLETEXT_EXTRAS;
+        super.INPUT_TYPE_EXTRAS = INPUT_TYPE_EXTRAS;
+        super.INPUT_HIDDEN_EXTRAS = INPUT_HIDDEN_EXTRAS;
+	}
+
+	public Nordnetdirekt(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        response = urlopen.open("https://www.nordnetdirekt.se/mux/oinloggad/startsida/index.html");
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("a4", "sv"));
+        postData.add(new BasicNameValuePair("a3", "ADSE"));
+        postData.add(new BasicNameValuePair("usa", "7"));
+        postData.add(new BasicNameValuePair("a1", username));
+        postData.add(new BasicNameValuePair("a2", password));
+        postData.add(new BasicNameValuePair("nyckel", key));
+        return new LoginPackage(urlopen, postData, response, "https://www.nordnetdirekt.se/mux/inloggad/lib/login.html");
+    }
+
+    @Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+            LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (response.contains("fel vid inloggningen")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+			Matcher matcher;
+			matcher = reBalance.matcher(response);
+			if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Currency          Dep&aring;v&auml;rde - SEK
+                 * 2: Kontantsaldo      13 264,53
+                 * 3: Värdepapper       111 909,05
+                 *  
+                 */
+                accounts.add(new Account(
+                        "Kontosaldo",
+                        Helpers.parseBalance(matcher.group(2)),
+                        "1"));
+                accounts.add(new Account(
+                        "Värdepapper",
+                        Helpers.parseBalance(matcher.group(3)),
+                        "2"));
+				balance = balance.add(Helpers.parseBalance(matcher.group(2)));				
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}		
+        finally {
+            super.updateComplete();
+        }
+	}
+
+    @Override
+    public String getExtras() {
+        return this.key;
+    }
+
+    public void setData(String username, String password, BigDecimal balance,
+            boolean disabled, long dbid, String currency, String customName) {
+        super.setData(username, password, balance, disabled, dbid, currency, customName);
+        if (password.contains("|")) {
+            String[] passkey = password.split("\\|", 2);
+            this.password = passkey[0];
+            this.key = passkey[1];
+        }
+    }
+
+    @Override
+    public void setExtras(String extras) {
+        this.key = extras;
+    }
+
+    @Override
+    public void setPassword(String password) {
+        this.password = password;
+        if (password.contains("|")) {
+            String[] passkey = password.split("\\|", 2);
+            this.password = passkey[0];
+            this.key = passkey[1];
+        }
+    }
+    
+    
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index fb9212e..0d50420 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -71,4 +71,5 @@ public interface IBankTypes {
     public final static int IKEA = 47;
     public final static int SPARBANKEN_SYD = 48;
     public final static int SPARBANKEN_ORESUND = 49;
+    public final static int NORDNETDIREKT = 50;
 }
\ No newline at end of file

commit d586075b11e5eae5c8b876ea1741ba9cf17f4b8b
Author: liato <x@x00.us>
Date:   Thu Apr 21 16:26:50 2011 +0200

    Add support for Sparbanken Oresund.

diff --git res/drawable/logo_sparbanken_oresund.png res/drawable/logo_sparbanken_oresund.png
new file mode 100644
index 0000000..983273e
Binary files /dev/null and res/drawable/logo_sparbanken_oresund.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 690d071..929216a 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -65,6 +65,7 @@ import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skoda;
+import com.liato.bankdroid.banking.banks.SparbankenOresund;
 import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
@@ -181,6 +182,8 @@ public class BankFactory {
             return new IKEA(context);
         case IBankTypes.SPARBANKEN_SYD:
             return new SparbankenSyd(context);
+        case IBankTypes.SPARBANKEN_ORESUND:
+            return new SparbankenOresund(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -238,6 +241,7 @@ public class BankFactory {
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
         banks.add(new SparbankenSyd(context));
+        banks.add(new SparbankenOresund(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/SparbankenOresund.java src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
new file mode 100644
index 0000000..ec0af22
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/SparbankenOresund.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class SparbankenOresund extends MobilbankenBase {
+	private static final String TAG = "SparbankenOresund";
+	private static final String NAME = "Sparbanken Öresund";
+	private static final String NAME_SHORT = "sparbanken_oresund";
+	private static final String URL = "https://mobil-banken.se/0002/login.html";
+	private static final int BANKTYPE_ID = Bank.SPARBANKEN_ORESUND;
+
+    public SparbankenOresund(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.targetId = "0002";
+    }
+
+    public SparbankenOresund(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 66b68aa..fb9212e 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -70,4 +70,5 @@ public interface IBankTypes {
     public final static int SKODA = 46;
     public final static int IKEA = 47;
     public final static int SPARBANKEN_SYD = 48;
+    public final static int SPARBANKEN_ORESUND = 49;
 }
\ No newline at end of file

commit 3f137a1a1f914d1ba43580132ecf785d427c4734
Author: liato <x@x00.us>
Date:   Thu Apr 21 16:20:52 2011 +0200

    Add support for Sparbanken Syd.

diff --git logos.psd logos.psd
index 6ed6821..2f42bfa 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_sparbanken_syd.png res/drawable/logo_sparbanken_syd.png
new file mode 100644
index 0000000..d5e85ca
Binary files /dev/null and res/drawable/logo_sparbanken_syd.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 259c6b4..690d071 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -65,6 +65,7 @@ import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Skoda;
+import com.liato.bankdroid.banking.banks.SparbankenSyd;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -178,6 +179,8 @@ public class BankFactory {
             return new Skoda(context);
         case IBankTypes.IKEA:
             return new IKEA(context);
+        case IBankTypes.SPARBANKEN_SYD:
+            return new SparbankenSyd(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -234,6 +237,7 @@ public class BankFactory {
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
         banks.add(new IKEA(context));
+        banks.add(new SparbankenSyd(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/MobilbankenBase.java src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
new file mode 100644
index 0000000..74ff752
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/MobilbankenBase.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public abstract class MobilbankenBase extends Bank {
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+    
+
+    private Pattern reTimestamp = Pattern.compile("name=\"user(\\d{1,})\"");
+    private Pattern reMsisdn = Pattern.compile("name=\"msisdn\"\\s*value=\"([^\"]+)\" />");
+    private Pattern reAccounts = Pattern.compile("accountmovement\\.html\\?account_no=([^\"]+)\">([^<]+)</a></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+><span[^>]+>([^<]+)</span></td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>[^<]+<span[^>]+>([^<]+)</");
+    private Pattern reTransactions = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*</div>\\s*<table[^>]+>\\s*<tr>\\s*<td[^>]+>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>([^<]+)</span>\\s*</td>\\s*</tr>\\s*</table>\\s*<div[^>]+>\\s*(\\d{4}\\.\\d{2}\\.\\d{2})\\s*</div>\\s*");
+    private String response = null;
+	protected String targetId;
+	
+
+	public MobilbankenBase(Context context) {
+		super(context);
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+	}
+
+	public MobilbankenBase(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true, true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        String postUrl = String.format("https://mobil-banken.se/%s/login.html", targetId);
+        response = urlopen.open(postUrl);
+        Matcher matcher = reMsisdn.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" msisdn.");
+        }
+        String msisdn = matcher.group(1);
+        matcher = reTimestamp.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" timestamp.");
+        }
+        String timestamp = matcher.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("msisdn", msisdn));
+        postData.add(new BasicNameValuePair("user"+timestamp, username));
+        postData.add(new BasicNameValuePair("password"+timestamp, password));
+        return new LoginPackage(urlopen, postData, response, postUrl);
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		
+			if (response.contains("eller pinkod")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		urlopen = login();
+		Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: ID                ?
+             * 2: Name              Sparkonto
+             * 3: Account number    9570 012.345.678-9 SEK
+             * 4: ?                 xxxxxxxxxxx
+             * 5: Amount            ?
+             *   
+             */
+			accounts.add(new Account(
+			        Html.fromHtml(matcher.group(2)).toString().trim(),
+			        Helpers.parseBalance(matcher.group(5)),
+			        matcher.group(1).trim()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(5)));
+		}
+		
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	}
+	
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        Matcher matcher;
+        try {
+            response = urlopen.open(String.format("https://mobil-banken.se/%s/accountmovement.html?account_no=%s", targetId, account.getId()));
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Transaction           Kortköp QPARKSTOCKHOLM,  STOCKHOLM
+                 * 2: Amount                -40,00
+                 * 3: Date                  2010.12.23 
+                 * 
+                 */
+                transactions.add(new Transaction(
+                        matcher.group(2).trim().replace(".", "-"),
+                        Html.fromHtml(matcher.group(1)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(3))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }   	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/SparbankenSyd.java src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
new file mode 100644
index 0000000..93b361a
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/SparbankenSyd.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class SparbankenSyd extends MobilbankenBase {
+	private static final String TAG = "SparbankenSyd";
+	private static final String NAME = "Sparbanken Syd";
+	private static final String NAME_SHORT = "sparbanken_syd";
+	private static final String URL = "https://mobil-banken.se/0004/login.html";
+	private static final int BANKTYPE_ID = Bank.SPARBANKEN_SYD;
+
+    public SparbankenSyd(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.targetId = "0004";
+    }
+
+    public SparbankenSyd(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index a3b703f..66b68aa 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -69,4 +69,5 @@ public interface IBankTypes {
     public final static int SEAT = 45;
     public final static int SKODA = 46;
     public final static int IKEA = 47;
+    public final static int SPARBANKEN_SYD = 48;
 }
\ No newline at end of file

commit 584377d57d3e7ccc20e534d56f69313036843598
Author: liato <x@x00.us>
Date:   Thu Apr 21 06:43:53 2011 +0200

    Add support for IKEA HANDLA kort.

diff --git res/drawable/logo_ikea.png res/drawable/logo_ikea.png
new file mode 100644
index 0000000..1a9ed00
Binary files /dev/null and res/drawable/logo_ikea.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 1323baa..259c6b4 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.banks.Handelsbanken;
 import com.liato.bankdroid.banking.banks.Hemkop;
 import com.liato.bankdroid.banking.banks.ICA;
 import com.liato.bankdroid.banking.banks.ICABanken;
+import com.liato.bankdroid.banking.banks.IKEA;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.Lansforsakringar;
@@ -175,6 +176,8 @@ public class BankFactory {
             return new Seat(context);
         case IBankTypes.SKODA:
             return new Skoda(context);
+        case IBankTypes.IKEA:
+            return new IKEA(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -230,6 +233,7 @@ public class BankFactory {
         banks.add(new Preem(context));
         banks.add(new Seat(context));
         banks.add(new Skoda(context));
+        banks.add(new IKEA(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/IKEA.java src/com/liato/bankdroid/banking/banks/IKEA.java
new file mode 100644
index 0000000..e85b632
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/IKEA.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class IKEA extends IkanoPartnerBase {
+	private static final String TAG = "IKEA";
+	private static final String NAME = "IKEA HANDLA kort";
+	private static final String NAME_SHORT = "ikea";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1420";
+	private static final int BANKTYPE_ID = Bank.SKODA;
+
+    public IKEA(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.structId = "1420";
+    }
+
+    public IKEA(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 5c61c29..a3b703f 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -68,4 +68,5 @@ public interface IBankTypes {
     public final static int PREEM = 44;
     public final static int SEAT = 45;
     public final static int SKODA = 46;
+    public final static int IKEA = 47;
 }
\ No newline at end of file

commit 0f3a9d8198057a1e50518c612ad4cbb0e72ebf12
Author: liato <x@x00.us>
Date:   Thu Apr 21 06:40:17 2011 +0200

    Fix license.

diff --git src/com/liato/bankdroid/banking/banks/Audi.java src/com/liato/bankdroid/banking/banks/Audi.java
index b0bf0e4..b1b2bea 100644
--- src/com/liato/bankdroid/banking/banks/Audi.java
+++ src/com/liato/bankdroid/banking/banks/Audi.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Preem.java src/com/liato/bankdroid/banking/banks/Preem.java
index 6df0414..cd16e0f 100644
--- src/com/liato/bankdroid/banking/banks/Preem.java
+++ src/com/liato/bankdroid/banking/banks/Preem.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Seat.java src/com/liato/bankdroid/banking/banks/Seat.java
index ea317a4..0ae1860 100644
--- src/com/liato/bankdroid/banking/banks/Seat.java
+++ src/com/liato/bankdroid/banking/banks/Seat.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Shell.java src/com/liato/bankdroid/banking/banks/Shell.java
index 238648b..7f5e74f 100644
--- src/com/liato/bankdroid/banking/banks/Shell.java
+++ src/com/liato/bankdroid/banking/banks/Shell.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Skoda.java src/com/liato/bankdroid/banking/banks/Skoda.java
index ec735f9..027dc7a 100644
--- src/com/liato/bankdroid/banking/banks/Skoda.java
+++ src/com/liato/bankdroid/banking/banks/Skoda.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Volkswagen.java src/com/liato/bankdroid/banking/banks/Volkswagen.java
index 2c5d64e..f2684e4 100644
--- src/com/liato/bankdroid/banking/banks/Volkswagen.java
+++ src/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

commit 73ecd98bb39ed0e0afc32c114d5c0e9732e41745
Author: liato <x@x00.us>
Date:   Thu Apr 21 06:38:00 2011 +0200

    Add support for Skodakortet.

diff --git res/drawable/logo_skoda.png res/drawable/logo_skoda.png
new file mode 100644
index 0000000..44417e2
Binary files /dev/null and res/drawable/logo_skoda.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 923ac3b..1323baa 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -63,6 +63,7 @@ import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
+import com.liato.bankdroid.banking.banks.Skoda;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -172,6 +173,8 @@ public class BankFactory {
             return new Preem(context);
         case IBankTypes.SEAT:
             return new Seat(context);
+        case IBankTypes.SKODA:
+            return new Skoda(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -226,6 +229,7 @@ public class BankFactory {
         banks.add(new Audi(context));
         banks.add(new Preem(context));
         banks.add(new Seat(context));
+        banks.add(new Skoda(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Skoda.java src/com/liato/bankdroid/banking/banks/Skoda.java
new file mode 100644
index 0000000..ec735f9
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Skoda.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Skoda extends IkanoPartnerBase {
+	private static final String TAG = "Skoda";
+	private static final String NAME = "Skodakortet";
+	private static final String NAME_SHORT = "skoda";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1541";
+	private static final int BANKTYPE_ID = Bank.SKODA;
+
+    public Skoda(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.structId = "1541";
+    }
+
+    public Skoda(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 03955ef..5c61c29 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -67,4 +67,5 @@ public interface IBankTypes {
     public final static int AUDI = 43;
     public final static int PREEM = 44;
     public final static int SEAT = 45;
+    public final static int SKODA = 46;
 }
\ No newline at end of file

commit 337168506068b1fb0088408c06305eb9e4e79f9d
Author: liato <x@x00.us>
Date:   Thu Apr 21 06:34:23 2011 +0200

    Add support for Seatkortet.

diff --git logos.psd logos.psd
index c91bbb4..6ed6821 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_seat.png res/drawable/logo_seat.png
new file mode 100644
index 0000000..5c33abc
Binary files /dev/null and res/drawable/logo_seat.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 136787a..923ac3b 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -60,6 +60,7 @@ import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
 import com.liato.bankdroid.banking.banks.SJPrio;
 import com.liato.bankdroid.banking.banks.Saab;
+import com.liato.bankdroid.banking.banks.Seat;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Statoil;
@@ -169,6 +170,8 @@ public class BankFactory {
             return new Audi(context);
         case IBankTypes.PREEM:
             return new Preem(context);
+        case IBankTypes.SEAT:
+            return new Seat(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -222,6 +225,7 @@ public class BankFactory {
         banks.add(new Volkswagen(context));
         banks.add(new Audi(context));
         banks.add(new Preem(context));
+        banks.add(new Seat(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Seat.java src/com/liato/bankdroid/banking/banks/Seat.java
new file mode 100644
index 0000000..ea317a4
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Seat.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Seat extends IkanoPartnerBase {
+	private static final String TAG = "Seat";
+	private static final String NAME = "Seatkortet";
+	private static final String NAME_SHORT = "seat";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1301";
+	private static final int BANKTYPE_ID = Bank.SEAT;
+
+    public Seat(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.structId = "1301";
+    }
+
+    public Seat(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 39eacf4..03955ef 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -66,4 +66,5 @@ public interface IBankTypes {
     public final static int VOLKSWAGEN = 42;
     public final static int AUDI = 43;
     public final static int PREEM = 44;
+    public final static int SEAT = 45;
 }
\ No newline at end of file

commit cd2bdccc135db2f1de959721b7f9f71f5b0f1197
Author: liato <x@x00.us>
Date:   Thu Apr 21 05:16:26 2011 +0200

    Add support for Preem Privatkort.

diff --git logos.psd logos.psd
index e3e2c5e..c91bbb4 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_preem.png res/drawable/logo_preem.png
new file mode 100644
index 0000000..9443e37
Binary files /dev/null and res/drawable/logo_preem.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index e627647..136787a 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -53,6 +53,7 @@ import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.PlusGirot;
+import com.liato.bankdroid.banking.banks.Preem;
 import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
@@ -166,6 +167,8 @@ public class BankFactory {
             return new Volkswagen(context);
         case IBankTypes.AUDI:
             return new Audi(context);
+        case IBankTypes.PREEM:
+            return new Preem(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -218,6 +221,7 @@ public class BankFactory {
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
         banks.add(new Audi(context));
+        banks.add(new Preem(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 5f099db..91de98a 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -49,9 +49,12 @@ public abstract class IkanoPartnerBase extends Bank {
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reCtl = Pattern.compile("(ctl\\d{1,})_CustomValidationSummary", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactionsUrl = Pattern.compile("(page___\\d{1,}\\.aspx)\"><span[^>]+>Transaktioner</span>", Pattern.CASE_INSENSITIVE);
     private Pattern reAccounts = Pattern.compile("captionLabel\">([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
     private Pattern reTransactions = Pattern.compile("<td\\s*class=\"TransactionDateRow\">([^>]+)</td><td[^>]+>(.+?)</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>");
+    private String response = null;
 	protected String structId;
+	
 
 	public IkanoPartnerBase(Context context) {
 		super(context);
@@ -69,7 +72,7 @@ public abstract class IkanoPartnerBase extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
-        String response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
+        response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
         Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
             throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
@@ -98,7 +101,7 @@ public abstract class IkanoPartnerBase extends Bank {
 	public Urllib login() throws LoginException, BankException {
 		try {
 		    LoginPackage lp = preLogin();
-			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 		
 			if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
 			        || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")) {
@@ -121,10 +124,14 @@ public abstract class IkanoPartnerBase extends Bank {
 		}
 		
 		urlopen = login();
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://partner.ikanobank.se/web/engines/page___2040.aspx");
+	        matcher = reTransactionsUrl.matcher(response);
+	        if (!matcher.find()) {
+	            throw new BankException(res.getText(R.string.unable_to_find).toString()+" transactions url.");
+	        }
+		    
+			response = urlopen.open("https://partner.ikanobank.se/web/engines/"+matcher.group(1));
 			matcher = reAccounts.matcher(response);
 			int accId = 0;
 			while (matcher.find()) {
diff --git src/com/liato/bankdroid/banking/banks/Preem.java src/com/liato/bankdroid/banking/banks/Preem.java
new file mode 100644
index 0000000..6df0414
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Preem.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Preem extends IkanoPartnerBase {
+	private static final String TAG = "Preem";
+	private static final String NAME = "Preem Privatkort";
+	private static final String NAME_SHORT = "preem";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1437";
+	private static final int BANKTYPE_ID = Bank.PREEM;
+
+    public Preem(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.structId = "1437";
+    }
+
+    public Preem(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index e7e96b7..39eacf4 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -65,4 +65,5 @@ public interface IBankTypes {
     public final static int SHELL = 41;
     public final static int VOLKSWAGEN = 42;
     public final static int AUDI = 43;
+    public final static int PREEM = 44;
 }
\ No newline at end of file

commit 25fa034336e26f1803d803944be5483ecf771a78
Author: liato <x@x00.us>
Date:   Thu Apr 21 04:47:11 2011 +0200

    Add support for AudiKortet.

diff --git logos.psd logos.psd
index 0fdbeb7..e3e2c5e 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_audi.png res/drawable/logo_audi.png
new file mode 100644
index 0000000..ae81cae
Binary files /dev/null and res/drawable/logo_audi.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 8bedf7e..e627647 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -26,6 +26,7 @@ import android.database.Cursor;
 import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.banking.banks.AmericanExpress;
+import com.liato.bankdroid.banking.banks.Audi;
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.CSN;
@@ -163,6 +164,8 @@ public class BankFactory {
             return new Shell(context);
         case IBankTypes.VOLKSWAGEN:
             return new Volkswagen(context);
+        case IBankTypes.AUDI:
+            return new Audi(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -214,6 +217,7 @@ public class BankFactory {
         banks.add(new PlusGirot(context));
         banks.add(new Shell(context));
         banks.add(new Volkswagen(context));
+        banks.add(new Audi(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Audi.java src/com/liato/bankdroid/banking/banks/Audi.java
new file mode 100644
index 0000000..b0bf0e4
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Audi.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Audi extends IkanoPartnerBase {
+	private static final String TAG = "Audi";
+	private static final String NAME = "AudiKortet";
+	private static final String NAME_SHORT = "audi";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=2177";
+	private static final int BANKTYPE_ID = Bank.AUDI;
+
+    public Audi(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.structId = "2177";
+    }
+
+    public Audi(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 07f7934..e7e96b7 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -64,4 +64,5 @@ public interface IBankTypes {
     public final static int PLUSGIROT = 40;
     public final static int SHELL = 41;
     public final static int VOLKSWAGEN = 42;
+    public final static int AUDI = 43;
 }
\ No newline at end of file

commit bcd7066e6216ca90a95b0afafb5d5a1b310be0fd
Author: liato <x@x00.us>
Date:   Thu Apr 21 04:34:15 2011 +0200

    Add support for Volkswagenkortet. Closes #60.

diff --git res/drawable/logo_volkswagen.png res/drawable/logo_volkswagen.png
new file mode 100644
index 0000000..77f603e
Binary files /dev/null and res/drawable/logo_volkswagen.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index ad2df16..8bedf7e 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -65,6 +65,7 @@ import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.Villabanken;
+import com.liato.bankdroid.banking.banks.Volkswagen;
 import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.exceptions.BankException;
@@ -160,6 +161,8 @@ public class BankFactory {
             return new PlusGirot(context);
         case IBankTypes.SHELL:
             return new Shell(context);
+        case IBankTypes.VOLKSWAGEN:
+            return new Volkswagen(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -210,6 +213,7 @@ public class BankFactory {
         banks.add(new Quintessentially(context));
         banks.add(new PlusGirot(context));
         banks.add(new Shell(context));
+        banks.add(new Volkswagen(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
index 18f2a4e..5f099db 100644
--- src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -29,7 +29,6 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
diff --git src/com/liato/bankdroid/banking/banks/Shell.java src/com/liato/bankdroid/banking/banks/Shell.java
index b5ef0be..238648b 100644
--- src/com/liato/bankdroid/banking/banks/Shell.java
+++ src/com/liato/bankdroid/banking/banks/Shell.java
@@ -25,7 +25,7 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 public class Shell extends IkanoPartnerBase {
 	private static final String TAG = "Shell";
-	private static final String NAME = "Shell Mastercard";
+	private static final String NAME = "Shell MasterCard";
 	private static final String NAME_SHORT = "shell";
 	private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
 	private static final int BANKTYPE_ID = Bank.SHELL;
diff --git src/com/liato/bankdroid/banking/banks/Shell.java src/com/liato/bankdroid/banking/banks/Volkswagen.java
similarity index 71%
copy from src/com/liato/bankdroid/banking/banks/Shell.java
copy to src/com/liato/bankdroid/banking/banks/Volkswagen.java
index b5ef0be..2c5d64e 100644
--- src/com/liato/bankdroid/banking/banks/Shell.java
+++ src/com/liato/bankdroid/banking/banks/Volkswagen.java
@@ -23,24 +23,24 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Shell extends IkanoPartnerBase {
-	private static final String TAG = "Shell";
-	private static final String NAME = "Shell Mastercard";
-	private static final String NAME_SHORT = "shell";
-	private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
-	private static final int BANKTYPE_ID = Bank.SHELL;
-
-    public Shell(Context context) {
+public class Volkswagen extends IkanoPartnerBase {
+	private static final String TAG = "Volkswagen";
+	private static final String NAME = "Volkswagenkortet";
+	private static final String NAME_SHORT = "volkswagen";
+	private static final String URL = "https://partner.ikanobank.se/web/engines/page.aspx?structid=1319";
+	private static final int BANKTYPE_ID = Bank.VOLKSWAGEN;
+
+    public Volkswagen(Context context) {
         super(context);
         super.TAG = TAG;
         super.NAME = NAME;
         super.NAME_SHORT = NAME_SHORT;
         super.BANKTYPE_ID = BANKTYPE_ID;
         super.URL = URL;
-        this.structId = "2035";
+        this.structId = "1319";
     }
 
-    public Shell(String username, String password, Context context) throws BankException, LoginException {
+    public Volkswagen(String username, String password, Context context) throws BankException, LoginException {
         this(context);
         this.update(username, password);
     }
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 1a18920..07f7934 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -63,4 +63,5 @@ public interface IBankTypes {
     public final static int QUINTESSENTIALLY = 39;
     public final static int PLUSGIROT = 40;
     public final static int SHELL = 41;
+    public final static int VOLKSWAGEN = 42;
 }
\ No newline at end of file

commit 6aec0f718cd2fa14b91a3a966c1cdb4e832c3b8f
Author: liato <x@x00.us>
Date:   Thu Apr 21 04:27:38 2011 +0200

    Add support for Shell Mastercard. Closes #63.

diff --git logos.psd logos.psd
index 95b715c..0fdbeb7 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_shell.png res/drawable/logo_shell.png
new file mode 100644
index 0000000..688b52a
Binary files /dev/null and res/drawable/logo_shell.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 77cca31..ad2df16 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -59,6 +59,7 @@ import com.liato.bankdroid.banking.banks.SEB;
 import com.liato.bankdroid.banking.banks.SJPrio;
 import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.SevenDay;
+import com.liato.bankdroid.banking.banks.Shell;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -157,6 +158,8 @@ public class BankFactory {
             return new Quintessentially(context);
         case IBankTypes.PLUSGIROT:
             return new PlusGirot(context);
+        case IBankTypes.SHELL:
+            return new Shell(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -206,6 +209,7 @@ public class BankFactory {
         banks.add(new Djurgarden(context));
         banks.add(new Quintessentially(context));
         banks.add(new PlusGirot(context));
+        banks.add(new Shell(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
new file mode 100644
index 0000000..18f2a4e
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/IkanoPartnerBase.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public abstract class IkanoPartnerBase extends Bank {
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+    
+
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reCtl = Pattern.compile("(ctl\\d{1,})_CustomValidationSummary", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("captionLabel\">([^<]+)</span>\\s*</span>\\s*<span\\s*id=\"[^\"]+ReadOnlyValueSpan\">([^<]+)</span>\\s*<span\\s*id=\"[^\"]+currencyTextLiteralSpan\">([^<]+)</span>");
+    private Pattern reTransactions = Pattern.compile("<td\\s*class=\"TransactionDateRow\">([^>]+)</td><td[^>]+>(.+?)</td><td[^>]+>([^<]+)</td><td[^>]+>([^<]+)</td>");
+	protected String structId;
+
+	public IkanoPartnerBase(Context context) {
+		super(context);
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+	}
+
+	public IkanoPartnerBase(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        String response = urlopen.open("https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String viewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String eventValidation = matcher.group(1);
+        matcher = reCtl.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ctl.");
+        }
+        String ctl = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair(ctl+"$LoginWebUserControl$SSNControl$SSNSimpleValueUsercontrol$editValueTextbox", username));
+        postData.add(new BasicNameValuePair(ctl+"$LoginWebUserControl$passwordSimpleValueControl$passwordSimpleValueControl$editValueTextbox", password));
+        postData.add(new BasicNameValuePair(ctl+"$LoginButton", "Logga in"));
+        return new LoginPackage(urlopen, postData, response, "https://partner.ikanobank.se/web/engines/page.aspx?structid="+structId);
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+		
+			if (response.contains("eller personnumme") || response.contains("elaktigt personnummer")
+			        || response.contains("ontrollera personnummer") || response.contains("elaktig inloggningskod")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://partner.ikanobank.se/web/engines/page___2040.aspx");
+			matcher = reAccounts.matcher(response);
+			int accId = 0;
+			while (matcher.find()) {
+	            /*
+	             * Capture groups:
+	             * GROUP                EXAMPLE DATA
+	             * 1: Name              Kvar att handla för
+	             * 2: Amount            17&nbsp;229,85
+	             * 3: Currency          &nbsp;kr 
+	             *   
+	             */
+				accounts.add(new Account(
+				        Html.fromHtml(matcher.group(1)).toString().trim(),
+				        Helpers.parseBalance(matcher.group(2)),
+				        Integer.toString(accId)));
+				accId++;
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+			 // Use the amount from "Kvar att handla för" which should be the last account in the list.
+		    this.balance = accounts.get(accounts.size()-1).getBalance();
+		    
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            matcher = reTransactions.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Date              2011-02-27
+                 * 2: Specification     Best Buy<br>
+                 * 3: Amount            143,07 kr
+                 * 4: Currency          SEK
+                 *   
+                 */                
+                Transaction transaction = new Transaction(
+                        matcher.group(1).trim(),
+                        Html.fromHtml(matcher.group(2).replaceAll("<br>", " ")).toString().trim(),
+                        Helpers.parseBalance(matcher.group(3)));
+                transactions.add(transaction);
+            }
+            accounts.get(0).setTransactions(transactions);
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		    super.updateComplete();
+		}
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/Shell.java src/com/liato/bankdroid/banking/banks/Shell.java
new file mode 100644
index 0000000..b5ef0be
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Shell.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Shell extends IkanoPartnerBase {
+	private static final String TAG = "Shell";
+	private static final String NAME = "Shell Mastercard";
+	private static final String NAME_SHORT = "shell";
+	private static final String URL = "https://partner.ikanobank.se/web/ShellCustomerLogin";
+	private static final int BANKTYPE_ID = Bank.SHELL;
+
+    public Shell(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        this.structId = "2035";
+    }
+
+    public Shell(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index bcd858d..1a18920 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -62,4 +62,5 @@ public interface IBankTypes {
     public final static int DJURGARDEN = 38;
     public final static int QUINTESSENTIALLY = 39;
     public final static int PLUSGIROT = 40;
+    public final static int SHELL = 41;
 }
\ No newline at end of file

commit 3f62f8a775293cf77329793629417861eec63a1f
Author: liato <x@x00.us>
Date:   Wed Apr 20 04:28:22 2011 +0200

    Fix for PlusGirot transactions.

diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java src/com/liato/bankdroid/banking/banks/PlusGirot.java
index bda531f..fea6cf2 100644
--- src/com/liato/bankdroid/banking/banks/PlusGirot.java
+++ src/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -50,7 +50,7 @@ public class PlusGirot extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
     private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+><font[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("href=\"details/Default\\.aspx\\?\\d{1,}\">\\s*<span\\s*title=\"(\\d{4}-\\d{2}-\\d{2})[^\"]+\">.*?Grid1_0_3_\\d{1,}_Hy[^>]+>([^<]+)<.*?Grid1_0_5_\\d{1,}_Hy[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</f", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	
 	public PlusGirot(Context context) {

commit cd07cdc49bf5a536c971b0710e828a6d47b22f03
Author: liato <x@x00.us>
Date:   Wed Apr 20 04:01:50 2011 +0200

    Add support for PlusGirot.

diff --git logos.psd logos.psd
index 787f9a0..95b715c 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_plusgirot.png res/drawable/logo_plusgirot.png
new file mode 100644
index 0000000..f73be33
Binary files /dev/null and res/drawable/logo_plusgirot.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index ad6c0f7..77cca31 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -51,6 +51,7 @@ import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.PlusGirot;
 import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
@@ -154,6 +155,8 @@ public class BankFactory {
             return new Djurgarden(context);
         case IBankTypes.QUINTESSENTIALLY:
             return new Quintessentially(context);
+        case IBankTypes.PLUSGIROT:
+            return new PlusGirot(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -202,6 +205,7 @@ public class BankFactory {
         banks.add(new Opel(context));
         banks.add(new Djurgarden(context));
         banks.add(new Quintessentially(context));
+        banks.add(new PlusGirot(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/PlusGirot.java src/com/liato/bankdroid/banking/banks/PlusGirot.java
new file mode 100644
index 0000000..bda531f
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/PlusGirot.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class PlusGirot extends Bank {
+	private static final String TAG = "PlusGirot";
+	private static final String NAME = "PlusGirot";
+	private static final String NAME_SHORT = "plusgirot";
+	private static final String URL = "https://kontoutdrag.plusgirot.se/";
+	private static final int BANKTYPE_ID = IBankTypes.PLUSGIROT;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	
+    private Pattern reAccounts = Pattern.compile("<tr>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+><font[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>\\s*</td>\\s*<td[^>]+>\\s*<font[^>]+>([^<]+)</font>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("href=\"details/Default\\.aspx\\?\\d{1,}\">\\s*<span\\s*title=\"(\\d{4}-\\d{2}-\\d{2})[^\"]+\">.*?Grid1_0_3_\\d{1,}_Hy[^>]+>([^<]+)<.*?Grid1_0_5_\\d{1,}_Hy[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private String response = null;
+	
+	public PlusGirot(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+	}
+
+	public PlusGirot(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        // Request first page to get cookies
+        response = urlopen.open("https://kontoutdrag.plusgirot.se/ku/html/epostllg.htm");
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("KONTO", username));
+        postData.add(new BasicNameValuePair("PIN_KOD", password));
+        return new LoginPackage(urlopen, postData, response, "https://kontoutdrag.plusgirot.se/ku/bgya006/init");
+    }
+
+    @Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+            LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (response.contains("elaktigt kontonummer"))  {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+			Matcher matcher;
+			matcher = reAccounts.matcher(response);
+			if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Account holder    Efternamn,Fornamn
+                 * 2: PG account        456 12 34-5
+                 * 3: Amount            123,45
+                 * 4: Credit            24,68
+                 *  
+                 */
+			    Account account = new Account(matcher.group(2).trim() + " (" + Html.fromHtml(matcher.group(1)).toString().trim() + ")",
+			                                    Helpers.parseBalance(matcher.group(3)),
+			                                    matcher.group(2).trim().replaceAll("[^0-9]*", ""));
+				accounts.add(account);
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+	
+	
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Date              2011-04-04
+                 * 2: Specification     UTTAG
+                 * 3: Payment code      Inr.
+                 * 4: Amount            -100,00
+                 *   
+                 */     
+				transactions.add(
+				        new Transaction(matcher.group(1).trim(),
+				        Html.fromHtml(matcher.group(2)).toString().trim() + " " + Html.fromHtml(matcher.group(3)).toString().trim(),
+				        Helpers.parseBalance(matcher.group(4))));
+			}
+			accounts.get(0).setTransactions(transactions);
+		}		
+        finally {
+            super.updateComplete();
+        }
+	}
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 09bbffa..bcd858d 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -61,4 +61,5 @@ public interface IBankTypes {
     public final static int OPEL = 37;
     public final static int DJURGARDEN = 38;
     public final static int QUINTESSENTIALLY = 39;
+    public final static int PLUSGIROT = 40;
 }
\ No newline at end of file

commit 7a045f086d369eb20c28044dbe4c78d49b933b7d
Author: liato <x@x00.us>
Date:   Sun Apr 17 19:47:49 2011 +0200

    Fix for McDonald's transactions.'

diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java src/com/liato/bankdroid/banking/banks/McDonalds.java
index 990aa95..f3619eb 100644
--- src/com/liato/bankdroid/banking/banks/McDonalds.java
+++ src/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -52,7 +52,7 @@ public class McDonalds extends Bank {
 	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;	
 
     private Pattern reBalance = Pattern.compile("saldo:\\s*([0-9,. -]+)\\s*kronor");
-    private Pattern reTransactions = Pattern.compile(    "<tr><td>(\\d{2}-\\d{2}-\\d{2})\\s*\\d{2}:\\d{2}</td><td>([^<]+)</tr><td>[^<]+</tr><td>([^<]+)</td></tr>");
+    private Pattern reTransactions = Pattern.compile("<tr><td>(\\d{2}-\\d{2}-\\d{2})\\s*\\d{2}:\\d{2}</td><td>([^<]+)</td><td>[^<]+</td><td>([^<]+)</td></tr>");
 	private String response = "";
 
 	public McDonalds(Context context) {

commit 67b3c4c7fe613b92bad6ccaef8524cc180cfed3d
Author: liato <x@x00.us>
Date:   Sun Apr 17 19:35:38 2011 +0200

    Fix license header in bank classes.

diff --git src/com/liato/bankdroid/banking/banks/Chevrolet.java src/com/liato/bankdroid/banking/banks/Chevrolet.java
index 96e5bbb..05515ed 100644
--- src/com/liato/bankdroid/banking/banks/Chevrolet.java
+++ src/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Djurgarden.java src/com/liato/bankdroid/banking/banks/Djurgarden.java
index 751d253..fda2846 100644
--- src/com/liato/bankdroid/banking/banks/Djurgarden.java
+++ src/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Opel.java src/com/liato/bankdroid/banking/banks/Opel.java
index fd08792..6b9be4c 100644
--- src/com/liato/bankdroid/banking/banks/Opel.java
+++ src/com/liato/bankdroid/banking/banks/Opel.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Quintessentially.java src/com/liato/bankdroid/banking/banks/Quintessentially.java
index 4757fbe..5d849c2 100644
--- src/com/liato/bankdroid/banking/banks/Quintessentially.java
+++ src/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/SJPrio.java src/com/liato/bankdroid/banking/banks/SJPrio.java
index 44c737d..10588a7 100644
--- src/com/liato/bankdroid/banking/banks/SJPrio.java
+++ src/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Saab.java src/com/liato/bankdroid/banking/banks/Saab.java
index 83d9971..c424f87 100644
--- src/com/liato/bankdroid/banking/banks/Saab.java
+++ src/com/liato/bankdroid/banking/banks/Saab.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git src/com/liato/bankdroid/banking/banks/Wallet.java src/com/liato/bankdroid/banking/banks/Wallet.java
index efe1cdb..37010f3 100644
--- src/com/liato/bankdroid/banking/banks/Wallet.java
+++ src/com/liato/bankdroid/banking/banks/Wallet.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- * Contributors: mhagander
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.

commit dec577b8558e811f830488979960ea301d13669b
Author: liato <x@x00.us>
Date:   Sun Apr 17 18:55:42 2011 +0200

    Add support for Quintessentially Credit Card.

diff --git res/drawable/logo_quintessentially.png res/drawable/logo_quintessentially.png
new file mode 100644
index 0000000..ba38bef
Binary files /dev/null and res/drawable/logo_quintessentially.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 42ae3fc..ad6c0f7 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -51,6 +51,7 @@ import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.Quintessentially;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
@@ -151,6 +152,8 @@ public class BankFactory {
             return new Opel(context);
         case IBankTypes.DJURGARDEN:
             return new Djurgarden(context);
+        case IBankTypes.QUINTESSENTIALLY:
+            return new Quintessentially(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -198,6 +201,7 @@ public class BankFactory {
         banks.add(new SJPrio(context));
         banks.add(new Opel(context));
         banks.add(new Djurgarden(context));
+        banks.add(new Quintessentially(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Quintessentially.java src/com/liato/bankdroid/banking/banks/Quintessentially.java
new file mode 100644
index 0000000..4757fbe
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Quintessentially.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Quintessentially extends SEBKortBase {
+	private static final String TAG = "Quintessentially";
+	private static final String NAME = "Quintessentially Credit Card";
+	private static final String NAME_SHORT = "quintessentially";
+	private static final int BANKTYPE_ID = Bank.QUINTESSENTIALLY;
+
+	public Quintessentially(Context context) {
+		super(context, "quse", "0119");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public Quintessentially(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "quse", "0119");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index cd6f38b..09bbffa 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -60,4 +60,5 @@ public interface IBankTypes {
     public final static int SJPRIO = 36;
     public final static int OPEL = 37;
     public final static int DJURGARDEN = 38;
+    public final static int QUINTESSENTIALLY = 39;
 }
\ No newline at end of file

commit 8c75f3144e7afe4409313f59098358f853c46d2c
Author: liato <x@x00.us>
Date:   Sun Apr 17 18:50:34 2011 +0200

    Add support for Djurgardskortet.

diff --git res/drawable/logo_djurgarden.png res/drawable/logo_djurgarden.png
new file mode 100644
index 0000000..7285764
Binary files /dev/null and res/drawable/logo_djurgarden.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 4c48260..42ae3fc 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -32,6 +32,7 @@ import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.Coop;
 import com.liato.bankdroid.banking.banks.DinersClub;
+import com.liato.bankdroid.banking.banks.Djurgarden;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
 import com.liato.bankdroid.banking.banks.Eurocard;
 import com.liato.bankdroid.banking.banks.FirstCard;
@@ -148,6 +149,8 @@ public class BankFactory {
             return new SJPrio(context);
         case IBankTypes.OPEL:
             return new Opel(context);
+        case IBankTypes.DJURGARDEN:
+            return new Djurgarden(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -194,6 +197,7 @@ public class BankFactory {
         banks.add(new Chevrolet(context));
         banks.add(new SJPrio(context));
         banks.add(new Opel(context));
+        banks.add(new Djurgarden(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Djurgarden.java src/com/liato/bankdroid/banking/banks/Djurgarden.java
new file mode 100644
index 0000000..751d253
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Djurgarden.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Djurgarden extends SEBKortBase {
+	private static final String TAG = "Djurgarden";
+	private static final String NAME = "Djurgårdskortet MasterCard";
+	private static final String NAME_SHORT = "djurgarden";
+	private static final int BANKTYPE_ID = Bank.DJURGARDEN;
+
+	public Djurgarden(Context context) {
+		super(context, "djse", "0116");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public Djurgarden(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "djse", "0116");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index a957da2..cd6f38b 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -59,4 +59,5 @@ public interface IBankTypes {
     public final static int CHEVROLET = 35;
     public final static int SJPRIO = 36;
     public final static int OPEL = 37;
+    public final static int DJURGARDEN = 38;
 }
\ No newline at end of file

commit 89387f9e5be7c75b152bd500dc18ad209002eec3
Author: liato <x@x00.us>
Date:   Sun Apr 17 18:43:14 2011 +0200

    Add support for OpelKortet.

diff --git res/drawable/logo_opel.png res/drawable/logo_opel.png
new file mode 100644
index 0000000..cb7626a
Binary files /dev/null and res/drawable/logo_opel.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 6c9c1cb..4c48260 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -46,6 +46,7 @@ import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.OKQ8;
+import com.liato.bankdroid.banking.banks.Opel;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
@@ -145,6 +146,8 @@ public class BankFactory {
             return new Chevrolet(context);
         case IBankTypes.SJPRIO:
             return new SJPrio(context);
+        case IBankTypes.OPEL:
+            return new Opel(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -190,6 +193,7 @@ public class BankFactory {
         banks.add(new Wallet(context));
         banks.add(new Chevrolet(context));
         banks.add(new SJPrio(context));
+        banks.add(new Opel(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Opel.java src/com/liato/bankdroid/banking/banks/Opel.java
new file mode 100644
index 0000000..fd08792
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Opel.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Opel extends SEBKortBase {
+	private static final String TAG = "Opel";
+	private static final String NAME = "OpelKortet";
+	private static final String NAME_SHORT = "opel";
+	private static final int BANKTYPE_ID = Bank.OPEL;
+
+	public Opel(Context context) {
+		super(context, "opse", "0107");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public Opel(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "opse", "0107");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 2badd15..a957da2 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -58,4 +58,5 @@ public interface IBankTypes {
     public final static int WALLET = 34;
     public final static int CHEVROLET = 35;
     public final static int SJPRIO = 36;
+    public final static int OPEL = 37;
 }
\ No newline at end of file

commit e5d79bc53814aaac102a3c4d5b6baf06062d67db
Author: liato <x@x00.us>
Date:   Sun Apr 17 18:39:32 2011 +0200

    Add support for SJ Prio MasterCard.

diff --git res/drawable/logo_sj_prio.png res/drawable/logo_sj_prio.png
new file mode 100644
index 0000000..1595331
Binary files /dev/null and res/drawable/logo_sj_prio.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 3fa7d08..6c9c1cb 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -52,6 +52,7 @@ import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
+import com.liato.bankdroid.banking.banks.SJPrio;
 import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Statoil;
@@ -142,6 +143,8 @@ public class BankFactory {
             return new Wallet(context);
         case IBankTypes.CHEVROLET:
             return new Chevrolet(context);
+        case IBankTypes.SJPRIO:
+            return new SJPrio(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -186,6 +189,7 @@ public class BankFactory {
         banks.add(new Saab(context));
         banks.add(new Wallet(context));
         banks.add(new Chevrolet(context));
+        banks.add(new SJPrio(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/SJPrio.java src/com/liato/bankdroid/banking/banks/SJPrio.java
new file mode 100644
index 0000000..44c737d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/SJPrio.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class SJPrio extends SEBKortBase {
+	private static final String TAG = "SJPrio";
+	private static final String NAME = "SJ Prio MasterCard";
+	private static final String NAME_SHORT = "sj_prio";
+	private static final int BANKTYPE_ID = Bank.SJPRIO;
+
+	public SJPrio(Context context) {
+		super(context, "sjse", "0104");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public SJPrio(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "sjse", "0104");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index fb16c71..2badd15 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -57,4 +57,5 @@ public interface IBankTypes {
     public final static int SAAB = 33;
     public final static int WALLET = 34;
     public final static int CHEVROLET = 35;
+    public final static int SJPRIO = 36;
 }
\ No newline at end of file

commit 91be2a6093182b8ded7b7591a7c51095be96bebe
Author: liato <x@x00.us>
Date:   Sun Apr 17 18:35:58 2011 +0200

    Add support for Chevrolet Big Plus Card.

diff --git res/drawable/logo_chevrolet.png res/drawable/logo_chevrolet.png
new file mode 100644
index 0000000..929ff78
Binary files /dev/null and res/drawable/logo_chevrolet.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 8a6be54..3fa7d08 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -29,6 +29,7 @@ import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.CSN;
+import com.liato.bankdroid.banking.banks.Chevrolet;
 import com.liato.bankdroid.banking.banks.Coop;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
@@ -139,6 +140,8 @@ public class BankFactory {
             return new Saab(context);
         case IBankTypes.WALLET:
             return new Wallet(context);
+        case IBankTypes.CHEVROLET:
+            return new Chevrolet(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -182,6 +185,7 @@ public class BankFactory {
         banks.add(new McDonalds(context));
         banks.add(new Saab(context));
         banks.add(new Wallet(context));
+        banks.add(new Chevrolet(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Chevrolet.java src/com/liato/bankdroid/banking/banks/Chevrolet.java
new file mode 100644
index 0000000..96e5bbb
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Chevrolet.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Chevrolet extends SEBKortBase {
+	private static final String TAG = "Chevrolet";
+	private static final String NAME = "Chevrolet Big Plus Card";
+	private static final String NAME_SHORT = "chevrolet";
+	private static final int BANKTYPE_ID = Bank.CHEVROLET;
+
+	public Chevrolet(Context context) {
+		super(context, "chse", "0086");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public Chevrolet(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "wase", "0086");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 6dc47f4..fb16c71 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -56,4 +56,5 @@ public interface IBankTypes {
     public final static int MCDONALDS = 32;
     public final static int SAAB = 33;
     public final static int WALLET = 34;
+    public final static int CHEVROLET = 35;
 }
\ No newline at end of file

commit 7746ff69afdce41484d71288f599d2b6c77c9b9c
Author: liato <x@x00.us>
Date:   Sun Apr 17 18:30:26 2011 +0200

    Add support for wallet MasterCard.

diff --git logos.psd logos.psd
index aeaf275..787f9a0 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_wallet.png res/drawable/logo_wallet.png
new file mode 100644
index 0000000..3b80a87
Binary files /dev/null and res/drawable/logo_wallet.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 8a8f82a..8a6be54 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -59,6 +59,7 @@ import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.banks.Volvofinans;
+import com.liato.bankdroid.banking.banks.Wallet;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
@@ -136,6 +137,8 @@ public class BankFactory {
             return new McDonalds(context);
         case IBankTypes.SAAB:
             return new Saab(context);
+        case IBankTypes.WALLET:
+            return new Wallet(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -178,6 +181,7 @@ public class BankFactory {
         //banks.add(new AmericanExpress(context));
         banks.add(new McDonalds(context));
         banks.add(new Saab(context));
+        banks.add(new Wallet(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Saab.java src/com/liato/bankdroid/banking/banks/Saab.java
index d014ded..83d9971 100644
--- src/com/liato/bankdroid/banking/banks/Saab.java
+++ src/com/liato/bankdroid/banking/banks/Saab.java
@@ -24,7 +24,7 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
 public class Saab extends SEBKortBase {
-	private static final String TAG = "SAB";
+	private static final String TAG = "SAAB";
 	private static final String NAME = "SaabKortet";
 	private static final String NAME_SHORT = "saab";
 	private static final int BANKTYPE_ID = Bank.SAAB;
diff --git src/com/liato/bankdroid/banking/banks/Saab.java src/com/liato/bankdroid/banking/banks/Wallet.java
similarity index 67%
copy from src/com/liato/bankdroid/banking/banks/Saab.java
copy to src/com/liato/bankdroid/banking/banks/Wallet.java
index d014ded..efe1cdb 100644
--- src/com/liato/bankdroid/banking/banks/Saab.java
+++ src/com/liato/bankdroid/banking/banks/Wallet.java
@@ -23,22 +23,22 @@ import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
 
-public class Saab extends SEBKortBase {
-	private static final String TAG = "SAB";
-	private static final String NAME = "SaabKortet";
-	private static final String NAME_SHORT = "saab";
-	private static final int BANKTYPE_ID = Bank.SAAB;
+public class Wallet extends SEBKortBase {
+	private static final String TAG = "wallet";
+	private static final String NAME = "wallet MasterCard";
+	private static final String NAME_SHORT = "wallet";
+	private static final int BANKTYPE_ID = Bank.WALLET;
 
-	public Saab(Context context) {
-		super(context, "sbse", "0106");
+	public Wallet(Context context) {
+		super(context, "wase", "0121");
 		super.TAG = TAG;
 		super.NAME = NAME;
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 	}
 	
-	public Saab(String username, String password, Context context) throws BankException, LoginException {
-		super(username, password, context, "sbse", "0106");
+	public Wallet(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "wase", "0121");
 	}
 
 }
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index fa53907..6dc47f4 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -55,4 +55,5 @@ public interface IBankTypes {
     public final static int AMERICANEXPRESS = 31;
     public final static int MCDONALDS = 32;
     public final static int SAAB = 33;
+    public final static int WALLET = 34;
 }
\ No newline at end of file

commit b42db9af04c64a113b7be4f7a5cc2a2b98e553d0
Author: liato <x@x00.us>
Date:   Sun Apr 17 16:31:29 2011 +0200

    Add support for SaabKortet.

diff --git logos.psd logos.psd
index ed4b381..aeaf275 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_saab.png res/drawable/logo_saab.png
new file mode 100644
index 0000000..4af4ca5
Binary files /dev/null and res/drawable/logo_saab.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 7d31c52..8a8f82a 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -51,6 +51,7 @@ import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
+import com.liato.bankdroid.banking.banks.Saab;
 import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
@@ -133,6 +134,8 @@ public class BankFactory {
             return new AmericanExpress(context);
         case IBankTypes.MCDONALDS:
             return new McDonalds(context);
+        case IBankTypes.SAAB:
+            return new Saab(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -174,6 +177,7 @@ public class BankFactory {
         //American Express doesn't work yet
         //banks.add(new AmericanExpress(context));
         banks.add(new McDonalds(context));
+        banks.add(new Saab(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Saab.java src/com/liato/bankdroid/banking/banks/Saab.java
new file mode 100644
index 0000000..d014ded
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Saab.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Saab extends SEBKortBase {
+	private static final String TAG = "SAB";
+	private static final String NAME = "SaabKortet";
+	private static final String NAME_SHORT = "saab";
+	private static final int BANKTYPE_ID = Bank.SAAB;
+
+	public Saab(Context context) {
+		super(context, "sbse", "0106");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public Saab(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "sbse", "0106");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index ec022d5..fa53907 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -54,4 +54,5 @@ public interface IBankTypes {
     public final static int RESURSBANK = 30;
     public final static int AMERICANEXPRESS = 31;
     public final static int MCDONALDS = 32;
+    public final static int SAAB = 33;
 }
\ No newline at end of file

commit fec08e34a157a3e0b455e4325a39f72a73599851
Author: liato <x@x00.us>
Date:   Fri Apr 15 00:04:26 2011 +0200

    Let the user choose whether to update the transaction history from the widget or not.

diff --git AndroidManifest.xml AndroidManifest.xml
index 815561b..942d71b 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="108" android:versionName="1.7.2-RC1">
+	android:versionName="1.7.2" android:versionCode="110">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 84e1481..7cd4e35 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -59,6 +59,8 @@
 	<string name="round_widget_balance_summary">Visa saldot på widgets utan decimaler</string>
 	<string name="widget_opens_transactions_title">Widget-klick öppnar kontoutdrag</string>
 	<string name="widget_opens_transactions_summary">Öppna kontoutdraget för kontot när du klickar på en widget.</string>
+	<string name="widget_updates_transactions_title">Uppdatera kontoutdrag från widget</string>
+	<string name="widget_updates_transactions_summary">Uppdatering från widget uppdaterar både saldo och kontoutdrag.</string>
 	<string name="notifications_title">Notifieringar</string>
 	<string name="enable_notifications_title">Aktivera notifieringar</string>
 	<string name="enable_notifications_summary">Notifiera vid kontoförändringar</string>
diff --git res/values/strings.xml res/values/strings.xml
index bbbc13d..55ae6f3 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -60,6 +60,8 @@
 	<string name="round_widget_balance_summary">Display the balance on widgets without decimals</string>
 	<string name="widget_opens_transactions_title">Widget click opens transactions</string>
 	<string name="widget_opens_transactions_summary">Open the transactions screen when a widget is clicked. If unchecked the main screen is shown.</string>
+	<string name="widget_updates_transactions_title">Update transactions from widget.</string>
+	<string name="widget_updates_transactions_summary">Updates from widgets will update both the balance and the transaction history.</string>
 	<string name="notifications_title">Notifications</string>
 	<string name="enable_notifications_title">Enable notifications</string>
 	<string name="enable_notifications_summary">Notify on account changes</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index b1bf8cc..c938dd4 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -68,6 +68,11 @@
 			android:defaultValue="true"
 			android:title="@string/widget_opens_transactions_title"
 			android:summary="@string/widget_opens_transactions_summary" />
+		<CheckBoxPreference
+			android:key="widget_updates_transactions"
+			android:defaultValue="false"
+			android:title="@string/widget_updates_transactions_title"
+			android:summary="@string/widget_updates_transactions_summary" />
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="@string/notifications_title">
diff --git src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 3d6506e..2d59bad 100644
--- src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -16,18 +16,6 @@
 
 package com.liato.bankdroid.appwidget;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.MainActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.drawable;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.layout;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-
 import android.app.PendingIntent;
 import android.app.Service;
 import android.appwidget.AppWidgetManager;
@@ -46,6 +34,15 @@ import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 	private final static String TAG = "BankdroidWidgetProvider";
     private final static String ACTION_WIDGET_BLUR = "com.liato.bankdroid.action.WIDGET_BLUR";
@@ -340,11 +337,13 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			private Context context;
 			private AppWidgetManager appWidgetManager;
 			private int appWidgetId;
+			private SharedPreferences prefs;
 
 			public WidgetUpdateTask(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
 				this.context = context;
 				this.appWidgetManager = appWidgetManager;
 				this.appWidgetId = appWidgetId;
+				this.prefs = PreferenceManager.getDefaultSharedPreferences(context);
 			}
 
 			@Override
@@ -363,6 +362,9 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 				try {
 					if (!bank.isDisabled()) {
 						bank.update();
+						if (prefs.getBoolean("widget_updates_transactions", false)) {
+						    bank.updateAllTransactions();
+						}
 						bank.closeConnection();
 						bank.save();
 					}

commit e6d9b6f2d2848709f47f4138f42b3a13fe7bd341
Author: liato <x@x00.us>
Date:   Thu Apr 14 17:25:05 2011 +0200

    Fix for Swedbank funds.

diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 2c13c07..fbdf2be 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -56,7 +56,7 @@ public class Swedbank extends Bank {
     
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\"[^>]*>\\s*(?:<span\\sclass=\"icon\">[^<]*</span>\\s*)?<span\\s*class=\"name\">([^<]+)</span>\\s*(?:<br/>\\s*)?<span\\s*class=\"amount\">([^<]+)</");
-	private Pattern reLinklessAccounts = Pattern.compile("<li>\\s*([^<]+)<br/?><span\\sclass=\"secondary\">([^<]+)</span>\\s*</li>", Pattern.CASE_INSENSITIVE);
+	private Pattern reLinklessAccounts = Pattern.compile("fix\">\\s*<span\\sclass=\"name\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\sclass=\"amount\">([^<]+)</span>\\s*</div>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("date\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"receiver\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"amount\">([^<]+)</span>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	private Pattern reLoanData = Pattern.compile("<li[^>]*>([^<]+)<br/><span\\s*class=\"secondary\">([^<]+)</span></li>");
 	public Swedbank(Context context) {

commit 183c749565ec93285ad101cf886d813edc090dc5
Author: liato <x@x00.us>
Date:   Thu Apr 14 12:43:45 2011 +0200

    Possible fix for Lansforsakringar.

diff --git AndroidManifest.xml AndroidManifest.xml
index f5ee057..815561b 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.7.1" android:versionCode="107">
+	android:versionCode="108" android:versionName="1.7.2-RC1">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index 15bd643..9d2c16e 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -113,6 +113,7 @@ public class Lansforsakringar extends Bank {
         postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
         postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
         postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
+        Log.d(TAG, "Posting to: "+urlopen.getCurrentURI());
         return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
     }
 
@@ -213,7 +214,7 @@ public class Lansforsakringar extends Bank {
             }
             mRequestToken = matcher.group(1);
 
-            response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=pension_undermenyosynlig&newUc=true&isTopLevel=true&_token=" + mRequestToken);
+            response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_pageLabel=pension_undermenyosynlig&newUc=true&isTopLevel=true&_token=" + mRequestToken);
             matcher = rePension.matcher(response);
             while (matcher.find()) {
                 /*
@@ -261,7 +262,7 @@ public class Lansforsakringar extends Bank {
 
         if (mFirstTransactionPage) {
             try {
-                response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
+                response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&isPortalLogLink=true&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
                 matcher = reViewState.matcher(response);
                 if (!matcher.find()) {
                     Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
@@ -294,7 +295,7 @@ public class Lansforsakringar extends Bank {
                 postData.add(new BasicNameValuePair("loginForm:_idcl", ""));            
                 postData.add(new BasicNameValuePair("loginForm:_link_hidden_", ""));            
                 postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
-                response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Findex_account.faces", postData);
+                response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Findex_account.faces", postData);
                 mFirstTransactionPage = false;
             }
             else {
@@ -304,7 +305,7 @@ public class Lansforsakringar extends Bank {
                 postData.add(new BasicNameValuePair("viewAccountListTransactionsForm:_link_hidden_", ""));            
                 postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
                 postData.add(new BasicNameValuePair("accountList", account.getId()));
-                response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Fjsp%2Faccount%2Fview%2FviewAccountTransactions.faces", postData);
+                response = urlopen.open("https://" + host + "/lfportal/privat.portal?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Fjsp%2Faccount%2Fview%2FviewAccountTransactions.faces", postData);
             }
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();

commit fa2da3042d54bf91ec22717f2d124f957974b4d3
Author: liato <x@x00.us>
Date:   Thu Apr 14 12:04:28 2011 +0200

    Fix for Swedbank transactions.

diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 354c34e..2c13c07 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -57,7 +57,7 @@ public class Swedbank extends Bank {
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\"[^>]*>\\s*(?:<span\\sclass=\"icon\">[^<]*</span>\\s*)?<span\\s*class=\"name\">([^<]+)</span>\\s*(?:<br/>\\s*)?<span\\s*class=\"amount\">([^<]+)</");
 	private Pattern reLinklessAccounts = Pattern.compile("<li>\\s*([^<]+)<br/?><span\\sclass=\"secondary\">([^<]+)</span>\\s*</li>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("date\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"receiver\">([^<]+)</span>\\s*<br\\s?/>\\s*<span\\s*class=\"amount\">([^<]+)</span>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	private Pattern reLoanData = Pattern.compile("<li[^>]*>([^<]+)<br/><span\\s*class=\"secondary\">([^<]+)</span></li>");
 	public Swedbank(Context context) {
 		super(context);
@@ -217,6 +217,14 @@ public class Swedbank extends Bank {
 	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
 	            matcher = reTransactions.matcher(response);
 	            while (matcher.find()) {
+                    /*
+                     * Capture groups:
+                     * GROUP                    EXAMPLE DATA
+                     * 1: Date                  11-04-06
+                     * 2: Specification         Pressbyran
+                     * 3: Amount                -20
+                     * 
+                     */	                
 	                transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 	            }
 		    }

commit e8a3873833d0ec7b0a35f98bdaf42f3439d28525
Author: liato <x@x00.us>
Date:   Tue Apr 12 16:30:28 2011 +0200

    Bump version to 1.7.1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0379c46..f5ee057 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="106" android:versionName="1.7.0">
+	android:versionName="1.7.1" android:versionCode="107">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 0a50dc38c32cc8947970f2e955866157f935ae5f
Author: liato <x@x00.us>
Date:   Tue Apr 12 16:29:50 2011 +0200

    Display both "saldo" and "disponibelt belopp" for ica banken.

diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index ceff363..4b53405 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -55,8 +55,9 @@ public class ICABanken extends Bank {
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	//private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	//private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)[^<]*<br/>.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
 	public ICABanken(Context context) {
@@ -139,15 +140,21 @@ public class ICABanken extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
-			matcher = reBalanceSald.matcher(response);
+			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-			matcher = reBalanceDisp.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: ID                0000000000
+                 * 2: Name              ICA KONTO
+                 * 3: Disponibelt       00.000,00
+                 * 4: Saldo             1.655,71
+                 *  
+                 */			    
+                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Disponibelt)", Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " (Saldo)", Helpers.parseBalance(matcher.group(4).trim()), "a:" + matcher.group(1).trim()));
+
+                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -164,6 +171,7 @@ public class ICABanken extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
+		if (account.getId().startsWith("a:")) return; // No transactions for "saldo"-accounts
 		String response = null;
 		Matcher matcher;
 		try {

commit e5a5edf75ef032c3415b2a0784db2395e72b0b21
Author: liato <x@x00.us>
Date:   Tue Apr 12 16:28:32 2011 +0200

    Fix for Swedbank.

diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 5792441..354c34e 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -55,7 +55,7 @@ public class Swedbank extends Bank {
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
     
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
+	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\"[^>]*>\\s*(?:<span\\sclass=\"icon\">[^<]*</span>\\s*)?<span\\s*class=\"name\">([^<]+)</span>\\s*(?:<br/>\\s*)?<span\\s*class=\"amount\">([^<]+)</");
 	private Pattern reLinklessAccounts = Pattern.compile("<li>\\s*([^<]+)<br/?><span\\sclass=\"secondary\">([^<]+)</span>\\s*</li>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	private Pattern reLoanData = Pattern.compile("<li[^>]*>([^<]+)<br/><span\\s*class=\"secondary\">([^<]+)</span></li>");
@@ -89,6 +89,16 @@ public class Swedbank extends Bank {
         String csrftoken = matcher.group(1);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("xyz", username));
+        postData.add(new BasicNameValuePair("auth-method", "code"));
+        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+        response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loginNext.html", postData);
+
+        matcher = reCSRF.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+        }
+        csrftoken = matcher.group(1);
+        postData.clear();
         postData.add(new BasicNameValuePair("zyx", password));
         postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
         return new LoginPackage(urlopen, postData, response, "https://mobilbank.swedbank.se/banking/swedbank/login.html");
@@ -127,6 +137,15 @@ public class Swedbank extends Bank {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Type              account|loan
+                 * 2: ID                0
+                 * 3: Name              Privatkonto
+                 * 4: Amount            5 678 
+                 *  
+                 */			    
 				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), "loan".equalsIgnoreCase(matcher.group(1).trim()) ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
 				if ("loan".equalsIgnoreCase(matcher.group(1).trim())) {
 				    account.setType(Account.LOANS);

commit 6654bfd4ff4100cc856acfcd57c9435ae6fdc695
Author: liato <x@x00.us>
Date:   Fri Apr 8 06:24:43 2011 +0200

    Always display the username/display name on one line.

diff --git res/layout/listitem_accounts_group.xml res/layout/listitem_accounts_group.xml
index a770075..46e62c3 100644
--- res/layout/listitem_accounts_group.xml
+++ res/layout/listitem_accounts_group.xml
@@ -49,8 +49,7 @@
 		android:gravity="center_vertical"
 		android:id="@+id/txtListitemAccountsGroupAccountname"
 		android:textColor="#000"
-		android:layout_width="wrap_content"
-		android:layout_alignParentRight="false" android:includeFontPadding="true" android:textSize="23dp" android:text="Personnummer"/>
+		android:layout_alignParentRight="false" android:includeFontPadding="true" android:textSize="23dp" android:text="Personnummer" android:lines="1" android:marqueeRepeatLimit="marquee_forever" android:scrollHorizontally="true" android:layout_width="fill_parent" android:ellipsize="marquee"/>
 	<ImageView
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"

commit d7ac70cc7101409b0c76f5818f29596242e61952
Author: liato <x@x00.us>
Date:   Thu Apr 7 16:55:27 2011 +0200

    Enable/disable navigation buttons on webview activity when appropriate.

diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index fd5e657..3c10aab 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -108,6 +108,19 @@ public class LockableActivity extends Activity {
             v.setVisibility(View.VISIBLE);
         }
     }
+
+    protected void setTitleButtonEnabled(String tag, boolean enabled) {
+        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
+        if (v != null) {
+            ImageButton button = (ImageButton)v.findViewById(R.id.imgItemIcon);
+            if (button != null) {
+                v.setEnabled(enabled);
+                v.setFocusable(enabled);
+                button.setEnabled(enabled);
+                button.setAlpha(enabled ? 255 : 50);
+            }
+        }
+    }
     
     protected void setProgressBar(int progress) {
         mProgressBar.setProgress(progress);
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 20dc484..37d34c8 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -55,6 +55,9 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         this.addTitleButton(R.drawable.title_icon_back, "back", this);
         this.addTitleButton(R.drawable.title_icon_forward, "forward", this);
         this.addTitleButton(R.drawable.title_icon_refresh, "refresh", this);
+        this.setTitleButtonEnabled("forward", false);
+        this.setTitleButtonEnabled("back", false);
+        this.setTitleButtonEnabled("refresh", false);
 
         final CookieSyncManager csm = CookieSyncManager.createInstance(this);
         mWebView = (WebView)findViewById(R.id.wvBank);
@@ -137,6 +140,14 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
 
     // Make sure clicked links are loaded in our webview.
     private class BankWebViewClient extends WebViewClient {
+
+        @Override
+        public void onLoadResource(WebView view, String url) {
+            super.onLoadResource(view, url);
+            if (mFirstPageLoaded) handleHistoryChange();
+        }
+
+
         @Override
         public void onPageFinished(WebView view, String url) {
             Log.d(TAG, "Finished loading: "+url);
@@ -149,6 +160,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                 //Remove the generated page from history.
                 mWebView.clearHistory();
                 mFirstPageLoaded = true;
+                activity.setTitleButtonEnabled("refresh", true);
                 return;
             }
         }
@@ -167,6 +179,11 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
             view.loadUrl(url);
             return true;
         }
+        
+        public void handleHistoryChange() {
+            activity.setTitleButtonEnabled("back", mWebView.canGoBack());
+            activity.setTitleButtonEnabled("forward", mWebView.canGoForward());
+        }
     }	
 
     //Handle the back key

commit c02dd18aed6d949b2052e7757bf455c8e192595a
Author: liato <x@x00.us>
Date:   Thu Apr 7 07:03:04 2011 +0200

    Move progress bar to title bar.

diff --git res/drawable/progress_horizontal.xml res/drawable/progress_horizontal.xml
index f628d89..99250a8 100644
--- res/drawable/progress_horizontal.xml
+++ res/drawable/progress_horizontal.xml
@@ -1,60 +1,34 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<layer-list
+	xmlns:android="http://schemas.android.com/apk/res/android">
 
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
+	<item
+		android:id="@android:id/background"
+		android:drawable="@android:color/transparent" />
 
-          http://www.apache.org/licenses/LICENSE-2.0
+	<item
+		android:id="@android:id/secondaryProgress">
+		<clip>
+			<shape>
+				<gradient
+					android:startColor="#589bd4"
+					android:endColor="#2b5b83"
+					android:angle="-90" />
+			</shape>
+		</clip>
+	</item>
 
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
+	<item
+		android:id="@android:id/progress">
+		<clip>
+			<shape>
+				<gradient
+					android:startColor="#589bd4"
+					android:endColor="#2b5b83"
+					android:angle="-90" />
+			</shape>
+		</clip>
+	</item>
 
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    
-    <item android:id="@android:id/background">
-        <shape>
-            <gradient
-                    android:startColor="#70FFFFFF"
-                    android:centerColor="#27FFFFFF"
-                    android:centerY="0.50"
-                    android:endColor="#70FFFFFF"
-                    android:angle="270"
-            />
-        </shape>
-    </item>
-    
-    <item android:id="@android:id/secondaryProgress">
-        <clip>
-            <shape>
-                <gradient
-                        android:startColor="#A2066CFF"
-                        android:centerColor="#BB066CFF"
-                        android:centerY="0.75"
-                        android:endColor="#DA066CFF"
-                        android:angle="270"
-                />
-            </shape>
-        </clip>
-    </item>
-    
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape>
-                <gradient
-                        android:startColor="#A2066CFF"
-                        android:centerColor="#BB066CFF"
-                        android:centerY="0.75"
-                        android:endColor="#DA066CFF"
-                        android:angle="270"
-                />
-            </shape>
-        </clip>
-    </item>
-    
 </layer-list>
 
diff --git res/layout/title.xml res/layout/title.xml
index 15d7895..20bfabb 100644
--- res/layout/title.xml
+++ res/layout/title.xml
@@ -4,10 +4,22 @@
 	android:layout_height="fill_parent"
 	android:background="@drawable/title_background"
 	android:id="@+id/layTitle">
+	<ProgressBar
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:id="@+id/progressBar"
+		android:focusable="false"
+		android:indeterminateOnly="false"
+		android:progressDrawable="@drawable/progress_horizontal" android:minHeight="7dp"
+	android:progress="0" android:visibility="gone"></ProgressBar>
 	<LinearLayout
 		android:layout_width="wrap_content"
 		android:id="@+id/layLogoContainer"
-		android:layout_height="fill_parent" android:layout_toLeftOf="@+id/layTitleButtons" android:layout_alignParentLeft="true" android:clickable="true" android:focusable="true">
+		android:layout_height="fill_parent"
+		android:layout_toLeftOf="@+id/layTitleButtons"
+		android:layout_alignParentLeft="true"
+		android:clickable="true"
+		android:focusable="true">
 		<ImageView
 			android:layout_height="wrap_content"
 			android:layout_width="wrap_content"
@@ -17,7 +29,8 @@
 			android:id="@+id/imgLogoIcon"
 			android:layout_gravity="center_vertical"
 			android:paddingLeft="2dp"
-			android:maxHeight="20dp" android:visibility="gone"></ImageView>
+			android:maxHeight="20dp"
+			android:visibility="gone"></ImageView>
 		<ImageView
 			android:layout_height="wrap_content"
 			android:layout_width="wrap_content"
@@ -26,7 +39,9 @@
 			android:adjustViewBounds="true"
 			android:id="@+id/imgTitle"
 			android:layout_gravity="center_vertical"
-			android:maxHeight="17dp" android:paddingLeft="6dp" android:duplicateParentState="true"></ImageView>
+			android:maxHeight="17dp"
+			android:paddingLeft="6dp"
+			android:duplicateParentState="true"></ImageView>
 	</LinearLayout>
 	<LinearLayout
 		android:layout_width="wrap_content"
diff --git res/layout/webview.xml res/layout/webview.xml
index 4f64fb4..9a8e84b 100644
--- res/layout/webview.xml
+++ res/layout/webview.xml
@@ -10,11 +10,4 @@
 		android:scrollbarAlwaysDrawHorizontalTrack="false"
 		android:scrollbarAlwaysDrawVerticalTrack="false"
 		android:background="@drawable/background_repeat" />
-	<ProgressBar
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:id="@+id/progressBar"
-		android:focusable="false"
-		android:indeterminateOnly="false"
-		android:progressDrawable="@drawable/progress_horizontal" android:minHeight="7dp" android:maxHeight="7dp" android:progress="0"></ProgressBar>
 </FrameLayout>
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 60897e5..fd5e657 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -27,9 +27,13 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.ProgressBar;
 
 import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
 import com.liato.bankdroid.lockpattern.LockPatternUtils;
@@ -42,6 +46,7 @@ public class LockableActivity extends Activity {
 	
 	private LinearLayout mTitlebarButtons;
 	private LayoutInflater mInflater;
+	private ProgressBar mProgressBar;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
@@ -63,6 +68,7 @@ public class LockableActivity extends Activity {
 
         ImageView homeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
         View homeButtonCont = titlebar.findViewById(R.id.layLogoContainer);
+        mProgressBar = (ProgressBar)titlebar.findViewById(R.id.progressBar);
         OnClickListener listener = new View.OnClickListener() {
             public void onClick(View v) {
                 Intent intent = new Intent(LockableActivity.this, MainActivity.class);
@@ -102,7 +108,33 @@ public class LockableActivity extends Activity {
             v.setVisibility(View.VISIBLE);
         }
     }
+    
+    protected void setProgressBar(int progress) {
+        mProgressBar.setProgress(progress);
+    }
 
+    protected void showProgressBar() {
+        mProgressBar.setVisibility(View.VISIBLE);
+    }
+
+    protected void hideProgressBar() {
+        AlphaAnimation animation = new AlphaAnimation(1, 0);
+        animation.setDuration(350);
+        animation.setAnimationListener(new AnimationListener() {
+            @Override
+            public void onAnimationEnd(Animation animation) {
+                mProgressBar.setVisibility(View.GONE);
+            }
+
+            @Override
+            public void onAnimationRepeat(Animation animation) {}
+
+            @Override
+            public void onAnimationStart(Animation animation) {}
+        });
+        mProgressBar.startAnimation(animation);
+    }
+    
     @Override
 	protected void onPause() {
 		super.onPause();
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index a75c323..20dc484 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -23,8 +23,8 @@ import org.apache.http.client.CookieStore;
 import org.apache.http.cookie.Cookie;
 
 import android.content.res.Resources.NotFoundException;
-import android.graphics.Color;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.Message;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -35,11 +35,10 @@ import android.webkit.CookieSyncManager;
 import android.webkit.WebChromeClient;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
-import android.widget.ProgressBar;
 
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.Bank.SessionPackage;
+import com.liato.bankdroid.banking.BankFactory;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -47,7 +46,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
     private final static String TAG = "WebViewActivity";
     private static WebView mWebView;
     private boolean mFirstPageLoaded = false;
-    private static ProgressBar mProgressBar;
+    private final LockableActivity activity = this;
     
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -56,8 +55,6 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         this.addTitleButton(R.drawable.title_icon_back, "back", this);
         this.addTitleButton(R.drawable.title_icon_forward, "forward", this);
         this.addTitleButton(R.drawable.title_icon_refresh, "refresh", this);
-        mProgressBar = (ProgressBar)findViewById(R.id.progressBar);
-        mProgressBar.setVisibility(View.GONE);
 
         final CookieSyncManager csm = CookieSyncManager.createInstance(this);
         mWebView = (WebView)findViewById(R.id.wvBank);
@@ -66,14 +63,23 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         mWebView.getSettings().setBuiltInZoomControls(true); 
         mWebView.getSettings().setUserAgentString(Urllib.USER_AGENT);
         mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
+        
         mWebView.setWebChromeClient(new WebChromeClient() {
             public void onProgressChanged(WebView view, int progress) {
-                mProgressBar.setProgress(progress);
+                activity.setProgressBar(progress);
                 if (progress == 100) {
-                    mProgressBar.setVisibility(View.GONE);
+                    Handler handler = new Handler();
+                    Runnable runnable = new Runnable() {
+                        public void run() {
+                            activity.hideProgressBar();
+                        }
+                    };
+                    // Let the progress bar hit 100% before we hide it.
+                    handler.postDelayed(runnable, 100);
+                    
                 }
-                else if (mFirstPageLoaded && mProgressBar.getVisibility() == View.GONE) {
-                    mProgressBar.setVisibility(View.VISIBLE);
+                else if (mFirstPageLoaded) {
+                    activity.showProgressBar();
                 }
             }
           });

commit da86753b7e59fddc202af263d2f89b05f5b4130f
Author: liato <x@x00.us>
Date:   Thu Apr 7 06:07:05 2011 +0200

    Add progress bar to webview.

diff --git res/drawable/progress_horizontal.xml res/drawable/progress_horizontal.xml
new file mode 100644
index 0000000..f628d89
--- /dev/null
+++ res/drawable/progress_horizontal.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    
+    <item android:id="@android:id/background">
+        <shape>
+            <gradient
+                    android:startColor="#70FFFFFF"
+                    android:centerColor="#27FFFFFF"
+                    android:centerY="0.50"
+                    android:endColor="#70FFFFFF"
+                    android:angle="270"
+            />
+        </shape>
+    </item>
+    
+    <item android:id="@android:id/secondaryProgress">
+        <clip>
+            <shape>
+                <gradient
+                        android:startColor="#A2066CFF"
+                        android:centerColor="#BB066CFF"
+                        android:centerY="0.75"
+                        android:endColor="#DA066CFF"
+                        android:angle="270"
+                />
+            </shape>
+        </clip>
+    </item>
+    
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <gradient
+                        android:startColor="#A2066CFF"
+                        android:centerColor="#BB066CFF"
+                        android:centerY="0.75"
+                        android:endColor="#DA066CFF"
+                        android:angle="270"
+                />
+            </shape>
+        </clip>
+    </item>
+    
+</layer-list>
+
diff --git res/layout/webview.xml res/layout/webview.xml
index d46671d..4f64fb4 100644
--- res/layout/webview.xml
+++ res/layout/webview.xml
@@ -7,5 +7,14 @@
 		android:id="@+id/wvBank"
 		android:layout_height="fill_parent"
 		android:layout_width="fill_parent"
-		android:scrollbarAlwaysDrawHorizontalTrack="false" android:scrollbarAlwaysDrawVerticalTrack="false" android:background="@drawable/background_repeat"/>
+		android:scrollbarAlwaysDrawHorizontalTrack="false"
+		android:scrollbarAlwaysDrawVerticalTrack="false"
+		android:background="@drawable/background_repeat" />
+	<ProgressBar
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:id="@+id/progressBar"
+		android:focusable="false"
+		android:indeterminateOnly="false"
+		android:progressDrawable="@drawable/progress_horizontal" android:minHeight="7dp" android:maxHeight="7dp" android:progress="0"></ProgressBar>
 </FrameLayout>
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 4a36cb3..a75c323 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -23,6 +23,7 @@ import org.apache.http.client.CookieStore;
 import org.apache.http.cookie.Cookie;
 
 import android.content.res.Resources.NotFoundException;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.os.Message;
 import android.util.Log;
@@ -31,8 +32,10 @@ import android.view.View;
 import android.view.View.OnClickListener;
 import android.webkit.CookieManager;
 import android.webkit.CookieSyncManager;
+import android.webkit.WebChromeClient;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
+import android.widget.ProgressBar;
 
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
@@ -44,6 +47,7 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
     private final static String TAG = "WebViewActivity";
     private static WebView mWebView;
     private boolean mFirstPageLoaded = false;
+    private static ProgressBar mProgressBar;
     
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -52,6 +56,8 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         this.addTitleButton(R.drawable.title_icon_back, "back", this);
         this.addTitleButton(R.drawable.title_icon_forward, "forward", this);
         this.addTitleButton(R.drawable.title_icon_refresh, "refresh", this);
+        mProgressBar = (ProgressBar)findViewById(R.id.progressBar);
+        mProgressBar.setVisibility(View.GONE);
 
         final CookieSyncManager csm = CookieSyncManager.createInstance(this);
         mWebView = (WebView)findViewById(R.id.wvBank);
@@ -60,6 +66,17 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
         mWebView.getSettings().setBuiltInZoomControls(true); 
         mWebView.getSettings().setUserAgentString(Urllib.USER_AGENT);
         mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
+        mWebView.setWebChromeClient(new WebChromeClient() {
+            public void onProgressChanged(WebView view, int progress) {
+                mProgressBar.setProgress(progress);
+                if (progress == 100) {
+                    mProgressBar.setVisibility(View.GONE);
+                }
+                else if (mFirstPageLoaded && mProgressBar.getVisibility() == View.GONE) {
+                    mProgressBar.setVisibility(View.VISIBLE);
+                }
+            }
+          });
         mWebView.setWebViewClient(new BankWebViewClient());
         String preloader = "Error...";
         try {

commit be5529414137ac93db0a610bdfea7970ca65fa7f
Author: liato <x@x00.us>
Date:   Thu Apr 7 01:27:16 2011 +0200

    Add missing bank spinner layout files.

diff --git res/layout/bank_spinner_dropdown_item.xml res/layout/bank_spinner_dropdown_item.xml
new file mode 100644
index 0000000..a043a94
--- /dev/null
+++ res/layout/bank_spinner_dropdown_item.xml
@@ -0,0 +1,25 @@
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	style="?android:attr/spinnerItemStyle"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	<ImageView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:src="@drawable/icon"
+		android:id="@+id/imgBank"
+		android:adjustViewBounds="true"
+		android:maxHeight="40dp"
+		android:maxWidth="40dp"
+		android:layout_gravity="center_vertical"
+		android:layout_marginRight="4dp"
+		android:layout_marginLeft="4dp"></ImageView>
+	<CheckedTextView
+		style="?android:attr/spinnerDropDownItemStyle"
+		android:lines="1"
+		android:layout_width="fill_parent"
+		android:layout_height="?android:attr/listPreferredItemHeight"
+		android:ellipsize="marquee"
+		android:id="@+id/txtBank"
+		android:layout_gravity="center" />
+</LinearLayout>
diff --git res/layout/bank_spinner_item.xml res/layout/bank_spinner_item.xml
new file mode 100644
index 0000000..c83a5b1
--- /dev/null
+++ res/layout/bank_spinner_item.xml
@@ -0,0 +1,24 @@
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	style="?android:attr/spinnerItemStyle"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	<ImageView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:src="@drawable/icon"
+		android:id="@+id/imgBank"
+		android:adjustViewBounds="true"
+		android:maxHeight="30dp"
+		android:maxWidth="30dp"
+		android:layout_gravity="center_vertical"
+		android:layout_marginRight="2dp"></ImageView>
+	<TextView
+		style="?android:attr/spinnerItemStyle"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:ellipsize="marquee"
+		android:lines="1"
+		android:id="@+id/txtBank"
+		android:layout_gravity="center" />
+</LinearLayout>

commit c33b376fc72e5848b205f9be66b643f49ee9b406
Author: liato <x@x00.us>
Date:   Thu Apr 7 01:26:50 2011 +0200

    Don't disable automatic updates for CSN if no error message is returned.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 54eab8d..84e1481 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -19,6 +19,7 @@
     <string name="no_accounts_found">Inga konton funna</string>
     <string name="transparent_background">Transparent bakgrund</string>
     <string name="bank_closed">Banken är för närvarande stängd.</string>
+    <string name="unable_to_login">Kunde ej logga in. Var vänlig försök igen senare.</string>
     
     <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
diff --git res/values/strings.xml res/values/strings.xml
index 4e3a1d5..bbbc13d 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -18,6 +18,7 @@
     <string name="no_accounts_found">No accounts found</string>
     <string name="transparent_background">Transparent background</string>
     <string name="bank_closed">The bank is currently closed.</string>
+    <string name="unable_to_login">Unable to login. Please try again later.</string>
     
     <string name="username">Username</string>
     <string name="password">Password</string>
@@ -268,6 +269,6 @@
 	<string name="card_id">Card ID</string>
 	<string name="card_number">Card number</string>
 	
-	<string name="permission_provider_label">Basic account information  and the transaction history</string>
+	<string name="permission_provider_label">Basic account information and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 </resources>
diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 0f19a7c..2f20c9f 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -116,7 +116,7 @@ public class CSN extends Bank {
 			    throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
 			}
 			if (!response.contains("Inloggad&nbsp;som")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+				throw new BankException(res.getText(R.string.unable_to_login).toString());
 			}
 		}
 		catch (ClientProtocolException e) {

commit 7a2a75c8e0f304cebf9438c72ca130a21d0dd1cf
Author: liato <x@x00.us>
Date:   Thu Apr 7 01:20:24 2011 +0200

    Correctly extract transactions made in foreign currencies.

diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index cb8936d..a565a0e 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -53,7 +53,7 @@ public class DinersClub extends Bank {
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reBalance = Pattern.compile("class=\"card\"[^>]+>\\s*<div[^>]+>\\s*<b>([^<]+)</b>\\s*<br ?/>\\s*<span[^>]+>([^<]+)</span>\\s*</div>\\s*<div[^>]+>\\s*<strong[^>]+>[^<]+</strong>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
 	private Pattern reInvoices = Pattern.compile("<tr[^>]+>\\s*<td class=\"right\">\\s*<a href='((Invoice|Nonbilled).aspx\\?card=\\d+&bdate=[\\d-]+)'>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<tr[^>]+>\\s*<td>\\s*<a.*? href='Transact[^']+'>\\s*([\\d-]+)\\s*</a>\\s*</td><td>\\s*<a.*? href='Transact[^']+'>\\s*(.*?)\\s*</a>\\s*</td><td class=\"right\">\\s*(.*?)\\s*</td><td class=\"right\">\\s*<a.*? href='Transact[^']+'>\\s*(.*?)\\s*</a>\\s*</td>\\s*</tr>");
+	private Pattern reTransactions = Pattern.compile("<tr[^>]+>\\s*<td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*([\\d-]+)\\s*</a>\\s*</td><td>\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td><td class=\"right\">\\s*(?:<span[^>]+>\\s*<a[^>]+>([^<]+)</a></span>\\s*)?</td><td class=\"right\">\\s*<a.*? href=[\"']Transact[^'\"]+[\"']>\\s*(.*?)\\s*</a>\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE);
 
 	private String response = null;
 	private String invoiceUrl;

commit 32991b2ba95f990c321e5c799b56fce8e7b4bd3d
Author: liato <x@x00.us>
Date:   Thu Apr 7 01:04:12 2011 +0200

    Only display the value for the first currency on Payson accounts.

diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
index 9fc95ae..19ea2d7 100644
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -51,7 +51,7 @@ public class Payson extends Bank {
 	
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reBalance = Pattern.compile("Saldo:\\s*<strong>([^<]+)<", Pattern.CASE_INSENSITIVE);
+    private Pattern reBalance = Pattern.compile("Saldo:\\s*<strong>([^<+]+)[<+]", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("href=\"details/Default\\.aspx\\?\\d{1,}\">\\s*<span\\s*title=\"(\\d{4}-\\d{2}-\\d{2})[^\"]+\">.*?Grid1_0_3_\\d{1,}_Hy[^>]+>([^<]+)<.*?Grid1_0_5_\\d{1,}_Hy[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private String response = null;
 	
@@ -134,8 +134,12 @@ public class Payson extends Bank {
                  * GROUP                EXAMPLE DATA
                  * 1: Balance           0,00 kr
                  *  
-                 */			    
-				accounts.add(new Account("Konto" , Helpers.parseBalance(matcher.group(1)), "1"));
+                 */
+			    Account account = new Account("Konto" , Helpers.parseBalance(matcher.group(1)), "1");
+			    String currency = Helpers.parseCurrency(matcher.group(1).trim(), "SEK");
+			    account.setCurrency(currency);
+			    this.setCurrency(currency);
+				accounts.add(account);
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 			}
 			

commit 823917faa99a2f6ae30cac273d2fb94bfce1284e
Author: liato <x@x00.us>
Date:   Wed Apr 6 06:01:33 2011 +0200

    Add options to disable visible pattern and enable tactile feedback when using pattern lock. Closes #67.

diff --git res/xml/settings.xml res/xml/settings.xml
index c7a36b8..b1bf8cc 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -12,6 +12,16 @@
 			android:summary="@string/change_patternlock_summary"
 			android:key="patternlock_change"
 			android:dependency="patternlock_enabled" />
+		<CheckBoxPreference
+			android:key="patternlock_visible_pattern"
+			android:defaultValue="true"
+			android:title="@string/lockpattern_settings_enable_visible_pattern_title"
+			android:dependency="patternlock_enabled" />
+		<CheckBoxPreference
+			android:key="patternlock_tactile_feedback"
+			android:defaultValue="false"
+			android:title="@string/lockpattern_settings_enable_tactile_feedback_title"
+			android:dependency="patternlock_enabled" />
 		<CheckBoxPreference
 			android:key="widget_blur_balance"
 			android:defaultValue="false"
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index bc464b5..60897e5 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -48,6 +48,8 @@ public class LockableActivity extends Activity {
 		super.onCreate(savedInstanceState);
 		prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		mLockPatternUtils = new LockPatternUtils(this);		
+        mLockPatternUtils.setVisiblePatternEnabled(prefs.getBoolean("patternlock_visible_pattern", true));
+        mLockPatternUtils.setTactileFeedbackEnabled(prefs.getBoolean("patternlock_tactile_feedback", false));
         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
     }
 	
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index cd5de32..c0384de 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -36,7 +36,9 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		mLockPatternUtils = new LockPatternUtils(this);		
+		mLockPatternUtils = new LockPatternUtils(this);
+        mLockPatternUtils.setVisiblePatternEnabled(prefs.getBoolean("patternlock_visible_pattern", true));
+        mLockPatternUtils.setTactileFeedbackEnabled(prefs.getBoolean("patternlock_tactile_feedback", false));
 	}
 
 	@Override
@@ -51,7 +53,7 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 	@Override
 	protected void onResume() {
 		super.onResume();
-        // Don't do anything if not lock pattern is set
+        // Don't do anything if lock pattern is not set
 		if (!mLockPatternUtils.isLockPatternEnabled() || !isLockEnabled()) {
 		    return;
 		}
diff --git src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
index a76e58f..1e9f3d5 100644
--- src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
+++ src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
@@ -114,6 +114,7 @@ public class ConfirmLockPattern extends Activity {
         }
 
         mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
         mLockPatternView.setOnPatternListener(mConfirmExistingLockPatternListener);
         updateStage(Stage.NeedToUnlock);
 
diff --git src/com/liato/bankdroid/lockpattern/LockPatternUtils.java src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index 39125ee..49e7167 100644
--- src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
+++ src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -35,7 +35,6 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.google.common.collect.Lists;
-import com.liato.bankdroid.lockpattern.LockPatternView.Cell;
 
 /**
  * Utilities for the lock patten and its settings.
diff --git src/com/liato/bankdroid/lockpattern/LockPatternView.java src/com/liato/bankdroid/lockpattern/LockPatternView.java
index b79ed01..f7a5d04 100644
--- src/com/liato/bankdroid/lockpattern/LockPatternView.java
+++ src/com/liato/bankdroid/lockpattern/LockPatternView.java
@@ -20,7 +20,6 @@ package com.liato.bankdroid.lockpattern;
 import java.util.ArrayList;
 import java.util.List;
 
-
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -258,9 +257,9 @@ public class LockPatternView extends View {
         mBitmapCircleDefault = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_default", null, null));
         mBitmapCircleGreen = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_green", null, null));
         mBitmapCircleRed = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_red", null, null));
-
+        
         mBitmapArrowGreenUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_green_up", null, null));
-        mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));     
+        mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));
 
         // we assume all bitmaps have the same size
         mBitmapWidth = mBitmapBtnDefault.getWidth();

commit 75913b3db238f883669a392b13d6fac6691355d4
Author: liato <x@x00.us>
Date:   Wed Apr 6 04:53:49 2011 +0200

    Prevent the soft keyboard from poping up when BankEditActivity is launched.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 91b8608..bdff952 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -36,6 +36,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
@@ -60,6 +61,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.bank);
+		this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 
 		ArrayList<Bank> items = BankFactory.listBanks(this);
 		Collections.sort(items);
 		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);

commit 21c0959428b9a9b18096650365592f651699b0d6
Author: liato <x@x00.us>
Date:   Wed Apr 6 04:51:41 2011 +0200

    Add bank icons to bank spinner.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index dbc5421..91b8608 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -40,6 +40,7 @@ import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.EditText;
+import android.widget.ImageView;
 import android.widget.Spinner;
 import android.widget.TextView;
 
@@ -62,7 +63,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 		ArrayList<Bank> items = BankFactory.listBanks(this);
 		Collections.sort(items);
 		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);
-		BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, android.R.layout.simple_spinner_item, items);
+		BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, items);
 		spnBanks.setAdapter(adapter);
 		spnBanks.setOnItemSelectedListener(this);
 
@@ -153,28 +154,31 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	}
 
 	private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
-		private int resource;
+		private LayoutInflater inflater;
+
 		@Override
 		public View getView(int position, View convertView, ViewGroup parent) {
 			if (convertView == null) {
-				convertView = ((LayoutInflater)super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(resource, parent, false);
+				convertView = inflater.inflate(R.layout.bank_spinner_item, parent, false);
 			}
-			((TextView)convertView).setText(((Bank)getItem(position)).getName());
+            ((TextView)convertView.findViewById(R.id.txtBank)).setText(((Bank)getItem(position)).getName());
+            ((ImageView)convertView.findViewById(R.id.imgBank)).setImageResource(((Bank)getItem(position)).getImageResource());
 			return convertView;			
 		}
 
-		public BankSpinnerAdapter(Context context, int textViewResourceId, List<T> items) {
-			super(context, textViewResourceId, items);
-			resource = textViewResourceId;
+		public BankSpinnerAdapter(Context context, List<T> items) {
+		    super(context, R.layout.bank_spinner_item, R.id.txtBank, items);
+			inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 		}
 
 		@Override
 		public View getDropDownView(int position, View convertView,
 				ViewGroup parent) {
 			if (convertView == null) {
-				convertView = ((LayoutInflater)super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
+				convertView = inflater.inflate(R.layout.bank_spinner_dropdown_item, parent, false);
 			}
-			((TextView)convertView).setText(((Bank)getItem(position)).getName());
+            ((TextView)convertView.findViewById(R.id.txtBank)).setText(((Bank)getItem(position)).getName());
+            ((ImageView)convertView.findViewById(R.id.imgBank)).setImageResource(((Bank)getItem(position)).getImageResource());
 			return convertView;
 		}
 
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 919ac93..bc464b5 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -16,9 +16,6 @@
 
 package com.liato.bankdroid;
 
-import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
-import com.liato.bankdroid.lockpattern.LockPatternUtils;
-
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +31,9 @@ import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 public class LockableActivity extends Activity {
     private static int PATTERNLOCK_UNLOCK = 42;
 	private SharedPreferences prefs;

commit 81e23246cebafc0d16eba5d0d83d6cfebbb73a42
Author: liato <x@x00.us>
Date:   Fri Mar 25 02:35:34 2011 +0100

    Bump version to 1.7.0.

diff --git AndroidManifest.xml AndroidManifest.xml
index dd745a7..0379c46 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="105" android:versionName="1.7.0-RC3">
+	android:versionCode="106" android:versionName="1.7.0">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index b084f95..7d31c52 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -171,7 +171,8 @@ public class BankFactory {
         banks.add(new Volvofinans(context));
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
-        banks.add(new AmericanExpress(context));
+        //American Express doesn't work yet
+        //banks.add(new AmericanExpress(context));
         banks.add(new McDonalds(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 

commit 8adebd2464508a07babda3466b7e32f9c4fbd613
Author: liato <x@x00.us>
Date:   Thu Mar 24 10:56:09 2011 +0100

    Fix account name overflow in small widgets.

diff --git res/layout/widget.xml res/layout/widget.xml
index d42b09a..a2cecef 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -26,27 +26,31 @@
 			android:baselineAlignBottom="true"
 			android:src="@drawable/icon"
 			android:scaleType="fitXY"></ImageView>
-		<TextView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:id="@+id/txtWidgetAccountname"
-			android:layout_gravity="center_vertical"
-			android:textColor="#a8a3a3"
-			android:textSize="11dp"
-			android:inputType="none"
-			android:layout_marginLeft="2dp"
-			android:text="Bankdroid"></TextView>
-		<TextView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:id="@+id/txtWidgetAccountnameBlur"
-			android:layout_gravity="center_vertical"
-			android:textColor="#a8a3a3"
-			android:textSize="11dp"
-			android:inputType="none"
-			android:layout_marginLeft="2dp"
-			android:text="Bankdroid"
-			android:visibility="gone"></TextView>
+	<TextView
+		android:id="@+id/txtWidgetAccountname"
+		android:layout_height="wrap_content"
+		android:layout_width="wrap_content"
+		android:layout_gravity="center_vertical"
+		android:textColor="#a8a3a3"
+		android:textSize="11dp"
+		android:inputType="none"
+		android:layout_marginLeft="2dp"
+		android:layout_marginRight="2dp"
+		android:text="Bankdroid"
+		android:lines="1"></TextView>
+	<TextView
+		android:id="@+id/txtWidgetAccountnameBlur"
+		android:layout_height="wrap_content"
+		android:layout_width="wrap_content"
+		android:layout_gravity="center_vertical"
+		android:textColor="#a8a3a3"
+		android:textSize="11dp"
+		android:inputType="none"
+		android:layout_marginLeft="2dp"
+		android:layout_marginRight="2dp"
+		android:text="Bankdroid"
+		android:lines="1"
+		android:visibility="gone"></TextView>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
diff --git res/layout/widget_transparent.xml res/layout/widget_transparent.xml
index 1a8e3de..cff8b4e 100644
--- res/layout/widget_transparent.xml
+++ res/layout/widget_transparent.xml
@@ -30,27 +30,31 @@
 			android:baselineAlignBottom="true"
 			android:src="@drawable/icon"
 			android:scaleType="fitXY"></ImageView>
-		<TextView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:id="@+id/txtWidgetAccountname"
-			android:layout_gravity="center_vertical"
-			android:textColor="#a8a3a3"
-			android:textSize="11dp"
-			android:inputType="none"
-			android:layout_marginLeft="2dp"
-			android:text="Bankdroid"></TextView>
-		<TextView
-			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:id="@+id/txtWidgetAccountnameBlur"
-			android:layout_gravity="center_vertical"
-			android:textColor="#a8a3a3"
-			android:textSize="11dp"
-			android:inputType="none"
-			android:layout_marginLeft="2dp"
-			android:text="Bankdroid"
-			android:visibility="gone"></TextView>			
+	<TextView
+		android:id="@+id/txtWidgetAccountname"
+		android:layout_height="wrap_content"
+		android:layout_width="wrap_content"
+		android:layout_gravity="center_vertical"
+		android:textColor="#a8a3a3"
+		android:textSize="11dp"
+		android:inputType="none"
+		android:layout_marginLeft="2dp"
+		android:layout_marginRight="2dp"
+		android:text="Bankdroid"
+		android:lines="1"></TextView>
+	<TextView
+		android:id="@+id/txtWidgetAccountnameBlur"
+		android:layout_height="wrap_content"
+		android:layout_width="wrap_content"
+		android:layout_gravity="center_vertical"
+		android:textColor="#a8a3a3"
+		android:textSize="11dp"
+		android:inputType="none"
+		android:layout_marginLeft="2dp"
+		android:layout_marginRight="2dp"
+		android:text="Bankdroid"
+		android:lines="1"
+		android:visibility="gone"></TextView>		
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"

commit 59ee83444ff305822c723c1f9aab6d11b638d99b
Author: liato <x@x00.us>
Date:   Thu Mar 24 00:40:45 2011 +0100

    Bump version to 1.7.0-RC3.

diff --git AndroidManifest.xml AndroidManifest.xml
index 89e252c..dd745a7 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="104" android:versionName="1.7.0-RC2">
+	android:versionCode="105" android:versionName="1.7.0-RC3">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 4f1d90fd9009c2fb305b5cc14c7fea485fc683a7
Author: liato <x@x00.us>
Date:   Thu Mar 24 00:39:19 2011 +0100

    Show savings accounts for Nordnet.

diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index c4aed2a..4d6d0ac 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -49,7 +49,7 @@ public class Nordnet extends Bank {
 	
     
 	private Pattern reLoginFields = Pattern.compile("class=\"formular\">\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"[^>]*>\\s*</fieldset>\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*\\s*<input.*name=\"([^\"]+)");
-    private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)(\\d{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
+    private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)([0-9 ]{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
 	private String response = null;
 	
 	public Nordnet(Context context) {
@@ -123,16 +123,22 @@ public class Nordnet extends Bank {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
-                 * 1: Name              Efternamnet Förnamnet
-                 * 2: Account name      Aktie- och fonddepå
-                 * 3: Account number    1234567
-                 * 4: Amount            31 337
+                 * 1: Name              Efternamnet Förnamnet | Sparkonto
+                 * 2: Account name      Aktie- och fonddepå   | Sparkonto
+                 * 3: Account number    1234567               | 1234 567890 1
+                 * 4: Amount            31 337                | 123
                  *  
-                 */			    
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
-				        + Html.fromHtml(matcher.group(3)).toString().trim(),
-				        Helpers.parseBalance(matcher.group(4)),
-				        Html.fromHtml(matcher.group(3)).toString().trim(), Account.FUNDS));
+                 */
+			    Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
+                        + Html.fromHtml(matcher.group(3)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(4)),
+                        Html.fromHtml(matcher.group(3)).toString().trim().replaceAll(" ", ""));
+
+			    // Saving accounts contain white space characters in the account number
+			    if (!matcher.group(3).trim().contains(" ")) {
+			        account.setType(Account.FUNDS);
+			    }
+				accounts.add(account);
 				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
 			

commit c04b45afdfaf31b41d005433293e80802ce26013
Author: liato <x@x00.us>
Date:   Thu Mar 24 00:22:31 2011 +0100

    Correctly detect loans.

diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index d07862e..5792441 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -127,8 +127,8 @@ public class Swedbank extends Bank {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim() == "loan" ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
-				if (matcher.group(1).trim() == "loan") {
+				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), "loan".equalsIgnoreCase(matcher.group(1).trim()) ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
+				if ("loan".equalsIgnoreCase(matcher.group(1).trim())) {
 				    account.setType(Account.LOANS);
 				}
 				else {
@@ -165,7 +165,7 @@ public class Swedbank extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getType() == Account.OTHER) return; //No transaction history for loans
+		if (account.getType() == Account.OTHER) return;
 
 		String response = null;
 		Matcher matcher;

commit ff8cb4d01aef57cd1acefeaa6bb38ac675441038
Author: liato <x@x00.us>
Date:   Thu Mar 24 00:22:07 2011 +0100

    Add completed payments to transactions in CSN.

diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 9b8a52a..0f19a7c 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -58,6 +58,7 @@ public class CSN extends Bank {
     private Pattern reLoginError = Pattern.compile("<h3>Observera</h3>\\s*<ul>\\s*<li>([^<]+)</li>", Pattern.CASE_INSENSITIVE);
     private Pattern reBalance = Pattern.compile("aktuellStudieskuld\\.do\\?metod=init&(?:amp;)?SpecNr=(\\d{1,})\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\">([^<]+)</", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reCompletedPayments = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\"[^>]+>([^<]+)</", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private String response = null;
 	
 	public CSN(Context context) {
@@ -208,7 +209,22 @@ public class CSN extends Bank {
                         Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
                         Helpers.parseBalance(matcher.group(4).replace(",", "")).negate()));
             }
-
+            
+            response = urlopen.open("https://www.csn.se/aterbetalning/harMinaInbetalningarKommitIn/registreradeInbetalningar.do?javascript=off");
+            matcher = reCompletedPayments.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                        EXAMPLE DATA
+                 * 1: Date                      2006-08-21
+                 * 2: Specification             Återkrav första halvåret 2006 lån 1
+                 * 3: Amount                    1,050
+                 * 
+                 */
+                transactions.add(new Transaction(matcher.group(1).trim(),
+                        Html.fromHtml(matcher.group(2)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(3).replace(",", "")).negate()));
+            }            
             
             Collections.sort(transactions, Collections.reverseOrder());
             account.setTransactions(transactions);

commit 5ac8ae864e17404c5eec040066e6dc0223ccdebb
Author: liato <x@x00.us>
Date:   Wed Mar 23 17:15:03 2011 +0100

    Fix for Nordea.

diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index 6d06ca3..1f30171 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -139,8 +139,12 @@ public class Nordea extends Bank {
              *   
              */
 			matcher = reBalance.matcher(response);
-            balance = Helpers.parseBalance(matcher.group(2));
-            this.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
+			String currency = "SEK";
+			if (matcher.find()) {
+			    balance = Helpers.parseBalance(matcher.group(2));
+			    currency = Html.fromHtml(matcher.group(1)).toString().trim();
+			}
+			this.setCurrency(currency);
 			
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
 			matcher = reFundsLoans.matcher(response);

commit c0e9af58afe8e5c39aa1b954a62a36d0c5131d3b
Author: liato <x@x00.us>
Date:   Wed Mar 23 17:04:36 2011 +0100

    Bump version to 1.7.0-RC2.

diff --git AndroidManifest.xml AndroidManifest.xml
index f6d52ad..89e252c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="103" android:versionName="1.7.0-RC1">
+	android:versionCode="104" android:versionName="1.7.0-RC2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 40c841c16523ac8069f375a54960b46a97ef41d9
Author: liato <x@x00.us>
Date:   Wed Mar 23 17:00:20 2011 +0100

    Add a bit of logging to AmericanExpress.

diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index 0c704a4..ddc60d2 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -121,7 +121,10 @@ public class AmericanExpress extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		
+		Log.d(TAG, "Logging in...");
 		urlopen = login();
+        Log.d(TAG, "Url after login: " + urlopen.getCurrentURI());
+		
 		Matcher matcher = reAccounts.matcher(response);
 		while (matcher.find()) {
             /*

commit 4a837ff67ff51cc8d73e07b41413c263ebfb8ae7
Author: liato <x@x00.us>
Date:   Wed Mar 23 16:57:08 2011 +0100

    Add back payments to CSN transactions.

diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 0b537ca..9b8a52a 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -192,6 +192,24 @@ public class CSN extends Bank {
                         Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
                         Helpers.parseBalance(matcher.group(4).replace(",", ""))));
             }
+            response = urlopen.open("https://www.csn.se/aterbetalning/vadSkallJagBetalUnderAret/betalningstillfallen.do?javascript=off");
+            matcher = reTransactions.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                        EXAMPLE DATA
+                 * 1: Date                      2010-11-25
+                 * 2: Specification             Bankgiro 5580-3084
+                 * 3: OCR-number                4576225900
+                 * 4: Amount                    1,234
+                 * 
+                 */
+                transactions.add(new Transaction(matcher.group(1).trim(),
+                        Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
+                        Helpers.parseBalance(matcher.group(4).replace(",", "")).negate()));
+            }
+
+            
             Collections.sort(transactions, Collections.reverseOrder());
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {

commit ae2f5572c1c40f94bf00ddf597267e331ff177a0
Author: liato <x@x00.us>
Date:   Wed Mar 23 16:43:07 2011 +0100

    Add support for multiple currencies in Nordea.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index c0971d0..1b84e8b 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -299,6 +299,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
                 if (oa != null) {
                     a.setHidden(oa.isHidden());
                     a.setNotify(oa.isNotify());
+                    a.setCurrency(oa.getCurrency());
                 }
             }
             a.setBank(this);
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index afce51f..6d06ca3 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -51,8 +51,10 @@ public class Nordea extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-	
-	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
+
+    private Pattern reCurrency = Pattern.compile("list-left\">\\s*Valuta\\s*</dt>\\s*<dd[^>]+>([^<]+)</dd>", Pattern.CASE_INSENSITIVE);
+    private Pattern reBalance = Pattern.compile("list-left\">\\s*Summa\\s*([a-zA-Z]{3})\\s*</dt>\\s*<dd[^>]+>([^<]+)</", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
 	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reCards = Pattern.compile("/card/details\\.html\\?id=(\\d{1,})[^\"]*\".*?>\\s*<span[^>]*>\\s*<span>([^<]+)</span>\\s*<span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -128,8 +130,17 @@ public class Nordea extends Bank {
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Currency          SEK
+             * 2: Amount            56,78  
+             *   
+             */
+			matcher = reBalance.matcher(response);
+            balance = Helpers.parseBalance(matcher.group(2));
+            this.setCurrency(Html.fromHtml(matcher.group(1)).toString().trim());
 			
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
 			matcher = reFundsLoans.matcher(response);
@@ -147,7 +158,6 @@ public class Nordea extends Bank {
 			matcher = reCards.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c:"+matcher.group(1).trim(), -1L, Account.CCARD));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 
 			if (accounts.isEmpty()) {
@@ -184,12 +194,29 @@ public class Nordea extends Bank {
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
 			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
+			matcher = reCurrency.matcher(response);
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Currency          SEK 
+             *   
+             */
+			String currency = "SEK";
+			if (matcher.find()) {
+			    currency = matcher.group(1).trim();
+			}
+			else {
+			    Log.d(TAG, "Unable to find currency, assuming SEK.");
+			}
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {
-				transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+                Transaction transaction = new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)));
+                transaction.setCurrency(currency);
+				transactions.add(transaction);
 			}
 			account.setTransactions(transactions);
+			account.setCurrency(currency);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();

commit 91239c0719fc66edb7fbec301fd61ba6486e07f0
Author: liato <x@x00.us>
Date:   Wed Mar 23 10:28:43 2011 +0100

    Fix for pension in Lansforsakringar. Extract the correct ID and set the account type to "other".

diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index 73c24aa..15bd643 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -57,7 +57,7 @@ public class Lansforsakringar extends Bank {
     private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa.*?internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_(?:[^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern rePension = Pattern.compile("occupationalPensionDataTable:\\d{1,}:pension_overview_\\d{1,}_([^>]+)>([^<]+)</span></a></span><span[^>]+>\\s*<sup>\\s*</span><span[^>]+></span><span[^>]+>\\s*</sup>\\s*</span>\\s*<table[^>]+>\\s*<tbody[^>]+></tbody></table>\\s*</td><td[^>]+><span[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+    private Pattern rePension = Pattern.compile("AvtalsID=([0-9_]+)[^<]+><span\\s*id=\"occupationalPensionDataTable:\\d{1,}:pension_overview_\\d{1,}_[^>]+>([^<]+)</span></a></span><span[^>]+>\\s*<sup>\\s*</span><span[^>]+></span><span[^>]+>\\s*</sup>\\s*</span>\\s*<table[^>]+>\\s*<tbody[^>]+></tbody></table>\\s*</td><td[^>]+><span[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
     private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
     private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+>(?:<a[^>]+>)?<span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>(?:</a>)?\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
@@ -219,12 +219,14 @@ public class Lansforsakringar extends Bank {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
-                 * 1: ID                    idJsp71
+                 * 1: ID                    00835742_0
                  * 2: Name                  Avtalspension ITP - Fond
                  * 3: Amount                10 587,40
                  * 
-                 */                
-                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+                 */
+                Account account = new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim());
+                account.setType(Account.OTHER);
+                accounts.add(account);
             }            
 
             // Save token for next request
@@ -329,7 +331,7 @@ public class Lansforsakringar extends Bank {
             // We need the second match, disregard the first one.
             matcher.find();
             if (!matcher.find()) {
-                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L304.");
+                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L334.");
                 return;
             }
             mViewState = matcher.group(1);
@@ -337,7 +339,7 @@ public class Lansforsakringar extends Bank {
 
             matcher = reToken.matcher(response);
             if (!matcher.find()) {
-                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" token. L312.");
+                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" token. L342.");
                 return;
             }
             mRequestToken = matcher.group(1);            
diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java src/com/liato/bankdroid/banking/banks/McDonalds.java
index 6b1d122..990aa95 100644
--- src/com/liato/bankdroid/banking/banks/McDonalds.java
+++ src/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -35,7 +35,6 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
-import com.liato.bankdroid.banking.Bank.LoginPackage;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 

commit 6b68845a4a0df19c423d4c4fc1032c34d9cb153c
Author: liato <x@x00.us>
Date:   Fri Mar 18 07:27:35 2011 +0100

    Add support for McDonald's gift cards.

diff --git logos.psd logos.psd
index 2e0f6b1..ed4b381 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_mcdonalds.png res/drawable/logo_mcdonalds.png
new file mode 100644
index 0000000..77b83c2
Binary files /dev/null and res/drawable/logo_mcdonalds.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 5c4f699..54eab8d 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -14,6 +14,7 @@
     <string name="menu_edit">Redigera</string>
     <string name="menu_remove">Radera</string>
     <string name="invalid_username_password">Användarnamn och lösenord stämmer ej.</string>
+    <string name="invalid_card_number">Ogiltigt kortnummer.</string>
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="no_accounts_found">Inga konton funna</string>
     <string name="transparent_background">Transparent bakgrund</string>
@@ -216,5 +217,6 @@
 	<string name="lock_cancel">Avbryt</string>
 	<string name="lock_ok">Ok</string>
     
-<string name="card_id">Kort ID</string>
+	<string name="card_id">Kort ID</string>
+	<string name="card_number">Kortnummer</string>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index d9e2447..4e3a1d5 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -13,6 +13,7 @@
     <string name="menu_edit">Edit</string>
     <string name="menu_remove">Remove</string>
     <string name="invalid_username_password">Invalid username or password.</string>
+    <string name="invalid_card_number">Invalid card number.</string>
     <string name="unable_to_find">Unable to find</string>
     <string name="no_accounts_found">No accounts found</string>
     <string name="transparent_background">Transparent background</string>
@@ -265,6 +266,8 @@
 	<string name="lock_ok">Ok</string>
          
 	<string name="card_id">Card ID</string>
+	<string name="card_number">Card number</string>
+	
 	<string name="permission_provider_label">Basic account information  and the transaction history</string>
 	<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 </resources>
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index dee4d0c..4e90ca8 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -90,6 +90,7 @@ public class Helpers {
             ret = new BigDecimal(balance);
         }
         catch (NumberFormatException e) {
+            Log.d("parseBalance", "Unable to parse: "+balance);
             ret = new BigDecimal(0);
         }
         return ret;
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 84d93f3..b084f95 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.banks.ICABanken;
 import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.McDonalds;
 import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.OKQ8;
@@ -130,6 +131,8 @@ public class BankFactory {
             return new ResursBank(context);
         case IBankTypes.AMERICANEXPRESS:
             return new AmericanExpress(context);
+        case IBankTypes.MCDONALDS:
+            return new McDonalds(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -169,6 +172,7 @@ public class BankFactory {
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
         banks.add(new AmericanExpress(context));
+        banks.add(new McDonalds(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/McDonalds.java src/com/liato/bankdroid/banking/banks/McDonalds.java
new file mode 100644
index 0000000..6b1d122
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/McDonalds.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: PMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.Bank.LoginPackage;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class McDonalds extends Bank {
+
+	private static final String TAG = "McDonalds";
+	private static final String NAME = "McDonald's Presentkort";
+	private static final String NAME_SHORT = "mcdonalds";
+	private static final String URL = "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm";
+	private static final int BANKTYPE_ID = Bank.MCDONALDS;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+	private static final boolean INPUT_HIDDEN_PASSWORD = true;
+	private static final int INPUT_TITLETEXT_USERNAME = R.string.card_number;	
+
+    private Pattern reBalance = Pattern.compile("saldo:\\s*([0-9,. -]+)\\s*kronor");
+    private Pattern reTransactions = Pattern.compile(    "<tr><td>(\\d{2}-\\d{2}-\\d{2})\\s*\\d{2}:\\d{2}</td><td>([^<]+)</tr><td>[^<]+</tr><td>([^<]+)</td></tr>");
+	private String response = "";
+
+	public McDonalds(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME= INPUT_TYPE_USERNAME;
+		super.INPUT_HIDDEN_PASSWORD = INPUT_HIDDEN_PASSWORD;
+		super.INPUT_TITLETEXT_USERNAME = INPUT_TITLETEXT_USERNAME;
+	}
+
+	public McDonalds(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+		urlopen = new Urllib();
+
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		postData.add(new BasicNameValuePair("__Click", "0"));
+		postData.add(new BasicNameValuePair("CardNumber", username));
+
+		return new LoginPackage(urlopen, postData, response, "http://apps.mcdonalds.se/sweden/giftquer.nsf/egift?OpenForm&Seq=1");
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("felaktigt kortnummer")) {
+                throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;		
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || username.length() != 19) {
+			throw new LoginException(res.getText(R.string.invalid_card_number).toString());
+		}
+		login();
+		Matcher matcher = reBalance.matcher(response);
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: balance               845
+             * 
+             */    		    
+		    Account account = new Account("Presentkort", Helpers.parseBalance(matcher.group(1)), "1");
+            balance = Helpers.parseBalance(matcher.group(1));
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		    matcher = reTransactions.matcher(response);
+	        while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Date                  11-03-17
+                 * 2: Location              Sthlm, Sk&ouml;ndal
+                 * 3: Amount                -144
+                 * 
+                 */
+                transactions.add(new Transaction("20"+matcher.group(1).trim(),
+                        Html.fromHtml(matcher.group(2)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(3))));	            
+                account.setTransactions(transactions);
+	        }
+            accounts.add(account);
+		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 047fb7e..ec022d5 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -53,4 +53,5 @@ public interface IBankTypes {
     public final static int CSN = 29;
     public final static int RESURSBANK = 30;
     public final static int AMERICANEXPRESS = 31;
+    public final static int MCDONALDS = 32;
 }
\ No newline at end of file

commit 5a11c2942a8828d70f5686aa0a63848122ff8ed6
Author: liato <x@x00.us>
Date:   Sat Mar 12 20:11:36 2011 +0100

    Change flag on PendingIntent used with AlarmService.

diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 178bc12..cececef 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -39,7 +39,7 @@ public class StartupReceiver extends BroadcastReceiver{
 	
 	public static void setAlarm(Context context) {
 		PendingIntent alarmSender;
-		alarmSender = PendingIntent.getService(context, 0, new Intent(context, AutoRefreshService.class), 0);
+		alarmSender = PendingIntent.getService(context, 0, new Intent(context, AutoRefreshService.class), PendingIntent.FLAG_UPDATE_CURRENT);
 		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         boolean autoUpdatesEnabled = prefs.getBoolean("autoupdates_enabled", true);
         Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0")); 
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 518162e..ee60675 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -60,7 +60,7 @@ public class AutoRefreshService extends Service {
 		new DataRetrieverTask().execute();
 	}
 
-	@Override
+    @Override
 	public void onDestroy() {
 	}
 

commit 60d5b72aef7bfc435016a30b50288dab92ac16cc
Author: liato <x@x00.us>
Date:   Sat Mar 12 20:10:00 2011 +0100

    Loan info for Swedbank.

diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 9eb7642..d07862e 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -17,7 +17,9 @@
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -56,6 +58,7 @@ public class Swedbank extends Bank {
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
 	private Pattern reLinklessAccounts = Pattern.compile("<li>\\s*([^<]+)<br/?><span\\sclass=\"secondary\">([^<]+)</span>\\s*</li>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reLoanData = Pattern.compile("<li[^>]*>([^<]+)<br/><span\\s*class=\"secondary\">([^<]+)</span></li>");
 	public Swedbank(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -162,18 +165,42 @@ public class Swedbank extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getType() == Account.LOANS || account.getType() == Account.OTHER) return; //No transaction history for loans
+		if (account.getType() == Account.OTHER) return; //No transaction history for loans
 
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
-			matcher = reTransactions.matcher(response);
-			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			while (matcher.find()) {
-				transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
-			}
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		    if (account.getType() == Account.LOANS) {
+		        String [] accountId = account.getId().split(":", 2);
+		        if (accountId.length < 2) return;
+	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]);
+	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/loan.html?id="+accountId[1]);
+	            matcher = reLoanData.matcher(response);
+	            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+	            Calendar cal = Calendar.getInstance(); 
+	            String date = sdf.format(cal.getTime());
+	            while (matcher.find()) {
+	                /*
+	                 * Capture groups:
+	                 * GROUP                    EXAMPLE DATA
+	                 * 1: Title                 Totalt | Clearingnummer
+	                 * 2: Value                 12 345 | 8032-5
+	                 * 
+	                 */
+	                Transaction transaction = new Transaction(date, Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)));
+	                transaction.setCurrency("");
+	                transactions.add(transaction);
+	            }
+		    }
+		    else {
+	            Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+	            response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+	            matcher = reTransactions.matcher(response);
+	            while (matcher.find()) {
+	                transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+	            }
+		    }
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block

commit 10c0e52f856fba6260be26026c377e2146f3a7a2
Author: liato <x@x00.us>
Date:   Wed Mar 9 19:38:57 2011 +0100

    Let American Express accept invalid certificates.

diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
index b54ccaa..0c704a4 100644
--- src/com/liato/bankdroid/banking/banks/AmericanExpress.java
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -74,7 +74,7 @@ public class AmericanExpress extends Bank {
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
-        urlopen = new Urllib();
+        urlopen = new Urllib(true, true);
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();

commit b4ffc1338020a9cd98364bd1c98fa900ea8d02c1
Author: liato <x@x00.us>
Date:   Wed Mar 9 19:21:25 2011 +0100

    Fix username hint for Volvofinans.

diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index ea58d17..459e11a 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -50,7 +50,7 @@ public class Volvofinans extends Bank {
 	private static final String URL = "https://secure.volvokort.com/";
 	private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
     
 	public Volvofinans(Context context) {
 		super(context);

commit 5829feadc3cfdd6e502a9779ada4e2cdead698c7
Author: liato <x@x00.us>
Date:   Wed Mar 9 03:58:07 2011 +0100

    Sort SEB transactions.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index d9fa9c5..a3eaa2c 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -18,6 +18,7 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -176,6 +177,7 @@ public class SEB extends Bank {
 			    }
 				transactions.add(new Transaction("20"+date, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4))));
 			}
+			Collections.sort(transactions, Collections.reverseOrder());
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block

commit e5b624241976fe3b02fa310b8d1fd44fac22fcd8
Author: Emil Hesslow <hesslow@gmail.com>
Date:   Tue Mar 8 20:25:35 2011 +0100

    - Removed unused import
    - Sort in reverse instead of sorting and then reversing everything

diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index fdd0e50..0b537ca 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -192,8 +192,7 @@ public class CSN extends Bank {
                         Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
                         Helpers.parseBalance(matcher.group(4).replace(",", ""))));
             }
-            Collections.sort(transactions);
-            Collections.reverse(transactions);
+            Collections.sort(transactions, Collections.reverseOrder());
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
             // TODO Auto-generated catch block
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 407d1c6..da82ce0 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -19,7 +19,6 @@ package com.liato.bankdroid.banking.banks;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 0ca4ef5..e05e75b 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -192,8 +192,7 @@ public abstract class SEBKortBase extends Bank {
 				transactions.add(new Transaction(Helpers.getTransactionDate(monthday[0], monthday[1]),
 				        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""),
 				        Helpers.parseBalance(matcher.group(7)).negate()));
-	            Collections.sort(transactions);
-	            Collections.reverse(transactions);
+	            Collections.sort(transactions, Collections.reverseOrder());
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index 4ceba37..0c8433f 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -159,8 +159,7 @@ public class Steam extends Bank {
                     Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
 		    }
-		    Collections.sort(transactions);
-		    Collections.reverse(transactions);
+		    Collections.sort(transactions, Collections.reverseOrder());
 		    account.setTransactions(transactions);
 		    accounts.add(account);
 		}

commit 9c88ee53ae2172c4ca758de4a84311048e968798
Author: liato <x@x00.us>
Date:   Tue Mar 8 07:32:26 2011 +0100

    Bump version to 1.7.0-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index f9b036c..f6d52ad 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.6.3" android:versionCode="102">
+	android:versionCode="103" android:versionName="1.7.0-RC1">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 9df6704..5c4f699 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -132,45 +132,6 @@
     <string name="tran_desc">Inget kontoutdrag tillgängligt för detta konto.</string>
 
     <string name="thanks_to">Tack till</string>
-    <string name="thanks"> 
-    Wendell Fernandes (Ikon)
-    \nKingcool (ICA Banken)
-    \ngrief (Länsförsäkringar)
-    \neinand (Länsförsäkringar)
-    \nAnders Widén (Länsförsäkringar)
-    \nHund (Handelsbanken)
-    \nTravolta (Coop)
-    \nDaniel Malmgren (Coop)
-    \nisocron (ICA)
-    \nDustin (ICA)
-    \ndimaZ (Statoil)
-    \nOxygen (Statoil)
-    \nOxygen (Nordea)
-	\nOzzy (Avanza)
-	\nasperon (Transparent widget)
-	\nDEGE (Handelsbanken)
-	\ncola (OKQ8)
-	\nRikko (FirstCard)
-	\nnihplod (Eurocard)
-	\nDaniel (Avanza)
-	\nRadioman62 (Coop)
-	\ns3 (Steam Wallet)
-	\nVarazir (Jojo Reskassa)
-	\nJohan (Länsförsäkringar)
-	\nRadioman62 (Handelsbanken)
-	\nLibodido (Coop)
-	\ngust (Handelsbanken)
-	\nbernard (Diners Club)
-	\npilang (Länsförsäkringar)
-	\nMidde (Ikano Bank)
-	\nweppe (Coop)
-	\nmagnusart (Content Provider)
-	\nPMC (Rikslunchen)
-	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
-	\nfiretech (Hemköp Kundkort)
-	\nebjsv (PayPal)
-	</string>
-    
 
 	<!-- Lock Pattern settings -->
     <!-- Unlock header -->
diff --git res/values/strings.xml res/values/strings.xml
index 4d2849a..d9e2447 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -171,6 +171,13 @@
 	\nfiretech (Hemköp Kundkort)
 	\nebjsv (PayPal)
 	\nHenrik (SEB)
+	\nMicke (American Express)
+	\nsjoch (Handelsbanken Finans &amp; Resurs Bank &amp; CSN)
+	\nThomas (Sevenday)
+	\nKalle (Nordnet)
+	\ncork (Volvofinans)
+	\nmarijo (Eurocard)
+	\nd98rolb (Osuuspankki)
      </string>
      
      

commit bb7dae9e1bf486fdce41b94a9eddc8e3653d8323
Author: liato <x@x00.us>
Date:   Tue Mar 8 07:03:55 2011 +0100

    Add support for American Express.

diff --git logos.psd logos.psd
index 057eb54..2e0f6b1 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_americanexpress.png res/drawable/logo_americanexpress.png
new file mode 100644
index 0000000..a14f1dd
Binary files /dev/null and res/drawable/logo_americanexpress.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 04a452d..84d93f3 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -25,6 +25,7 @@ import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
 
+import com.liato.bankdroid.banking.banks.AmericanExpress;
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.CSN;
@@ -127,6 +128,8 @@ public class BankFactory {
             return new CSN(context);
         case IBankTypes.RESURSBANK:
             return new ResursBank(context);
+        case IBankTypes.AMERICANEXPRESS:
+            return new AmericanExpress(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -165,6 +168,7 @@ public class BankFactory {
         banks.add(new Volvofinans(context));
         banks.add(new CSN(context));
         banks.add(new ResursBank(context));
+        banks.add(new AmericanExpress(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/AmericanExpress.java src/com/liato/bankdroid/banking/banks/AmericanExpress.java
new file mode 100644
index 0000000..b54ccaa
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/AmericanExpress.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class AmericanExpress extends Bank {
+	private static final String TAG = "AmericanExpress";
+	private static final String NAME = "American Express";
+	private static final String NAME_SHORT = "americanexpress";
+	private static final String URL = "https://home.americanexpress.com/home/se/home_c.shtml";
+	private static final int BANKTYPE_ID = IBankTypes.AMERICANEXPRESS;
+	
+	private Pattern reAccounts = Pattern.compile("leftnav'\\)\">([^<]+)</a></div>\\s*</td>\\s*<td\\s*colspan=\"6\"\\s*id=\"headerSectionLeft\">\\s*<span\\s*class=\"cardTitle\">.*?BPIndex=(\\d{1,})&[^>]+>([^<]+)</a>.*?Utest&aring;ende skuld</div>\\s*<div[^>]+>[^<]+</div>\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("tableStandardText\"\\s*id=\"Roc\\d{1,}\">\\s*<td[^>]+>\\s*(\\d{1,2}\\s[a-z]{3}\\s\\d{4})</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
+	
+	private String response = null;
+
+	public AmericanExpress(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public AmericanExpress(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        response = urlopen.open("https://home.americanexpress.com/home/se/home_c.shtml");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+
+        postData.add(new BasicNameValuePair("request_type", "LogLogonHandler"));
+        postData.add(new BasicNameValuePair("DestPage", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("Face", "sv_SE"));
+        postData.add(new BasicNameValuePair("brandname", ""));
+        postData.add(new BasicNameValuePair("TARGET", "https://global.americanexpress.com/myca/intl/acctsumm/emea/accountSummary.do?request_type=&Face=sv_SE"));
+        postData.add(new BasicNameValuePair("CHECKBOXSTATUS", "1"));
+        postData.add(new BasicNameValuePair("Logon", "Continue..."));
+        postData.add(new BasicNameValuePair("devicePrint", "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%3B%20u%3B%20windows%20nt%206%2E1%3B%20en%2Dus%3B%20rv%3A1%2E9%2E2%2E7%29%20gecko%2F20100713%20firefox%2F3%2E6%2E7%20%28%20%2Enet%20clr%203%2E5%2E30729%3B%20%2Enet4%2E0c%29%7C5%2E0%20%28Windows%3B%20en%2DUS%29%7CWin32%26pm%5Ffpsc%3D24%7C1680%7C1050%7C988%26pm%5Ffpsw%3Dswf%7Cdef%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D1%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"));
+        postData.add(new BasicNameValuePair("REMEMBERME", "on"));
+        postData.add(new BasicNameValuePair("manage", "option1"));
+        postData.add(new BasicNameValuePair("UserID", username));
+        postData.add(new BasicNameValuePair("USERID", username));
+        postData.add(new BasicNameValuePair("Password", password));
+        postData.add(new BasicNameValuePair("PWD", password));
+
+        return new LoginPackage(urlopen, postData, response, "https://global.americanexpress.com/myca/logon/emea/action?request_type=LogLogonHandler&Face=sv_SE");
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
+			if (!response.contains("Your Personal Cards")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		urlopen = login();
+		Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Account number        XXX-11111
+             * 2: ID                    0
+             * 3: Name                  SAS EuroBonus American Express&reg; Card
+             * 4: Amount                1.111,11 kr
+             * 
+             */   			    
+			accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(),
+			        Helpers.parseBalance(matcher.group(4)).negate(),
+			        matcher.group(2).trim()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(4)).negate());
+		}
+		
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	    super.updateComplete();
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		try {
+			response = urlopen.open("https://www99.americanexpress.com/myca/intl/estatement/emea/statement.do?request_type=&Face=sv_SE&sorted_index=0&BPIndex=" + account.getId());
+			Matcher matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Date                  17 jan 2011
+                 * 2: Specification         xx
+                 * 3: Amount                2,00&nbsp;kr
+                 * 
+                 */
+                SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
+                SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
+                Date transactionDate;
+                try {
+                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
+                    String strDate = sdfTo.format(transactionDate);
+                    transactions.add(new Transaction(strDate,
+                                                     Html.fromHtml(matcher.group(2)).toString().trim(),
+                                                     Helpers.parseBalance(matcher.group(3).trim()).negate()));
+                }
+                catch (ParseException e) {
+                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                }
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
index 3382cec..658369a 100644
--- src/com/liato/bankdroid/banking/banks/ResursBank.java
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -49,7 +49,7 @@ public class ResursBank extends Bank {
 	private static final int BANKTYPE_ID = IBankTypes.RESURSBANK;
 	
 	private Pattern reAccounts = Pattern.compile("kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]+)</", Pattern.CASE_INSENSITIVE);
 	
 	private String response = null;
 
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 4babf32..047fb7e 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -52,4 +52,5 @@ public interface IBankTypes {
     public final static int VOLVOFINANS = 28;
     public final static int CSN = 29;
     public final static int RESURSBANK = 30;
+    public final static int AMERICANEXPRESS = 31;
 }
\ No newline at end of file

commit e732de1658791f42a82e15b0f80815bd15070ee6
Author: liato <x@x00.us>
Date:   Tue Mar 8 05:47:38 2011 +0100

    Add support for Resurs Bank. Closes #43

diff --git res/drawable/logo_resursbank.png res/drawable/logo_resursbank.png
new file mode 100644
index 0000000..2ab7e88
Binary files /dev/null and res/drawable/logo_resursbank.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 5cdc73d..04a452d 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -46,6 +46,7 @@ import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.ResursBank;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
 import com.liato.bankdroid.banking.banks.SevenDay;
@@ -124,6 +125,8 @@ public class BankFactory {
             return new Volvofinans(context);
         case IBankTypes.CSN:
             return new CSN(context);
+        case IBankTypes.RESURSBANK:
+            return new ResursBank(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -161,6 +164,7 @@ public class BankFactory {
         banks.add(new Osuuspankki(context));
         banks.add(new Volvofinans(context));
         banks.add(new CSN(context));
+        banks.add(new ResursBank(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/ResursBank.java src/com/liato/bankdroid/banking/banks/ResursBank.java
new file mode 100644
index 0000000..3382cec
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/ResursBank.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class ResursBank extends Bank {
+	private static final String TAG = "ResursBank";
+	private static final String NAME = "Resurs Bank";
+	private static final String NAME_SHORT = "resursbank";
+	private static final String URL = "https://secure.resurs.se/internetbank/default.jsp";
+	private static final int BANKTYPE_ID = IBankTypes.RESURSBANK;
+	
+	private Pattern reAccounts = Pattern.compile("kontonummer</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Beviljad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Utnyttjad\\s*kredit</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Reserverat\\s*belopp</td>\\s*<td>([^<]+)</td>\\s*</tr>\\s*<tr>\\s*<td[^>]+>Kvar\\s*att\\s*utnyttja</td>\\s*<td>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	
+	private String response = null;
+
+	public ResursBank(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public ResursBank(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        response = urlopen.open("https://secure.resurs.se/internetbank/default.jsp");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("kontonummer", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("page", "privat"));
+        return new LoginPackage(urlopen, postData, response, "https://secure.resurs.se/internetbank/login.jsp");
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
+			if (response.contains("vid inloggningen")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		
+		urlopen = login();
+	    Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Account number        0000000000000000
+             * 2: Beviljad kredit       0,00 kr
+             * 3: Utnyttjad kredit      0,00 kr
+             * 4: Reserverat  belopp    0,00 kr
+             * 5: Kvar att utnyttja     0,00 kr
+             * 
+             */
+		    String accountId = Html.fromHtml(matcher.group(1)).toString().trim().replaceAll("[^0-9]*", "");
+			accounts.add(new Account("Beviljad kredit",
+			        Helpers.parseBalance(matcher.group(2)),
+			        "b_"+accountId));
+			
+			BigDecimal utnyttjad = Helpers.parseBalance(matcher.group(3));
+			utnyttjad = utnyttjad.add(Helpers.parseBalance(matcher.group(4)));
+			utnyttjad = utnyttjad.negate();
+            accounts.add(new Account("Utnyttjad kredit",
+                    utnyttjad,
+                    "u_"+accountId));
+			
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+            balance = balance.add(utnyttjad);
+		}
+		
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	    super.updateComplete();
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		// Only update transactions for the main account
+		if (!account.getId().startsWith("b_")) return;
+		
+		try {
+			response = urlopen.open("https://secure.resurs.se/internetbank/kontoutdrag.jsp");
+			Matcher matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Date                  2010-04-17
+                 * 2: Transaction           ONOFF L+äNNA
+                 * 3: Currency              always null?
+                 * 4: Amount                -95,00 kr 
+                 * 
+                 */
+				transactions.add(new Transaction(matcher.group(1),
+				        Html.fromHtml(matcher.group(2)).toString().trim(),
+				        Helpers.parseBalance(matcher.group(4))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index c89f150..4babf32 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -51,4 +51,5 @@ public interface IBankTypes {
     public final static int OSUUSPANKKI = 27;
     public final static int VOLVOFINANS = 28;
     public final static int CSN = 29;
+    public final static int RESURSBANK = 30;
 }
\ No newline at end of file

commit 90820187369c67aa954651375ebba6cbbb0512a6
Author: liato <x@x00.us>
Date:   Tue Mar 8 04:40:09 2011 +0100

    Add pension for Lansforsakringar.

diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 5022e92..407d1c6 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -178,8 +178,6 @@ public class Eurocard extends Bank {
 			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			String strDate = null;
-			Calendar cal = Calendar.getInstance();
 			while (matcher.find()) {
                 /*
                  * Capture groups:
@@ -192,9 +190,11 @@ public class Eurocard extends Bank {
                  * 6: amount/tax        147,64
                  * 7: amount in sek     5791,18
                  * 
-                 */     			    
-				strDate = ""+cal.get(Calendar.YEAR)+"-"+Html.fromHtml(matcher.group(1)).toString().trim();
-				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(7)).negate()));
+                 */
+			    String[] monthday = matcher.group(1).trim().split("-");
+				transactions.add(new Transaction(Helpers.getTransactionDate(monthday[0], monthday[1]),
+				        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""),
+				        Helpers.parseBalance(matcher.group(7)).negate()));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index 43ed038..73c24aa 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -57,6 +57,7 @@ public class Lansforsakringar extends Bank {
     private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa.*?internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_(?:[^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern rePension = Pattern.compile("occupationalPensionDataTable:\\d{1,}:pension_overview_\\d{1,}_([^>]+)>([^<]+)</span></a></span><span[^>]+>\\s*<sup>\\s*</span><span[^>]+></span><span[^>]+>\\s*</sup>\\s*</span>\\s*<table[^>]+>\\s*<tbody[^>]+></tbody></table>\\s*</td><td[^>]+><span[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
     private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
     private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+>(?:<a[^>]+>)?<span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>(?:</a>)?\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
@@ -212,6 +213,27 @@ public class Lansforsakringar extends Bank {
             }
             mRequestToken = matcher.group(1);
 
+            response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=pension_undermenyosynlig&newUc=true&isTopLevel=true&_token=" + mRequestToken);
+            matcher = rePension.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: ID                    idJsp71
+                 * 2: Name                  Avtalspension ITP - Fond
+                 * 3: Amount                10 587,40
+                 * 
+                 */                
+                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+            }            
+
+            // Save token for next request
+            matcher = reToken.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+            }
+            mRequestToken = matcher.group(1);
+            
             if (accounts.isEmpty()) {
                 throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
index a4b730d..ea58d17 100644
--- src/com/liato/bankdroid/banking/banks/Volvofinans.java
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -19,21 +19,17 @@ package com.liato.bankdroid.banking.banks;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HTTP;
-
-import org.json.JSONTokener;
 import org.json.JSONArray;
-import org.json.JSONObject;
 import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
 
 import android.content.Context;
-import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
@@ -41,7 +37,6 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;

commit 3bc7e729f11d40b2b5a40cbcdf06f40c98022466
Author: liato <x@x00.us>
Date:   Tue Mar 8 04:05:36 2011 +0100

    Get all transactions for Eurocard. Closes #57.

diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 1a308b8..5022e92 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -55,7 +55,7 @@ public class Eurocard extends Bank {
 	
 	private Pattern reAccounts = Pattern.compile("Welcomepagecardimagecontainer\">\\s*[^<]+<br>[^>]+<br>([^>]+)</div>\\s*</div>\\s*</div>.*?indentationwrapper\">\\s*<a\\s*href=\"getPendingTransactions\\.do\\?id=([^\"]+)\">.*?billedamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reSaldo = Pattern.compile("Billingunitbalanceamount\">\\s*([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*(?:<div[^>]+>\\s*)?<span>([^<]*)</span>\\s*(?:</div>\\s*)?</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
     private ArrayList<String> accountIds = new ArrayList<String>();
 	private String response = null;
 	public Eurocard(Context context) {
diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 88e0bed..0ca4ef5 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -18,7 +18,6 @@ package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
 import java.util.regex.Matcher;

commit e3e138a02a8a7dfa0524ea17e5f1d33ebf882c91
Author: liato <x@x00.us>
Date:   Tue Mar 8 03:47:38 2011 +0100

    Improve date detection and sort transactions for Statoil and Eurobonus.

diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 7aca4b7..88e0bed 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -176,7 +176,6 @@ public abstract class SEBKortBase extends Bank {
 			response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			Calendar cal = Calendar.getInstance();
 			while (matcher.find()) {
 				/*
 				 * Capture groups:
@@ -189,8 +188,13 @@ public abstract class SEBKortBase extends Bank {
 				 * 6: Amount			local currency amount (in $currency) for transactions in non-SEK
 				 * 7: Amount in sek		5791,18
 				 * 
-				 */				
-				transactions.add(new Transaction(""+cal.get(Calendar.YEAR)+"-"+matcher.group(1).trim(), Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(7)).negate()));
+				 */
+			    String[] monthday = matcher.group(1).trim().split("-");
+				transactions.add(new Transaction(Helpers.getTransactionDate(monthday[0], monthday[1]),
+				        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""),
+				        Helpers.parseBalance(matcher.group(7)).negate()));
+	            Collections.sort(transactions);
+	            Collections.reverse(transactions);
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {

commit 73418f44d3298f7c30a9a95c10a0ad15da2d7f71
Author: liato <x@x00.us>
Date:   Tue Mar 8 03:42:03 2011 +0100

    Sort CSN transaction by date.

diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
index 57ebe86..fdd0e50 100644
--- src/com/liato/bankdroid/banking/banks/CSN.java
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -19,6 +19,7 @@ package com.liato.bankdroid.banking.banks;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -191,6 +192,8 @@ public class CSN extends Bank {
                         Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
                         Helpers.parseBalance(matcher.group(4).replace(",", ""))));
             }
+            Collections.sort(transactions);
+            Collections.reverse(transactions);
             account.setTransactions(transactions);
         } catch (ClientProtocolException e) {
             // TODO Auto-generated catch block

commit 585eb890159cada21b4d2196b2e7c77b5b914225
Author: liato <x@x00.us>
Date:   Thu Mar 3 03:20:56 2011 +0100

    Add support for CSN. Closes #35.

diff --git res/drawable/logo_csn.png res/drawable/logo_csn.png
new file mode 100644
index 0000000..2f9493d
Binary files /dev/null and res/drawable/logo_csn.png differ
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 86db0fa..dee4d0c 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -116,10 +116,13 @@ public class Helpers {
     }
 
     public static void slowDebug(String TAG, String text) {
+        slowDebug(TAG, text, 100);
+    }
+    public static void slowDebug(String TAG, String text, int sleep) {
         for (String s : text.split("\n")) {
             Log.d(TAG, s);
             try {
-                Thread.sleep(100);
+                Thread.sleep(sleep);
             }
             catch (InterruptedException e) {
                 // TODO Auto-generated catch block
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 45e458f..5cdc73d 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -27,6 +27,7 @@ import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.CSN;
 import com.liato.bankdroid.banking.banks.Coop;
 import com.liato.bankdroid.banking.banks.DinersClub;
 import com.liato.bankdroid.banking.banks.EurobonusMastercard;
@@ -121,6 +122,8 @@ public class BankFactory {
             return new Osuuspankki(context);
         case IBankTypes.VOLVOFINANS:
             return new Volvofinans(context);
+        case IBankTypes.CSN:
+            return new CSN(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -157,6 +160,7 @@ public class BankFactory {
         banks.add(new SevenDay(context));
         banks.add(new Osuuspankki(context));
         banks.add(new Volvofinans(context));
+        banks.add(new CSN(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/CSN.java src/com/liato/bankdroid/banking/banks/CSN.java
new file mode 100644
index 0000000..57ebe86
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/CSN.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class CSN extends Bank {
+	private static final String TAG = "CSN";
+	private static final String NAME = "CSN";
+	private static final String NAME_SHORT = "csn";
+	private static final String URL = "https://www.csn.se/bas/inloggning/pinkod.do";
+	private static final int BANKTYPE_ID = IBankTypes.CSN;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final boolean STATIC_BALANCE = true;
+	
+    private Pattern reLoginError = Pattern.compile("<h3>Observera</h3>\\s*<ul>\\s*<li>([^<]+)</li>", Pattern.CASE_INSENSITIVE);
+    private Pattern reBalance = Pattern.compile("aktuellStudieskuld\\.do\\?metod=init&(?:amp;)?SpecNr=(\\d{1,})\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]+)</td>.*?startHideInfoBoxTimer\\(\\d{1,}\\);\">([^<]+)</", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private String response = null;
+	
+	public CSN(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+        super.STATIC_BALANCE = STATIC_BALANCE;
+    }
+
+	public CSN(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(false, true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        urlopen.addHeader("Referer", "https://www.csn.se/bas/");
+        response = urlopen.open("https://www.csn.se/bas/inloggning/pinkod.do");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("javascript", "on"));
+        try {
+            response = urlopen.open("https://www.csn.se/bas/javascript", postData);
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException("pl:CPE:"+e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException("pl:IOE:"+e.getMessage());
+        }        
+        postData.clear();
+        
+        postData.add(new BasicNameValuePair("metod", "validerapinkod"));
+        postData.add(new BasicNameValuePair("pnr", username));
+        postData.add(new BasicNameValuePair("pinkod", password));
+        return new LoginPackage(urlopen, postData, response, "https://www.csn.se/bas/inloggning/Pinkod.do");
+    }
+
+    @Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+            LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reLoginError.matcher(response);
+			if (matcher.find()) {
+			    throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
+			}
+			if (!response.contains("Inloggad&nbsp;som")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException("login:CPE:"+e.getCause().getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException("login:IOE:"+e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+		    response = urlopen.open("https://www.csn.se/aterbetalning/hurStorArMinSkuld/aktuellStudieskuld.do?javascript=off");
+			Matcher matcher;
+			matcher = reBalance.matcher(response);
+			if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: ID                0
+                 * 2: Name              Lån efter 30 juni 2001 (annuitetslån)
+                 * 3: Amount            123,456
+                 *  
+                 */
+			    BigDecimal amount = Helpers.parseBalance(matcher.group(3).replace(",", "")).negate();
+				accounts.add(new Account("Annuitetslån",
+				        amount, matcher.group(1).trim(), Account.LOANS));
+				balance = amount;
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+        catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }		
+        finally {
+            super.updateComplete();
+        }
+	}
+	
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://www.csn.se/studiemedel/utbetalningar/utbetalningar.do?javascript=off");
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                        EXAMPLE DATA
+                 * 1: Date                      2010-11-25
+                 * 2: Specification             Vecka 47-50
+                 * 3: Status                    Utbetald
+                 * 4: Amount                    8,140
+                 * 
+                 */
+                transactions.add(new Transaction(matcher.group(1).trim(),
+                        Html.fromHtml(matcher.group(2)).toString().trim()+ " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")",
+                        Helpers.parseBalance(matcher.group(4).replace(",", ""))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }	
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 12eb809..c89f150 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -50,4 +50,5 @@ public interface IBankTypes {
     public final static int SEVENDAY = 26;
     public final static int OSUUSPANKKI = 27;
     public final static int VOLVOFINANS = 28;
+    public final static int CSN = 29;
 }
\ No newline at end of file

commit 8ab03305eec9aa3cb01f140285882342edf9ce88
Author: liato <x@x00.us>
Date:   Thu Mar 3 00:41:12 2011 +0100

    Fix for FirstCard.

diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index 66dd01f..43223b7 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -46,7 +46,7 @@ public class FirstCard extends Bank {
 	private static final String TAG = "FirstCard";
 	private static final String NAME = "First Card";
 	private static final String NAME_SHORT = "firstcard";
-	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
+	private static final String URL = "https://www.firstcard.se/login.jsp";
 	private static final int BANKTYPE_ID = IBankTypes.FIRSTCARD;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
@@ -75,14 +75,13 @@ public class FirstCard extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
+        response = urlopen.open("https://www.firstcard.se/login.jsp");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("op", "login"));                
-        postData.add(new BasicNameValuePair("searchIndex", ""));                
-        postData.add(new BasicNameValuePair("country", "0"));               
-        postData.add(new BasicNameValuePair("soktext", "Skriv sökord här"));                
+        postData.add(new BasicNameValuePair("errorpage", "login.jsp"));                
         postData.add(new BasicNameValuePair("pnr", username));
         postData.add(new BasicNameValuePair("intpwd", password));
-        return new LoginPackage(urlopen, postData, null, "https://www.firstcard.se/valkom.jsp");
+        return new LoginPackage(urlopen, postData, null, "https://www.firstcard.se/login.jsp");
     }
 
 	@Override
@@ -90,7 +89,7 @@ public class FirstCard extends Bank {
 		try {
 			LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("felaktig identitet") || response.contains("obligatoriskt") || response.contains("ange en internetkod")) {
+			if (response.contains("Logga in med din kod")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			

commit e1733a74d781b9fda37c2dec36050bc87da1f7fe
Author: liato <x@x00.us>
Date:   Sun Feb 27 01:28:19 2011 +0100

    Clear activity stack when clicking the home button.

diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 85f4273..919ac93 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -64,6 +64,7 @@ public class LockableActivity extends Activity {
         OnClickListener listener = new View.OnClickListener() {
             public void onClick(View v) {
                 Intent intent = new Intent(LockableActivity.this, MainActivity.class);
+                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                 startActivity(intent);
                 LockableActivity.this.finish();
             }

commit 7b499f4b95823a9cb112b042a1ec4701e81f3e76
Author: liato <x@x00.us>
Date:   Sun Feb 27 01:27:34 2011 +0100

    Add Volvofinans logo.

diff --git logos.psd logos.psd
index f74cd58..057eb54 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_volvofinans.png res/drawable/logo_volvofinans.png
new file mode 100644
index 0000000..60a8c19
Binary files /dev/null and res/drawable/logo_volvofinans.png differ

commit 3b4e833206827ef55bcd686b391111855c600def
Merge: 39978fc 5f46487
Author: liato <x@x00.us>
Date:   Sun Feb 27 01:24:56 2011 +0100

    Merge branch 'master' of git://github.com/cork/android-bankdroid into cork-master

commit 39978fca132667c52a79c68afda49f3c198a46df
Author: liato <x@x00.us>
Date:   Sun Feb 27 01:08:19 2011 +0100

    Replace Ikano Bank logo.

diff --git logos.psd logos.psd
index 8521d2a..f74cd58 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_ikanobank.png res/drawable/logo_ikanobank.png
index 5a709ad..eb26ef0 100644
Binary files res/drawable/logo_ikanobank.png and res/drawable/logo_ikanobank.png differ

commit ed339a58c5aa6194a3dbb3a3ec0840bba38007bb
Author: liato <x@x00.us>
Date:   Sun Feb 27 01:00:21 2011 +0100

    Fix for missing transactions in SEB.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index 2da80b4..d9fa9c5 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -52,7 +52,7 @@ public class SEB extends Bank {
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
 	private Pattern reAccounts = Pattern.compile("/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)/(\\d{2}-\\d{2}-\\d{2})</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("(\\d{6})\\s*<br\\s?/>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)(?:/(\\d{2}-\\d{2}-\\d{2}))?</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
 	
 	private String response = null;
 
@@ -160,12 +160,21 @@ public class SEB extends Bank {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
-                 * 1: Transaction           Swedbank Atm
-                 * 2: Date                  11-01-14
-                 * 3: Amount                -100,00 
+                 * 1: Book. date            101214
+                 * 2: Transaction           St1
+                 * 3: Trans. date           10-12-11
+                 * 4: Amount                -200,07  
                  * 
-                 */                 
-				transactions.add(new Transaction("20"+Html.fromHtml(matcher.group(2)).toString().trim(), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+                 */
+			    String date;
+			    if (matcher.group(3) == null || matcher.group(3).length() == 0) {
+			        date = Html.fromHtml(matcher.group(1)).toString().trim();
+			        date = String.format("%s-%s-%s", date.substring(0,2), date.substring(2,4), date.substring(4,6));
+			    }
+			    else {
+			        date = Html.fromHtml(matcher.group(3)).toString().trim();
+			    }
+				transactions.add(new Transaction("20"+date, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4))));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {

commit 5f46487e2ced20d6ff08cbd32bb6bec6a8339afa
Author: Cork <Cork@Tele2.se>
Date:   Thu Feb 24 17:07:22 2011 +0100

    Add support for Volvofinans

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index e1fdf91..9df6704 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -17,6 +17,7 @@
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="no_accounts_found">Inga konton funna</string>
     <string name="transparent_background">Transparent bakgrund</string>
+    <string name="bank_closed">Banken är för närvarande stängd.</string>
     
     <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
diff --git res/values/strings.xml res/values/strings.xml
index 2b27fbb..4d2849a 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -16,6 +16,7 @@
     <string name="unable_to_find">Unable to find</string>
     <string name="no_accounts_found">No accounts found</string>
     <string name="transparent_background">Transparent background</string>
+    <string name="bank_closed">The bank is currently closed.</string>
     
     <string name="username">Username</string>
     <string name="password">Password</string>
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 600447c..45e458f 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -53,6 +53,7 @@ import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
 import com.liato.bankdroid.banking.banks.TestBank;
 import com.liato.bankdroid.banking.banks.Villabanken;
+import com.liato.bankdroid.banking.banks.Volvofinans;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
@@ -118,6 +119,8 @@ public class BankFactory {
             return new SevenDay(context);
         case IBankTypes.OSUUSPANKKI:
             return new Osuuspankki(context);
+        case IBankTypes.VOLVOFINANS:
+            return new Volvofinans(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -153,6 +156,7 @@ public class BankFactory {
         banks.add(new Nordnet(context));
         banks.add(new SevenDay(context));
         banks.add(new Osuuspankki(context));
+        banks.add(new Volvofinans(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Volvofinans.java src/com/liato/bankdroid/banking/banks/Volvofinans.java
new file mode 100644
index 0000000..a4b730d
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Volvofinans.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import org.json.JSONTokener;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.json.JSONException;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Volvofinans extends Bank {
+	private static final String TAG = "Volvofinans";
+	private static final String NAME = "Volvofinans";
+	private static final String NAME_SHORT = "volvofinans";
+	private static final String URL = "https://secure.volvokort.com/";
+	private static final int BANKTYPE_ID = IBankTypes.VOLVOFINANS;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDD-XXXX";
+    
+	public Volvofinans(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+	}
+
+	public Volvofinans(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+		Log.d("Volvofinans", "preLogin");
+        urlopen = new Urllib(true);
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        postData.add(new BasicNameValuePair("TARGET", "https://www.volvokort.com/privat/inloggning/redirect.html"));
+        postData.add(new BasicNameValuePair("REFERER", "https://www.volvokort.com/privat/inloggning/forenklad.html"));
+        return new LoginPackage(urlopen, postData, null, "https://secure.volvokort.com/neas/KodAuth");
+    }
+
+    @Override
+	public Urllib login() throws LoginException, BankException {
+		Log.d("Volvofinans", "login");
+	    
+	    try {
+	        LoginPackage lp = preLogin();
+	        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+
+			if (response.contains("Fel personr/organisationsnr och/eller lösenord.")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+
+			if (response.contains("Internetbanken är stängd för tillfället och beräknas vara tillgänglig")) {
+				throw new LoginException(res.getText(R.string.bank_closed).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		Log.d("Volvofinans", "update");
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		String response = null;
+		try {
+			response = urlopen.open("https://www.volvokort.com/privat/kund/kortkonto/oversikt/kortkonton.html");
+			
+			Log.d("Volvofinans", response);
+
+			try {
+				JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
+				JSONArray data = object.getJSONArray("data");
+
+				int length = data.length();
+				for (int index = 0; index < length; index++) {
+					JSONObject account = data.getJSONObject(index);
+
+					Log.d("Volvofinans", account.getString("kontonummer"));
+					
+					accounts.add(new Account(account.getString("kontonummer"), Helpers.parseBalance(account.getString("disponibeltBelopp")), "1"));
+				}
+			}
+			catch (JSONException e) {
+				throw new BankException(e.getMessage());
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+	      super.updateComplete();
+		}
+	}
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 28a9601..12eb809 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -49,4 +49,5 @@ public interface IBankTypes {
     public final static int NORDNET = 25;
     public final static int SEVENDAY = 26;
     public final static int OSUUSPANKKI = 27;
+    public final static int VOLVOFINANS = 28;
 }
\ No newline at end of file

commit 03c5bd224dd2b35e3326a28d40d73ba69b6e3e8c
Author: liato <x@x00.us>
Date:   Mon Feb 21 03:03:35 2011 +0100

    Let the user decide if a widget click opens the main activity or transactions activity. Closes #46.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index ea034eb..e1fdf91 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -54,6 +54,8 @@
 	<string name="appearance_title">Utseende</string>
 	<string name="round_widget_balance_title">Avrunda saldo på widgets</string>
 	<string name="round_widget_balance_summary">Visa saldot på widgets utan decimaler</string>
+	<string name="widget_opens_transactions_title">Widget-klick öppnar kontoutdrag</string>
+	<string name="widget_opens_transactions_summary">Öppna kontoutdraget för kontot när du klickar på en widget.</string>
 	<string name="notifications_title">Notifieringar</string>
 	<string name="enable_notifications_title">Aktivera notifieringar</string>
 	<string name="enable_notifications_summary">Notifiera vid kontoförändringar</string>
diff --git res/values/strings.xml res/values/strings.xml
index d10f7ab..2b27fbb 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -55,6 +55,8 @@
 	<string name="appearance_title">Appearance</string>
 	<string name="round_widget_balance_title">Round widget balance</string>
 	<string name="round_widget_balance_summary">Display the balance on widgets without decimals</string>
+	<string name="widget_opens_transactions_title">Widget click opens transactions</string>
+	<string name="widget_opens_transactions_summary">Open the transactions screen when a widget is clicked. If unchecked the main screen is shown.</string>
 	<string name="notifications_title">Notifications</string>
 	<string name="enable_notifications_title">Enable notifications</string>
 	<string name="enable_notifications_summary">Notify on account changes</string>
diff --git res/xml/settings.xml res/xml/settings.xml
index a4a44f0..c7a36b8 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -53,6 +53,11 @@
 			android:defaultValue="false"
 			android:title="@string/round_widget_balance_title"
 			android:summary="@string/round_widget_balance_summary" />
+		<CheckBoxPreference
+			android:key="widget_opens_transactions"
+			android:defaultValue="true"
+			android:title="@string/widget_opens_transactions_title"
+			android:summary="@string/widget_opens_transactions_summary" />
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="@string/notifications_title">
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index fbff60f..2674c94 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -65,8 +65,6 @@ public class MainActivity extends LockableActivity {
 		super.onCreate(savedInstanceState);
 
 		initialSetupApiKey();
-
-
 		setContentView(R.layout.main);
 		final OnClickListener listener = new View.OnClickListener() {
 			public void onClick(final View v) {
@@ -121,10 +119,13 @@ public class MainActivity extends LockableActivity {
 		// Clicking on widgets opens their transaction history through MainActivity so that
 		// the user can back out to the main window.
 		if (AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS.equals(getIntent().getAction())) {
-			final Intent intent = new Intent(this, TransactionsActivity.class);
-			intent.putExtra("account", extras.getString("account"));
-			intent.putExtra("bank", extras.getLong("bank"));
-			startActivity(intent);
+	        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		    if (prefs.getBoolean("widget_opens_transactions", true)) {
+    			final Intent intent = new Intent(this, TransactionsActivity.class);
+    			intent.putExtra("account", extras.getString("account"));
+    			intent.putExtra("bank", extras.getLong("bank"));
+    			startActivity(intent);
+		    }
 		}
 	}
 

commit 5248d49a271d98a000aae54c928b6c96bcf2137f
Merge: 90418ae 50a534d
Author: liato <x@x00.us>
Date:   Mon Feb 21 01:33:32 2011 +0100

    Merge branch 'master' of git://github.com/magnusart/android-bankdroid into magnusart-master

commit 90418ae4bcfbed3f2adb1b2617635953c399ce94
Author: liato <x@x00.us>
Date:   Mon Feb 21 01:25:15 2011 +0100

    Add support for Osuuspankki. Closes #44.

diff --git res/drawable/logo_osuuspankki.png res/drawable/logo_osuuspankki.png
new file mode 100644
index 0000000..fe20e9d
Binary files /dev/null and res/drawable/logo_osuuspankki.png differ
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 202f0fe..86db0fa 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -20,6 +20,8 @@ import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
 import java.util.List;
 
 import org.apache.http.NameValuePair;
@@ -161,5 +163,43 @@ public class Helpers {
         return form.toString();
         
     }
+    
+
+    /**
+     * Determines what year a transaction belongs to.
+     * 
+     * If the given <code>day</code> of the given <code>month</code> for the current year
+     * is in the future the transaction is probably from last year.
+     * 
+     * @param month     The month, where January is 1.
+     * @param day       The day of the month, starting from 1.
+     * @return          An ISO 8601 formatted date.
+     */
+    public static String getTransactionDate(String month, String day) {
+        return getTransactionDate(Integer.parseInt(month), Integer.parseInt(day));
+    }
+
+    /**
+     * Determines what year a transaction belongs to.
+     * 
+     * If the given <code>day</code> of the given <code>month</code> for the current year
+     * is in the future the transaction is probably from last year.
+     * 
+     * @param month     The month, where January is 1.
+     * @param day       The day of the month, starting from 1.
+     * @return          An ISO 8601 formatted date.
+     */
+    public static String getTransactionDate(int month, int day) {
+        month--; // Java-months start at 0
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Calendar cal = Calendar.getInstance(); 
+        int currentYear = cal.get(Calendar.YEAR);
+        cal.set(currentYear, month, day, 0, 0);
+        if (cal.getTime().after(Calendar.getInstance().getTime())) {
+            //If the transaction is in the future the year is probably of by +1.
+            cal.add(Calendar.YEAR, -1);
+        }
+        return sdf.format(cal.getTime());
+    }
 
 }
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 563bfa7..600447c 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.banking.banks.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.OKQ8;
+import com.liato.bankdroid.banking.banks.Osuuspankki;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
@@ -114,7 +115,9 @@ public class BankFactory {
         case IBankTypes.NORDNET:
             return new Nordnet(context);            
         case IBankTypes.SEVENDAY:
-            return new SevenDay(context);            
+            return new SevenDay(context);
+        case IBankTypes.OSUUSPANKKI:
+            return new Osuuspankki(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -149,6 +152,7 @@ public class BankFactory {
         banks.add(new SEB(context));
         banks.add(new Nordnet(context));
         banks.add(new SevenDay(context));
+        banks.add(new Osuuspankki(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Osuuspankki.java src/com/liato/bankdroid/banking/banks/Osuuspankki.java
new file mode 100644
index 0000000..8dd3c8b
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Osuuspankki.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Osuuspankki extends Bank {
+	private static final String TAG = "Osuuspankki";
+	private static final String NAME = "Osuuspankki";
+	private static final String NAME_SHORT = "osuuspankki";
+	private static final String URL = "https://www.op.fi/op?kielikoodi=sv";
+	private static final int BANKTYPE_ID = IBankTypes.OSUUSPANKKI;
+	
+	private Pattern reAccounts = Pattern.compile("href=\"\\?id=(\\d{1,})&(?:amp;)?tilinro=([^&]+)&[^>]+>([^<]+)</a>\\s*<br\\s?/>\\s*<span[^>]+>\\s*<b>([^<]+)</b>([^<]+)</span>");
+	private Pattern reTransactions = Pattern.compile("<tr[^>]*>\\s*<td>\\s*<div\\s*class=\"Ensimmainen\">\\s*(\\d{2}\\.\\d{2})\\.<br.?/>\\s*\\s*(\\d{2}\\.\\d{2})\\.\\s*</div>\\s*</td>\\s*<td>\\s*<div>([^<]+)<br.?/>.*?</div>\\s*</td>\\s*<td>\\s*<div\\s*class=\"Nowrap\">\\s*<a[^>]+>([^<]+)<br.?/>\\s*</a>.*?</div>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]*>([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
+	private String response = null;
+
+	public Osuuspankki(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Osuuspankki(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        response = urlopen.open("https://www.op.fi/op?kielikoodi=sv");
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("REQUEST_LOGIN_ATTEMPTED", "true"));
+        postData.add(new BasicNameValuePair("REQUEST_PREVIOUS_QUERYSTRING", ""));
+        postData.add(new BasicNameValuePair("x", "24"));
+        postData.add(new BasicNameValuePair("y", "5"));
+        postData.add(new BasicNameValuePair("USERNAME", username));
+        postData.add(new BasicNameValuePair("PWD", password));
+       
+        return new LoginPackage(urlopen, postData, response, "https://www.op.fi/op?kielikoodi=sv");
+    }
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			
+			if (response.contains("du nya koder genom att bes")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		Matcher matcher;
+		matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: Account type          12401 | 12701
+             * 2: Account id            ecb_5f0e0dfcbc1e8aabe4f5ab85e3382266
+             * 3: Account name          FI91 5553 5140 0165 27
+             * 4: Amount                +882,35
+             * 5: Currency              &nbsp;&euro;
+             * 
+             */
+		    String currency = Helpers.parseCurrency(Html.fromHtml(matcher.group(5)).toString().trim(), "EUR");
+		    Account account = new Account(Html.fromHtml(matcher.group(3)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim());
+		    account.setCurrency(currency);
+            //Bonuskonto
+		    if ("12701".equals(matcher.group(1))) {
+		        account.setType(Account.OTHER);
+		    }
+            this.setCurrency(currency);
+			accounts.add(account);
+			balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+		}
+		
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	    super.updateComplete();
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		Matcher matcher;
+		try {
+			response = urlopen.open(String.format("https://www.op.fi/?id=%s&tilinro=%s&ecb=1&srcpl=4", (account.getType() == Account.OTHER ? "12701" : "12401"),account.getId()));
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Book. date            21.01
+                 * 2: Trans. date           20.01
+                 * 3: Description           ITUNES-EURO LUXEMBOURG
+                 * 4: Transaction type      BANKKORTSBET.
+                 * 5: Amount in EUR         -3,99 
+                 * 
+                 */
+			    String[] date = Html.fromHtml(matcher.group(2)).toString().trim().split(".");
+			    Transaction transaction = new Transaction(Helpers.getTransactionDate(date[1], date[0]),
+                        Html.fromHtml(matcher.group(3)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(5)));
+			    transaction.setCurrency(account.getCurrency());
+				transactions.add(transaction);
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index fce75f7..28a9601 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -48,4 +48,5 @@ public interface IBankTypes {
     public final static int SEB = 24;
     public final static int NORDNET = 25;
     public final static int SEVENDAY = 26;
+    public final static int OSUUSPANKKI = 27;
 }
\ No newline at end of file

commit ab17b9491b62bd96b35b8406533fe3f28a76d5bc
Author: liato <x@x00.us>
Date:   Mon Feb 21 01:22:54 2011 +0100

    Fix login fields extraction for Nordnet.

diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index 0399ad0..c4aed2a 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -48,7 +48,7 @@ public class Nordnet extends Bank {
 	private static final int BANKTYPE_ID = IBankTypes.NORDNET;
 	
     
-	private Pattern reLoginFields = Pattern.compile("class=\"formular\">\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"[^>]*>\\s*</fieldset>\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"");
+	private Pattern reLoginFields = Pattern.compile("class=\"formular\">\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"[^>]*>\\s*</fieldset>\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*\\s*<input.*name=\"([^\"]+)");
     private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)(\\d{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
 	private String response = null;
 	

commit 50a534dc475daaac219ec033c1d80d10c17d67ea
Merge: 484b339 a9f790e
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sun Feb 20 18:04:05 2011 +0100

    Merge branch 'master' of https://github.com/liato/android-bankdroid
    
    Conflicts:
            src/com/liato/bankdroid/BankEditActivity.java

commit a9f790e479ccc9f438546c6b32f5c973ab78783b
Author: liato <x@x00.us>
Date:   Tue Feb 15 07:42:25 2011 +0100

    Add support for SevenDay.

diff --git res/drawable/logo_sevenday.png res/drawable/logo_sevenday.png
new file mode 100644
index 0000000..7b9d590
Binary files /dev/null and res/drawable/logo_sevenday.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 889f736..563bfa7 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -46,6 +46,7 @@ import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.SEB;
+import com.liato.bankdroid.banking.banks.SevenDay;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -112,6 +113,8 @@ public class BankFactory {
             return new SEB(context);            
         case IBankTypes.NORDNET:
             return new Nordnet(context);            
+        case IBankTypes.SEVENDAY:
+            return new SevenDay(context);            
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -145,6 +148,7 @@ public class BankFactory {
         banks.add(new Hemkop(context));
         banks.add(new SEB(context));
         banks.add(new Nordnet(context));
+        banks.add(new SevenDay(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
index c252062..0399ad0 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -29,13 +29,11 @@ import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
 import android.text.Html;
-import android.text.InputType;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
@@ -61,7 +59,6 @@ public class Nordnet extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Nordnet(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/SevenDay.java
similarity index 60%
copy from src/com/liato/bankdroid/banking/banks/Nordnet.java
copy to src/com/liato/bankdroid/banking/banks/SevenDay.java
index c252062..aecda4f 100644
--- src/com/liato/bankdroid/banking/banks/Nordnet.java
+++ src/com/liato/bankdroid/banking/banks/SevenDay.java
@@ -25,7 +25,6 @@ import java.util.regex.Pattern;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
 import android.text.Html;
@@ -35,36 +34,38 @@ import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
-public class Nordnet extends Bank {
-	private static final String TAG = "Nordnet";
-	private static final String NAME = "Nordnet";
-	private static final String NAME_SHORT = "nordnet";
-	private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
-	private static final int BANKTYPE_ID = IBankTypes.NORDNET;
+public class SevenDay extends Bank {
+	private static final String TAG = "SevenDay";
+	private static final String NAME = "SevenDay";
+	private static final String NAME_SHORT = "sevenday";
+	private static final String URL = "https://www.sevenday.se/mina-sidor/mina-sidor.htm";
+	private static final int BANKTYPE_ID = IBankTypes.SEVENDAY;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 	
     
-	private Pattern reLoginFields = Pattern.compile("class=\"formular\">\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"[^>]*>\\s*</fieldset>\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"");
-    private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)(\\d{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
+	private Pattern reViewState = Pattern.compile("ViewState\"\\s+value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("'depositAccountNum':'([^=]+)=='[^>]+>([^<]+)</a></td>\\s*<td[^>]+>\\s*<span[^>]+>\\s*([0-9,]+)[^<]+</span>\\s*</td>\\s*<td[^>]+>\\s*<span[^>]+>\\s*([^<]+)<");
 	private String response = null;
 	
-	public Nordnet(Context context) {
+	public SevenDay(Context context) {
 		super(context);
 		super.TAG = TAG;
 		super.NAME = NAME;
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Nordnet(String username, String password, Context context) throws BankException, LoginException {
+	public SevenDay(String username, String password, Context context) throws BankException, LoginException {
 		this(context);
 		this.update(username, password);
 	}
@@ -74,24 +75,22 @@ public class Nordnet extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib();
-        urlopen.setContentCharset(HTTP.ISO_8859_1);
-        response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
+        response = urlopen.open("https://www.sevenday.se/mina-sidor/mina-sidor.htm");
         
-        Matcher matcher = reLoginFields.matcher(response);
+        Matcher matcher = reViewState.matcher(response);
         if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login fields.");
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
         }
-        String loginFieldName = matcher.group(1);
-        String loginFieldPassword = matcher.group(2);
+        String viewState = matcher.group(1);
 
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("checksum", ""));
-        postData.add(new BasicNameValuePair("referer", ""));
-        postData.add(new BasicNameValuePair("encryption", "0"));
-        postData.add(new BasicNameValuePair(loginFieldName, username));
-        postData.add(new BasicNameValuePair(loginFieldPassword, password));
+        postData.add(new BasicNameValuePair("loginForm", "loginForm"));
+        postData.add(new BasicNameValuePair("login", "login"));
+        postData.add(new BasicNameValuePair("javax.faces.ViewState", viewState));
+        postData.add(new BasicNameValuePair("ssn", username));
+        postData.add(new BasicNameValuePair("password", password));
         
-        return new LoginPackage(urlopen, postData, response, "https://www.nordnet.se/mux/login/login.html");
+        return new LoginPackage(urlopen, postData, response, "https://www.sevenday.se/mina-sidor/mina-sidor.htm");
     }
 
     @Override
@@ -99,7 +98,7 @@ public class Nordnet extends Bank {
 		try {
             LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			if (response.contains("fel vid inloggningen")) {
+			if (response.contains("Logga in med personnummer") || response.contains("kommer automatiskt till startsidan")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		}
@@ -121,21 +120,20 @@ public class Nordnet extends Bank {
 		urlopen = login();
 		try {
 			Matcher matcher;
-			matcher = reBalance.matcher(response);
+			matcher = reAccounts.matcher(response);
 			if (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
-                 * 1: Name              Efternamnet Förnamnet
-                 * 2: Account name      Aktie- och fonddepå
-                 * 3: Account number    1234567
-                 * 4: Amount            31 337
+                 * 1: Account id        JigBFAUETrrqVKY+V4Dm3tcoY1n6Usa21IuHxa1BV7MnJT3T6rrGChDcDK0RSuM731uAeB/f9rvPRXRFYCCBcQ
+                 * 2: Account name      Sparkonto: XXX
+                 * 3: Interest          2,55
+                 * 4: Amount            10&nbsp;kr
                  *  
                  */			    
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
-				        + Html.fromHtml(matcher.group(3)).toString().trim(),
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(),
 				        Helpers.parseBalance(matcher.group(4)),
-				        Html.fromHtml(matcher.group(3)).toString().trim(), Account.FUNDS));
+				        Html.fromHtml(matcher.group(1)).toString().trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
 			
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index afc3268..fce75f7 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -21,7 +21,6 @@ package com.liato.bankdroid.provider;
  * @since 8 jan 2011
  */
 public interface IBankTypes {
-
 	public final static int TESTBANK = 0;
 	public final static int SWEDBANK = 1;
 	public final static int NORDEA = 2;
@@ -48,5 +47,5 @@ public interface IBankTypes {
     public final static int HEMKOP = 23;
     public final static int SEB = 24;
     public final static int NORDNET = 25;
-
+    public final static int SEVENDAY = 26;
 }
\ No newline at end of file

commit b63c4e51e50f5275267009cffd65e02b9462e7ce
Author: liato <x@x00.us>
Date:   Tue Feb 15 06:50:48 2011 +0100

    Add support for Nordnet.

diff --git res/drawable/logo_nordnet.png res/drawable/logo_nordnet.png
new file mode 100644
index 0000000..977d82d
Binary files /dev/null and res/drawable/logo_nordnet.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 11e6118..889f736 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.banks.IkanoBank;
 import com.liato.bankdroid.banking.banks.Jojo;
 import com.liato.bankdroid.banking.banks.Lansforsakringar;
 import com.liato.bankdroid.banking.banks.Nordea;
+import com.liato.bankdroid.banking.banks.Nordnet;
 import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
@@ -109,6 +110,8 @@ public class BankFactory {
             return new Hemkop(context);            
         case IBankTypes.SEB:
             return new SEB(context);            
+        case IBankTypes.NORDNET:
+            return new Nordnet(context);            
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -141,6 +144,7 @@ public class BankFactory {
         banks.add(new Rikslunchen(context));
         banks.add(new Hemkop(context));
         banks.add(new SEB(context));
+        banks.add(new Nordnet(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Nordnet.java src/com/liato/bankdroid/banking/banks/Nordnet.java
new file mode 100644
index 0000000..c252062
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Nordnet.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Nordnet extends Bank {
+	private static final String TAG = "Nordnet";
+	private static final String NAME = "Nordnet";
+	private static final String NAME_SHORT = "nordnet";
+	private static final String URL = "https://www.nordnet.se/mux/login/startSE.html";
+	private static final int BANKTYPE_ID = IBankTypes.NORDNET;
+	
+    
+	private Pattern reLoginFields = Pattern.compile("class=\"formular\">\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"[^>]*>\\s*</fieldset>\\s*<fieldset>\\s*<label>[^<]+</label>\\s*<input.*?name=\"([^\"]+)\"");
+    private Pattern reBalance = Pattern.compile("<a[^>]+>([^<]+)</a>\\s*<span\\s*class=\"bullet\">.*?</span>\\s*<span>([^\\d]+)(\\d{1,})</span>\\s*</div>\\s*</div>\\s*<div\\s*class=\"value\">\\s*([0-9][^<]+)<");
+	private String response = null;
+	
+	public Nordnet(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+	}
+
+	public Nordnet(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        response = urlopen.open("https://www.nordnet.se/mux/login/startSE.html");
+        
+        Matcher matcher = reLoginFields.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login fields.");
+        }
+        String loginFieldName = matcher.group(1);
+        String loginFieldPassword = matcher.group(2);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("checksum", ""));
+        postData.add(new BasicNameValuePair("referer", ""));
+        postData.add(new BasicNameValuePair("encryption", "0"));
+        postData.add(new BasicNameValuePair(loginFieldName, username));
+        postData.add(new BasicNameValuePair(loginFieldPassword, password));
+        
+        return new LoginPackage(urlopen, postData, response, "https://www.nordnet.se/mux/login/login.html");
+    }
+
+    @Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+            LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			if (response.contains("fel vid inloggningen")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+			Matcher matcher;
+			matcher = reBalance.matcher(response);
+			if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Name              Efternamnet Förnamnet
+                 * 2: Account name      Aktie- och fonddepå
+                 * 3: Account number    1234567
+                 * 4: Amount            31 337
+                 *  
+                 */			    
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() + " "
+				        + Html.fromHtml(matcher.group(3)).toString().trim(),
+				        Helpers.parseBalance(matcher.group(4)),
+				        Html.fromHtml(matcher.group(3)).toString().trim(), Account.FUNDS));
+				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}		
+        finally {
+            super.updateComplete();
+        }
+	}
+}
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index de01a8e..afc3268 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -47,5 +47,6 @@ public interface IBankTypes {
     public final static int RIKSLUNCHEN = 22;
     public final static int HEMKOP = 23;
     public final static int SEB = 24;
+    public final static int NORDNET = 25;
 
 }
\ No newline at end of file

commit ea5144788e13d08d191f17e93b7c6c6e482f275d
Author: liato <x@x00.us>
Date:   Tue Feb 15 06:49:33 2011 +0100

    Set Keep-Alive timout to 5 seconds on SEB.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index c817396..2da80b4 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -78,6 +78,7 @@ public class SEB extends Bank {
         urlopen = new Urllib();
         urlopen.setContentCharset(HTTP.ISO_8859_1);
         urlopen.addHeader("Referer", "https://m.seb.se/");
+        urlopen.setKeepAliveTimeout(5);
         //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("A1", username));
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 06896bb..e191627 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.List;
 
 import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
@@ -31,6 +32,7 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
 import org.apache.http.conn.scheme.PlainSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
@@ -146,7 +148,16 @@ public class Urllib {
     }    
     public void addHeader(String key, String value) {
         this.headers.put(key, value);
-    }    
+    }
+    
+    public void setKeepAliveTimeout(final int seconds) {
+        httpclient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { 
+            @Override
+            public long getKeepAliveDuration(HttpResponse response, HttpContext arg1) {
+                // TODO Auto-generated method stub
+                return seconds;
+            }});
+    }
 
     public String removeHeader(String key) {
         return this.headers.remove(key);

commit 612aae755a82008f44a6633db13ebec34037b052
Author: liato <x@x00.us>
Date:   Tue Feb 15 06:47:51 2011 +0100

    Fix cosmetic bug and bump version to 1.6.3.

diff --git AndroidManifest.xml AndroidManifest.xml
index de19a9f..f9b036c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="101" android:versionName="1.6.2">
+	android:versionName="1.6.3" android:versionCode="102">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/layout/transaction_date.xml res/layout/transaction_date.xml
index a5f6236..ceb30eb 100644
--- res/layout/transaction_date.xml
+++ res/layout/transaction_date.xml
@@ -2,14 +2,25 @@
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent"
-	android:paddingLeft="10dp" android:paddingRight="0dp" android:clickable="true" android:background="@drawable/date_bg" android:layout_height="28dp" android:gravity="center_vertical">
-
+	android:paddingLeft="10dp"
+	android:paddingRight="0dp"
+	android:background="@drawable/date_bg"
+	android:layout_height="28dp"
+	android:gravity="center_vertical" android:clickable="false" android:focusable="false" android:focusableInTouchMode="false">
 	<TextView
 		android:inputType="none"
-		android:scrollHorizontally="true" android:layout_width="fill_parent" android:layout_toLeftOf="@+id/txtAmount" android:textStyle="bold" android:text="2010-11-12" android:typeface="sans" android:shadowColor="#000" android:id="@+id/txtDate" android:shadowDx="0" android:shadowDy="0" android:shadowRadius="1" android:textSize="16dp" android:layout_height="wrap_content" android:gravity="center_vertical" android:paddingTop="1dp" android:textColor="#fff"/>
-
-
-	
-
-
+		android:scrollHorizontally="true"
+		android:layout_width="fill_parent"
+		android:textStyle="bold"
+		android:text="2010-11-12"
+		android:typeface="sans"
+		android:shadowColor="#000"
+		android:id="@+id/txtDate"
+		android:shadowDx="0"
+		android:shadowDy="0"
+		android:shadowRadius="1"
+		android:textSize="16dp"
+		android:gravity="center_vertical"
+		android:textColor="#fff"
+		android:layout_height="fill_parent" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:focusable="false" android:clickable="false" android:focusableInTouchMode="false"/>
 </RelativeLayout>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 853b3a4..ea034eb 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -113,8 +113,8 @@
     <string name="popup_www">WWW</string>
     <string name="popup_remove">Radera</string>
 
-    <string name="popup_hide">Göm</string>
-    <string name="popup_unhide">Göm ej</string>
+    <string name="popup_hide">Dölj</string>
+    <string name="popup_unhide">Dölj ej</string>
     <string name="popup_enable_notifications">Aktivera notifieringar</string>
     <string name="popup_disable_notifications">Inaktivera notifieringar</string>
 
@@ -123,8 +123,8 @@
     <string name="yes">Ja</string>
     <string name="no">Nej</string>
  
-    <string name="menu_show_hidden">Visa gömda konton</string>
-    <string name="menu_hide_hidden">Göm gömda konton</string>
+    <string name="menu_show_hidden">Visa dolda konton</string>
+    <string name="menu_hide_hidden">Göm dolda konton</string>
     
     <string name="tran_desc">Inget kontoutdrag tillgängligt för detta konto.</string>
 
@@ -164,7 +164,7 @@
 	\nmagnusart (Content Provider)
 	\nPMC (Rikslunchen)
 	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
-	\nfiretech (Hemköp)
+	\nfiretech (Hemköp Kundkort)
 	\nebjsv (PayPal)
 	</string>
     
diff --git res/values/strings.xml res/values/strings.xml
index c2b88a0..d10f7ab 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -165,7 +165,7 @@
 	\nmagnusart (Content Provider)
 	\nPMC (Rikslunchen)
 	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
-	\nfiretech (Hemköp)
+	\nfiretech (Hemköp Kundkort)
 	\nebjsv (PayPal)
 	\nHenrik (SEB)
      </string>

commit 662630553ec6eea15ae77033cea675532967beb2
Author: liato <x@x00.us>
Date:   Sun Feb 6 05:45:46 2011 +0100

    Move translation of settings to values.xml. Fix FC bug when settings activity is opened with swedish locale.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 3979b77..853b3a4 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -35,6 +35,53 @@
 
 	<string name="choose_an_account">Välj ett konto</string>
 	
+	<!--  Settings  -->
+	<string name="security_and_privacy">Säkerhet</string>
+	<string name="enable_patternlock_title">Aktivera grafiskt lösenord</string>
+	<string name="enable_patternlock_summary">Skydda appen och widgets med ett grafiskt lösenord</string>
+	<string name="change_patternlock_title">Ändra grafiskt lösenord</string>
+	<string name="change_patternlock_summary">Ändra ditt nuvarande grafiska lösenord</string>
+	<string name="blur_widget_title">Dölj widgetsaldo</string>
+	<string name="blur_widget_summary">Saldot på widgeten visas endast då du klickat på den</string>
+	<string name="unblur_widget_timeout_title">Dölj saldot efter</string>
+	<string name="unblur_widget_timeout_summary">Dölj saldot igen efter angiven tid</string>
+	<string name="automatic_updates_title">Automatiska Uppdateringar</string>
+	<string name="autoupdates_enabled_title">Aktivera</string>
+	<string name="autoupdates_enabled_summary">Aktivera automatiska uppdateringar</string>
+	<string name="update_frequency_title">Uppdateringsfrekvens</string>
+	<string name="update_transaction_history_title">Uppdatera kontoutdrag</string>
+	<string name="update_transaction_history_summary">Uppdatera kontoutdrag vid automatiska uppdateringar</string>
+	<string name="appearance_title">Utseende</string>
+	<string name="round_widget_balance_title">Avrunda saldo på widgets</string>
+	<string name="round_widget_balance_summary">Visa saldot på widgets utan decimaler</string>
+	<string name="notifications_title">Notifieringar</string>
+	<string name="enable_notifications_title">Aktivera notifieringar</string>
+	<string name="enable_notifications_summary">Notifiera vid kontoförändringar</string>
+	<string name="vibrate_title">Vibrera</string>
+	<string name="vibrate_summary">Vibrera vid kontoförändringar</string>
+	<string name="notification_sound_title">Notifieringsljud</string>
+	<string name="notification_sound_summary">Välj ett notifieringsljud</string>
+	<string name="notification_sound_name">Välj ljud</string>
+	<string name="account_types_title">Kontotyper</string>
+	<string name="account_types_summary">Visa endast notifieringar för valda kontotyper</string>
+	<string name="remote_notifier_title">Remote Notifier-integrering</string>
+	<string name="remote_notifier_enable_title">Aktivera</string>
+	<string name="remote_notifier_enable_summary">Aktivera Remote Notifier-integrering</string>
+	<string name="remote_notifier_help_title">Vad är Remote Notifier?</string>
+	<string name="remote_notifier_help_summary">Läs mer om Remote Notifier på deras webbsida</string>
+	<string name="openwatch_title">OpenWatch-integrering</string>
+	<string name="openwatch_enable_title">Aktivera</string>
+	<string name="openwatch_enable_summary">Aktivera OpenWatch-integrering</string>
+	<string name="openwatch_vibrate_title">Vibrera</string>
+	<string name="openwatch_vibrate_summary">Vibrera OpenWatch-enheten</string>
+	<string name="openwatch_help_title">Vad är OpenWatch?</string>
+	<string name="openwatch_help_summary">Läs mer om OpenWatch på deras webbsida</string>
+	<string name="share_data_title">Dela ut data</string>
+	<string name="share_data_enable_title">Aktivera utdelninga av data</string>
+	<string name="share_data_enable_summary">Medge andra installerade applikationer åtkomst till kontoutdrag</string>
+	<string name="api_key_title">API-nyckel</string>
+	<string name="api_key_summary">Använd denna nyckel för för att komma åt kontoutdrag från andra applikationer</string>
+
 	<string name="update_frequency">Uppdateringsfrekvens</string>
 	<string name="access_code">Lösenord</string>
 	<string name="access_code_repeat">Upprepa lösenord</string>
@@ -50,7 +97,8 @@
 	<string name="loans">Lån</string>
 	<string name="deposit_account">Transaktionskonto</string>
 	<string name="other">Andra</string>
-	
+	<!--  /Settings  -->
+		
     <string name="login">Logga in</string>
     <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
     
diff --git res/values/strings.xml res/values/strings.xml
index 423ca11..c2b88a0 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -35,6 +35,54 @@
 
 	<string name="choose_an_account">Choose an account</string>
 	
+	
+	<!--  Settings  -->
+	<string name="security_and_privacy">Security and Privacy</string>
+	<string name="enable_patternlock_title">Enable Pattern Lock</string>
+	<string name="enable_patternlock_summary">Lock the app and widgets with a pattern lock</string>
+	<string name="change_patternlock_title">Change lock pattern</string>
+	<string name="change_patternlock_summary">Change your current lock pattern</string>
+	<string name="blur_widget_title">Blur widget balance</string>
+	<string name="blur_widget_summary">Blur the balance on the widget, click widget to unblur for a few seconds</string>
+	<string name="unblur_widget_timeout_title">Unblur timeout</string>
+	<string name="unblur_widget_timeout_summary">Blur the balance again after this many seconds</string>
+	<string name="automatic_updates_title">Automatic Updates</string>
+	<string name="autoupdates_enabled_title">Enable</string>
+	<string name="autoupdates_enabled_summary">Enable automatic updates</string>
+	<string name="update_frequency_title">Update frequency</string>
+	<string name="update_transaction_history_title">Update transaction history</string>
+	<string name="update_transaction_history_summary">Update transaction history when updating automatically</string>
+	<string name="appearance_title">Appearance</string>
+	<string name="round_widget_balance_title">Round widget balance</string>
+	<string name="round_widget_balance_summary">Display the balance on widgets without decimals</string>
+	<string name="notifications_title">Notifications</string>
+	<string name="enable_notifications_title">Enable notifications</string>
+	<string name="enable_notifications_summary">Notify on account changes</string>
+	<string name="vibrate_title">Vibrate</string>
+	<string name="vibrate_summary">Vibrate on account changes</string>
+	<string name="notification_sound_title">Notification sound</string>
+	<string name="notification_sound_summary">Select notification sound</string>
+	<string name="notification_sound_name">Select sound</string>
+	<string name="account_types_title">Account types</string>
+	<string name="account_types_summary">Only show notifications for selected account types</string>
+	<string name="remote_notifier_title">Remote Notifier Integration</string>
+	<string name="remote_notifier_enable_title">Enable</string>
+	<string name="remote_notifier_enable_summary">Enable Remote Notifier integration</string>
+	<string name="remote_notifier_help_title">What is Remote Notifier?</string>
+	<string name="remote_notifier_help_summary">Read more about Remote Notifier on their website</string>
+	<string name="openwatch_title">OpenWatch Integration</string>
+	<string name="openwatch_enable_title">Enable</string>
+	<string name="openwatch_enable_summary">Enable OpenWatch integration</string>
+	<string name="openwatch_vibrate_title">Vibrate</string>
+	<string name="openwatch_vibrate_summary">Vibrate the OpenWatch device</string>
+	<string name="openwatch_help_title">What is OpenWatch?</string>
+	<string name="openwatch_help_summary">Read more about OpenWatch on their website</string>
+	<string name="share_data_title">Share data</string>
+	<string name="share_data_enable_title">Enable data sharing</string>
+	<string name="share_data_enable_summary">Grant other installed apps access to your transaction history</string>
+	<string name="api_key_title">API Key</string>
+	<string name="api_key_summary">Use this key to allow access for trusted applications</string>
+	
 	<string name="update_frequency">Update frequency</string>
 	<string name="access_code">Access code</string>
 	<string name="access_code_repeat">Repeat access code</string>
@@ -50,6 +98,7 @@
 	<string name="loans">Loans</string>
 	<string name="deposit_account">Deposit accounts</string>
 	<string name="other">Other</string>
+	<!--  /Settings  -->
 	
     <string name="login">Login</string>
     <string name="invalid_access_code">Invalid access code. Try again.</string>
diff --git res/xml-sv/settings.xml res/xml-sv/settings.xml
deleted file mode 100644
index 5611d6a..0000000
--- res/xml-sv/settings.xml
+++ /dev/null
@@ -1,176 +0,0 @@
-<PreferenceScreen
-	xmlns:android="http://schemas.android.com/apk/res/android">
-	<PreferenceCategory
-		android:title="Säkerhet">
-		<CheckBoxPreference
-			android:key="patternlock_enabled"
-			android:defaultValue="false"
-			android:title="Aktivera grafiskt lösenord"
-			android:summary="Skydda appen och widgets med ett grafiskt lösenord" />
-		<Preference
-			android:title="Ändra grafiskt lösenord"
-			android:summary="Ändra ditt nuvarande grafiska lösenord"
-			android:key="patternlock_change"
-			android:dependency="patternlock_enabled" />
-		<CheckBoxPreference
-			android:key="widget_blur_balance"
-			android:defaultValue="false"
-			android:title="Dölj widgetsaldo"
-			android:summary="Saldot på widgeten visas endast då du klickat på den" />
-		<ListPreference
-			android:title="Dölj saldot efter"
-			android:key="widget_blur_balance_timeout"
-			android:defaultValue="5"
-			android:entries="@array/unblurTimeoutNames"
-			android:entryValues="@array/unblurTimeoutValues"
-			android:summary="Dölj saldot igen efter angiven tid"
-			android:dependency="widget_blur_balance" />
-	</PreferenceCategory>
-	<PreferenceCategory
-		android:title="Utseende">
-		<CheckBoxPreference
-			android:key="round_widget_balance"
-			android:defaultValue="false"
-			android:title="Avrunda saldo på widgets"
-			android:summary="Visa saldot på widgets utan decimaler" />
-	</PreferenceCategory>
-	<PreferenceCategory
-		android:title="Automatiska Uppdateringar">
-		<CheckBoxPreference
-			android:key="autoupdates_enabled"
-			android:defaultValue="true"
-			android:title="Aktivera"
-			android:summary="Aktivera automatiska uppdateringar" />
-		<ListPreference
-			android:title="Uppdateringsfrekvens"
-			android:key="refresh_rate"
-			android:defaultValue="60"
-			android:entries="@array/refreshrateNames"
-			android:entryValues="@array/refreshrateValues"
-			android:dependency="autoupdates_enabled" />
-		<CheckBoxPreference
-			android:key="autoupdates_transactions_enabled"
-			android:defaultValue="true"
-			android:title="Uppdatera kontoutdrag"
-			android:summary="Uppdatera kontoutdrag vid automatiska uppdateringar" />
-	</PreferenceCategory>
-	<PreferenceCategory
-		android:title="Notifieringar">
-		<CheckBoxPreference
-			android:key="notify_on_change"
-			android:defaultValue="true"
-			android:title="Aktivera notifieringar"
-			android:summary="Notifiera vid kontoförändringar" />
-		<CheckBoxPreference
-			android:key="notify_with_vibration"
-			android:defaultValue="true"
-			android:title="Vibrera"
-			android:summary="Vibrera vid kontoförändringar"
-			android:dependency="notify_on_change" />
-		<RingtonePreference
-			android:key="notification_sound"
-			android:name="Välj ljud"
-			android:summary="Välj ett notifieringsljud"
-			android:title="Notifieringsljud"
-			android:ringtoneType="notification"
-			android:showDefault="true"
-			android:showSilent="true"
-
-			android:dependency="notify_on_change" />
-		<PreferenceScreen
-			android:key="account_types_screen"
-			android:title="Kontotyper"
-			android:summary="Visa endast notifieringar för valda kontotyper"
-			android:dependency="notify_on_change">
-			<CheckBoxPreference
-				android:key="notify_for_deposit"
-				android:defaultValue="true"
-				android:title="@string/deposit_account" />
-			<CheckBoxPreference
-				android:key="notify_for_funds"
-				android:defaultValue="false"
-				android:title="@string/loans" />
-			<CheckBoxPreference
-				android:key="notify_for_loans"
-				android:defaultValue="false"
-				android:title="@string/funds" />
-			<CheckBoxPreference
-				android:key="notify_for_ccards"
-				android:defaultValue="true"
-				android:title="@string/ccards" />
-			<CheckBoxPreference
-				android:key="notify_for_other"
-				android:defaultValue="false"
-				android:title="@string/other" />
-		</PreferenceScreen>
-		<PreferenceScreen
-			android:key="remotenotifier_screen"
-			android:title="Remote Notifier-integrering"
-			android:dependency="notify_on_change">
-			<CheckBoxPreference
-				android:key="notify_remotenotifier"
-				android:defaultValue="false"
-				android:title="Aktivera"
-				android:summary="Aktivera Remote Notifier-integrering" />
-			<Preference
-				android:title="Vad är Remote Notifier?"
-				android:summary="Läs mer om Remote Notifier på deras webbsida"
-				android:key="remotenotifier_help" />
-		</PreferenceScreen>
-		<PreferenceScreen
-			android:key="openwatch_screen"
-			android:title="OpenWatch-integrering"
-			android:dependency="notify_on_change">
-			<CheckBoxPreference
-				android:key="notify_openwatch"
-				android:defaultValue="false"
-				android:title="Aktivera"
-				android:summary="Aktivera OpenWatch-integrering" />
-			<CheckBoxPreference
-				android:key="notify_openwatch_vibrate"
-				android:defaultValue="false"
-				android:title="Vibrera"
-				android:summary="Vibrera OpenWatch-enheten" />
-			<Preference
-				android:title="Vad är OpenWatch?"
-				android:summary="Läs mer om OpenWatch på deras webbsida"
-				android:key="openwatch_help" />
-		</PreferenceScreen>
-	</PreferenceCategory>
-	<PreferenceCategory
-		android:title="Debug">
-		<PreferenceScreen
-			android:key="debug_screen_pre"
-			android:title="Debug Settings"
-			android:summary="Don't touch if you don't know what you're doing">
-			<PreferenceScreen
-				android:key="debug_screen"
-				android:title="Seriously"
-				android:summary="You might break things">
-				<CheckBoxPreference
-					android:key="debug_mode"
-					android:defaultValue="false"
-					android:title="Enable"
-					android:summary="Enable debug mode" />
-				<CheckBoxPreference
-					android:key="debug_refreshrate_in_seconds"
-					android:defaultValue="false"
-					android:title="Update freq. in sec."
-					android:summary="Update frequenzy is given in seconds instead of minutes"
-					android:dependency="debug_mode" />
-				<CheckBoxPreference
-					android:key="debug_only_testbank"
-					android:defaultValue="false"
-					android:title="Testbank only"
-					android:summary="Only auto update 'Testbank' banks"
-					android:dependency="debug_mode" />
-				<CheckBoxPreference
-					android:key="debug_coop_sendmail"
-					android:defaultValue="false"
-					android:title="Coop - Mail on error"
-					android:summary="Open your email client with the html response when Bankdroid fails to login to your Coop account."
-					android:dependency="debug_mode" />
-			</PreferenceScreen>
-		</PreferenceScreen>
-	</PreferenceCategory>
-</PreferenceScreen>
\ No newline at end of file
diff --git res/xml/settings.xml res/xml/settings.xml
index 6701158..a4a44f0 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -1,40 +1,40 @@
 <PreferenceScreen
 	xmlns:android="http://schemas.android.com/apk/res/android">
 	<PreferenceCategory
-		android:title="Security and Privacy">
+		android:title="@string/security_and_privacy">
 		<CheckBoxPreference
 			android:key="patternlock_enabled"
 			android:defaultValue="false"
-			android:title="Enable Pattern Lock"
-			android:summary="Lock the app and widgets with a pattern lock" />
+			android:title="@string/enable_patternlock_title"
+			android:summary="@string/enable_patternlock_summary" />
 		<Preference
-			android:title="Change pattern"
-			android:summary="Change your current lock pattern"
+			android:title="@string/change_patternlock_title"
+			android:summary="@string/change_patternlock_summary"
 			android:key="patternlock_change"
 			android:dependency="patternlock_enabled" />
 		<CheckBoxPreference
 			android:key="widget_blur_balance"
 			android:defaultValue="false"
-			android:title="Blur widget balance"
-			android:summary="Blur the balance on the widget, click widget to unblur for a few seconds" />
+			android:title="@string/blur_widget_title"
+			android:summary="@string/blur_widget_summary" />
 		<ListPreference
-			android:title="Unblur timeout"
+			android:title="@string/unblur_widget_timeout_title"
 			android:key="widget_blur_balance_timeout"
 			android:defaultValue="5"
 			android:entries="@array/unblurTimeoutNames"
 			android:entryValues="@array/unblurTimeoutValues"
-			android:summary="Blur the balance again after this many seconds"
+			android:summary="@string/unblur_widget_timeout_summary"
 			android:dependency="widget_blur_balance" />
 	</PreferenceCategory>
 	<PreferenceCategory
-		android:title="Automatic Updates">
+		android:title="@string/automatic_updates_title">
 		<CheckBoxPreference
 			android:key="autoupdates_enabled"
 			android:defaultValue="true"
-			android:title="Enable"
-			android:summary="Enable automatic updates" />
+			android:title="@string/autoupdates_enabled_title"
+			android:summary="@string/autoupdates_enabled_summary" />
 		<ListPreference
-			android:title="Update frequency"
+			android:title="@string/update_frequency_title"
 			android:key="refresh_rate"
 			android:defaultValue="60"
 			android:entries="@array/refreshrateNames"
@@ -43,42 +43,42 @@
 		<CheckBoxPreference
 			android:key="autoupdates_transactions_enabled"
 			android:defaultValue="true"
-			android:title="Update transaction history"
-			android:summary="Update transaction history when updating automatically" />
+			android:title="@string/update_transaction_history_title"
+			android:summary="@string/update_transaction_history_summary" />
 	</PreferenceCategory>
 	<PreferenceCategory
-		android:title="Appearance">
+		android:title="@string/appearance_title">
 		<CheckBoxPreference
 			android:key="round_widget_balance"
 			android:defaultValue="false"
-			android:title="Round widget balance"
-			android:summary="Display the balance on widgets without decimals" />
+			android:title="@string/round_widget_balance_title"
+			android:summary="@string/round_widget_balance_summary" />
 	</PreferenceCategory>
 	<PreferenceCategory
-		android:title="Notifications">
+		android:title="@string/notifications_title">
 		<CheckBoxPreference
 			android:key="notify_on_change"
 			android:defaultValue="true"
-			android:title="Enable notifications"
-			android:summary="Notify on account changes" />
+			android:title="@string/enable_notifications_title"
+			android:summary="@string/enable_notifications_summary" />
 		<CheckBoxPreference
 			android:key="notify_with_vibration"
 			android:defaultValue="true"
-			android:title="Vibrate"
-			android:summary="Vibrate on account changes"
+			android:title="@string/vibrate_title"
+			android:summary="@string/vibrate_summary"
 			android:dependency="notify_on_change" />
 		<RingtonePreference
 			android:key="notification_sound"
-			android:summary="Select notification sound"
-			android:title="Notification sound"
+			android:title="@string/notification_sound_title"
+			android:summary="@string/notification_sound_summary"
 			android:ringtoneType="notification"
 			android:showDefault="true"
 			android:showSilent="true"
-			android:dependency="notify_on_change" android:name="Select sound"/>
+			android:dependency="notify_on_change" android:name="@string/notification_sound_name"/>
 		<PreferenceScreen
 			android:key="account_types_screen"
-			android:title="Account types"
-			android:summary="Only show notifications for selected account types"
+			android:title="@string/account_types_title"
+			android:summary="@string/account_types_summary"
 			android:dependency="notify_on_change">
 			<CheckBoxPreference
 				android:key="notify_for_deposit"
@@ -103,43 +103,49 @@
 		</PreferenceScreen>
 		<PreferenceScreen
 			android:key="remotenotifier_screen"
-			android:title="Remote Notifier Integration"
+			android:title="@string/remote_notifier_title"
 			android:dependency="notify_on_change">
 			<CheckBoxPreference
 				android:key="notify_remotenotifier"
 				android:defaultValue="false"
-				android:title="Enable"
-				android:summary="Enable Remote Notifier integration" />
+				android:title="@string/remote_notifier_enable_title"
+				android:summary="@string/remote_notifier_enable_summary" />
 			<Preference
-				android:title="What is Remote Notifier?"
-				android:summary="Read more about Remote Notifier on their website"
+				android:title="@string/remote_notifier_help_title"
+				android:summary="@string/remote_notifier_help_summary"
 				android:key="remotenotifier_help" />
 		</PreferenceScreen>
 		<PreferenceScreen
 			android:key="openwatch_screen"
-			android:title="OpenWatch Integration"
+			android:title="@string/openwatch_title"
 			android:dependency="notify_on_change">
 			<CheckBoxPreference
 				android:key="notify_openwatch"
 				android:defaultValue="false"
-				android:title="Enable"
-				android:summary="Enable OpenWatch integration" />
+				android:title="@string/openwatch_enable_title"
+				android:summary="@string/openwatch_enable_summary" />
 			<CheckBoxPreference
 				android:key="notify_openwatch_vibrate"
 				android:defaultValue="false"
-				android:title="Vibrate"
-				android:summary="Vibrate the OpenWatch device" />
+				android:title="@string/openwatch_vibrate_title"
+				android:summary="@string/openwatch_vibrate_summary" />
 			<Preference
-				android:title="What is OpenWatch?"
-				android:summary="Read more about OpenWatch on their website"
+				android:title="@string/openwatch_help_title"
+				android:summary="@string/openwatch_help_summary"
 				android:key="openwatch_help" />
 		</PreferenceScreen>
 	</PreferenceCategory>
 	<PreferenceCategory
-		android:title="Share data">
-		
-	<CheckBoxPreference android:title="Enable Sharing Data" android:summary="Enable other installed apps access to your transaction history" android:key="content_provider_enabled"></CheckBoxPreference>
-<EditTextPreference android:title="API Key" android:key="content_provider_api_key" android:dependency="content_provider_enabled" android:summary="Use this key to allow access for trusted applications"></EditTextPreference>
+		android:title="@string/share_data_title">
+	<CheckBoxPreference
+		android:title="@string/share_data_enable_title"
+		android:summary="@string/share_data_enable_summary"
+		android:key="content_provider_enabled" />
+	<EditTextPreference
+		android:title="@string/api_key_title"
+		android:key="content_provider_api_key"
+		android:dependency="content_provider_enabled"
+		android:summary="@string/api_key_summary" />
 </PreferenceCategory>
 	<PreferenceCategory
 		android:title="Debug">

commit 5815d9df97fc32618993e1eb410e121452457b27
Author: liato <x@x00.us>
Date:   Sun Feb 6 05:44:20 2011 +0100

    Better login error detection for SEB. Fix username hint. Cloeses #47.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index fe865b7..c817396 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -49,7 +49,7 @@ public class SEB extends Bank {
 	private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm";
 	private static final int BANKTYPE_ID = IBankTypes.SEB;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
 	private Pattern reAccounts = Pattern.compile("/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)/(\\d{2}-\\d{2}-\\d{2})</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
@@ -91,7 +91,7 @@ public class SEB extends Bank {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			
-			if (response.contains("9000/mpo9001.aspx?P1=mps1065.htm")) {
+			if (!response.contains("1100/mps1101.aspx?X1=passWord")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		} catch (ClientProtocolException e) {

commit 3a3e84b0ee9aa1dd67fc8708fccac51410d40ea9
Author: liato <x@x00.us>
Date:   Sat Feb 5 02:20:00 2011 +0100

    Bump version to 1.6.2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 5ed4daf..de19a9f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="100" android:versionName="1.6.1">
+	android:versionCode="101" android:versionName="1.6.2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3309f2f..11e3b90 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -60,7 +60,6 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 		Collections.sort(items);
 		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);
 		BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, android.R.layout.simple_spinner_item, items);
-		//adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		spnBanks.setAdapter(adapter);
 		spnBanks.setOnItemSelectedListener(this);
 
@@ -249,5 +248,6 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	@Override
 	protected void onSaveInstanceState(Bundle outState) {
 		super.onSaveInstanceState(outState);
-	}   
+	}
+	
 }
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 673b928..85f4273 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -65,6 +65,7 @@ public class LockableActivity extends Activity {
             public void onClick(View v) {
                 Intent intent = new Intent(LockableActivity.this, MainActivity.class);
                 startActivity(intent);
+                LockableActivity.this.finish();
             }
         };
         homeButton.setOnClickListener(listener);
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 58323db..4a36cb3 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -97,12 +97,10 @@ public class WebViewActivity extends LockableActivity implements OnClickListener
                                     cookie.getExpiryDate() == null ? "" : "expires="+cookie.getExpiryDate()+"; ",
                                     cookie.getPath() == null ? "/" : cookie.getPath(),
                                     cookie.getDomain());
-                            Log.d(TAG, "Cookiestring: " + cookieString);
                             cookieManager.setCookie(cookie.getDomain(), cookieString);
                         }
                         csm.sync();
                     }
-                    Log.d("HTML", loginPackage.getHtml());
                     mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", loginPackage.getHtml(), "text/html", "utf-8", null);
                 }
               };

commit a2d1034e4b719a098c22fe71fbb93b686e749cec
Author: liato <x@x00.us>
Date:   Sat Feb 5 01:45:25 2011 +0100

    Add ability to add custom headers to Urllib. Fix for SEB.

diff --git src/com/liato/bankdroid/banking/banks/SEB.java src/com/liato/bankdroid/banking/banks/SEB.java
index dea700a..fe865b7 100644
--- src/com/liato/bankdroid/banking/banks/SEB.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -25,11 +25,11 @@ import java.util.regex.Pattern;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
-import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
@@ -76,7 +76,9 @@ public class SEB extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib();
-        response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
+        urlopen.addHeader("Referer", "https://m.seb.se/");
+        //response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
         postData.add(new BasicNameValuePair("A1", username));
         postData.add(new BasicNameValuePair("A2", password));
@@ -88,12 +90,10 @@ public class SEB extends Bank {
 		try {
 		    LoginPackage lp = preLogin();
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
 			
 			if (response.contains("9000/mpo9001.aspx?P1=mps1065.htm")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
-			
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 7ced4dc..06896bb 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -18,6 +18,7 @@ package eu.nullbyte.android.urllib;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 import org.apache.http.HttpHost;
@@ -53,6 +54,7 @@ public class Urllib {
 	private String currentURI;
 	private boolean acceptInvalidCertificates = false;
 	private String charset = HTTP.UTF_8;
+	private HashMap<String, String> headers;
 	
 	public Urllib() {
 		this(false);
@@ -63,6 +65,7 @@ public class Urllib {
 
 	public Urllib(boolean acceptInvalidCertificates, boolean allowCircularRedirects) {
 		this.acceptInvalidCertificates = acceptInvalidCertificates;
+		this.headers = new HashMap<String, String>();
     	HttpParams params = new BasicHttpParams(); 
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, this.charset);
@@ -92,17 +95,25 @@ public class Urllib {
     public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
     	this.currentURI = url;
     	String response;
+        String[] headerKeys = (String[]) this.headers.keySet().toArray(new String[headers.size()]);
+        String[] headerVals = (String[]) this.headers.values().toArray(new String[headers.size()]);
     	ResponseHandler<String> responseHandler = new BasicResponseHandler();
     	if (postData.isEmpty()) {
     		//URL urli = new URL(url); 
     		HttpGet urlConnection = new HttpGet(url);
     		urlConnection.addHeader("User-Agent", USER_AGENT);
+            for (int i = 0; i < headerKeys.length; i++) {
+                urlConnection.addHeader(headerKeys[i], headerVals[i]);
+            }
     		response = httpclient.execute(urlConnection, responseHandler, context);
     	}
     	else {
     		HttpPost urlConnection = new HttpPost(url);
     		urlConnection.setEntity(new UrlEncodedFormEntity(postData, this.charset));
     		urlConnection.addHeader("User-Agent", USER_AGENT);
+            for (int i = 0; i < headerKeys.length; i++) {
+                urlConnection.addHeader(headerKeys[i], headerVals[i]);
+            }
     		response = httpclient.execute(urlConnection, responseHandler, context); 
     	}
 
@@ -133,6 +144,23 @@ public class Urllib {
         this.charset = charset;
         HttpProtocolParams.setContentCharset(httpclient.getParams(), this.charset);
     }    
+    public void addHeader(String key, String value) {
+        this.headers.put(key, value);
+    }    
+
+    public String removeHeader(String key) {
+        return this.headers.remove(key);
+    }  
+    
+    public void clearHeaders() {
+        this.headers.clear();
+    }
+    
+    public HashMap<String, String> getHeaders() {
+        return this.headers;
+    }
+
+    
     public boolean acceptsInvalidCertificates() {
     	return acceptInvalidCertificates;
     }

commit 99480eb9f033c05bdcd0d7bc4968f84d2ede58e3
Author: liato <x@x00.us>
Date:   Sat Feb 5 01:43:41 2011 +0100

    Change the name of Statoil to Statoil Mastercard.

diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
index 027f82c..a1a70df 100644
--- src/com/liato/bankdroid/banking/banks/Statoil.java
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -24,7 +24,7 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 public class Statoil extends SEBKortBase {
 	private static final String TAG = "Statoil";
-	private static final String NAME = "Statoil";
+	private static final String NAME = "Statoil Mastercard";
 	private static final String NAME_SHORT = "statoil";
 	private static final int BANKTYPE_ID = IBankTypes.STATOIL;
 

commit d2394389fa8ad5da21ce549cd3bc7ca9c12d63b9
Author: liato <x@x00.us>
Date:   Fri Jan 28 20:27:45 2011 +0100

    Negate values for loans on lansforsakringar.

diff --git logos.psd logos.psd
index 2c327b1..8521d2a 100644
Binary files logos.psd and logos.psd differ
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index e2d1d4e..43ed038 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -202,7 +202,7 @@ public class Lansforsakringar extends Bank {
                  * 4: Debt                  1,00
                  * 
                  */                
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()), matcher.group(2).trim(), Account.LOANS));
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()).negate(), matcher.group(2).trim(), Account.LOANS));
             }
 
             // Save token for next request

commit a296bf56cc579c3d14f34e2f15c923b4a5f0908f
Author: liato <x@x00.us>
Date:   Fri Jan 28 15:01:23 2011 +0100

    Add support for SEB. Closes #40.

diff --git logos.psd logos.psd
index 5ba4029..2c327b1 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_seb.png res/drawable/logo_seb.png
new file mode 100644
index 0000000..bdae10f
Binary files /dev/null and res/drawable/logo_seb.png differ
diff --git res/values/strings.xml res/values/strings.xml
index d30299e..423ca11 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -84,7 +84,7 @@
     <string name="thanks_to">Thanks to</string>
     <string name="thanks"> 
     Wendell Fernandes (Icon)
-    \nKingcool (ICA Banken)
+    \nKingcool (ICA Banken &amp; SEB)
     \ngrief (Länsförsäkringar)
     \neinand (Länsförsäkringar)
     \nAnders Widén (Länsförsäkringar)
@@ -118,6 +118,7 @@
 	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
 	\nfiretech (Hemköp)
 	\nebjsv (PayPal)
+	\nHenrik (SEB)
      </string>
      
      
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 54dfb20..11e6118 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -44,6 +44,7 @@ import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
 import com.liato.bankdroid.banking.banks.Rikslunchen;
+import com.liato.bankdroid.banking.banks.SEB;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -106,6 +107,8 @@ public class BankFactory {
             return new Rikslunchen(context);            
         case IBankTypes.HEMKOP:
             return new Hemkop(context);            
+        case IBankTypes.SEB:
+            return new SEB(context);            
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -137,6 +140,7 @@ public class BankFactory {
         banks.add(new EurobonusMastercard(context));
         banks.add(new Rikslunchen(context));
         banks.add(new Hemkop(context));
+        banks.add(new SEB(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index 4090f1d..afce51f 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -95,12 +95,10 @@ public class Nordea extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
 		try {
 		    LoginPackage lp = preLogin();
 			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
 			
 			if (response.contains("felaktiga uppgifter")) {
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/SEB.java
similarity index 51%
copy from src/com/liato/bankdroid/banking/banks/Nordea.java
copy to src/com/liato/bankdroid/banking/banks/SEB.java
index 4090f1d..dea700a 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/SEB.java
@@ -42,23 +42,21 @@ import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
-public class Nordea extends Bank {
-	private static final String TAG = "Nordea";
-	private static final String NAME = "Nordea";
-	private static final String NAME_SHORT = "nordea";
-	private static final String URL = "https://mobil.nordea.se/";
-	private static final int BANKTYPE_ID = IBankTypes.NORDEA;
+public class SEB extends Bank {
+	private static final String TAG = "SEB";
+	private static final String NAME = "SEB";
+	private static final String NAME_SHORT = "seb";
+	private static final String URL = "https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm";
+	private static final int BANKTYPE_ID = IBankTypes.SEB;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 	
-	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
-	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reCards = Pattern.compile("/card/details\\.html\\?id=(\\d{1,})[^\"]*\".*?>\\s*<span[^>]*>\\s*<span>([^<]+)</span>\\s*<span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
+	private Pattern reAccounts = Pattern.compile("/cgi-bin/pts3/mps/1100/mps1102\\.aspx\\?M1=show&amp;P1=([^&]+)&amp;P2=1&amp;P4=1\">([^<]+)</a></td>\\s*</tr>\\s*<tr[^>]+>\\s*<td>[^<]+</td>\\s*<td[^>]+>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>\\s*", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"name\">([^/]+)/(\\d{2}-\\d{2}-\\d{2})</span>\\s*<span\\s*id=\"MPSMaster_MainPlaceHolder_repAccountTransactions[^\"]+\"\\s*class=\"value\">([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	
+	private String response = null;
 
-	public Nordea(Context context) {
+	public SEB(Context context) {
 		super(context);
 		super.TAG = TAG;
 		super.NAME = NAME;
@@ -66,11 +64,10 @@ public class Nordea extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
         super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
-	public Nordea(String username, String password, Context context) throws BankException, LoginException {
+	public SEB(String username, String password, Context context) throws BankException, LoginException {
 		this(context);
 		this.update(username, password);
 	}
@@ -79,31 +76,21 @@ public class Nordea extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib();
-        Matcher matcher;
-        String response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-        matcher = reCSRF.matcher(response);
-        if (!matcher.find()) {
-            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-        }
-        String csrftoken = matcher.group(1);
+        response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mpo/9000/mpo9001.aspx?P1=logon.htm");
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        postData.add(new BasicNameValuePair("xyz", username));
-        postData.add(new BasicNameValuePair("zyx", password));
-        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-        return new LoginPackage(urlopen, postData, response, "https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+        postData.add(new BasicNameValuePair("A1", username));
+        postData.add(new BasicNameValuePair("A2", password));
+        return new LoginPackage(urlopen, postData, response, "https://m.seb.se/cgi-bin/pts3/mps/1000/mps1001b.aspx");
     }
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
 		try {
 		    LoginPackage lp = preLogin();
-			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
 			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
-			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
+			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
 			
-			if (response.contains("felaktiga uppgifter")) {
+			if (response.contains("9000/mpo9001.aspx?P1=mps1065.htm")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			
@@ -123,35 +110,23 @@ public class Nordea extends Bank {
 		}
 		
 		urlopen = login();
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+			response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1101.aspx?X1=passWord");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: ID                    GJmQRqlrOPmM++1zf50d6Q==
+                 * 2: Name                  Personkonto
+                 * 3: Amount                2.208,03
+                 * 
+                 */   			    
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 			
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
-			matcher = reFundsLoans.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f:"+matcher.group(1).trim(), -1L, Account.FUNDS));
-			}
-
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
-			matcher = reFundsLoans.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l:"+matcher.group(1).trim(), -1L, Account.LOANS));
-			}
-
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
-			matcher = reCards.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c:"+matcher.group(1).trim(), -1L, Account.CCARD));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
@@ -165,11 +140,6 @@ public class Nordea extends Bank {
 		finally {
 		    super.updateComplete();
 		}
-		
-        // Demo account to use with screenshots
-        //accounts.add(new Account("Personkonto", Helpers.parseBalance("7953.37"), "1"));
-        //accounts.add(new Account("Kapitalkonto", Helpers.parseBalance("28936.08"), "0"));
-
 	}
 
 	@Override
@@ -180,16 +150,21 @@ public class Nordea extends Bank {
 		int accType = account.getType();
 		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
 
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
+			response = urlopen.open("https://m.seb.se/cgi-bin/pts3/mps/1100/mps1102.aspx?M1=show&P2=1&P4=1&P1=" + account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {
-				transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Transaction           Swedbank Atm
+                 * 2: Date                  11-01-14
+                 * 3: Amount                -100,00 
+                 * 
+                 */                 
+				transactions.add(new Transaction("20"+Html.fromHtml(matcher.group(2)).toString().trim(), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 618babf..de01a8e 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -46,5 +46,6 @@ public interface IBankTypes {
     public final static int EUROBONUSMASTERCARD = 21;
     public final static int RIKSLUNCHEN = 22;
     public final static int HEMKOP = 23;
+    public final static int SEB = 24;
 
 }
\ No newline at end of file

commit 5f1480e2323f43b1153a976f270aa7b87f03a3a7
Author: liato <x@x00.us>
Date:   Fri Jan 28 13:44:01 2011 +0100

    Change pattern lock background.

diff --git res/layout/confirm_lock_pattern.xml res/layout/confirm_lock_pattern.xml
index 828d7e7..c48d232 100644
--- res/layout/confirm_lock_pattern.xml
+++ res/layout/confirm_lock_pattern.xml
@@ -19,7 +19,7 @@
     android:orientation="vertical"
     android:layout_width="wrap_content"
     android:layout_height="fill_parent"
-    android:background="@color/black">
+    android:background="@drawable/background_repeat">
 
     <TextView android:id="@+id/headerText"
         android:layout_width="fill_parent"
@@ -35,10 +35,10 @@
     <com.liato.bankdroid.lockpattern.LockPatternView android:id="@+id/lockPattern"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />
-    <View
+    <!-- <View
          android:background="@*android:drawable/code_lock_bottom"
          android:layout_width="fill_parent"
-         android:layout_height="8dip" />
+         android:layout_height="8dip" /> -->
 
     <TextView android:id="@+id/footerText"
         android:layout_width="fill_parent"
diff --git src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
index 60b54de..4e974d6 100644
--- src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
+++ src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
@@ -367,8 +367,8 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
      * @see #onActivityResult(int, int, android.content.Intent)
      */
     protected void confirmPattern() {
-        final Intent intent = new Intent();
-        intent.setClassName("com.liato.bankdroid", "com.liato.bankdroid.ConfirmLockPattern");
+        final Intent intent = new Intent(this, ConfirmLockPattern.class);
+        //intent.setClassName("com.liato.bankdroid.lockpattern", "com.liato.bankdroid.lockpattern.ConfirmLockPattern");
         startActivityForResult(intent, 55);
     }
 

commit c9a01aec6ee940343440ed3be302263c25b4e71d
Author: liato <x@x00.us>
Date:   Fri Jan 28 11:00:26 2011 +0100

    Notification test button.

diff --git res/raw/swedbank_transactions.htm res/raw/swedbank_transactions.htm
new file mode 100644
index 0000000..c5e9440
--- /dev/null
+++ res/raw/swedbank_transactions.htm
@@ -0,0 +1,123 @@
+
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> 
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="sv"> 
+  <head> 
+    <title>Swedbank mobil</title> 
+    <meta http-equiv="Content-Type" content="application/vnd.wap.xhtml+xml; charset=iso-8859-1" /> 
+    <meta http-equiv="Content-Style-Type" content="text/css" /> 
+    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/> 
+    <meta name="format-detection" content="telephone=no" /> 
+    <link href="/banking/swedbank/css/style.css" rel="stylesheet" type="text/css" media="all" /> 
+        <link href="/banking/swedbank/css/screen.css" rel="stylesheet" type="text/css" media="Screen" /> 
+            <link href="/banking/swedbank/css/iphone.css" rel="stylesheet" type="text/css" media="Screen" /> 
+    <link rel="apple-touch-icon" href="/banking/swedbank/images/icon.png"/> 
+      </head> 
+    <body> 
+      <div id="header"> 
+            <img class="logo" alt="Swedbank" src="/banking/swedbank/images/18114_mynt_hk_2.png"/> 
+          </div> 
+    <div id="content"> 
+<h1> Privatkont </h1> 
+<ul class="grouped">    
+  <li class="first">Clearingnummer<br/><span class="secondary">1234-5</span></li> 
+  <li>Kontonummer<br/><span class="secondary">123 456 789-0</span></li> 
+  <li>Tillg. belopp<br/><span class="secondary">1 234</span></li>          
+</ul> 
+<br /> 
+                              <h2>De senaste transaktionerna</h2> 
+<ul class="grouped"> 
+  
+              <li  class="first" > 
+        <div class="trans-date"> 11-01-28 </div> 
+        <div class="trans-subject"> SF BIO AB </div> 
+        <div class="trans-amount"> -375 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-28 </div> 
+        <div class="trans-subject"> Ins&auml;ttning </div> 
+        <div class="trans-amount"> 1 100 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-25 </div> 
+        <div class="trans-subject"> MCDONALDS </div> 
+        <div class="trans-amount"> -75 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-25 </div> 
+        <div class="trans-subject"> ICA SUPERMARKET </div> 
+        <div class="trans-amount"> -45 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-25 </div> 
+        <div class="trans-subject"> LöN </div> 
+        <div class="trans-amount"> 9876.54 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-24 </div> 
+        <div class="trans-subject"> COOP KONSUM</div> 
+        <div class="trans-amount"> -24 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-21 </div> 
+        <div class="trans-subject"> KONTANTEN DIREKT </div> 
+        <div class="trans-amount"> -500 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-19 </div> 
+        <div class="trans-subject"> ICA KVANTUM </div> 
+        <div class="trans-amount"> -17 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-18 </div> 
+        <div class="trans-subject"> COOP KONSUM </div> 
+        <div class="trans-amount"> -84 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-17 </div> 
+        <div class="trans-subject"> ICA KVANTUM </div> 
+        <div class="trans-amount"> -91 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-17 </div> 
+        <div class="trans-subject"> CLAS OHLSON AB </div> 
+        <div class="trans-amount"> -69 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-17 </div> 
+        <div class="trans-subject"> BURGER KING </div> 
+        <div class="trans-amount"> -72 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-14 </div> 
+        <div class="trans-subject"> CDON AB </div> 
+        <div class="trans-amount"> -384 </div> 
+      </li> 
+                <li > 
+        <div class="trans-date"> 11-01-14 </div> 
+        <div class="trans-subject"> Överföring </div> 
+        <div class="trans-amount"> 3000 </div> 
+      </li> 
+      </ul> 
+ 
+  <p class="trans-nav"> 
+      &nbsp;
+        <a href="?id=0&amp;action=next" class="trans-next">N&auml;sta</a> 
+    </p> 
+ 
+</div> 
+<div id="nav"> 
+        <a href="/banking/swedbank/accounts.html" class="back">Tillbaka</a>&nbsp; &nbsp;
+    <a href="/banking/swedbank/logout.html" class="logout">Logga ut</a> 
+</div> 
+    <div id="footer"><p>Swedbank</p></div> 
+  </body> 
+</html> 
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index b7e9f73..3979b77 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -117,6 +117,7 @@
 	\nPMC (Rikslunchen)
 	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
 	\nfiretech (Hemköp)
+	\nebjsv (PayPal)
 	</string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index 4e4156f..d30299e 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -117,6 +117,7 @@
 	\nPMC (Rikslunchen)
 	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
 	\nfiretech (Hemköp)
+	\nebjsv (PayPal)
      </string>
      
      
diff --git res/xml/settings.xml res/xml/settings.xml
index d15e9b8..6701158 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -173,7 +173,11 @@
 					android:defaultValue="false"
 					android:title="Coop - Mail on error"
 					android:summary="Open your email client with the html response when Bankdroid fails to login to your Coop account."
-					android:dependency="debug_mode" />					
+					android:dependency="debug_mode" />
+			<Preference
+				android:title="Test notification"
+				android:summary="A demo notification"
+				android:key="test_notification" />								
 			</PreferenceScreen>
 		</PreferenceScreen>
 	</PreferenceCategory>
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 5bbd4fd..b787f27 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -52,7 +52,8 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 		(findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
 		(findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
 		(findPreference("autoupdates_enabled")).setOnPreferenceClickListener(this);
-		(findPreference("notification_sound")).setOnPreferenceClickListener(this);
+        (findPreference("notification_sound")).setOnPreferenceClickListener(this);
+        (findPreference("test_notification")).setOnPreferenceClickListener(this);
 		final CheckBoxPreference patternLock = ((CheckBoxPreference)findPreference("patternlock_enabled"));
 		patternLock.setOnPreferenceClickListener(this);
 		// Check the pattern lock check box if the lock pattern is enabled
@@ -101,6 +102,16 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
 					Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));
 			return true;
 		}
+		else if ("test_notification".equals(prefKey)) {
+            Log.d(TAG, "Sending test notification.");
+            AutoRefreshService.showNotification(
+                    "Personkonto: -143,50 SEK (8 351,00 SEK)",
+                    R.drawable.logo_swedbank,
+                    "Familjekonto",
+                    "Swedbank",
+                    this);      
+		    return true;
+		}
 		return false;
 	}
 
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index be593d2..c830807 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -55,11 +55,8 @@ public class AutoRefreshService extends Service {
 	public final static String ACTION_MAIN_SHOW_TRANSACTIONS = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
 	public final static String BROADCAST_TRANSACTIONS_UPDATED = "com.liato.bankdroid.action.TRANSACTIONS";
 
-	NotificationManager notificationManager;
-
 	@Override
 	public void onCreate() {
-		notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
 		new DataRetrieverTask().execute();
 	}
 
@@ -72,14 +69,15 @@ public class AutoRefreshService extends Service {
 		return null;
 	}
 
-	private void showNotification(final String text, final int icon,
-			final String title, final String bank) {
+	public static void showNotification(final String text, final int icon,
+			final String title, final String bank, Context context) {
 		final SharedPreferences prefs = PreferenceManager
-				.getDefaultSharedPreferences(this);
+				.getDefaultSharedPreferences(context);
 		if (!prefs.getBoolean("notify_on_change", true)) {
 			return;
 		}
 
+        final NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
 		final Notification notification = new Notification(icon, text,
 				System.currentTimeMillis());
 		// Remove notification from statusbar when clicked
@@ -99,10 +97,10 @@ public class AutoRefreshService extends Service {
 			notification.vibrate = vib;
 			// notification.defaults |= Notification.DEFAULT_VIBRATE;
 		}
-		final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
-				new Intent(this, MainActivity.class), 0);
+		final PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
+				new Intent(context, MainActivity.class), 0);
 
-		notification.setLatestEventInfo(this, title, text, contentIntent);
+		notification.setLatestEventInfo(context, title, text, contentIntent);
 
 		notificationManager.notify(R.id.about, notification);
 
@@ -112,7 +110,7 @@ public class AutoRefreshService extends Service {
 			final Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
 			i.putExtra("title", String.format("%s (%s)", bank, title));
 			i.putExtra("description", text);
-			sendBroadcast(i);
+			context.sendBroadcast(i);
 		}
 
 		// Broadcast to OpenWatch if enabled
@@ -126,7 +124,7 @@ public class AutoRefreshService extends Service {
 			}
 			i.putExtra("line1", String.format("%s (%s)", bank, title));
 			i.putExtra("line2", text);
-			sendBroadcast(i);
+			context.sendBroadcast(i);
 		}
 
 	}
@@ -242,7 +240,8 @@ public class AutoRefreshService extends Service {
 														+ ")",
 												bank.getImageResource(),
 												bank.getDisplayName(),
-												bank.getName());
+												bank.getName(),
+												AutoRefreshService.this);
 									}
 
 									refreshWidgets = true;
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index d06ddee..4090f1d 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -121,38 +121,32 @@ public class Nordea extends Bank {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
+		
 		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
-		    
-		    Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 			
-			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
-
 			matcher = reFundsLoans.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f:"+matcher.group(1).trim(), -1L, Account.FUNDS));
 			}
 
-			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
-			
 			matcher = reFundsLoans.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l:"+matcher.group(1).trim(), -1L, Account.LOANS));
 			}
-			matcher = reCards.matcher(response);
-			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
+
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
+			matcher = reCards.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c:"+matcher.group(1).trim(), -1L, Account.CCARD));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
@@ -161,10 +155,6 @@ public class Nordea extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-			
-			// Konungens konto
-			//accounts.add(new Account("Personkonto", Helpers.parseBalance("568268.37"), "1"));
-			//accounts.add(new Account("Kapitalkonto", Helpers.parseBalance("5789002.00"), "0"));
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
@@ -175,6 +165,11 @@ public class Nordea extends Bank {
 		finally {
 		    super.updateComplete();
 		}
+		
+        // Demo account to use with screenshots
+        //accounts.add(new Account("Personkonto", Helpers.parseBalance("7953.37"), "1"));
+        //accounts.add(new Account("Kapitalkonto", Helpers.parseBalance("28936.08"), "0"));
+
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 388c30d..9eb7642 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -144,9 +144,6 @@ public class Swedbank extends Bank {
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-			// Konungens konto
-			//accounts.add(new Account("Personkonto", Helpers.parseBalance("85351"), "0"));
-			//accounts.add(new Account("Sparkonto", Helpers.parseBalance("8590700"), "1"));
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
@@ -157,6 +154,9 @@ public class Swedbank extends Bank {
 		finally {
 	      super.updateComplete();
 		}
+        // Demo account to use with screenshots
+        //accounts.add(new Account("Personkonto", Helpers.parseBalance("8351"), "0"));
+        //accounts.add(new Account("Sparkonto", Helpers.parseBalance("59070"), "1"));
 	}
 	
 	@Override
@@ -182,5 +182,26 @@ public class Swedbank extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
+
+		// Demo transactions to use with screenshots
+		/*
+		try {
+            response = IOUtils.toString(context.getResources().openRawResource(R.raw.swedbank_transactions));
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+            }
+            account.setTransactions(transactions);
+        }
+        catch (NotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        */
 	}
 }

commit 484b3394b10fa3767f1a5458fd4c393fc8255234
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Mon Jan 24 23:20:27 2011 +0100

    Fixed bug with the broadcasted accountId that was not correct which
    meant no transaction history.
    
    Made sure the broadcast is also sent when adding a new bank.
    
    Change-Id: Ic7a9e667a5e809832a80758d9b0778728a297de7

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3309f2f..889ca33 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -24,10 +24,12 @@ import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.preference.PreferenceManager;
 import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -42,51 +44,57 @@ import android.widget.Spinner;
 import android.widget.TextView;
 
 import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.BankFactory;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
-public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
+public class BankEditActivity extends LockableActivity implements
+		OnClickListener, OnItemSelectedListener {
 	private final static String TAG = "AccountActivity";
 	private Bank SELECTED_BANK;
 	private long BANKID = -1;
 
 	@Override
-	public void onCreate(Bundle savedInstanceState) {
+	public void onCreate(final Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.bank);
-		ArrayList<Bank> items = BankFactory.listBanks(this);
+		final ArrayList<Bank> items = BankFactory.listBanks(this);
 		Collections.sort(items);
-		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);
-		BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, android.R.layout.simple_spinner_item, items);
-		//adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+		final Spinner spnBanks = (Spinner) findViewById(R.id.spnBankeditBanklist);
+		final BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(
+				this, android.R.layout.simple_spinner_item, items);
+		// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		spnBanks.setAdapter(adapter);
 		spnBanks.setOnItemSelectedListener(this);
 
 		findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
 		findViewById(R.id.btnSettingsOk).setOnClickListener(this);
 
-		Bundle extras = getIntent().getExtras(); 
+		final Bundle extras = getIntent().getExtras();
 		if (extras != null) {
 			BANKID = extras.getLong("id", -1);
 			if (BANKID != -1) {
-				Bank bank = BankFactory.bankFromDb(BANKID, this, false);
+				final Bank bank = BankFactory.bankFromDb(BANKID, this, false);
 				if (bank != null) {
-					((EditText)findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
-                    ((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
-                    ((EditText)findViewById(R.id.edtBankeditCustomName)).setText(bank.getCustomName());
-                    
-					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
+					((EditText) findViewById(R.id.edtBankeditUsername))
+							.setText(bank.getUsername());
+					((EditText) findViewById(R.id.edtBankeditPassword))
+							.setText(bank.getPassword());
+					((EditText) findViewById(R.id.edtBankeditCustomName))
+							.setText(bank.getCustomName());
+
+					final TextView errorDesc = (TextView) findViewById(R.id.txtErrorDesc);
 					if (bank.isDisabled()) {
 						errorDesc.setVisibility(View.VISIBLE);
-					}
-					else {
+					} else {
 						errorDesc.setVisibility(View.INVISIBLE);
 					}
 					SELECTED_BANK = bank;
 					for (int i = 0; i < items.size(); i++) {
-						if (bank.getBanktypeId() == items.get(i).getBanktypeId()) {
+						if (bank.getBanktypeId() == items.get(i)
+								.getBanktypeId()) {
 							spnBanks.setSelection(i);
 							break;
 						}
@@ -97,14 +105,19 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	}
 
 	@Override
-	public void onClick(View v) {
+	public void onClick(final View v) {
 		if (v.getId() == R.id.btnSettingsCancel) {
 			this.finish();
-		}
-		else if (v.getId() == R.id.btnSettingsOk){
-			SELECTED_BANK.setUsername(((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim());
-            SELECTED_BANK.setPassword(((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
-            SELECTED_BANK.setCustomName(((EditText) findViewById(R.id.edtBankeditCustomName)).getText().toString().trim());
+		} else if (v.getId() == R.id.btnSettingsOk) {
+			SELECTED_BANK
+					.setUsername(((EditText) findViewById(R.id.edtBankeditUsername))
+							.getText().toString().trim());
+			SELECTED_BANK
+					.setPassword(((EditText) findViewById(R.id.edtBankeditPassword))
+							.getText().toString().trim());
+			SELECTED_BANK
+					.setCustomName(((EditText) findViewById(R.id.edtBankeditCustomName))
+							.getText().toString().trim());
 			SELECTED_BANK.setDbid(BANKID);
 			new DataRetrieverTask(this, SELECTED_BANK).execute();
 		}
@@ -112,125 +125,156 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	}
 
 	@Override
-	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
-		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
-        EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
-        TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
-        TextView txtPassword = (TextView)findViewById(R.id.txtBankeditPassword);
-        
+	public void onItemSelected(final AdapterView<?> parentView,
+			final View selectedItemView, final int pos, final long id) {
+		SELECTED_BANK = (Bank) parentView.getItemAtPosition(pos);
+		final EditText edtUsername = (EditText) findViewById(R.id.edtBankeditUsername);
+		final EditText edtPassword = (EditText) findViewById(R.id.edtBankeditPassword);
+		final TextView txtUsername = (TextView) findViewById(R.id.txtBankeditUsername);
+		final TextView txtPassword = (TextView) findViewById(R.id.txtBankeditPassword);
+
 		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
 		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
 		edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+		edtPassword.setTransformationMethod(PasswordTransformationMethod
+				.getInstance());
 		edtPassword.setTypeface(Typeface.MONOSPACE);
-        txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
-        txtPassword.setText(SELECTED_BANK.getInputTitlePassword());
-		
-        if (SELECTED_BANK.isInputUsernameHidden()) {
-            edtUsername.setVisibility(View.GONE);
-            txtUsername.setVisibility(View.GONE);
-        }
-        else {
-            edtUsername.setVisibility(View.VISIBLE);
-            txtUsername.setVisibility(View.VISIBLE);
-        }
-        
-        if (SELECTED_BANK.isInputPasswordHidden()) {
-            edtPassword.setVisibility(View.GONE);
-            txtPassword.setVisibility(View.GONE);
-        }
-        else {
-            edtPassword.setVisibility(View.VISIBLE);
-            txtPassword.setVisibility(View.VISIBLE);
-        }        
+		txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
+		txtPassword.setText(SELECTED_BANK.getInputTitlePassword());
+
+		if (SELECTED_BANK.isInputUsernameHidden()) {
+			edtUsername.setVisibility(View.GONE);
+			txtUsername.setVisibility(View.GONE);
+		} else {
+			edtUsername.setVisibility(View.VISIBLE);
+			txtUsername.setVisibility(View.VISIBLE);
+		}
+
+		if (SELECTED_BANK.isInputPasswordHidden()) {
+			edtPassword.setVisibility(View.GONE);
+			txtPassword.setVisibility(View.GONE);
+		} else {
+			edtPassword.setVisibility(View.VISIBLE);
+			txtPassword.setVisibility(View.VISIBLE);
+		}
 	}
 
 	@Override
-	public void onNothingSelected(AdapterView<?> arg) {
+	public void onNothingSelected(final AdapterView<?> arg) {
 	}
 
 	private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
-		private int resource;
+		private final int resource;
+
 		@Override
-		public View getView(int position, View convertView, ViewGroup parent) {
+		public View getView(final int position, View convertView,
+				final ViewGroup parent) {
 			if (convertView == null) {
-				convertView = ((LayoutInflater)super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(resource, parent, false);
+				convertView = ((LayoutInflater) super.getContext()
+						.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
+						.inflate(resource, parent, false);
 			}
-			((TextView)convertView).setText(((Bank)getItem(position)).getName());
-			return convertView;			
+			((TextView) convertView).setText(((Bank) getItem(position))
+					.getName());
+			return convertView;
 		}
 
-		public BankSpinnerAdapter(Context context, int textViewResourceId, List<T> items) {
+		public BankSpinnerAdapter(final Context context,
+				final int textViewResourceId, final List<T> items) {
 			super(context, textViewResourceId, items);
 			resource = textViewResourceId;
 		}
 
 		@Override
-		public View getDropDownView(int position, View convertView,
-				ViewGroup parent) {
+		public View getDropDownView(final int position, View convertView,
+				final ViewGroup parent) {
 			if (convertView == null) {
-				convertView = ((LayoutInflater)super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
+				convertView = ((LayoutInflater) super.getContext()
+						.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
+						.inflate(android.R.layout.simple_spinner_dropdown_item,
+								parent, false);
 			}
-			((TextView)convertView).setText(((Bank)getItem(position)).getName());
+			((TextView) convertView).setText(((Bank) getItem(position))
+					.getName());
 			return convertView;
 		}
 
-
 	}
+
 	private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
-		private final ProgressDialog dialog = new ProgressDialog(BankEditActivity.this);
+		private final ProgressDialog dialog = new ProgressDialog(
+				BankEditActivity.this);
 		private Exception exc = null;
-		private Bank bank;
-		private BankEditActivity context;
-		private Resources res;
+		private final Bank bank;
+		private final BankEditActivity context;
+		private final Resources res;
 
-		public DataRetrieverTask(BankEditActivity context, Bank bank) {
+		public DataRetrieverTask(final BankEditActivity context, final Bank bank) {
 			this.context = context;
 			this.res = context.getResources();
 			this.bank = bank;
 		}
+
+		@Override
 		protected void onPreExecute() {
 			this.dialog.setMessage(res.getText(R.string.logging_in));
 			this.dialog.show();
 		}
 
+		@Override
 		protected Void doInBackground(final String... args) {
 			try {
-				Log.d(TAG, "Updating "+bank);
+				Log.d(TAG, "Updating " + bank);
 				bank.update();
 				bank.updateAllTransactions();
 				bank.closeConnection();
-				Log.d(TAG, "Saving "+bank);
+				Log.d(TAG, "Saving " + bank);
 				bank.save();
-				Log.d(TAG, "Disabled: "+bank.isDisabled());
-			} 
-			catch (BankException e) {
+				Log.d(TAG, "Disabled: " + bank.isDisabled());
+
+				// Transactions updated.
+				final SharedPreferences prefs = PreferenceManager
+						.getDefaultSharedPreferences(getBaseContext());
+				if (prefs.getBoolean("content_provider_enabled", false)) {
+					final ArrayList<Account> accounts = bank.getAccounts();
+					for (final Account account : accounts) {
+						AutoRefreshService.broadcastTransactionUpdate(
+								getBaseContext(), bank.getDbId(),
+								account.getId());
+					}
+				}
+			} catch (final BankException e) {
 				this.exc = e;
-			} catch (LoginException e) {
+			} catch (final LoginException e) {
 				this.exc = e;
 			}
 			return null;
 		}
 
+		@Override
 		protected void onPostExecute(final Void unused) {
 			AutoRefreshService.sendWidgetRefresh(context);
 			if (this.dialog.isShowing()) {
 				this.dialog.dismiss();
 			}
 			if (this.exc != null) {
-				AlertDialog.Builder builder = new AlertDialog.Builder(BankEditActivity.this);
-				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
-						dialog.cancel();
-					}
-				});
-				AlertDialog alert = builder.create();
+				final AlertDialog.Builder builder = new AlertDialog.Builder(
+						BankEditActivity.this);
+				builder.setMessage(this.exc.getMessage())
+						.setTitle(
+								res.getText(R.string.could_not_create_account))
+						.setIcon(android.R.drawable.ic_dialog_alert)
+						.setNeutralButton("Ok",
+								new DialogInterface.OnClickListener() {
+									public void onClick(
+											final DialogInterface dialog,
+											final int id) {
+										dialog.cancel();
+									}
+								});
+				final AlertDialog alert = builder.create();
 				alert.show();
-			}
-			else {
+			} else {
 				context.finish();
 			}
 		}
@@ -247,7 +291,7 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	}
 
 	@Override
-	protected void onSaveInstanceState(Bundle outState) {
+	protected void onSaveInstanceState(final Bundle outState) {
 		super.onSaveInstanceState(outState);
-	}   
+	}
 }
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index 46e32fa..ea5a5ea 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -112,7 +112,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 				final ArrayList<Account> accounts = bank.getAccounts();
 				for (final Account account : accounts) {
 					AutoRefreshService.broadcastTransactionUpdate(parent,
-							account);
+							bank.getDbId(), account.getId());
 				}
 			}
 		}
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index be593d2..567bf2c 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -256,6 +256,15 @@ public class AutoRefreshService extends Service {
 					}
 					bank.closeConnection();
 					db.updateBank(bank);
+
+					// Send update for all accounts since we're overwriting the
+					// database transaction history
+					if (prefs.getBoolean("content_provider_enabled", false)) {
+						for (final Account account : bank.getAccounts()) {
+							broadcastTransactionUpdate(getBaseContext(),
+									bank.getDbId(), account.getId());
+						}
+					}
 				} catch (final BankException e) {
 					// Refresh widgets if an update fails
 					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
@@ -268,20 +277,13 @@ public class AutoRefreshService extends Service {
 				}
 			}
 
-			// Sending updates for all accounts, because we overwrite everything
-			// at this point.
-			if (prefs.getBoolean("content_provider_enabled", false)) {
-				for (final Account account : accounts.values()) {
-					broadcastTransactionUpdate(getBaseContext(), account);
-				}
-			}
-
 			if (refreshWidgets) {
 				final Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
 				sendBroadcast(updateIntent);
 				sendWidgetRefresh(AutoRefreshService.this);
 			}
 			db.close();
+
 			return null;
 		}
 
@@ -306,9 +308,9 @@ public class AutoRefreshService extends Service {
 	}
 
 	public static void broadcastTransactionUpdate(final Context context,
-			final Account account) {
+			final long bankId, final String accountId) {
 		final Intent i = new Intent(BROADCAST_TRANSACTIONS_UPDATED);
-		i.putExtra("accountId", account.getId());
+		i.putExtra("accountId", new Long(bankId).toString() + "_" + accountId);
 		context.sendBroadcast(i);
 	}
 
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index 2ad9523..c0971d0 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -241,7 +241,7 @@ public abstract class Bank implements Comparable<Bank>, IBankTypes {
     public void save() {
         DBAdapter db = new DBAdapter(context);
         db.open();
-        db.updateBank(this);
+        dbid = db.updateBank(this); // Update ID on insert as well.
         db.close();
     }
 

commit 9c3b58830b447896d66f005a16c0c907c53ef36d
Author: liato <x@x00.us>
Date:   Thu Jan 20 12:25:43 2011 +0100

    Add support for PayPal business accounts.

diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 7cec132..62ab052 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -51,7 +51,7 @@ public class PayPal extends Bank {
 	private static final boolean STATIC_BALANCE = true;
 	
 	private Pattern reFormAction = Pattern.compile("<form.*?login_form.*?action=\"([^\"]+)\".*?>", Pattern.CASE_INSENSITIVE);
-	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*<span\\s*class=\"balance\">\\s*<[^<]+>[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*(?:</strong>)?<span\\s*class=\"balance\">[^<]+<[^<]+>\\s*(?:<strong>)?[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*(?:</strong>)?\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
 	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	public PayPal(Context context) {

commit abc6d74fd6132dc2a9fb808900ae0a00e1c819ad
Author: liato <x@x00.us>
Date:   Thu Jan 20 12:09:02 2011 +0100

    ICA Banken: Only throw a LoginException if the error message is about the username or password.

diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index ee6b1f2..ceff363 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -107,7 +107,13 @@ public class ICABanken extends Bank {
 			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			Matcher matcher = reError.matcher(response);
 			if (matcher.find()) {
-				throw new LoginException(Html.fromHtml(matcher.group(1).trim()).toString());
+			    String errormsg = Html.fromHtml(matcher.group(1).trim()).toString();
+			    if (errormsg.contains("ord eller personnummer") || errormsg.contains("et alternativ") || errormsg.contains("fyra siffror")) {
+			        throw new LoginException(errormsg);    
+			    }
+			    else {
+	                 throw new BankException(errormsg);    
+			    }
 			}
 		}
 		catch (ClientProtocolException e) {
@@ -133,7 +139,6 @@ public class ICABanken extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
-			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_oversikt.htm");
 			matcher = reBalanceSald.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));

commit 019a216f0e48fd611a6855474be882b6ca15c1cb
Author: liato <x@x00.us>
Date:   Thu Jan 20 11:58:10 2011 +0100

    Use the correct charset for Swedbank. Closes #29.

diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index 52237e6..388c30d 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -25,6 +25,7 @@ import java.util.regex.Pattern;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
 
 import android.content.Context;
 import android.text.Html;
@@ -75,6 +76,7 @@ public class Swedbank extends Bank {
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib();
+        urlopen.setContentCharset(HTTP.ISO_8859_1);
         Matcher matcher;
         String response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
         matcher = reCSRF.matcher(response);
diff --git src/eu/nullbyte/android/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
index 93a2f56..7ced4dc 100644
--- src/eu/nullbyte/android/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -52,6 +52,7 @@ public class Urllib {
 	private HttpContext context;
 	private String currentURI;
 	private boolean acceptInvalidCertificates = false;
+	private String charset = HTTP.UTF_8;
 	
 	public Urllib() {
 		this(false);
@@ -64,7 +65,7 @@ public class Urllib {
 		this.acceptInvalidCertificates = acceptInvalidCertificates;
     	HttpParams params = new BasicHttpParams(); 
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
-        HttpProtocolParams.setContentCharset(params, "UTF-8");
+        HttpProtocolParams.setContentCharset(params, this.charset);
         params.setBooleanParameter("http.protocol.expect-continue", false);
         if (allowCircularRedirects) params.setBooleanParameter("http.protocol.allow-circular-redirects", true);
 		if (acceptInvalidCertificates) {
@@ -100,7 +101,7 @@ public class Urllib {
     	}
     	else {
     		HttpPost urlConnection = new HttpPost(url);
-    		urlConnection.setEntity(new UrlEncodedFormEntity(postData, HTTP.UTF_8));
+    		urlConnection.setEntity(new UrlEncodedFormEntity(postData, this.charset));
     		urlConnection.addHeader("User-Agent", USER_AGENT);
     		response = httpclient.execute(urlConnection, responseHandler, context); 
     	}
@@ -127,6 +128,11 @@ public class Urllib {
     public DefaultHttpClient getHttpclient() {
         return httpclient;
     }
+
+    public void setContentCharset(String charset) {
+        this.charset = charset;
+        HttpProtocolParams.setContentCharset(httpclient.getParams(), this.charset);
+    }    
     public boolean acceptsInvalidCertificates() {
     	return acceptInvalidCertificates;
     }

commit 420b0c1b87b35ba74a89f5147dd9694638a5919c
Author: liato <x@x00.us>
Date:   Thu Jan 20 11:39:33 2011 +0100

    Update "thanks to".

diff --git AndroidManifest.xml AndroidManifest.xml
index 50d1bc7..5ed4daf 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -117,7 +117,7 @@
 		android:multiprocess="true"
 		android:exported="true"
 		android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
-		android:permission="com.liato.bankdroid.premission.READ_ACCESS_BANK_TRANSACTIONS"/>
+		android:permission="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS"/>
 </application>
 	<uses-sdk
 		android:targetSdkVersion="4"
@@ -134,7 +134,7 @@
 		android:smallScreens="true"
 		android:anyDensity="true" />
 	<permission 
-		android:name="com.liato.bankdroid.premission.READ_ACCESS_BANK_TRANSACTIONS" 
+		android:name="com.liato.bankdroid.permission.READ_ACCESS_BANK_TRANSACTIONS" 
 		android:label="@string/permission_provider_label" 
 		android:description="@string/permission_provider_desc"
 		android:protectionLevel="dangerous"/>
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index b1c4ff8..b7e9f73 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -113,7 +113,11 @@
 	\npilang (Länsförsäkringar)
 	\nMidde (Ikano Bank)
 	\nweppe (Coop)
-    </string>
+	\nmagnusart (Content Provider)
+	\nPMC (Rikslunchen)
+	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
+	\nfiretech (Hemköp)
+	</string>
     
 
 	<!-- Lock Pattern settings -->
diff --git res/values/strings.xml res/values/strings.xml
index ad1ffcd..4e4156f 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -94,8 +94,7 @@
     \nisocron (ICA)
     \nDustin (ICA)
     \ndimaZ (Statoil)
-    \nOxygen (Statoil)
-    \nOxygen (Nordea)
+    \nOxygen (Statoil &amp; Nordea)
 	\nOzzy (Avanza)
 	\nasperon (Transparent widget)
 	\nDEGE (Handelsbanken)
@@ -114,6 +113,10 @@
 	\npilang (Länsförsäkringar)
 	\nMidde (Ikano Bank)
 	\nweppe (Coop)
+	\nmagnusart (Content Provider)
+	\nPMC (Rikslunchen)
+	\nmhagander (Diners Club &amp; SAS EuroBonus Mastercard)
+	\nfiretech (Hemköp)
      </string>
      
      

commit 2c23ba6f9101f36a6644e20f2aecce80225e8bdc
Author: liato <x@x00.us>
Date:   Thu Jan 20 11:37:24 2011 +0100

    Add support for Hemkop Kundkort.

diff --git logos.psd logos.psd
index 4fc7071..5ba4029 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_hemkop.png res/drawable/logo_hemkop.png
new file mode 100644
index 0000000..8c80d19
Binary files /dev/null and res/drawable/logo_hemkop.png differ
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 16acd0f..54dfb20 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -33,6 +33,7 @@ import com.liato.bankdroid.banking.banks.EurobonusMastercard;
 import com.liato.bankdroid.banking.banks.Eurocard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.Handelsbanken;
+import com.liato.bankdroid.banking.banks.Hemkop;
 import com.liato.bankdroid.banking.banks.ICA;
 import com.liato.bankdroid.banking.banks.ICABanken;
 import com.liato.bankdroid.banking.banks.IkanoBank;
@@ -99,10 +100,12 @@ public class BankFactory {
             return new DinersClub(context);
         case IBankTypes.IKANOBANK:
             return new IkanoBank(context);
-        case Bank.EUROBONUSMASTERCARD:
+        case IBankTypes.EUROBONUSMASTERCARD:
         	return new EurobonusMastercard(context);
-        case Bank.RIKSLUNCHEN:
+        case IBankTypes.RIKSLUNCHEN:
             return new Rikslunchen(context);            
+        case IBankTypes.HEMKOP:
+            return new Hemkop(context);            
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -133,6 +136,7 @@ public class BankFactory {
         banks.add(new IkanoBank(context));
         banks.add(new EurobonusMastercard(context));
         banks.add(new Rikslunchen(context));
+        banks.add(new Hemkop(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Hemkop.java src/com/liato/bankdroid/banking/banks/Hemkop.java
new file mode 100644
index 0000000..f9adae6
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Hemkop.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: firetech
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Hemkop extends Bank {
+    private static final String TAG = "Hemkop";
+    private static final String NAME = "Hemköp Kundkort";
+    private static final String NAME_SHORT = "hemkop";
+    private static final String URL = "http://www.hemkop.se/showdoc.asp?docid=780&show=minasidor";
+    private static final int BANKTYPE_ID = IBankTypes.HEMKOP;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅÅÅMMDDXXXX";
+
+    private Pattern reBalance = Pattern.compile("<span id=\"ctl00_cpTop_lblAktuelltSaldoRubrik\">(.*):</span>\\s*<strong><span id=\"ctl00_cpTop_lbl(AktuelltSaldo)\">(.*)</span></strong>");
+    private Pattern reBonusIn = Pattern.compile("<span id=\"ctl00_cpTop_lblBonusInfoRubrik\">(.*):</span>\\s*<strong><span id=\"ctl00_cpTop_lbl(BonusInfo)\">(.*)</span></strong>");
+    private Pattern reBonusMonth = Pattern.compile("<span id=\"ctl00_cpTop_lblBonusInfoSumRubrik\">(.*):</span>\\s*<strong><span id=\"ctl00_cpTop_lbl(BonusInfoSum)\">(.*)</span></strong>");
+    private Pattern reTransaction = Pattern.compile("<tr class=\\s*\"transaction_row\">\\s*<td class=\"date\">\\s*(.*)\\s*</td>\\s*<td class=\"event\">\\s*(.*)\\s*</td>\\s*(<td class=\"currency\">\\s*(.*)\\s*</td>\\s*)?<td class=\"value\">\\s*(.*)\\s*</td>\\s*</tr>");
+    // space here due to a bug on the bonus transactions page -^^^^
+
+    private String response = null;
+
+    public Hemkop(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public Hemkop(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("hemkop_personnummer", username));
+        postData.add(new BasicNameValuePair("hemkop_password", password));
+        return new LoginPackage(urlopen, postData, response, "https://www.hemkop.se/scripts/cgiip.exe/WService=axfood/axfood/common/loginhemkopkundkort.p");
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("status=failed")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+            //Login result contains a meta redirect to this page.
+            response = urlopen.open("https://www.hemkop.se/showdoc.asp?docid=780&show=minasidor");
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        
+        ArrayList<Pattern> arrPat = new ArrayList<Pattern>();
+        arrPat.add(reBalance);    // Balance (for VISA only)
+        arrPat.add(reBonusIn);    // Collected bonus before this month
+        arrPat.add(reBonusMonth); // Collected bonus this month
+        
+        for (Pattern p : arrPat) {
+            Matcher matcher = p.matcher(response);
+            if (matcher.find()) {
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim()));
+                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+            }
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+     
+        try {
+            String url = null;
+            GregorianCalendar from = new GregorianCalendar();
+            GregorianCalendar tom = new GregorianCalendar();
+            if (account.getId().equals("AktuelltSaldo")) {
+                // Get a year's worth of card transactions (VISA only)
+                from.set(Calendar.YEAR, from.get(Calendar.YEAR) - 1);
+                url = String.format("https://www.hemkop.se/showdoc.asp?docid=785&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
+            } else if (account.getId().equals("BonusInfo")) {
+                // Get a year's worth of bonus transactions (shopping within Hemköp) until the current month.
+                from.set(Calendar.YEAR, from.get(Calendar.YEAR) - 1);
+                tom.set(Calendar.DATE, 0);
+                url = String.format("https://www.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
+            } else if (account.getId().equals("BonusInfoSum")) {
+                // Get a bonus transactions (shopping within Hemköp) during the current month.
+                from.set(Calendar.DATE, 1);
+                url = String.format("https://www.hemkop.se/showdoc.asp?docid=849&hemkop_datumFrom=%tF&hemkop_datumTom=%tF", from, tom);
+            }
+            
+            if (url != null) {
+                Log.d(TAG, "Opening "+url);
+                response = urlopen.open(url);
+    
+                Matcher matcher = reTransaction.matcher(response);
+                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                while (matcher.find()) {
+                    Transaction t = new Transaction(matcher.group(1).trim(),
+                            Html.fromHtml(matcher.group(2)).toString().trim(),
+                            Helpers.parseBalance(matcher.group(5)));
+                    if (matcher.group(4) != null && matcher.group(4).length() > 0) {
+                        t.setCurrency(Html.fromHtml(matcher.group(4)).toString().trim());
+                    }
+                    transactions.add(t);
+                }
+                account.setTransactions(transactions);
+            }
+        } catch (ClientProtocolException e) {
+            Log.e(TAG, e.getMessage());
+        } catch (IOException e) {
+            Log.e(TAG, e.getMessage());
+        }
+        finally {
+            super.updateComplete();
+        }
+    }
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
index 3b542a4..618babf 100644
--- src/com/liato/bankdroid/provider/IBankTypes.java
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -45,5 +45,6 @@ public interface IBankTypes {
 	public final static int DINERSCLUB = 20;
     public final static int EUROBONUSMASTERCARD = 21;
     public final static int RIKSLUNCHEN = 22;
+    public final static int HEMKOP = 23;
 
 }
\ No newline at end of file

commit 5b227817327820d691b826305eaa8b25815f4ba9
Merge: e426868 9b4f7ee
Author: liato <x@x00.us>
Date:   Thu Jan 20 10:53:22 2011 +0100

    Merge branch 'transaction-broadcast' of git://github.com/magnusart/android-bankdroid into magnusart-transaction-broadcast

commit e426868e581d8abb6f99418be2d7218a652c6e96
Merge: 77330eb 9d3be7e
Author: liato <x@x00.us>
Date:   Thu Jan 20 10:50:56 2011 +0100

    Merge branch 'content-provider' of git://github.com/magnusart/android-bankdroid into magnusart-content-provider
    
    Conflicts:
            res/values/strings.xml
            src/com/liato/bankdroid/banking/Bank.java
            src/com/liato/bankdroid/banking/banks/Statoil.java

commit 77330eb5dd2efdb5cf7ec26f7a0ff4a971f4032f
Author: liato <x@x00.us>
Date:   Thu Jan 20 10:37:29 2011 +0100

    Fix small cosmetig bug.

diff --git res/layout/listitem_accounts_group.xml res/layout/listitem_accounts_group.xml
index abfbb02..a770075 100644
--- res/layout/listitem_accounts_group.xml
+++ res/layout/listitem_accounts_group.xml
@@ -30,17 +30,13 @@
 	<TextView
 		android:id="@+id/txtListitemAccountsGroupBankname"
 
-		android:layout_height="26dip"
-
 		android:layout_toRightOf="@id/imgListitemAccountsGroup"
-		android:layout_alignParentBottom="true"
 		android:singleLine="true"
 		android:ellipsize="marquee"
-		android:gravity="center_vertical"
 		android:text="Banknamn"
 		android:textColor="#000"
 		android:layout_width="wrap_content"
-		android:layout_alignParentRight="false" />
+		android:layout_alignParentRight="false" android:layout_alignParentBottom="true" android:layout_height="21dip" android:gravity="top"/>
 
 	<TextView
 		android:layout_height="wrap_content"
@@ -52,11 +48,9 @@
 
 		android:gravity="center_vertical"
 		android:id="@+id/txtListitemAccountsGroupAccountname"
-		android:textSize="23sp"
-		android:text="Personnummer"
 		android:textColor="#000"
 		android:layout_width="wrap_content"
-		android:layout_alignParentRight="false" />
+		android:layout_alignParentRight="false" android:includeFontPadding="true" android:textSize="23dp" android:text="Personnummer"/>
 	<ImageView
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
@@ -67,15 +61,13 @@
 		android:visibility="invisible"></ImageView>
 	<TextView
 		android:id="@+id/txtListitemAccountsGroupTotal"
-		android:layout_height="26dip"
 		android:layout_alignParentBottom="true"
 		android:singleLine="true"
 		android:ellipsize="marquee"
-		android:gravity="center_vertical"
 		android:text="00000 SEK"
 		android:layout_width="wrap_content"
 		android:layout_alignParentRight="true"
-		android:textColor="#333" />
+		android:textColor="#333" android:layout_height="21dp" android:gravity="top"/>
         
 
 </RelativeLayout>
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 8dfb682..3309f2f 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -116,8 +116,8 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
 		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
         EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
-        TextView txtUsername = (EditText)findViewById(R.id.txtBankeditUsername);
-        TextView txtPassword = (EditText)findViewById(R.id.txtBankeditPassword);
+        TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
+        TextView txtPassword = (TextView)findViewById(R.id.txtBankeditPassword);
         
 		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
 		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());

commit 9b6e3926251072601aeec3784d698c6163f81043
Author: liato <x@x00.us>
Date:   Thu Jan 20 10:16:21 2011 +0100

    Handle the orientation change manually in the webview activity to prevent the webview from being reloaded on every orientation change. Closes #32.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0e572f8..aa9dc1b 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -29,7 +29,8 @@
 		<activity
 			android:name=".WebViewActivity"
 			android:label="@string/app_name"
-			android:theme="@style/BankdroidTheme">
+			android:theme="@style/BankdroidTheme"
+			android:configChanges="keyboardHidden|orientation">
 		</activity>
 		<activity
 			android:name=".BankEditActivity"

commit 9d3a8deed59e2020820faf2c7330bacfd9a3ab18
Author: liato <x@x00.us>
Date:   Thu Jan 20 10:14:12 2011 +0100

    Add license and change the way username/password fields are hidden when editing a bank.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index fa92375..8dfb682 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -20,12 +20,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
@@ -34,7 +28,6 @@ import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.text.InputFilter;
 import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -48,6 +41,12 @@ import android.widget.EditText;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
 public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private final static String TAG = "AccountActivity";
 	private Bank SELECTED_BANK;
@@ -115,54 +114,36 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
 		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
-		
-		if (SELECTED_BANK.getBanktypeId() == Bank.RIKSLUNCHEN)
-		{
-			displayOnlyCardID();			
-		}
-		else
-		{		
-			EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
-			
-			if (edtUsername.getVisibility() == EditText.GONE)
-			{			
-				restoreLayout();
-			}
-			
-			edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
-			edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
-	        //Not possible to set a textfield to both PHONE and PASSWORD :\
-			EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
-			edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-			edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
-			edtPassword.setTypeface(Typeface.MONOSPACE);
-		}
+		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
+        EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+        TextView txtUsername = (EditText)findViewById(R.id.txtBankeditUsername);
+        TextView txtPassword = (EditText)findViewById(R.id.txtBankeditPassword);
         
-	}
-
-	private void restoreLayout() {
-		findViewById(R.id.edtBankeditUsername).setVisibility(EditText.VISIBLE);
-		findViewById(R.id.txtBankeditUsername).setVisibility(TextView.VISIBLE);
-		TextView txtBankeditPassword = (TextView)findViewById(R.id.txtBankeditPassword);
-		txtBankeditPassword.setText(R.string.password);
-	}
-
-	private void displayOnlyCardID() {
-		//Remove Username
-		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);			
-		edtUsername.setVisibility(EditText.GONE);	
-		edtUsername.setText("");
-		TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
-		txtUsername.setVisibility(TextView.GONE);		
-		EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
+		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
 		edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-		
-		//Change Password to Card ID
-		TextView txtBankeditPassword = (TextView)findViewById(R.id.txtBankeditPassword);
-		txtBankeditPassword.setText(R.string.card_id);
-					
 		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
 		edtPassword.setTypeface(Typeface.MONOSPACE);
+        txtUsername.setText(SELECTED_BANK.getInputTitleUsername());
+        txtPassword.setText(SELECTED_BANK.getInputTitlePassword());
+		
+        if (SELECTED_BANK.isInputUsernameHidden()) {
+            edtUsername.setVisibility(View.GONE);
+            txtUsername.setVisibility(View.GONE);
+        }
+        else {
+            edtUsername.setVisibility(View.VISIBLE);
+            txtUsername.setVisibility(View.VISIBLE);
+        }
+        
+        if (SELECTED_BANK.isInputPasswordHidden()) {
+            edtPassword.setVisibility(View.GONE);
+            txtPassword.setVisibility(View.GONE);
+        }
+        else {
+            edtPassword.setVisibility(View.VISIBLE);
+            txtPassword.setVisibility(View.VISIBLE);
+        }        
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index dd7e138..553310c 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -29,7 +29,6 @@ import org.apache.http.client.CookieStore;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.raw;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
@@ -45,20 +44,20 @@ import eu.nullbyte.android.urllib.Urllib;
 public abstract class Bank implements Comparable<Bank> {
     public final static int TESTBANK = 0;
     public final static int SWEDBANK = 1;
-	public final static int NORDEA = 2;
-	public final static int ICABANKEN = 3;
-	public final static int LANSFORSAKRINGAR = 4;
-	public final static int HANDELSBANKEN = 5;
-	public final static int COOP = 6;
-	public final static int ICA = 7;
-	public final static int STATOIL = 8;
-	public final static int AVANZA = 9;
-	public final static int VILLABANKEN = 10;
-	public final static int AVANZAMINI = 11;
-	public final static int OKQ8 = 12;
-	public final static int EUROCARD = 13;
-	public final static int FIRSTCARD = 14;
-	public final static int PAYPAL = 15;
+    public final static int NORDEA = 2;
+    public final static int ICABANKEN = 3;
+    public final static int LANSFORSAKRINGAR = 4;
+    public final static int HANDELSBANKEN = 5;
+    public final static int COOP = 6;
+    public final static int ICA = 7;
+    public final static int STATOIL = 8;
+    public final static int AVANZA = 9;
+    public final static int VILLABANKEN = 10;
+    public final static int AVANZAMINI = 11;
+    public final static int OKQ8 = 12;
+    public final static int EUROCARD = 13;
+    public final static int FIRSTCARD = 14;
+    public final static int PAYPAL = 15;
     public final static int PAYSON = 16;
     public final static int JOJO = 17;
     public final static int IKANOBANK = 18;
@@ -67,139 +66,143 @@ public abstract class Bank implements Comparable<Bank> {
     public final static int EUROBONUSMASTERCARD = 21;
     public final static int RIKSLUNCHEN = 22;
 
-	protected String TAG = "Bank";
-	protected String NAME = "Bank";
-	protected String NAME_SHORT = "bank";
-	protected int BANKTYPE_ID = 0;
-	protected String URL;
+    protected String TAG = "Bank";
+    protected String NAME = "Bank";
+    protected String NAME_SHORT = "bank";
+    protected int BANKTYPE_ID = 0;
+    protected String URL;
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
     protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
     protected String INPUT_HINT_USERNAME = null;
+    protected boolean INPUT_HIDDEN_USERNAME = false;
+    protected boolean INPUT_HIDDEN_PASSWORD = false;
+    protected int INPUT_TITLETEXT_USERNAME = R.string.username;
+    protected int INPUT_TITLETEXT_PASSWORD = R.string.password;
     protected boolean STATIC_BALANCE = false;
     protected boolean BROKEN = false;
 
-	protected Context context;
-	protected Resources res;
-	
-	protected String username;
-	protected String password;
-	protected ArrayList<Account> accounts = new ArrayList<Account>();
-	protected HashMap<String, Account> oldAccounts;
-	protected BigDecimal balance = new BigDecimal(0);
-	protected boolean disabled = false;
-	protected long dbid = -1;
-	protected Urllib urlopen = null;
-	protected String customName;
-	protected String currency = "SEK";
-
-	public Urllib getUrlopen() {
-		return urlopen;
-	}
-
-	public void setUrlopen(Urllib urlopen) {
-		this.urlopen = urlopen;
-	}
-
-	public void setDbid(long dbid) {
-		this.dbid = dbid;
-	}
-
-	public Bank(Context context) {
-		this.context = context;
-		this.res = this.context.getResources();
-	}
-
-	public void update(String username, String password) throws BankException, LoginException {
-		this.username = username;
-		this.password = password;
-		this.update();
-	}
-
-	public void update() throws BankException, LoginException {
-		balance = new BigDecimal(0);
-		oldAccounts = new HashMap<String, Account>();
-		for(Account account: accounts) {
-		    oldAccounts.put(account.getId(), account);
-		}
-		accounts = new ArrayList<Account>();
-	}
-
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-	}
-
-	public void updateAllTransactions() throws LoginException, BankException {
-		if (urlopen == null) {
-			urlopen = login();
-		}
-		for (Account account: accounts) {
-			updateTransactions(account, urlopen);
-		}
-		if (urlopen != null) {
-			urlopen.close();
-		}
-		
-	}
-	
-	public Urllib login() throws LoginException, BankException {
-		return null;
-	}
-
-	public void closeConnection() {
-		if (urlopen != null) {
-			urlopen.close();
-		}
-	}
-	public ArrayList<Account> getAccounts() {
-		return this.accounts;
-	}
-	
-	public void setAccounts(ArrayList<Account> accounts) {
-		this.accounts = accounts;
-		for (Account a : accounts) {
-		    a.setBank(this);
-		}
-	}
-
-	public String getPassword() {
-		return password;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public BigDecimal getBalance() {
-	    if (STATIC_BALANCE) {
-	        return balance;
-	    }
-	    else {
-	        BigDecimal bal = new BigDecimal(0); 
-	        for (Account account : accounts) {
-	            if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
-	                if (!account.isHidden()) {
-	                    bal = bal.add(account.getBalance());
-	                }
-	            }
-	        }
-	        return bal;
-	    }
-	}
-
-	public int getBanktypeId() {
-		return BANKTYPE_ID;
-	}
-
-	public String getName() {
-		return NAME;
-	}
-
-	public String getDisplayName() {
-		if (customName != null && customName.length() > 0) return customName;
-		return username;
-	}
-
-	
-	public String getCustomName() {
+    protected Context context;
+    protected Resources res;
+
+    protected String username;
+    protected String password;
+    protected ArrayList<Account> accounts = new ArrayList<Account>();
+    protected HashMap<String, Account> oldAccounts;
+    protected BigDecimal balance = new BigDecimal(0);
+    protected boolean disabled = false;
+    protected long dbid = -1;
+    protected Urllib urlopen = null;
+    protected String customName;
+    protected String currency = "SEK";
+
+    public Urllib getUrlopen() {
+        return urlopen;
+    }
+
+    public void setUrlopen(Urllib urlopen) {
+        this.urlopen = urlopen;
+    }
+
+    public void setDbid(long dbid) {
+        this.dbid = dbid;
+    }
+
+    public Bank(Context context) {
+        this.context = context;
+        this.res = this.context.getResources();
+    }
+
+    public void update(String username, String password) throws BankException, LoginException {
+        this.username = username;
+        this.password = password;
+        this.update();
+    }
+
+    public void update() throws BankException, LoginException {
+        balance = new BigDecimal(0);
+        oldAccounts = new HashMap<String, Account>();
+        for(Account account: accounts) {
+            oldAccounts.put(account.getId(), account);
+        }
+        accounts = new ArrayList<Account>();
+    }
+
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+    }
+
+    public void updateAllTransactions() throws LoginException, BankException {
+        if (urlopen == null) {
+            urlopen = login();
+        }
+        for (Account account: accounts) {
+            updateTransactions(account, urlopen);
+        }
+        if (urlopen != null) {
+            urlopen.close();
+        }
+
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        return null;
+    }
+
+    public void closeConnection() {
+        if (urlopen != null) {
+            urlopen.close();
+        }
+    }
+    public ArrayList<Account> getAccounts() {
+        return this.accounts;
+    }
+
+    public void setAccounts(ArrayList<Account> accounts) {
+        this.accounts = accounts;
+        for (Account a : accounts) {
+            a.setBank(this);
+        }
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public BigDecimal getBalance() {
+        if (STATIC_BALANCE) {
+            return balance;
+        }
+        else {
+            BigDecimal bal = new BigDecimal(0); 
+            for (Account account : accounts) {
+                if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
+                    if (!account.isHidden()) {
+                        bal = bal.add(account.getBalance());
+                    }
+                }
+            }
+            return bal;
+        }
+    }
+
+    public int getBanktypeId() {
+        return BANKTYPE_ID;
+    }
+
+    public String getName() {
+        return NAME;
+    }
+
+    public String getDisplayName() {
+        if (customName != null && customName.length() > 0) return customName;
+        return username;
+    }
+
+
+    public String getCustomName() {
         return customName;
     }
 
@@ -208,21 +211,21 @@ public abstract class Bank implements Comparable<Bank> {
     }
 
     public String getShortName() {
-		return NAME_SHORT;
-	}
-
-	public void setData(String username, String password, BigDecimal balance,
-			boolean disabled, long dbid, String currency, String customName) {
-		this.username = username;
-		this.password = password;
-		this.balance = balance;
-		this.disabled = disabled;
-		this.dbid = dbid;
-		this.currency = currency;
-		this.customName = customName;
-	}
-	
-	public String getCurrency() {
+        return NAME_SHORT;
+    }
+
+    public void setData(String username, String password, BigDecimal balance,
+            boolean disabled, long dbid, String currency, String customName) {
+        this.username = username;
+        this.password = password;
+        this.balance = balance;
+        this.disabled = disabled;
+        this.dbid = dbid;
+        this.currency = currency;
+        this.customName = customName;
+    }
+
+    public String getCurrency() {
         return currency;
     }
 
@@ -231,45 +234,45 @@ public abstract class Bank implements Comparable<Bank> {
     }
 
     public long getDbId() {
-		return dbid;
-	}
-
-	public boolean isDisabled() {
-		return disabled;
-	}
-	
-	public void disable() {
-		DBAdapter db = new DBAdapter(context);
-		db.open();
-		db.disableBank(dbid);
-		db.close();
-	}
-	
-	public void setDisabled(boolean disabled) {
-		this.disabled = disabled;
-	}
-
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-	
-	public void save() {
-		DBAdapter db = new DBAdapter(context);
-		db.open();
-		db.updateBank(this);
-		db.close();
-	}
-	
-	public String getURL() {
-		return URL;
-	}
-	
-	public int getInputTypeUsername() {
+        return dbid;
+    }
+
+    public boolean isDisabled() {
+        return disabled;
+    }
+
+    public void disable() {
+        DBAdapter db = new DBAdapter(context);
+        db.open();
+        db.disableBank(dbid);
+        db.close();
+    }
+
+    public void setDisabled(boolean disabled) {
+        this.disabled = disabled;
+    }
+
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public void save() {
+        DBAdapter db = new DBAdapter(context);
+        db.open();
+        db.updateBank(this);
+        db.close();
+    }
+
+    public String getURL() {
+        return URL;
+    }
+
+    public int getInputTypeUsername() {
         return INPUT_TYPE_USERNAME;
     }
 
@@ -281,18 +284,35 @@ public abstract class Bank implements Comparable<Bank> {
         return INPUT_HINT_USERNAME;
     }
 
+    public boolean isInputUsernameHidden() {
+        return INPUT_HIDDEN_USERNAME;
+    }
+
+    public boolean isInputPasswordHidden() {
+        return INPUT_HIDDEN_PASSWORD;
+    }
+
+    public int getInputTitleUsername() {
+        return INPUT_TITLETEXT_USERNAME;
+    }
+
+    public int getInputTitlePassword() {
+        return INPUT_TITLETEXT_PASSWORD;
+    }
+
+
     // Returns true if the current implementation of this bank is broken.
     public boolean isBroken() {
         return BROKEN;
     }
 
     public int getImageResource() {
-		return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
-	}
+        return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
+    }
 
-	public int compareTo(Bank another) {
-		return this.toString().compareToIgnoreCase(another.toString());
-	}
+    public int compareTo(Bank another) {
+        return this.toString().compareToIgnoreCase(another.toString());
+    }
 
     public void updateComplete() {
         for (Account a : this.accounts) {
@@ -307,7 +327,7 @@ public abstract class Bank implements Comparable<Bank> {
             a.setBank(this);
         }
     }
-    
+
     public SessionPackage getSessionPackage(Context context) {
         String preloader = "Error...";
         try {
@@ -321,17 +341,17 @@ public abstract class Bank implements Comparable<Bank> {
             // TODO Auto-generated catch block
             e1.printStackTrace();
         }
- 
+
         try {
             LoginPackage lp = preLogin();
             if (lp == null) {
                 throw new BankException("No automatic login for this bank. preLogin() is not implemented or has failed.");
             }
             String html = String.format(preloader,
-                                        "function go(){document.getElementById('submitform').submit(); }", // Javascript function
-                                        Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
-                                        );        
-            
+                    "function go(){document.getElementById('submitform').submit(); }", // Javascript function
+                    Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
+            );        
+
             CookieStore cookies = urlopen.getHttpclient().getCookieStore();
             return new SessionPackage(html, cookies);
         }
@@ -347,7 +367,7 @@ public abstract class Bank implements Comparable<Bank> {
         String html = String.format(preloader,
                 String.format("function go(){window.location=\"%s\" }", this.URL), // Javascript function
                 "<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
-                );          
+        );          
         return new SessionPackage(html, null);
     }
 
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index d08f270..da6f423 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
- *
+ * Contributors: mhagander
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
index 63b5792..e4f6627 100644
--- src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: mhagander
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
index 39afb08..2df172d 100644
--- src/com/liato/bankdroid/banking/banks/Rikslunchen.java
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: PMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
@@ -37,6 +53,8 @@ public class Rikslunchen extends Bank {
 	private static final String URL = "http://www.rikslunchen.se/index.html";
 	private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
 	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    protected boolean INPUT_HIDDEN_USERNAME = true;
+    protected int INPUT_TITLETEXT_PASSWORD = R.string.card_id;	
 
 	private String myResponse = "";
 
@@ -49,6 +67,8 @@ public class Rikslunchen extends Bank {
 		super.URL = URL;
 		super.INPUT_HINT_USERNAME = "Rikslunchen";
 		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HIDDEN_USERNAME = INPUT_HIDDEN_USERNAME;
+		super.INPUT_TITLETEXT_PASSWORD = INPUT_TITLETEXT_PASSWORD;
 	}
 
 	public Rikslunchen(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
index af42be4..f792b99 100644
--- src/com/liato/bankdroid/banking/banks/Statoil.java
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.liato.bankdroid.banking.banks;
 
 import android.content.Context;

commit 53000e17cac5b8cb785634088bca076cab0ff26a
Author: liato <x@x00.us>
Date:   Thu Jan 20 09:50:53 2011 +0100

    New rikslunchen logo.

diff --git logos.psd logos.psd
index e5c4859..4fc7071 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_rikslunchen.png res/drawable/logo_rikslunchen.png
index fb3e088..94cbe5f 100644
Binary files res/drawable/logo_rikslunchen.png and res/drawable/logo_rikslunchen.png differ

commit 88e81b42f6fb053cd129b88709ff5bcda432cf2a
Merge: 31fce77 b0652ec
Author: liato <x@x00.us>
Date:   Thu Jan 20 09:27:46 2011 +0100

    Merge branch 'master' of git://github.com/PMC/android-bankdroid into PMC-master
    
    Conflicts:
            src/com/liato/bankdroid/banking/Bank.java
            src/com/liato/bankdroid/banking/BankFactory.java

commit 9b4f7ee7af72b72a237d4eda8bb2832c00e90945
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Wed Jan 19 22:54:20 2011 +0100

    Corrected bad grammar in settings activity.
    
    Change-Id: I8d0d6f911b46541538925c73d9eeee4cd316b59c
    Signed-off-by: Magnus Andersson <magnus@magnusart.com>

diff --git res/xml/settings.xml res/xml/settings.xml
index 850f2ee..d15e9b8 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -139,7 +139,7 @@
 		android:title="Share data">
 		
 	<CheckBoxPreference android:title="Enable Sharing Data" android:summary="Enable other installed apps access to your transaction history" android:key="content_provider_enabled"></CheckBoxPreference>
-<EditTextPreference android:title="API Key" android:key="content_provider_api_key" android:summary="Use this key into trusted applications" android:dependency="content_provider_enabled"></EditTextPreference>
+<EditTextPreference android:title="API Key" android:key="content_provider_api_key" android:dependency="content_provider_enabled" android:summary="Use this key to allow access for trusted applications"></EditTextPreference>
 </PreferenceCategory>
 	<PreferenceCategory
 		android:title="Debug">

commit b0652ec5b4eabab4f0040319436fe59aec829489
Author: Pierre Chateau <pierre@chateau.se>
Date:   Wed Jan 19 09:31:28 2011 +0100

    Fixed a bug where browsing to Rikslunchen and then browsing away wouldnt display username.

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index f13a621..fa92375 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -118,31 +118,17 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 		
 		if (SELECTED_BANK.getBanktypeId() == Bank.RIKSLUNCHEN)
 		{
-			//Remove Username
-			EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);			
-			edtUsername.setVisibility(EditText.GONE);			
-			TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
-			txtUsername.setVisibility(TextView.GONE);
-			
-			EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
-			edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-			
-			//Change Password to Card ID
-			TextView txtBankeditPassword = (TextView)findViewById(R.id.txtBankeditPassword);
-			txtBankeditPassword.setText(R.string.card_id);
-			
-			// Max 8 numeric characters
-			InputFilter[] filterArray = new InputFilter[1];
-			filterArray[0] = new InputFilter.LengthFilter(8);
-			edtPassword.setFilters(filterArray);			
-			
-			edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
-			edtPassword.setTypeface(Typeface.MONOSPACE);			
+			displayOnlyCardID();			
 		}
 		else
 		{		
-			SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
 			EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
+			
+			if (edtUsername.getVisibility() == EditText.GONE)
+			{			
+				restoreLayout();
+			}
+			
 			edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
 			edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
 	        //Not possible to set a textfield to both PHONE and PASSWORD :\
@@ -154,6 +140,31 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
         
 	}
 
+	private void restoreLayout() {
+		findViewById(R.id.edtBankeditUsername).setVisibility(EditText.VISIBLE);
+		findViewById(R.id.txtBankeditUsername).setVisibility(TextView.VISIBLE);
+		TextView txtBankeditPassword = (TextView)findViewById(R.id.txtBankeditPassword);
+		txtBankeditPassword.setText(R.string.password);
+	}
+
+	private void displayOnlyCardID() {
+		//Remove Username
+		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);			
+		edtUsername.setVisibility(EditText.GONE);	
+		edtUsername.setText("");
+		TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
+		txtUsername.setVisibility(TextView.GONE);		
+		EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+		edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
+		
+		//Change Password to Card ID
+		TextView txtBankeditPassword = (TextView)findViewById(R.id.txtBankeditPassword);
+		txtBankeditPassword.setText(R.string.card_id);
+					
+		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+		edtPassword.setTypeface(Typeface.MONOSPACE);
+	}
+
 	@Override
 	public void onNothingSelected(AdapterView<?> arg) {
 	}

commit 2248defe87e22d09bf09bc9e72c9a1f22665dd73
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Tue Jan 18 22:29:34 2011 +0100

    Added a broadcast when transactions have been updated. Right now it
    sends all the accounts because of the semantics in the application of
    clearing all the transactions for each account.
    
    Change-Id: I589a2a0dae5e079f37b8efb9b1619246d7152c70

diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index 0be3b68..46e32fa 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -18,115 +18,145 @@ package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.DialogInterface;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.os.AsyncTask;
+import android.preference.PreferenceManager;
 import android.util.Log;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
-	private ProgressDialog dialog;
+	private final ProgressDialog dialog;
 	private ArrayList<String> errors;
-	private MainActivity parent;
+	private final MainActivity parent;
 	private int bankcount;
-	private Resources res;
+	private final Resources res;
 	private long bankId = -1;
 
-	public DataRetrieverTask(MainActivity parent) {
+	public DataRetrieverTask(final MainActivity parent) {
 		this.parent = parent;
 		this.res = parent.getResources();
-		this.dialog =  new ProgressDialog(parent);
+		this.dialog = new ProgressDialog(parent);
 	}
-	public DataRetrieverTask(MainActivity parent, long bankId) {
+
+	public DataRetrieverTask(final MainActivity parent, final long bankId) {
 		this(parent);
 		this.bankId = bankId;
-	}	
+	}
+
+	@Override
 	protected void onPreExecute() {
-		this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n ");
+		this.dialog.setMessage(res.getText(R.string.updating_account_balance)
+				+ "\n ");
 		this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
 		this.dialog.setCancelable(false);
 		this.dialog.show();
 	}
 
+	@Override
 	protected Void doInBackground(final String... args) {
 		errors = new ArrayList<String>();
 		ArrayList<Bank> banks;
 		if (bankId != -1) {
 			banks = new ArrayList<Bank>();
 			banks.add(BankFactory.bankFromDb(bankId, parent, true));
-		}
-		else {
-			banks = BankFactory.banksFromDb(parent, true);	
+		} else {
+			banks = BankFactory.banksFromDb(parent, true);
 		}
 		bankcount = banks.size();
 		this.dialog.setMax(bankcount);
 		int i = 0;
-		for (Bank bank : banks) {
-			publishProgress(new String[] {new Integer(i).toString(), bank.getName()+" ("+bank.getUsername()+")"});
+		for (final Bank bank : banks) {
+			publishProgress(new String[] { new Integer(i).toString(),
+					bank.getName() + " (" + bank.getUsername() + ")" });
 			if (bank.isDisabled()) {
-				Log.d("AA", bank.getName()+" ("+bank.getUsername()+") is disabled. Skipping refresh.");
+				Log.d("AA", bank.getName() + " (" + bank.getUsername()
+						+ ") is disabled. Skipping refresh.");
 				continue;
 			}
-			Log.d("AA", "Refreshing "+bank.getName()+" ("+bank.getUsername()+").");
+			Log.d("AA",
+					"Refreshing " + bank.getName() + " (" + bank.getUsername()
+							+ ").");
 			try {
-                //Log.d("AA", "bank.update()");
-                bank.update();
-                //Log.d("AA", "bank.updateAllTransactions()");
-                bank.updateAllTransactions();
-                //Log.d("AA", "bank.closeConnction()");
-                bank.closeConnection();
-                //Log.d("AA", "bank.save()");
-                bank.save();
-                //Log.d("AA", "DONE!");
+				// Log.d("AA", "bank.update()");
+				bank.update();
+				// Log.d("AA", "bank.updateAllTransactions()");
+				bank.updateAllTransactions();
+				// Log.d("AA", "bank.closeConnction()");
+				bank.closeConnection();
+				// Log.d("AA", "bank.save()");
+				bank.save();
+				// Log.d("AA", "DONE!");
 				i++;
-			} 
-			catch (BankException e) {
-				this.errors.add(bank.getName()+" ("+bank.getUsername()+")");
-			} catch (LoginException e) {
-				this.errors.add(bank.getName()+" ("+bank.getUsername()+")");
+			} catch (final BankException e) {
+				this.errors.add(bank.getName() + " (" + bank.getUsername()
+						+ ")");
+			} catch (final LoginException e) {
+				this.errors.add(bank.getName() + " (" + bank.getUsername()
+						+ ")");
 				bank.disable();
 			}
+
+			final SharedPreferences prefs = PreferenceManager
+					.getDefaultSharedPreferences(parent);
+			if (prefs.getBoolean("content_provider_enabled", false)) {
+				final ArrayList<Account> accounts = bank.getAccounts();
+				for (final Account account : accounts) {
+					AutoRefreshService.broadcastTransactionUpdate(parent,
+							account);
+				}
+			}
 		}
-		publishProgress(new String[] {new Integer(i).toString(), ""});
+		publishProgress(new String[] { new Integer(i).toString(), "" });
 		return null;
 	}
 
-	protected void onProgressUpdate(String... args) {
+	@Override
+	protected void onProgressUpdate(final String... args) {
 		this.dialog.setProgress(new Integer(args[0]));
-		this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n"+args[1]);
+		this.dialog.setMessage(res.getText(R.string.updating_account_balance)
+				+ "\n" + args[1]);
 	}
+
+	@Override
 	protected void onPostExecute(final Void unused) {
 		parent.refreshView();
 		AutoRefreshService.sendWidgetRefresh(parent);
 		if (this.dialog.isShowing()) {
 			this.dialog.dismiss();
 		}
-		
-		if (this.errors != null && !this.errors.isEmpty()) {
-			StringBuilder errormsg = new StringBuilder();
-			errormsg.append(res.getText(R.string.accounts_were_not_updated)+":\n");
-			for (String err : errors)
-			{
-			  errormsg.append(err);
-			  errormsg.append("\n");
+
+		if ((this.errors != null) && !this.errors.isEmpty()) {
+			final StringBuilder errormsg = new StringBuilder();
+			errormsg.append(res.getText(R.string.accounts_were_not_updated)
+					+ ":\n");
+			for (final String err : errors) {
+				errormsg.append(err);
+				errormsg.append("\n");
 			}
-			AlertDialog.Builder builder = new AlertDialog.Builder(parent);
-			builder.setMessage(errormsg.toString()).setTitle(res.getText(R.string.errors_when_updating))
-			.setIcon(android.R.drawable.ic_dialog_alert)
-			.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-				public void onClick(DialogInterface dialog, int id) {
-					dialog.cancel();
-				}
-			});
-			AlertDialog alert = builder.create();
+			final AlertDialog.Builder builder = new AlertDialog.Builder(parent);
+			builder.setMessage(errormsg.toString())
+					.setTitle(res.getText(R.string.errors_when_updating))
+					.setIcon(android.R.drawable.ic_dialog_alert)
+					.setNeutralButton("Ok",
+							new DialogInterface.OnClickListener() {
+								public void onClick(
+										final DialogInterface dialog,
+										final int id) {
+									dialog.cancel();
+								}
+							});
+			final AlertDialog alert = builder.create();
 			alert.show();
 		}
 	}
-}	
+}
diff --git src/com/liato/bankdroid/appwidget/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index 7036a4c..be593d2 100644
--- src/com/liato/bankdroid/appwidget/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -20,23 +20,11 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
 
-import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.MainActivity;
-import com.liato.bankdroid.R;
-import com.liato.bankdroid.R.id;
-import com.liato.bankdroid.R.string;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.banking.exceptions.BankException;
-import com.liato.bankdroid.banking.exceptions.LoginException;
-import com.liato.bankdroid.db.DBAdapter;
-
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.app.Service;
 import android.app.PendingIntent.CanceledException;
+import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -47,6 +35,16 @@ import android.os.IBinder;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+
 public class AutoRefreshService extends Service {
 	private final static String TAG = "AutoRefreshService";
 	public final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
@@ -55,213 +53,275 @@ public class AutoRefreshService extends Service {
 	public final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
 	public final static String BROADCAST_OPENWATCH_VIBRATE = "com.smartmadsoft.openwatch.action.VIBRATE";
 	public final static String ACTION_MAIN_SHOW_TRANSACTIONS = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
-    
-    NotificationManager notificationManager;
+	public final static String BROADCAST_TRANSACTIONS_UPDATED = "com.liato.bankdroid.action.TRANSACTIONS";
+
+	NotificationManager notificationManager;
 
-    @Override
-    public void onCreate() {
-        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
-        new DataRetrieverTask().execute();
-    }
+	@Override
+	public void onCreate() {
+		notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+		new DataRetrieverTask().execute();
+	}
 
-    @Override
-    public void onDestroy() {
-    }
+	@Override
+	public void onDestroy() {
+	}
 
+	@Override
+	public IBinder onBind(final Intent intent) {
+		return null;
+	}
 
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
+	private void showNotification(final String text, final int icon,
+			final String title, final String bank) {
+		final SharedPreferences prefs = PreferenceManager
+				.getDefaultSharedPreferences(this);
+		if (!prefs.getBoolean("notify_on_change", true)) {
+			return;
+		}
+
+		final Notification notification = new Notification(icon, text,
+				System.currentTimeMillis());
+		// Remove notification from statusbar when clicked
+		notification.flags |= Notification.FLAG_AUTO_CANCEL;
 
-    private void showNotification(String text, int icon, String title, String bank) {
-    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		if (!prefs.getBoolean("notify_on_change", true)) return;
-		
-        Notification notification = new Notification(icon, text,
-                System.currentTimeMillis());
-        // Remove notification from statusbar when clicked
-        notification.flags |= Notification.FLAG_AUTO_CANCEL;
-        
-        
-        //http://www.freesound.org/samplesViewSingle.php?id=75235
-        //http://www.freesound.org/samplesViewSingle.php?id=91924
-        Log.d(TAG, "Notification sound: "+prefs.getString("notification_sound", "none"));
-        if (prefs.getString("notification_sound", null) != null) {
-            notification.sound = Uri.parse(prefs.getString("notification_sound", null));
-        }
+		// http://www.freesound.org/samplesViewSingle.php?id=75235
+		// http://www.freesound.org/samplesViewSingle.php?id=91924
+		Log.d(TAG,
+				"Notification sound: "
+						+ prefs.getString("notification_sound", "none"));
+		if (prefs.getString("notification_sound", null) != null) {
+			notification.sound = Uri.parse(prefs.getString(
+					"notification_sound", null));
+		}
 		if (prefs.getBoolean("notify_with_vibration", true)) {
-			long[] vib = {0, 90, 130, 80, 350, 190, 20, 380};
+			final long[] vib = { 0, 90, 130, 80, 350, 190, 20, 380 };
 			notification.vibrate = vib;
-			//notification.defaults |= Notification.DEFAULT_VIBRATE;
+			// notification.defaults |= Notification.DEFAULT_VIBRATE;
 		}
-        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
-                new Intent(this, MainActivity.class), 0);
+		final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+				new Intent(this, MainActivity.class), 0);
 
-        notification.setLatestEventInfo(this, title, text, contentIntent);
+		notification.setLatestEventInfo(this, title, text, contentIntent);
 
-        notificationManager.notify(R.id.about, notification);
-        
-        // Broadcast to Remote Notifier if enabled
-        // http://code.google.com/p/android-notifier/
-        if (prefs.getBoolean("notify_remotenotifier", false)) {
-            Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
-            i.putExtra("title", String.format("%s (%s)", bank, title));
-            i.putExtra("description", text);
-            sendBroadcast(i);
-        }
+		notificationManager.notify(R.id.about, notification);
 
-        // Broadcast to OpenWatch if enabled
-        // http://forum.xda-developers.com/showthread.php?t=554551
-        if (prefs.getBoolean("notify_openwatch", false)) {
-            Intent i;
-            if (prefs.getBoolean("notify_openwatch_vibrate", false)) {
-                i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
-            }
-            else {
-                i = new Intent(BROADCAST_OPENWATCH_TEXT);
-            }
-            i.putExtra("line1", String.format("%s (%s)", bank, title));
-            i.putExtra("line2", text);
-            sendBroadcast(i);
-        }
-        
-        
-    }
-    
-    private class DataRetrieverTask extends AsyncTask<String, String, Void> {
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(AutoRefreshService.this);
-    	private ArrayList<String> errors;
-    	private Resources res;
+		// Broadcast to Remote Notifier if enabled
+		// http://code.google.com/p/android-notifier/
+		if (prefs.getBoolean("notify_remotenotifier", false)) {
+			final Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
+			i.putExtra("title", String.format("%s (%s)", bank, title));
+			i.putExtra("description", text);
+			sendBroadcast(i);
+		}
+
+		// Broadcast to OpenWatch if enabled
+		// http://forum.xda-developers.com/showthread.php?t=554551
+		if (prefs.getBoolean("notify_openwatch", false)) {
+			Intent i;
+			if (prefs.getBoolean("notify_openwatch_vibrate", false)) {
+				i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
+			} else {
+				i = new Intent(BROADCAST_OPENWATCH_TEXT);
+			}
+			i.putExtra("line1", String.format("%s (%s)", bank, title));
+			i.putExtra("line2", text);
+			sendBroadcast(i);
+		}
 
-    	public DataRetrieverTask() {
-    	}
-    	protected void onPreExecute() {
-    	}
+	}
+
+	private class DataRetrieverTask extends AsyncTask<String, String, Void> {
+		SharedPreferences prefs = PreferenceManager
+				.getDefaultSharedPreferences(AutoRefreshService.this);
+		private ArrayList<String> errors;
+		private Resources res;
+
+		public DataRetrieverTask() {
+		}
 
-    	protected Void doInBackground(final String... args) {
-    		errors = new ArrayList<String>();
-    		Boolean refreshWidgets = false;
-    		ArrayList<Bank> banks = BankFactory.banksFromDb(AutoRefreshService.this, true);
-    		if (banks.isEmpty()) {
-    			return null;
-    		}
-    		DBAdapter db = new DBAdapter(AutoRefreshService.this);
-    		db.open();    		
-    		BigDecimal currentBalance;
-    		BigDecimal diff;
-    		HashMap<String, Account> accounts = new HashMap<String, Account>();
-    		
-    		for (Bank bank : banks) {
-                if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_only_testbank", false)) {
-                    Log.d(TAG, "Debug::Only_Testbank is ON. Skipping update for "+bank.getName());
-                    continue;
-                }
-    			if (bank.isDisabled()) {
-    				Log.d(TAG, bank.getName()+" ("+bank.getDisplayName()+") is disabled. Skipping refresh.");
-    				continue;
-    			}
-				Log.d(TAG, "Refreshing "+bank.getName()+" ("+bank.getDisplayName()+").");
-    			try {
-    				currentBalance = bank.getBalance();
-    				accounts.clear();
-    				for(Account account : bank.getAccounts()) {
-    					accounts.put(account.getId(), account);
-    				}
-    				bank.update();
+		@Override
+		protected void onPreExecute() {
+		}
+
+		@Override
+		protected Void doInBackground(final String... args) {
+			errors = new ArrayList<String>();
+			Boolean refreshWidgets = false;
+			final ArrayList<Bank> banks = BankFactory.banksFromDb(
+					AutoRefreshService.this, true);
+			if (banks.isEmpty()) {
+				return null;
+			}
+			final DBAdapter db = new DBAdapter(AutoRefreshService.this);
+			db.open();
+			BigDecimal currentBalance;
+			BigDecimal diff;
+			final HashMap<String, Account> accounts = new HashMap<String, Account>();
+
+			for (final Bank bank : banks) {
+				if (prefs.getBoolean("debug_mode", false)
+						&& prefs.getBoolean("debug_only_testbank", false)) {
+					Log.d(TAG,
+							"Debug::Only_Testbank is ON. Skipping update for "
+									+ bank.getName());
+					continue;
+				}
+				if (bank.isDisabled()) {
+					Log.d(TAG, bank.getName() + " (" + bank.getDisplayName()
+							+ ") is disabled. Skipping refresh.");
+					continue;
+				}
+				Log.d(TAG,
+						"Refreshing " + bank.getName() + " ("
+								+ bank.getDisplayName() + ").");
+				try {
+					currentBalance = bank.getBalance();
+					accounts.clear();
+					for (final Account account : bank.getAccounts()) {
+						accounts.put(account.getId(), account);
+					}
+					bank.update();
 					diff = currentBalance.subtract(bank.getBalance());
-    				if (diff.compareTo(new BigDecimal(0)) != 0) {
-    					Account oldAccount;
-    					for(Account account : bank.getAccounts()) {
-    						oldAccount = accounts.get(account.getId());
-    						if (oldAccount != null) {
-    							if (account.getBalance().compareTo(oldAccount.getBalance()) != 0) {
-    							    boolean notify = false;
-    							    switch (account.getType()) {
-    							    case Account.REGULAR:
-    							        notify = prefs.getBoolean("notify_for_deposit", true);
-    							        break;
-    							    case Account.FUNDS:
-    							        notify = prefs.getBoolean("notify_for_funds", false);
-    							        break;
-    							    case Account.LOANS:
-    							        notify = prefs.getBoolean("notify_for_loans", false);
-    							        break;
-    							    case Account.CCARD:
-    							        notify = prefs.getBoolean("notify_for_ccards", true);
-    							        break;
-    							    case Account.OTHER:
-    							        notify = prefs.getBoolean("notify_for_other", false);
-    							        break;
-    							    }
-    							    Log.d(TAG, "Account type: "+account.getType()+"; notify: "+notify);
-    							    if (account.isHidden() || !account.isNotify()) {
-    							        notify = false;
-    							    }
-    		                        if (notify) {
-    		                            diff = account.getBalance().subtract(oldAccount.getBalance());
-        								showNotification(account.getName()+ ": "+ ((diff.compareTo(new BigDecimal(0)) == 1) ? "+" : "") + Helpers.formatBalance(diff, account.getCurrency()) + " ("+Helpers.formatBalance(account.getBalance(), account.getCurrency())+")",
-        												 bank.getImageResource(), bank.getDisplayName(), bank.getName());
-                                    }
-    								refreshWidgets = true;
-    							}
-    						}
-    					}
-    					if (prefs.getBoolean("autoupdates_transactions_enabled", true)) {
-    					    bank.updateAllTransactions();    					    
-    					}
-    				}
-    				bank.closeConnection();
-    				db.updateBank(bank);
-    			} 
-    			catch (BankException e) {
-    				// Refresh widgets if an update fails
-    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; BankException: "+e.getMessage());
-    			} catch (LoginException e) {
-                    Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; LoginException: "+e.getMessage());
-    				refreshWidgets = true;
-    				db.disableBank(bank.getDbId());
+					if (diff.compareTo(new BigDecimal(0)) != 0) {
+						Account oldAccount;
+						for (final Account account : bank.getAccounts()) {
+							oldAccount = accounts.get(account.getId());
+							if (oldAccount != null) {
+								if (account.getBalance().compareTo(
+										oldAccount.getBalance()) != 0) {
+									boolean notify = false;
+									switch (account.getType()) {
+									case Account.REGULAR:
+										notify = prefs.getBoolean(
+												"notify_for_deposit", true);
+										break;
+									case Account.FUNDS:
+										notify = prefs.getBoolean(
+												"notify_for_funds", false);
+										break;
+									case Account.LOANS:
+										notify = prefs.getBoolean(
+												"notify_for_loans", false);
+										break;
+									case Account.CCARD:
+										notify = prefs.getBoolean(
+												"notify_for_ccards", true);
+										break;
+									case Account.OTHER:
+										notify = prefs.getBoolean(
+												"notify_for_other", false);
+										break;
+									}
+									Log.d(TAG,
+											"Account type: "
+													+ account.getType()
+													+ "; notify: " + notify);
+									if (account.isHidden()
+											|| !account.isNotify()) {
+										notify = false;
+									}
+									if (notify) {
+										diff = account.getBalance().subtract(
+												oldAccount.getBalance());
+										showNotification(
+												account.getName()
+														+ ": "
+														+ ((diff.compareTo(new BigDecimal(
+																0)) == 1) ? "+"
+																: "")
+														+ Helpers
+																.formatBalance(
+																		diff,
+																		account.getCurrency())
+														+ " ("
+														+ Helpers
+																.formatBalance(
+																		account.getBalance(),
+																		account.getCurrency())
+														+ ")",
+												bank.getImageResource(),
+												bank.getDisplayName(),
+												bank.getName());
+									}
+
+									refreshWidgets = true;
+								}
+							}
+						}
+						if (prefs.getBoolean(
+								"autoupdates_transactions_enabled", true)) {
+							bank.updateAllTransactions();
+						}
+					}
+					bank.closeConnection();
+					db.updateBank(bank);
+				} catch (final BankException e) {
+					// Refresh widgets if an update fails
+					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+							+ "'; BankException: " + e.getMessage());
+				} catch (final LoginException e) {
+					Log.d(TAG, "Error while updating bank '" + bank.getDbId()
+							+ "'; LoginException: " + e.getMessage());
+					refreshWidgets = true;
+					db.disableBank(bank.getDbId());
+				}
+			}
+
+			// Sending updates for all accounts, because we overwrite everything
+			// at this point.
+			if (prefs.getBoolean("content_provider_enabled", false)) {
+				for (final Account account : accounts.values()) {
+					broadcastTransactionUpdate(getBaseContext(), account);
 				}
-    		}
-    		
+			}
+
 			if (refreshWidgets) {
-				Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
+				final Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
 				sendBroadcast(updateIntent);
 				sendWidgetRefresh(AutoRefreshService.this);
 			}
-    		db.close();
-    		return null;
-    	}
+			db.close();
+			return null;
+		}
 
-    	protected void onProgressUpdate(String... args) {
-    	}
-    	protected void onPostExecute(final Void unused) {
-    		if (this.errors != null && !this.errors.isEmpty()) {
-    			StringBuilder errormsg = new StringBuilder();
-    			errormsg.append(res.getText(R.string.accounts_were_not_updated)+":\n");
-    			for (String err : errors)
-    			{
-    			  errormsg.append(err);
-    			  errormsg.append("\n");
-    			}
-    			Log.d("aa", errormsg.toString());
-    		}
-    		AutoRefreshService.this.stopSelf();
-    	}
-    }	
+		@Override
+		protected void onProgressUpdate(final String... args) {
+		}
 
-    
-    public static void sendWidgetRefresh(Context context) {
-    	//Send intent to BankdroidWidgetProvider
-        Intent updateIntent = new Intent(BROADCAST_WIDGET_REFRESH);
-        PendingIntent pendingIntent = PendingIntent.getBroadcast(
-        		context, 0, updateIntent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-            try {
-				pendingIntent.send();
-			} catch (CanceledException e) {
-				// TODO Auto-generated catch block
-				Log.e("", e.getMessage(), e);
+		@Override
+		protected void onPostExecute(final Void unused) {
+			if ((this.errors != null) && !this.errors.isEmpty()) {
+				final StringBuilder errormsg = new StringBuilder();
+				errormsg.append(res.getText(R.string.accounts_were_not_updated)
+						+ ":\n");
+				for (final String err : errors) {
+					errormsg.append(err);
+					errormsg.append("\n");
+				}
+				Log.d("aa", errormsg.toString());
 			}
-    }    
+			AutoRefreshService.this.stopSelf();
+		}
+	}
+
+	public static void broadcastTransactionUpdate(final Context context,
+			final Account account) {
+		final Intent i = new Intent(BROADCAST_TRANSACTIONS_UPDATED);
+		i.putExtra("accountId", account.getId());
+		context.sendBroadcast(i);
+	}
+
+	public static void sendWidgetRefresh(final Context context) {
+		// Send intent to BankdroidWidgetProvider
+		final Intent updateIntent = new Intent(BROADCAST_WIDGET_REFRESH);
+		final PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
+				0, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+		try {
+			pendingIntent.send();
+		} catch (final CanceledException e) {
+			// TODO Auto-generated catch block
+			Log.e("", e.getMessage(), e);
+		}
+	}
 }
\ No newline at end of file

commit 9d3be7e3ab5aeefca40cf251dff753c755e3e044
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Tue Jan 18 23:49:41 2011 +0100

    Made sure that null is returned when the api key is not enabled.
    
    Change-Id: Ide3a3b52829c62b579612ff6630336d49e6692e9

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index a421328..fb47b37 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -148,6 +148,10 @@ public class BankTransactionsProvider extends ContentProvider implements
 			final String selection, final String[] selectionArgs,
 			final String sortOrder) {
 
+		if (!isApiKeyEnabled(getContext())) {
+			return null;
+		}
+
 		final String apiKey = uri.getPathSegments().get(1);
 
 		Log.d(TAG, "Trying to access database with " + apiKey);
@@ -203,7 +207,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 		final SharedPreferences prefs = PreferenceManager
 				.getDefaultSharedPreferences(ctx);
 		if (!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {
-			throw new IllegalArgumentException(
+			throw new IllegalStateException(
 					"Access to Content Provider is not enabled.");
 		}
 
@@ -215,4 +219,10 @@ public class BankTransactionsProvider extends ContentProvider implements
 
 		return apiKey;
 	}
+
+	private boolean isApiKeyEnabled(final Context ctx) {
+		final SharedPreferences prefs = PreferenceManager
+				.getDefaultSharedPreferences(ctx);
+		return prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false);
+	}
 }

commit 692d521cc0f6c1a45b72ac8ee0260d23cf252c3a
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Tue Jan 18 00:26:12 2011 +0100

    Reverted to returning null cursor instead of throwing Exceptions in
    the content provider, because remote exceptions are not supported
    from content providers at this time.
    
    Change-Id: Ib6ce7f16d87fc949529b82bd521801becf6c3726

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 3c1a4b2..a421328 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -44,7 +44,7 @@ import com.liato.bankdroid.db.DatabaseHelper;
  * @see IBankTransactionsProvider
  */
 public class BankTransactionsProvider extends ContentProvider implements
-IBankTransactionsProvider {
+		IBankTransactionsProvider {
 
 	private static final String CONTENT_PROVIDER_ENABLED = "content_provider_enabled";
 	private static final String CONTENT_PROVIDER_API_KEY = "content_provider_api_key";
@@ -55,7 +55,7 @@ IBankTransactionsProvider {
 	private static final String WILD_CARD = "*";
 
 	private static final String BANK_ACCOUNT_TABLES = "banks LEFT JOIN accounts ON banks."
-		+ BANK_ID + " = accounts.bankid";
+			+ BANK_ID + " = accounts.bankid";
 	private static final String TRANSACTIONS_TABLE = "transactions";
 
 	private DatabaseHelper dbHelper;
@@ -102,7 +102,7 @@ IBankTransactionsProvider {
 	public int delete(final Uri uri, final String selection,
 			final String[] selectionArgs) {
 		throw new UnsupportedOperationException(
-		"This provider does not implement the delete method");
+				"This provider does not implement the delete method");
 	}
 
 	/**
@@ -128,7 +128,7 @@ IBankTransactionsProvider {
 	@Override
 	public Uri insert(final Uri uri, final ContentValues values) {
 		throw new UnsupportedOperationException(
-		"This provider does not implement the insert method");
+				"This provider does not implement the insert method");
 	}
 
 	/**
@@ -152,14 +152,18 @@ IBankTransactionsProvider {
 
 		Log.d(TAG, "Trying to access database with " + apiKey);
 
-		if( !apiKey.startsWith(API_KEY, 0 )) {
-			throw new IllegalArgumentException(API_KEY + "<API-KEY> must be a part of the URI!");
+		if (!apiKey.startsWith(API_KEY, 0)) {
+			return null;
+			// throw new IllegalArgumentException(API_KEY +
+			// "<API-KEY> must be a part of the URI!");
 		}
 
-		final String key = apiKey.replace(API_KEY,"");
+		final String key = apiKey.replace(API_KEY, "");
 
-		if( !key.equals(getApiKey(getContext())) ) {
-			throw new IllegalAccessError("The supplied API_KEY does not exist");
+		if (!key.equals(getApiKey(getContext()))) {
+			return null;
+			// throw new
+			// IllegalAccessError("The supplied API_KEY does not exist");
 		}
 
 		final SQLiteDatabase db = dbHelper.getReadableDatabase();
@@ -192,18 +196,20 @@ IBankTransactionsProvider {
 	public int update(final Uri uri, final ContentValues values,
 			final String selection, final String[] selectionArgs) {
 		throw new UnsupportedOperationException(
-		"This provider does not implement the update method");
+				"This provider does not implement the update method");
 	}
 
 	private static String getApiKey(final Context ctx) {
-		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
-		if(!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {
-			throw new IllegalArgumentException("Access to Content Provider is not enabled.");
+		final SharedPreferences prefs = PreferenceManager
+				.getDefaultSharedPreferences(ctx);
+		if (!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {
+			throw new IllegalArgumentException(
+					"Access to Content Provider is not enabled.");
 		}
 
 		final String apiKey = prefs.getString(CONTENT_PROVIDER_API_KEY, "");
 
-		if(apiKey.equals("")) {
+		if (apiKey.equals("")) {
 			throw new IllegalArgumentException("The API-Key must be set.");
 		}
 
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index 884b920..c650c42 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -37,7 +37,8 @@ import java.math.BigDecimal;
  * interface:</b>
  * 
  * <pre>
- * final Uri uri = Uri.parse(&quot;content://&quot; + AUTHORITY + &quot;/&quot; + TRANSACTIONS_CAT);
+ * final Uri uri = Uri.parse(&quot;content://&quot; + AUTHORITY + &quot;/&quot; + TRANSACTIONS_CAT
+ * 		+ &quot;/&quot; + API_KEY + apiKey);
  * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION,
  * 		ACCOUNT_SELECTION_FILTER, new String[] { currentAccountId }, null);
  * startManagingCursor(cur);

commit 4e983816fe3b235de46ea332dceb17f217849fa1
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Mon Jan 17 19:31:31 2011 +0100

    Added support for enabling data sharing and viewing the API-Key
    in the settings dialog. Also enabled so that the API-key is checked when
    trying to access the content provider.

diff --git res/xml/settings.xml res/xml/settings.xml
index 027f3f8..850f2ee 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -69,13 +69,12 @@
 			android:dependency="notify_on_change" />
 		<RingtonePreference
 			android:key="notification_sound"
-			android:name="Select sound"
 			android:summary="Select notification sound"
 			android:title="Notification sound"
 			android:ringtoneType="notification"
 			android:showDefault="true"
 			android:showSilent="true"
-			android:dependency="notify_on_change" />
+			android:dependency="notify_on_change" android:name="Select sound"/>
 		<PreferenceScreen
 			android:key="account_types_screen"
 			android:title="Account types"
@@ -136,6 +135,12 @@
 				android:key="openwatch_help" />
 		</PreferenceScreen>
 	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Share data">
+		
+	<CheckBoxPreference android:title="Enable Sharing Data" android:summary="Enable other installed apps access to your transaction history" android:key="content_provider_enabled"></CheckBoxPreference>
+<EditTextPreference android:title="API Key" android:key="content_provider_api_key" android:summary="Use this key into trusted applications" android:dependency="content_provider_enabled"></EditTextPreference>
+</PreferenceCategory>
 	<PreferenceCategory
 		android:title="Debug">
 		<PreferenceScreen
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 43f9d86..fbff60f 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -18,13 +18,6 @@ package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
-import com.liato.bankdroid.adapters.AccountsAdapter;
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.banking.Account;
-import com.liato.bankdroid.banking.Bank;
-import com.liato.bankdroid.banking.BankFactory;
-import com.liato.bankdroid.db.DBAdapter;
-
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
@@ -32,10 +25,12 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
+import android.preference.PreferenceManager;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -51,105 +46,131 @@ import android.widget.Button;
 import android.widget.ListView;
 import android.widget.TextView;
 
+import com.liato.bankdroid.adapters.AccountsAdapter;
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.db.DBAdapter;
+
 public class MainActivity extends LockableActivity {
 	private final static String TAG = "MainActivity";
 	protected AccountsAdapter adapter = null;
-    private static Bank selected_bank = null;
-    private static Account selected_account = null;
-    protected static boolean showHidden = false;
+	private static Bank selected_bank = null;
+	private static Account selected_account = null;
+	protected static boolean showHidden = false;
 
 	@Override
-	public void onCreate(Bundle savedInstanceState) {
+	public void onCreate(final Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
-        
-        setContentView(R.layout.main);
-        OnClickListener listener = new View.OnClickListener() {
-            public void onClick(View v) {
-                Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
-                startActivity(intentAccount);
-            }
-        };
-		OnClickListener listener2 = new View.OnClickListener() {
-			public void onClick(View v) {
+		initialSetupApiKey();
+
+
+		setContentView(R.layout.main);
+		final OnClickListener listener = new View.OnClickListener() {
+			public void onClick(final View v) {
+				final Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
+				startActivity(intentAccount);
+			}
+		};
+		final OnClickListener listener2 = new View.OnClickListener() {
+			public void onClick(final View v) {
 				new DataRetrieverTask(MainActivity.this).execute();
 			}
 		};
-        this.addTitleButton(R.drawable.title_icon_add, "add", listener);
+		this.addTitleButton(R.drawable.title_icon_add, "add", listener);
 		this.addTitleButton(R.drawable.title_icon_refresh, "refresh", listener2);
 
 		adapter = new AccountsAdapter(this, showHidden);
-		ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
+		final ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
 		adapter.setGroups(banks);
-        ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-        lv.setAdapter(adapter);
+		final ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+		lv.setAdapter(adapter);
 		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
-            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
-                Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
-                if (adapter.getItem(position) instanceof Account) {
-                    selected_account = (Account)adapter.getItem(position);
-                    PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
-                    pmenu.showLikeQuickAction(0, 12);
-                    return true;
-                }
-                return false;
-            }
-        });
+			public boolean onItemLongClick(final AdapterView<?> parent, final View view, final int position, final long id) {
+				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
+				if (adapter.getItem(position) instanceof Account) {
+					selected_account = (Account)adapter.getItem(position);
+					final PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
+					pmenu.showLikeQuickAction(0, 12);
+					return true;
+				}
+				return false;
+			}
+		});
 		lv.setOnItemClickListener(new OnItemClickListener() {
-			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+			public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
 				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
 				if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
-					PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
-					pmenu.showLikeQuickAction(0, 12);					
+					final PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
+					pmenu.showLikeQuickAction(0, 12);
 				}
 				else {
-					Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
-					Account account = (Account) adapter.getItem(position);
+					final Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
+					final Account account = (Account) adapter.getItem(position);
 					intent.putExtra("account", account.getId());
 					intent.putExtra("bank", account.getBankDbId());
 					MainActivity.this.startActivity(intent);
 				}
 			}
 		});
-		
-		Bundle extras = getIntent().getExtras();
+
+		final Bundle extras = getIntent().getExtras();
 		// Clicking on widgets opens their transaction history through MainActivity so that
 		// the user can back out to the main window.
 		if (AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS.equals(getIntent().getAction())) {
-            Intent intent = new Intent(this, TransactionsActivity.class);
-            intent.putExtra("account", extras.getString("account"));
-            intent.putExtra("bank", extras.getLong("bank"));
-            startActivity(intent);		    
+			final Intent intent = new Intent(this, TransactionsActivity.class);
+			intent.putExtra("account", extras.getString("account"));
+			intent.putExtra("bank", extras.getLong("bank"));
+			startActivity(intent);
 		}
 	}
-	
+
+	private void initialSetupApiKey() {
+		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		final String apiKey = prefs.getString("content_provider_api_key", "");
+		if(apiKey.equals("")) {
+			final SharedPreferences.Editor editor = prefs.edit();
+
+			// Create a random HEX String
+			final String genKey = Long.toHexString(Double.doubleToLongBits(Math.random()));
+
+			// Commit to preferences
+			editor.putString("content_provider_api_key", genKey.toUpperCase());
+			editor.commit();
+		}
+	}
+
+	@Override
 	public void onResume() {
 		super.onResume();
 		// Receive refresh Intent from AutoRefreshService and refresh the main view if changes
 		// have been detected.
-		registerReceiver(receiver, new IntentFilter(AutoRefreshService.BROADCAST_MAIN_REFRESH));		
+		registerReceiver(receiver, new IntentFilter(AutoRefreshService.BROADCAST_MAIN_REFRESH));
 		refreshView();
 	}
 
-	private BroadcastReceiver receiver=new BroadcastReceiver() {
-		public void onReceive(Context context, Intent intent) {
+	private final BroadcastReceiver receiver=new BroadcastReceiver() {
+		@Override
+		public void onReceive(final Context context, final Intent intent) {
 			refreshView();
 		}
-	};	
-	
+	};
+
 	public void refreshView() {
 		Log.d(TAG, "refreshView()");
-		ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
+		final ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
 		Log.d(TAG, "Bank count: "+banks.size());
 		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-            showTitleButton("refresh");
+			showTitleButton("refresh");
 			//findViewById(R.id.btnAccountsRefresh).setClickable(true);
 		}
 		else {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
-            hideTitleButton("refresh");
+			hideTitleButton("refresh");
 			//findViewById(R.id.btnAccountsRefresh).setClickable(false);
 		}
 
@@ -158,49 +179,51 @@ public class MainActivity extends LockableActivity {
 		adapter.notifyDataSetChanged();
 	}
 
-	public boolean onCreateOptionsMenu(Menu menu) {
+	@Override
+	public boolean onCreateOptionsMenu(final Menu menu) {
 		super.onCreateOptionsMenu(menu);
-		MenuInflater inflater = new MenuInflater(this);
+		final MenuInflater inflater = new MenuInflater(this);
 		inflater.inflate(R.menu.menu, menu);
 		return true;
 	}
 
 
 	@Override
-	protected Dialog onCreateDialog(int id) {
+	protected Dialog onCreateDialog(final int id) {
 		super.onCreateDialog(id);
-		Dialog dialog = new Dialog(this);
+		final Dialog dialog = new Dialog(this);
 		dialog.setContentView(R.layout.about);
 		dialog.setTitle(getString(R.string.about));
 		PackageInfo pInfo;
 		String version = "v1.x.x";
 		try {
 			pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
-			version = pInfo.versionName;		
-		} catch (NameNotFoundException e) {
+			version = pInfo.versionName;
+		} catch (final NameNotFoundException e) {
 			e.printStackTrace();
 		}
 		((TextView)dialog.findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));
 		return dialog;
 	}
 
-	public boolean onOptionsItemSelected (MenuItem item){
+	@Override
+	public boolean onOptionsItemSelected (final MenuItem item){
 		Intent intent;
 		switch (item.getItemId()) {
 		case R.id.toggle_hidden:
-		    showHidden = !showHidden;
-		    if (showHidden) {
-		        item.setTitle(R.string.menu_hide_hidden);
-		    }
-		    else {
-		        item.setTitle(R.string.menu_show_hidden);
-		    }
-		    refreshView();
+			showHidden = !showHidden;
+			if (showHidden) {
+				item.setTitle(R.string.menu_hide_hidden);
+			}
+			else {
+				item.setTitle(R.string.menu_show_hidden);
+			}
+			refreshView();
 			return true;
 		case R.id.settings:
 			intent = new Intent(this, SettingsActivity.class);
 			this.startActivity(intent);
-	        //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
+			//Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
 			return true;
 		case R.id.about:
 			showDialog(0);
@@ -209,9 +232,10 @@ public class MainActivity extends LockableActivity {
 		return false;
 	}
 
+	@Override
 	public void onDestroy() {
 		super.onDestroy();
-		unregisterReceiver(receiver);  
+		unregisterReceiver(receiver);
 	}
 
 	/**
@@ -224,7 +248,7 @@ public class MainActivity extends LockableActivity {
 	 */
 	private static class PopupMenuBank extends BetterPopupWindow implements OnClickListener {
 		MainActivity parent = null;
-		public PopupMenuBank(View anchor, MainActivity parent) {
+		public PopupMenuBank(final View anchor, final MainActivity parent) {
 			super(anchor);
 			this.parent = parent;
 		}
@@ -232,10 +256,10 @@ public class MainActivity extends LockableActivity {
 		@Override
 		protected void onCreate() {
 			// inflate layout
-			LayoutInflater inflater =
+			final LayoutInflater inflater =
 				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-			ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
+			final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
 			root.findViewById(R.id.btnRefresh).setOnClickListener(this);
 			root.findViewById(R.id.btnWWW).setOnClickListener(this);
 			root.findViewById(R.id.btnEdit).setOnClickListener(this);
@@ -246,39 +270,39 @@ public class MainActivity extends LockableActivity {
 		}
 
 		@Override
-		public void onClick(View v) {
+		public void onClick(final View v) {
 			final Context context = this.anchor.getContext();
-			int id = v.getId();
+			final int id = v.getId();
 			switch (id) {
 			case R.id.btnWWW:
 				if (selected_bank != null) {
 					//Uri uri = Uri.parse(selected_bank.getURL());
 					//Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-				    Intent intent = new Intent(context, WebViewActivity.class);
-	                intent.putExtra("bankid", selected_bank.getDbId());
+					final Intent intent = new Intent(context, WebViewActivity.class);
+					intent.putExtra("bankid", selected_bank.getDbId());
 					context.startActivity(intent);
 				}
 				this.dismiss();
-				return; 
+				return;
 			case R.id.btnEdit:
-				Intent intent = new Intent(context, BankEditActivity.class);
+				final Intent intent = new Intent(context, BankEditActivity.class);
 				intent.putExtra("id", selected_bank.getDbId());
 				context.startActivity(intent);
 				this.dismiss();
-				return; 
+				return;
 			case R.id.btnRefresh:
 				this.dismiss();
 				new DataRetrieverTask(parent, selected_bank.getDbId()).execute();
-				return; 
+				return;
 			case R.id.btnRemove:
 				this.dismiss();
-				AlertDialog.Builder builder = new AlertDialog.Builder(context);
+				final AlertDialog.Builder builder = new AlertDialog.Builder(context);
 				//builder.setMessage(getText(R.string.passwords_mismatch)).setTitle(getText(R.string.passwords_mismatch_title))
 				builder.setMessage(context.getText(R.string.remove_bank_msg)).setTitle(context.getText(R.string.remove_bank_title))
 				.setIcon(android.R.drawable.ic_dialog_alert)
 				.setPositiveButton(context.getText(R.string.yes), new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
-						DBAdapter db = new DBAdapter(context);
+					public void onClick(final DialogInterface dialog, final int id) {
+						final DBAdapter db = new DBAdapter(context);
 						db.open();
 						db.deleteBank(selected_bank.getDbId());
 						db.close();
@@ -287,101 +311,101 @@ public class MainActivity extends LockableActivity {
 					}
 				})
 				.setNegativeButton(context.getText(R.string.no), new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
+					public void onClick(final DialogInterface dialog, final int id) {
 						dialog.cancel();
 					}
-				});				
-				AlertDialog alert = builder.create();
+				});
+				final AlertDialog alert = builder.create();
 				alert.show();
 				return;
 			}
 
 		}
 	}
-	
-	
-    /**
-     * Extends {@link BetterPopupWindow}
-     * <p>
-     * Overrides onCreate to create the view and register the button listeners
-     * 
-     * @author qbert
-     * 
-     */
-    private static class PopupMenuAccount extends BetterPopupWindow implements OnClickListener {
-        MainActivity parent = null;
-        public PopupMenuAccount(View anchor, MainActivity parent) {
-            super(anchor);
-            this.parent = parent;
-        }
-
-        @Override
-        protected void onCreate() {
-            Log.d(TAG, "PopUpMenuAcc, oncreate");
-            // inflate layout
-            LayoutInflater inflater =
-                (LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-            ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, null);
-            Button btnHide = (Button) root.findViewById(R.id.btnHide);
-            Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
-            Button btnDisableNotifications = (Button)root.findViewById(R.id.btnDisableNotifications);
-            Button btnEnableNotifications = (Button)root.findViewById(R.id.btnEnableNotifications);
-            if (selected_account.isHidden()) {
-                btnHide.setVisibility(View.GONE);
-                btnUnhide.setVisibility(View.VISIBLE);
-                btnUnhide.setOnClickListener(this);
-            }
-            else {
-                btnHide.setVisibility(View.VISIBLE);
-                btnUnhide.setVisibility(View.GONE);
-                btnHide.setOnClickListener(this);
-            }
-            if (selected_account.isNotify()) {
-                btnDisableNotifications.setVisibility(View.VISIBLE);
-                btnDisableNotifications.setOnClickListener(this);
-                btnEnableNotifications.setVisibility(View.GONE);
-            }
-            else {
-                btnDisableNotifications.setVisibility(View.GONE);
-                btnEnableNotifications.setOnClickListener(this);
-                btnEnableNotifications.setVisibility(View.VISIBLE);
-            }            
-            this.setContentView(root);
-        }
-
-        @Override
-        public void onClick(View v) {
-            int id = v.getId();
-            switch (id) {
-            case R.id.btnHide:
-                this.dismiss();
-                selected_account.setHidden(true);
-                selected_account.getBank().save();
-                parent.refreshView();
-                return; 
-            case R.id.btnUnhide:
-                this.dismiss();
-                selected_account.setHidden(false);
-                selected_account.getBank().save();
-                parent.refreshView();
-                return; 
-            case R.id.btnEnableNotifications:
-                this.dismiss();
-                selected_account.setNotify(true);
-                selected_account.getBank().save();
-                parent.refreshView();
-                return; 
-            case R.id.btnDisableNotifications:
-                this.dismiss();
-                selected_account.setNotify(false);
-                selected_account.getBank().save();
-                parent.refreshView();
-                return; 
-
-            }
-
-        }
-    }	
+
+
+	/**
+	 * Extends {@link BetterPopupWindow}
+	 * <p>
+	 * Overrides onCreate to create the view and register the button listeners
+	 * 
+	 * @author qbert
+	 * 
+	 */
+	private static class PopupMenuAccount extends BetterPopupWindow implements OnClickListener {
+		MainActivity parent = null;
+		public PopupMenuAccount(final View anchor, final MainActivity parent) {
+			super(anchor);
+			this.parent = parent;
+		}
+
+		@Override
+		protected void onCreate() {
+			Log.d(TAG, "PopUpMenuAcc, oncreate");
+			// inflate layout
+			final LayoutInflater inflater =
+				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+			final ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, null);
+			final Button btnHide = (Button) root.findViewById(R.id.btnHide);
+			final Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
+			final Button btnDisableNotifications = (Button)root.findViewById(R.id.btnDisableNotifications);
+			final Button btnEnableNotifications = (Button)root.findViewById(R.id.btnEnableNotifications);
+			if (selected_account.isHidden()) {
+				btnHide.setVisibility(View.GONE);
+				btnUnhide.setVisibility(View.VISIBLE);
+				btnUnhide.setOnClickListener(this);
+			}
+			else {
+				btnHide.setVisibility(View.VISIBLE);
+				btnUnhide.setVisibility(View.GONE);
+				btnHide.setOnClickListener(this);
+			}
+			if (selected_account.isNotify()) {
+				btnDisableNotifications.setVisibility(View.VISIBLE);
+				btnDisableNotifications.setOnClickListener(this);
+				btnEnableNotifications.setVisibility(View.GONE);
+			}
+			else {
+				btnDisableNotifications.setVisibility(View.GONE);
+				btnEnableNotifications.setOnClickListener(this);
+				btnEnableNotifications.setVisibility(View.VISIBLE);
+			}
+			this.setContentView(root);
+		}
+
+		@Override
+		public void onClick(final View v) {
+			final int id = v.getId();
+			switch (id) {
+			case R.id.btnHide:
+				this.dismiss();
+				selected_account.setHidden(true);
+				selected_account.getBank().save();
+				parent.refreshView();
+				return;
+			case R.id.btnUnhide:
+				this.dismiss();
+				selected_account.setHidden(false);
+				selected_account.getBank().save();
+				parent.refreshView();
+				return;
+			case R.id.btnEnableNotifications:
+				this.dismiss();
+				selected_account.setNotify(true);
+				selected_account.getBank().save();
+				parent.refreshView();
+				return;
+			case R.id.btnDisableNotifications:
+				this.dismiss();
+				selected_account.setNotify(false);
+				selected_account.getBank().save();
+				parent.refreshView();
+				return;
+
+			}
+
+		}
+	}
 
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index d413e92..5bbd4fd 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -16,130 +16,131 @@
 
 package com.liato.bankdroid;
 
-import com.liato.bankdroid.appwidget.AutoRefreshService;
-import com.liato.bankdroid.lockpattern.ChooseLockPattern;
-import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
-import com.liato.bankdroid.lockpattern.LockPatternUtils;
-
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
-import android.preference.PreferenceScreen;
 import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
 import android.util.Log;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.lockpattern.ChooseLockPattern;
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 public class SettingsActivity extends LockablePreferenceActivity implements OnPreferenceClickListener {
-    private final static String TAG = "SettingsActivity";
-    private final static int DISABLE_LOCKPATTERN = 1;
-    private final static int ENABLE_LOCKPATTERN = 2;
-    private final static int CHANGE_LOCKPATTERN = 3;
-    private LockPatternUtils mLockPatternUtils;
-    
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mLockPatternUtils = new LockPatternUtils(this);
-        addPreferencesFromResource(R.xml.settings);
-        getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
-        ((Preference)findPreference("patternlock_change")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("patternlock_change")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("remotenotifier_help")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("openwatch_help")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("account_types_screen")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("autoupdates_enabled")).setOnPreferenceClickListener(this);
-        ((Preference)findPreference("notification_sound")).setOnPreferenceClickListener(this);
-        CheckBoxPreference patternLock = ((CheckBoxPreference)findPreference("patternlock_enabled"));
-        patternLock.setOnPreferenceClickListener(this);
-        // Check the pattern lock check box if the lock pattern is enabled
-        patternLock.setChecked(mLockPatternUtils.isLockPatternEnabled());
-    }
+	private final static String TAG = "SettingsActivity";
+	private final static int DISABLE_LOCKPATTERN = 1;
+	private final static int ENABLE_LOCKPATTERN = 2;
+	private final static int CHANGE_LOCKPATTERN = 3;
+	private LockPatternUtils mLockPatternUtils;
+
+	/** Called when the activity is first created. */
+	@Override
+	public void onCreate(final Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		mLockPatternUtils = new LockPatternUtils(this);
+		addPreferencesFromResource(R.xml.settings);
+		getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
+		(findPreference("patternlock_change")).setOnPreferenceClickListener(this);
+		(findPreference("patternlock_change")).setOnPreferenceClickListener(this);
+		(findPreference("remotenotifier_help")).setOnPreferenceClickListener(this);
+		(findPreference("openwatch_help")).setOnPreferenceClickListener(this);
+		(findPreference("account_types_screen")).setOnPreferenceClickListener(this);
+		(findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
+		(findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
+		(findPreference("autoupdates_enabled")).setOnPreferenceClickListener(this);
+		(findPreference("notification_sound")).setOnPreferenceClickListener(this);
+		final CheckBoxPreference patternLock = ((CheckBoxPreference)findPreference("patternlock_enabled"));
+		patternLock.setOnPreferenceClickListener(this);
+		// Check the pattern lock check box if the lock pattern is enabled
+		patternLock.setChecked(mLockPatternUtils.isLockPatternEnabled());
+	}
+
+	@Override
+	public boolean onPreferenceClick(final Preference pref) {
+		final String prefKey = pref.getKey();
+		if ("account_types_screen".equals(prefKey) || "openwatch_screen".equals(prefKey) || "remotenotifier_screen".equals(prefKey)) {
+			((PreferenceScreen)pref).getDialog().getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
+			return false;
+		}
+
+		if ("notification_sound".equals(prefKey)) {
+			this.setLockEnabled(false);
+			return false;
+		}
+
+		if ("patternlock_enabled".equals(prefKey)) {
+			this.setLockEnabled(false);
+			if (mLockPatternUtils.isLockPatternEnabled()) {
+				// The user is trying to disable the lock pattern,
+				// only disable if the user knows the pattern.
+				startActivityForResult(new Intent(this, ConfirmLockPattern.class), DISABLE_LOCKPATTERN);
+				return true;
+			}
+			else {
+				// No lock pattern has been set yet, let the user choose a new one.
+				startActivityForResult(new Intent(this, ChooseLockPattern.class), ENABLE_LOCKPATTERN);
+				return true;
+			}
+		}
+		else if ("patternlock_change".equals(prefKey)) {
+			this.setLockEnabled(false);
+			startActivityForResult(new Intent(this, ChooseLockPattern.class), CHANGE_LOCKPATTERN);
+			return true;
+		}
+		else if ("remotenotifier_help".equals(prefKey)) {
+			startActivity(new Intent(Intent.ACTION_VIEW,
+					Uri.parse("http://code.google.com/p/android-notifier/")));
+			return true;
+		}
+		else if ("openwatch_help".equals(prefKey)) {
+			startActivity(new Intent(Intent.ACTION_VIEW,
+					Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	protected void onActivityResult(final int requestCode, final int resultCode,
+			final Intent data) {
+		super.onActivityResult(requestCode, resultCode, data);
+		Log.d(TAG, "onActivityResult: req:"+requestCode+"; res:"+resultCode);
+		if (requestCode == DISABLE_LOCKPATTERN) {
+			if (resultCode == RESULT_OK) {
+				mLockPatternUtils.setLockPatternEnabled(false);
+				mLockPatternUtils.saveLockPattern(null);
+				((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(false);
+				Log.d(TAG, "Pattern lock has been disabled.");
+			}
+			else {
+				Log.d(TAG, "User was unable to disable pattern lock.");
+			}
+		}
+		else if (requestCode == ENABLE_LOCKPATTERN) {
+			// User attempted to enable the pattern lock, toggle the checkbox.
+			((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(mLockPatternUtils.isLockPatternEnabled());
+		}
+		else if (requestCode == CHANGE_LOCKPATTERN) {
+			// Don't do anything special
+		}
+	}
 
-    @Override
-    public boolean onPreferenceClick(Preference pref) {
-        String prefKey = pref.getKey();
-        if ("account_types_screen".equals(prefKey) || "openwatch_screen".equals(prefKey) || "remotenotifier_screen".equals(prefKey)) {
-            ((PreferenceScreen)pref).getDialog().getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
-            return false;            
-        }
-        
-        if ("notification_sound".equals(prefKey)) {
-            this.setLockEnabled(false);
-            return false;
-        }
-        
-        if ("patternlock_enabled".equals(prefKey)) {
-            this.setLockEnabled(false);
-            if (mLockPatternUtils.isLockPatternEnabled()) {
-                // The user is trying to disable the lock pattern,
-                // only disable if the user knows the pattern.
-                startActivityForResult(new Intent(this, ConfirmLockPattern.class), DISABLE_LOCKPATTERN);
-                return true;
-            }
-            else {
-                // No lock pattern has been set yet, let the user choose a new one.
-                startActivityForResult(new Intent(this, ChooseLockPattern.class), ENABLE_LOCKPATTERN);
-                return true;
-            }
-        }
-        else if ("patternlock_change".equals(prefKey)) {
-            this.setLockEnabled(false);
-            startActivityForResult(new Intent(this, ChooseLockPattern.class), CHANGE_LOCKPATTERN);
-            return true;
-        }
-        else if ("remotenotifier_help".equals(prefKey)) {
-            startActivity(new Intent(Intent.ACTION_VIEW,
-                    Uri.parse("http://code.google.com/p/android-notifier/")));            
-            return true;
-        }
-        else if ("openwatch_help".equals(prefKey)) {
-            startActivity(new Intent(Intent.ACTION_VIEW,
-                                     Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));            
-            return true;
-        }
-        return false;
-    }
-    
-    protected void onActivityResult(int requestCode, int resultCode,
-            Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-        Log.d(TAG, "onActivityResult: req:"+requestCode+"; res:"+resultCode);
-        if (requestCode == DISABLE_LOCKPATTERN) {
-            if (resultCode == RESULT_OK) {
-                mLockPatternUtils.setLockPatternEnabled(false);
-                mLockPatternUtils.saveLockPattern(null);
-                ((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(false);
-                Log.d(TAG, "Pattern lock has been disabled.");
-            }
-            else {
-                Log.d(TAG, "User was unable to disable pattern lock.");
-            }
-        }
-        else if (requestCode == ENABLE_LOCKPATTERN) {
-            // User attempted to enable the pattern lock, toggle the checkbox.
-            ((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(mLockPatternUtils.isLockPatternEnabled());
-        }
-        else if (requestCode == CHANGE_LOCKPATTERN) {
-            // Don't do anything special
-        }
-    }
+	@Override
+	protected void onResume() {
+		super.onResume();
+		this.setLockEnabled(true);
+	}
 
-    @Override
-    protected void onResume() {
-        super.onResume();
-        this.setLockEnabled(true);
-    }
+	@Override
+	protected void onPause() {
+		super.onPause();
+		StartupReceiver.setAlarm(this);
+		// Blur/unblur the widget balance
+		AutoRefreshService.sendWidgetRefresh(this);
+	}
 
-    @Override
-    protected void onPause() {
-        super.onPause();
-        StartupReceiver.setAlarm(this);
-        // Blur/unblur the widget balance
-        AutoRefreshService.sendWidgetRefresh(this);
-    }
-    
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 906d8ef..3c1a4b2 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -21,11 +21,14 @@ import java.util.Map;
 
 import android.content.ContentProvider;
 import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.UriMatcher;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
+import android.preference.PreferenceManager;
 import android.util.Log;
 
 import com.liato.bankdroid.db.DatabaseHelper;
@@ -41,7 +44,10 @@ import com.liato.bankdroid.db.DatabaseHelper;
  * @see IBankTransactionsProvider
  */
 public class BankTransactionsProvider extends ContentProvider implements
-		IBankTransactionsProvider {
+IBankTransactionsProvider {
+
+	private static final String CONTENT_PROVIDER_ENABLED = "content_provider_enabled";
+	private static final String CONTENT_PROVIDER_API_KEY = "content_provider_api_key";
 
 	private final static String TAG = "BankTransactionsProvider";
 	private final static int TRANSACTIONS = 0;
@@ -49,7 +55,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 	private static final String WILD_CARD = "*";
 
 	private static final String BANK_ACCOUNT_TABLES = "banks LEFT JOIN accounts ON banks."
-			+ BANK_ID + " = accounts.bankid";
+		+ BANK_ID + " = accounts.bankid";
 	private static final String TRANSACTIONS_TABLE = "transactions";
 
 	private DatabaseHelper dbHelper;
@@ -96,7 +102,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 	public int delete(final Uri uri, final String selection,
 			final String[] selectionArgs) {
 		throw new UnsupportedOperationException(
-				"This provider does not implement the delete method");
+		"This provider does not implement the delete method");
 	}
 
 	/**
@@ -122,7 +128,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 	@Override
 	public Uri insert(final Uri uri, final ContentValues values) {
 		throw new UnsupportedOperationException(
-				"This provider does not implement the insert method");
+		"This provider does not implement the insert method");
 	}
 
 	/**
@@ -143,11 +149,17 @@ public class BankTransactionsProvider extends ContentProvider implements
 			final String sortOrder) {
 
 		final String apiKey = uri.getPathSegments().get(1);
+
 		Log.d(TAG, "Trying to access database with " + apiKey);
 
-		if (apiKey == null) {
+		if( !apiKey.startsWith(API_KEY, 0 )) {
+			throw new IllegalArgumentException(API_KEY + "<API-KEY> must be a part of the URI!");
+		}
+
+		final String key = apiKey.replace(API_KEY,"");
+
+		if( !key.equals(getApiKey(getContext())) ) {
 			throw new IllegalAccessError("The supplied API_KEY does not exist");
-			// TODO: API_KEY: Implement property loader here.
 		}
 
 		final SQLiteDatabase db = dbHelper.getReadableDatabase();
@@ -180,7 +192,21 @@ public class BankTransactionsProvider extends ContentProvider implements
 	public int update(final Uri uri, final ContentValues values,
 			final String selection, final String[] selectionArgs) {
 		throw new UnsupportedOperationException(
-				"This provider does not implement the update method");
+		"This provider does not implement the update method");
 	}
 
+	private static String getApiKey(final Context ctx) {
+		final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
+		if(!prefs.getBoolean(CONTENT_PROVIDER_ENABLED, false)) {
+			throw new IllegalArgumentException("Access to Content Provider is not enabled.");
+		}
+
+		final String apiKey = prefs.getString(CONTENT_PROVIDER_API_KEY, "");
+
+		if(apiKey.equals("")) {
+			throw new IllegalArgumentException("The API-Key must be set.");
+		}
+
+		return apiKey;
+	}
 }

commit 31fce77cc4053e5d9f123b09164a5c8e8bf68328
Merge: 38ca090 e86a926
Author: liato <x@x00.us>
Date:   Mon Jan 17 03:08:50 2011 +0100

    Merge branch 'dinerstransact' of git://github.com/mhagander/android-bankdroid into mhagander-dinerstransact

commit 80bb35158320654bc89b8053cd9d4eff4fe5baf0
Author: Pierre Chateau <pierre@chateau.se>
Date:   Sat Jan 15 21:24:49 2011 +0100

    Placeholder logo

diff --git res/drawable/logo_rikslunchen.png res/drawable/logo_rikslunchen.png
new file mode 100644
index 0000000..fb3e088
Binary files /dev/null and res/drawable/logo_rikslunchen.png differ

commit 23c60c840ae34211393d47fb51ce718e24b97b34
Author: Pierre Chateau <pierre@chateau.se>
Date:   Sat Jan 15 21:24:15 2011 +0100

    Added Rikslunchen support

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index d1988b1..b12d339 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -64,7 +64,8 @@ public abstract class Bank implements Comparable<Bank> {
     public final static int IKANOBANK = 18;
     public final static int STEAM = 19;
     public final static int DINERSCLUB = 20;
-
+    public final static int RIKSLUNCHEN = 21;
+    
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
 	protected String NAME_SHORT = "bank";
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 9fad560..a16bcd1 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -41,6 +41,7 @@ import com.liato.bankdroid.banking.banks.Nordea;
 import com.liato.bankdroid.banking.banks.OKQ8;
 import com.liato.bankdroid.banking.banks.PayPal;
 import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.Rikslunchen;
 import com.liato.bankdroid.banking.banks.Statoil;
 import com.liato.bankdroid.banking.banks.Steam;
 import com.liato.bankdroid.banking.banks.Swedbank;
@@ -96,6 +97,8 @@ public class BankFactory {
             return new DinersClub(context);
         case Bank.IKANOBANK:
             return new IkanoBank(context);
+        case Bank.RIKSLUNCHEN:
+            return new Rikslunchen(context);            
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -124,6 +127,7 @@ public class BankFactory {
         banks.add(new Steam(context));
         banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
+        banks.add(new Rikslunchen(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/Rikslunchen.java src/com/liato/bankdroid/banking/banks/Rikslunchen.java
new file mode 100644
index 0000000..39afb08
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Rikslunchen.java
@@ -0,0 +1,125 @@
+package com.liato.bankdroid.banking.banks;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.InputType;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
+
+public class Rikslunchen extends Bank {
+
+	private static final String TAG = "Rikslunchen";
+	private static final String NAME = "Rikslunchen";
+	private static final String NAME_SHORT = "rikslunchen";
+	private static final String URL = "http://www.rikslunchen.se/index.html";
+	private static final int BANKTYPE_ID = Bank.RIKSLUNCHEN;
+	private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+
+	private String myResponse = "";
+
+	public Rikslunchen(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_HINT_USERNAME = "Rikslunchen";
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+	}
+
+	public Rikslunchen(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+		urlopen = new Urllib(true, true);
+
+		List<NameValuePair> postData = new ArrayList<NameValuePair>();
+		postData.add(new BasicNameValuePair("c0-param0", "string:" + password));
+		postData.add(new BasicNameValuePair("callCount", "1"));
+		postData.add(new BasicNameValuePair("windowName", ""));
+		postData.add(new BasicNameValuePair("c0-scriptName", "cardUtil"));
+		postData.add(new BasicNameValuePair("c0-methodName", "getCardData"));
+		postData.add(new BasicNameValuePair("c0-id", "0"));
+		postData.add(new BasicNameValuePair("batchId", "1"));
+		postData.add(new BasicNameValuePair("page", "%2Findex.html"));
+		postData.add(new BasicNameValuePair("httpSessionId", ""));
+		postData.add(new BasicNameValuePair("scriptSessionId", ""));
+
+		HttpClient httpclient = new DefaultHttpClient();
+		HttpPost httppost = new HttpPost("http://www.rikslunchen.se/dwr/call/plaincall/cardUtil.getCardData.dwr");
+		httppost.setEntity(new UrlEncodedFormEntity(postData));
+
+		HttpResponse response = httpclient.execute(httppost);
+		InputStream streamResponse = response.getEntity().getContent();
+		StringWriter writer = new StringWriter();
+		IOUtils.copy(streamResponse, writer);
+
+		return new LoginPackage(urlopen, postData, writer.toString(), "http://www.rikslunchen.se/dwr/call/plaincall/cardUtil.getCardData.dwr");
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		try {
+			LoginPackage lp = preLogin();
+
+			if (lp.getResponse().contains("Ange giltigt kortnummer.")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+
+			myResponse = lp.getResponse();
+
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (password == null || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		try {
+
+			int begin = myResponse.indexOf("balance");
+			int end = myResponse.indexOf("cardNo");
+			BigDecimal balance = Helpers.parseBalance(myResponse.substring(begin + 9, end - 2));
+
+			accounts.add(new Account("Rikslunchen", balance, "1"));
+		} finally {
+			super.updateComplete();
+		}
+	}
+}
\ No newline at end of file

commit a0855f732bdc7a6dfca8951a802b368a64438de2
Author: Pierre Chateau <pierre@chateau.se>
Date:   Sat Jan 15 21:22:25 2011 +0100

    Changed onItemSelected so that if Rikslunchen is being edited, then Username is removed and Password is changed to @string/card_id

diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 1939fb6..f13a621 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -34,6 +34,7 @@ import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.text.InputFilter;
 import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -114,14 +115,42 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
 		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
-		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
-		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
-		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
-        //Not possible to set a textfield to both PHONE and PASSWORD :\
-		EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
-		edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
-		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
-		edtPassword.setTypeface(Typeface.MONOSPACE);
+		
+		if (SELECTED_BANK.getBanktypeId() == Bank.RIKSLUNCHEN)
+		{
+			//Remove Username
+			EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);			
+			edtUsername.setVisibility(EditText.GONE);			
+			TextView txtUsername = (TextView)findViewById(R.id.txtBankeditUsername);
+			txtUsername.setVisibility(TextView.GONE);
+			
+			EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+			edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
+			
+			//Change Password to Card ID
+			TextView txtBankeditPassword = (TextView)findViewById(R.id.txtBankeditPassword);
+			txtBankeditPassword.setText(R.string.card_id);
+			
+			// Max 8 numeric characters
+			InputFilter[] filterArray = new InputFilter[1];
+			filterArray[0] = new InputFilter.LengthFilter(8);
+			edtPassword.setFilters(filterArray);			
+			
+			edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+			edtPassword.setTypeface(Typeface.MONOSPACE);			
+		}
+		else
+		{		
+			SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
+			EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
+			edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
+			edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
+	        //Not possible to set a textfield to both PHONE and PASSWORD :\
+			EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+			edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
+			edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+			edtPassword.setTypeface(Typeface.MONOSPACE);
+		}
         
 	}
 

commit a8abf81fd3a5b9711741859b5071457054e7143a
Author: Pierre Chateau <pierre@chateau.se>
Date:   Sat Jan 15 21:21:46 2011 +0100

    Added strings for card_id

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 43a69e7..b1c4ff8 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -199,4 +199,5 @@
 	<string name="lock_cancel">Avbryt</string>
 	<string name="lock_ok">Ok</string>
     
+<string name="card_id">Kort ID</string>
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 9397845..a53716b 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -200,4 +200,5 @@
 	<string name="lock_cancel">Cancel</string>
 	<string name="lock_ok">Ok</string>
          
+<string name="card_id">Card ID</string>
 </resources>

commit 9ed46c18c9040e5056bb559a8406742abe89f7a9
Author: Pierre Chateau <pierre@chateau.se>
Date:   Sat Jan 15 21:19:53 2011 +0100

    Added IDs to Username and Password TextViews, so they can be manipulated in code.

diff --git res/layout/bank.xml res/layout/bank.xml
index 4d22c6b..1c096b9 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -25,7 +25,8 @@
 				android:layout_height="wrap_content"
 				android:typeface="sans"
 				android:textSize="20sp"
-				android:text="@string/username" />
+				android:text="@string/username"				
+				android:id="@+id/txtBankeditUsername"/>
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
@@ -34,8 +35,9 @@
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
 				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/password" />
+				android:textSize="20sp"				
+				android:text="@string/password" 
+				android:id="@+id/txtBankeditPassword"/>
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"

commit c76ffaf430b7b446afde7694e0ddf8072d879c4f
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sun Jan 9 04:28:49 2011 +0100

    Marked where API_KEY property loader needs to be implemented.
    
    Change-Id: Iffb0364da71efc9255a9025b08d143ce3d6762b6

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index f1d87e0..906d8ef 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -147,7 +147,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 
 		if (apiKey == null) {
 			throw new IllegalAccessError("The supplied API_KEY does not exist");
-			// TODO: Implement property loader here.
+			// TODO: API_KEY: Implement property loader here.
 		}
 
 		final SQLiteDatabase db = dbHelper.getReadableDatabase();

commit 8478b7aed00a26e745595c86e1adc1b23312b7e6
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sun Jan 9 04:22:07 2011 +0100

    Added so that the API_KEY is ready for implementation, need to
     add property to allow the user to set it themselves.
    
    Change-Id: I5405bda01ffadbbdb23fccd5fed099bcd8ef4cf8

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index b961343..f1d87e0 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -44,9 +44,9 @@ public class BankTransactionsProvider extends ContentProvider implements
 		IBankTransactionsProvider {
 
 	private final static String TAG = "BankTransactionsProvider";
-
 	private final static int TRANSACTIONS = 0;
-	private static final int BANK_ACCOUNTS = 1;
+	private final static int BANK_ACCOUNTS = 1;
+	private static final String WILD_CARD = "*";
 
 	private static final String BANK_ACCOUNT_TABLES = "banks LEFT JOIN accounts ON banks."
 			+ BANK_ID + " = accounts.bankid";
@@ -59,8 +59,10 @@ public class BankTransactionsProvider extends ContentProvider implements
 
 	static {
 		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-		uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT, TRANSACTIONS);
-		uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT, BANK_ACCOUNTS);
+		uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/" + WILD_CARD,
+				TRANSACTIONS);
+		uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT + "/" + WILD_CARD,
+				BANK_ACCOUNTS);
 
 		// Projections are "Poor mans views" of the data.
 		bankAccountProjectionMap = new HashMap<String, String>();
@@ -102,6 +104,8 @@ public class BankTransactionsProvider extends ContentProvider implements
 	 */
 	@Override
 	public String getType(final Uri uri) {
+		Log.d(TAG, "Got URI " + uri.toString());
+
 		switch (uriMatcher.match(uri)) {
 		case BANK_ACCOUNTS:
 			return BANK_ACCOUNTS_MIME;
@@ -138,14 +142,22 @@ public class BankTransactionsProvider extends ContentProvider implements
 			final String selection, final String[] selectionArgs,
 			final String sortOrder) {
 
+		final String apiKey = uri.getPathSegments().get(1);
+		Log.d(TAG, "Trying to access database with " + apiKey);
+
+		if (apiKey == null) {
+			throw new IllegalAccessError("The supplied API_KEY does not exist");
+			// TODO: Implement property loader here.
+		}
+
 		final SQLiteDatabase db = dbHelper.getReadableDatabase();
 		SQLiteQueryBuilder qb;
+
 		if (BANK_ACCOUNTS_MIME.equals(getType(uri))) {
 			qb = new SQLiteQueryBuilder();
 			qb.setTables(BANK_ACCOUNT_TABLES);
 			qb.setProjectionMap(bankAccountProjectionMap);
 			qb.setDistinct(true);
-			Log.d(TAG, "");
 		} else if (TRANSACTIONS_MIME.equals(getType(uri))) {
 			qb = new SQLiteQueryBuilder();
 			qb.setTables(TRANSACTIONS_TABLE);
@@ -153,12 +165,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 		} else {
 			throw new IllegalArgumentException("Unsupported URI: " + uri);
 		}
-		/*
-		 * Select Statement to build: SELECT banks._id, banks.custname,
-		 * banks.banktype, banks.updated, accounts.id, accounts.name,
-		 * accounts.acctype FROM banks, accounts WHERE banks._id =
-		 * accounts.bankid AND accounts.hidden = 0;
-		 */
+
 		final Cursor cur = qb.query(db, projection, selection, selectionArgs,
 				null, null, sortOrder);
 
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index 11eb764..884b920 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -26,7 +26,9 @@ import java.math.BigDecimal;
  * <p>
  * Uri format for querying for all transaction of a given bank/account
  * combination:<br/>
- * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}</code>
+ * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}/{{@link #API_KEY}}={yourkey}</code>
+ * <br>
+ * <code><b>Would result in: content://com.liato.bankdroid.provider.BankTransactionsProvider/transactions/API_KEY=AAABBBCCC111222</code>
  * </b>
  * </p>
  * 
@@ -57,6 +59,13 @@ public interface IBankTransactionsProvider {
 	 */
 	String AUTHORITY = "com.liato.bankdroid.provider.BankTransactionsProvider";
 
+	/**
+	 * <p>
+	 * The API Key part of the URI.
+	 * </p>
+	 */
+	String API_KEY = "API_KEY=";
+
 	// ====================================MIME-TYPES======================================
 	/**
 	 * <p>

commit 96603a39bc3ab3037402785419d3030d9d7dc189
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sun Jan 9 02:23:36 2011 +0100

    Added permission READ_ACCESS_BANK_TRANSACTIONS.
    Write access is disabled in the code so there is no need for write permission.
    Fixed bug so that the selection is a JOIN on banks._id = accounts.bankid
    
    Change-Id: I2704fe7644ed38da0a33a0822ac9bc5950db6294

diff --git AndroidManifest.xml AndroidManifest.xml
index 942ad52..8dcdb40 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -110,8 +110,13 @@
 					android:path="com.liato.bankdroid" />
 			</intent-filter>
 		</receiver>
-	<provider android:name=".provider.BankTransactionsProvider" android:syncable="false" android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider">
-</provider>
+	<provider 
+		android:name=".provider.BankTransactionsProvider" 
+		android:syncable="false"
+		android:multiprocess="true"
+		android:exported="true"
+		android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider" 
+		android:permission="com.liato.bankdroid.premission.READ_ACCESS_BANK_TRANSACTIONS"/>
 </application>
 	<uses-sdk
 		android:targetSdkVersion="4"
@@ -127,4 +132,9 @@
 		android:normalScreens="true"
 		android:smallScreens="true"
 		android:anyDensity="true" />
+	<permission 
+		android:name="com.liato.bankdroid.premission.READ_ACCESS_BANK_TRANSACTIONS" 
+		android:label="@string/permission_provider_label" 
+		android:description="@string/permission_provider_desc"
+		android:protectionLevel="dangerous"/>
 </manifest> 
\ No newline at end of file
diff --git res/values/strings.xml res/values/strings.xml
index 9397845..88ecc11 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -200,4 +200,6 @@
 	<string name="lock_cancel">Cancel</string>
 	<string name="lock_ok">Ok</string>
          
+<string name="permission_provider_label">Basic account information  and the transaction history</string>
+<string name="permission_provider_desc">Allows the application to access what banks and accounts are configured in BankDroids. Your Bank credentials are not exposed. Transaction history can also be accessed.</string>
 </resources>

commit bb2d60992fb705e794411b1b81b5188a3696a876
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sun Jan 9 01:43:07 2011 +0100

    Fixed bug so that the selection is a JOIN on banks._id = accounts.bankid
    
    Change-Id: I3e6815d0a71052d150f277e9e1e791391fe06b99

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index b6324c2..b961343 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -26,6 +26,7 @@ import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
+import android.util.Log;
 
 import com.liato.bankdroid.db.DatabaseHelper;
 
@@ -42,10 +43,13 @@ import com.liato.bankdroid.db.DatabaseHelper;
 public class BankTransactionsProvider extends ContentProvider implements
 		IBankTransactionsProvider {
 
+	private final static String TAG = "BankTransactionsProvider";
+
 	private final static int TRANSACTIONS = 0;
 	private static final int BANK_ACCOUNTS = 1;
 
-	private static final String BANK_ACCOUNT_TABLES = "banks, accounts";
+	private static final String BANK_ACCOUNT_TABLES = "banks LEFT JOIN accounts ON banks."
+			+ BANK_ID + " = accounts.bankid";
 	private static final String TRANSACTIONS_TABLE = "transactions";
 
 	private DatabaseHelper dbHelper;
@@ -140,6 +144,8 @@ public class BankTransactionsProvider extends ContentProvider implements
 			qb = new SQLiteQueryBuilder();
 			qb.setTables(BANK_ACCOUNT_TABLES);
 			qb.setProjectionMap(bankAccountProjectionMap);
+			qb.setDistinct(true);
+			Log.d(TAG, "");
 		} else if (TRANSACTIONS_MIME.equals(getType(uri))) {
 			qb = new SQLiteQueryBuilder();
 			qb.setTables(TRANSACTIONS_TABLE);
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index 6fcc492..11eb764 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -78,7 +78,7 @@ public interface IBankTransactionsProvider {
 	 * A category part of the URI.
 	 * </p>
 	 */
-	String BANK_ACCOUNTS_CAT = "banksaccounts";
+	String BANK_ACCOUNTS_CAT = "bankaccounts";
 
 	/**
 	 * <p>

commit 0adaaa69c8cbb39eedd01813b69cb990e0b2aeb9
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 22:48:03 2011 +0100

    Extracted two interfaces IBankTypes and IAccountTypes and put them
    in the provider package to allow these constants to be used by other
    applications.
    
    Change-Id: I3100dce9bce5647860d5b16bbbe662ec96f9b1f4

diff --git src/com/liato/bankdroid/banking/Account.java src/com/liato/bankdroid/banking/Account.java
index 60ede1a..47a1b5c 100644
--- src/com/liato/bankdroid/banking/Account.java
+++ src/com/liato/bankdroid/banking/Account.java
@@ -19,17 +19,12 @@ package com.liato.bankdroid.banking;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 
+import com.liato.bankdroid.provider.IAccountTypes;
 
-public class Account {
-	public final static int REGULAR = 1;
-	public final static int FUNDS = 2;
-	public final static int LOANS = 3;
-	public final static int CCARD = 4;
-	public final static int OTHER = 5;
-	
+public class Account implements IAccountTypes {
 	private String name;
 	private BigDecimal balance;
-	private String id;
+	private final String id;
 	private Bank bank = null;
 	private long bankId = -1;
 	private int type = Account.REGULAR;
@@ -42,12 +37,13 @@ public class Account {
 		return transactions;
 	}
 
-	public void setTransactions(ArrayList<Transaction> transactions) {
+	public void setTransactions(final ArrayList<Transaction> transactions) {
 		this.transactions = transactions;
 	}
 
-	public Account(String name, BigDecimal balance, String id, long bankId,
-	               int type, String currency) {
+	public Account(final String name, final BigDecimal balance,
+			final String id, final long bankId, final int type,
+			final String currency) {
 		this.name = name;
 		this.balance = balance;
 		this.id = id;
@@ -56,35 +52,39 @@ public class Account {
 		this.currency = currency;
 	}
 
-    public Account(String name, BigDecimal balance, String id, long bankId) {
-        this(name, balance, id, bankId, REGULAR, "SEK");
-    }
-    
-	public Account(String name, BigDecimal balance, String id, long bankId, int type) {
-        this(name, balance, id, bankId, type, "SEK");
-    }
-    
-    public Account(String name, BigDecimal balance, String id) {
-        this(name, balance, id, -1L);
-    }
-    
-    public Account(String name, BigDecimal balance, String id, int type) {
-        this(name, balance, id, -1L, type);
-    }	
-
-    public Account(String name, BigDecimal balance, String id, int type, String currency) {
-        this(name, balance, id, -1L, type, currency);
-    }
-
-    public boolean isNotify() {
-        return notify;
-    }
-
-    public void setNotify(boolean notify) {
-        this.notify = notify;
-    }
-    
-    public void setBalance(BigDecimal balance) {
+	public Account(final String name, final BigDecimal balance,
+			final String id, final long bankId) {
+		this(name, balance, id, bankId, REGULAR, "SEK");
+	}
+
+	public Account(final String name, final BigDecimal balance,
+			final String id, final long bankId, final int type) {
+		this(name, balance, id, bankId, type, "SEK");
+	}
+
+	public Account(final String name, final BigDecimal balance, final String id) {
+		this(name, balance, id, -1L);
+	}
+
+	public Account(final String name, final BigDecimal balance,
+			final String id, final int type) {
+		this(name, balance, id, -1L, type);
+	}
+
+	public Account(final String name, final BigDecimal balance,
+			final String id, final int type, final String currency) {
+		this(name, balance, id, -1L, type, currency);
+	}
+
+	public boolean isNotify() {
+		return notify;
+	}
+
+	public void setNotify(final boolean notify) {
+		this.notify = notify;
+	}
+
+	public void setBalance(final BigDecimal balance) {
 		this.balance = balance;
 	}
 
@@ -95,28 +95,28 @@ public class Account {
 	public String getName() {
 		return name;
 	}
-	
-	public void setName(String name) {
-        this.name = name;
-    }
 
-    public String getId() {
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	public String getId() {
 		return id;
 	}
-	
+
 	public Bank getBank() {
 		return bank;
 	}
-	
-	public void setBank(Bank bank) {
+
+	public void setBank(final Bank bank) {
 		this.bank = bank;
 	}
-	
+
 	public long getBankDbId() {
 		return bankId;
 	}
 
-	public void setType(int type) {
+	public void setType(final int type) {
 		this.type = type;
 	}
 
@@ -124,20 +124,20 @@ public class Account {
 		return type;
 	}
 
-    public boolean isHidden() {
-        return this.hidden;
-    }
-    
-    public void setHidden(boolean hidden) {
-        this.hidden = hidden;
-    }
+	public boolean isHidden() {
+		return this.hidden;
+	}
 
-    public String getCurrency() {
-        return currency;
-    }
+	public void setHidden(final boolean hidden) {
+		this.hidden = hidden;
+	}
+
+	public String getCurrency() {
+		return currency;
+	}
+
+	public void setCurrency(final String currency) {
+		this.currency = currency;
+	}
 
-    public void setCurrency(String currency) {
-        this.currency = currency;
-    }
-    
 }
diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index d1988b1..95dca9d 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -33,6 +33,7 @@ import com.liato.bankdroid.R.raw;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -42,30 +43,8 @@ import android.util.Log;
 
 import eu.nullbyte.android.urllib.Urllib;
 
-public abstract class Bank implements Comparable<Bank> {
-    public final static int TESTBANK = 0;
-    public final static int SWEDBANK = 1;
-	public final static int NORDEA = 2;
-	public final static int ICABANKEN = 3;
-	public final static int LANSFORSAKRINGAR = 4;
-	public final static int HANDELSBANKEN = 5;
-	public final static int COOP = 6;
-	public final static int ICA = 7;
-	public final static int STATOIL = 8;
-	public final static int AVANZA = 9;
-	public final static int VILLABANKEN = 10;
-	public final static int AVANZAMINI = 11;
-	public final static int OKQ8 = 12;
-	public final static int EUROCARD = 13;
-	public final static int FIRSTCARD = 14;
-	public final static int PAYPAL = 15;
-    public final static int PAYSON = 16;
-    public final static int JOJO = 17;
-    public final static int IKANOBANK = 18;
-    public final static int STEAM = 19;
-    public final static int DINERSCLUB = 20;
-
-	protected String TAG = "Bank";
+public abstract class Bank implements Comparable<Bank>, IBankTypes {
+    protected String TAG = "Bank";
 	protected String NAME = "Bank";
 	protected String NAME_SHORT = "bank";
 	protected int BANKTYPE_ID = 0;
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 9fad560..b5996b5 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -49,52 +49,53 @@ import com.liato.bankdroid.banking.banks.Villabanken;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.db.Crypto;
 import com.liato.bankdroid.db.DBAdapter;
+import com.liato.bankdroid.provider.IBankTypes;
 
 public class BankFactory {
 
 	public static Bank fromBanktypeId(int id, Context context) throws BankException {
 		switch (id) {
-        case Bank.TESTBANK:
+        case IBankTypes.TESTBANK:
             return new TestBank(context);
-        case Bank.SWEDBANK:
+        case IBankTypes.SWEDBANK:
             return new Swedbank(context);
-		case Bank.NORDEA:
+		case IBankTypes.NORDEA:
 			return new Nordea(context);
-		case Bank.LANSFORSAKRINGAR:
+		case IBankTypes.LANSFORSAKRINGAR:
 			return new Lansforsakringar(context);
-		case Bank.ICABANKEN:
+		case IBankTypes.ICABANKEN:
 			return new ICABanken(context);
-		case Bank.HANDELSBANKEN:
+		case IBankTypes.HANDELSBANKEN:
 			return new Handelsbanken(context);
-		case Bank.COOP:
+		case IBankTypes.COOP:
 			return new Coop(context);
-		case Bank.ICA:
+		case IBankTypes.ICA:
 			return new ICA(context);
-		case Bank.STATOIL:
+		case IBankTypes.STATOIL:
 			return new Statoil(context);
-		case Bank.AVANZA:
+		case IBankTypes.AVANZA:
 			return new Avanza(context);
-		case Bank.VILLABANKEN:
+		case IBankTypes.VILLABANKEN:
 			return new Villabanken(context);
-        case Bank.AVANZAMINI:
+        case IBankTypes.AVANZAMINI:
             return new AvanzaMini(context);
-        case Bank.OKQ8:
+        case IBankTypes.OKQ8:
             return new OKQ8(context);
-        case Bank.EUROCARD:
+        case IBankTypes.EUROCARD:
             return new Eurocard(context);
-        case Bank.FIRSTCARD:
+        case IBankTypes.FIRSTCARD:
             return new FirstCard(context);
-        case Bank.PAYPAL:
+        case IBankTypes.PAYPAL:
             return new PayPal(context);
-        case Bank.PAYSON:
+        case IBankTypes.PAYSON:
             return new Payson(context);
-        case Bank.JOJO:
+        case IBankTypes.JOJO:
             return new Jojo(context);
-        case Bank.STEAM:
+        case IBankTypes.STEAM:
             return new Steam(context);
-        case Bank.DINERSCLUB:
+        case IBankTypes.DINERSCLUB:
             return new DinersClub(context);
-        case Bank.IKANOBANK:
+        case IBankTypes.IKANOBANK:
             return new IkanoBank(context);
 		default:
 			throw new BankException("BankType id not found.");
diff --git src/com/liato/bankdroid/banking/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
index b2cddb9..7bae4f6 100644
--- src/com/liato/bankdroid/banking/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class Avanza extends Bank {
 	private static final String NAME = "Avanza";
 	private static final String NAME_SHORT = "avanza";
 	private static final String URL = "https://www.avanza.se/";
-    private static final int BANKTYPE_ID = Bank.AVANZA;
+    private static final int BANKTYPE_ID = IBankTypes.AVANZA;
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>([^<]+)<.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
diff --git src/com/liato/bankdroid/banking/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index c2fcc8f..26de2bf 100644
--- src/com/liato/bankdroid/banking/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -43,7 +44,7 @@ public class AvanzaMini extends Bank {
 	private static final String NAME = "Avanza Mini";
 	private static final String NAME_SHORT = "avanzamini";
 	private static final String URL = "https://www.avanza.se/mini/hem/";
-	private static final int BANKTYPE_ID = Bank.AVANZAMINI;
+	private static final int BANKTYPE_ID = IBankTypes.AVANZAMINI;
 	
     private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tbody>\\s*(.*)</tbody>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern accountsAvanzaMini = Pattern.compile("<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
diff --git src/com/liato/bankdroid/banking/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
index 257ddbc..fd1fb7c 100644
--- src/com/liato/bankdroid/banking/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -47,7 +48,7 @@ public class Coop extends Bank {
     private static final String NAME = "Coop";
     private static final String NAME_SHORT = "coop";
     private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
-    private static final int BANKTYPE_ID = Bank.COOP;
+    private static final int BANKTYPE_ID = IBankTypes.COOP;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index 1a2f264..ff02197 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -43,7 +44,7 @@ public class DinersClub extends Bank {
 	private static final String NAME = "Diners Club";
 	private static final String NAME_SHORT = "dinersclub";
 	private static final String URL = "https://www.dinersclub.se/dcs/login.aspx";
-	private static final int BANKTYPE_ID = Bank.DINERSCLUB;
+	private static final int BANKTYPE_ID = IBankTypes.DINERSCLUB;
 	
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
diff --git src/com/liato/bankdroid/banking/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
index 5932112..1a308b8 100644
--- src/com/liato/bankdroid/banking/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -48,7 +49,7 @@ public class Eurocard extends Bank {
 	private static final String NAME = "Eurocard";
 	private static final String NAME_SHORT = "eurocard";
 	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
-	private static final int BANKTYPE_ID = Bank.EUROCARD;
+	private static final int BANKTYPE_ID = IBankTypes.EUROCARD;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
diff --git src/com/liato/bankdroid/banking/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
index 50994ff..66dd01f 100644
--- src/com/liato/bankdroid/banking/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class FirstCard extends Bank {
 	private static final String NAME = "First Card";
 	private static final String NAME_SHORT = "firstcard";
 	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
-	private static final int BANKTYPE_ID = Bank.FIRSTCARD;
+	private static final int BANKTYPE_ID = IBankTypes.FIRSTCARD;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
diff --git src/com/liato/bankdroid/banking/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 4b5e93b..0a85e8f 100644
--- src/com/liato/bankdroid/banking/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -39,6 +39,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -47,7 +48,7 @@ public class Handelsbanken extends Bank {
 	private static final String NAME = "Handelsbanken";
 	private static final String NAME_SHORT = "handelsbanken";
 	private static final String URL = "https://m.handelsbanken.se/";
-	private static final int BANKTYPE_ID = Bank.HANDELSBANKEN;
+	private static final int BANKTYPE_ID = IBankTypes.HANDELSBANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
diff --git src/com/liato/bankdroid/banking/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
index 1b5a6f5..00083c3 100644
--- src/com/liato/bankdroid/banking/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -45,7 +46,7 @@ public class ICA extends Bank {
 	private static final String NAME = "ICA";
 	private static final String NAME_SHORT = "ica";
 	private static final String URL = "http://mobil.ica.se/";
-	private static final int BANKTYPE_ID = Bank.ICA;
+	private static final int BANKTYPE_ID = IBankTypes.ICA;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
diff --git src/com/liato/bankdroid/banking/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
index 347ca41..ee6b1f2 100644
--- src/com/liato/bankdroid/banking/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class ICABanken extends Bank {
 	private static final String NAME = "ICA Banken";
 	private static final String NAME_SHORT = "icabanken";
 	private static final String URL = "https://mobil.icabanken.se/";
-	private static final int BANKTYPE_ID = Bank.ICABANKEN;
+	private static final int BANKTYPE_ID = IBankTypes.ICABANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
diff --git src/com/liato/bankdroid/banking/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
index 64740e6..3319ec7 100644
--- src/com/liato/bankdroid/banking/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class IkanoBank extends Bank {
     private static final String NAME = "Ikano Bank";
     private static final String NAME_SHORT = "ikanobank";
     private static final String URL = "https://secure.ikanobank.se/engines/page.aspx?structid=1895";
-    private static final int BANKTYPE_ID = Bank.IKANOBANK;
+    private static final int BANKTYPE_ID = IBankTypes.IKANOBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
diff --git src/com/liato/bankdroid/banking/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
index 2837fb2..6af89ef 100644
--- src/com/liato/bankdroid/banking/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -35,6 +35,7 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -43,7 +44,7 @@ public class Jojo extends Bank {
     private static final String NAME = "Jojo Reskassa";
     private static final String NAME_SHORT = "jojo";
     private static final String URL = "https://www.skanetrafiken.se/templates/MSRootPage.aspx?id=2935&epslanguage=SV";
-    private static final int BANKTYPE_ID = Bank.JOJO;
+    private static final int BANKTYPE_ID = IBankTypes.JOJO;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
     private Pattern reAccounts = Pattern.compile("1_mRepeaterMyCards_ctl(\\d{2,3})_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>\\s*</td>\\s*<td[^>]+>\\s*<a\\s*id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl\\d{2,3}_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>", Pattern.CASE_INSENSITIVE);
diff --git src/com/liato/bankdroid/banking/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index bcc39ee..e2d1d4e 100644
--- src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class Lansforsakringar extends Bank {
     private static final String NAME = "Länsförsäkringar";
     private static final String NAME_SHORT = "lansforsakringar";
     private static final String URL = "https://secure246.lansforsakringar.se/lfportal/login/privat";
-    private static final int BANKTYPE_ID = Bank.LANSFORSAKRINGAR;
+    private static final int BANKTYPE_ID = IBankTypes.LANSFORSAKRINGAR;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
diff --git src/com/liato/bankdroid/banking/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
index 6456ee2..d06ddee 100644
--- src/com/liato/bankdroid/banking/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class Nordea extends Bank {
 	private static final String NAME = "Nordea";
 	private static final String NAME_SHORT = "nordea";
 	private static final String URL = "https://mobil.nordea.se/";
-	private static final int BANKTYPE_ID = Bank.NORDEA;
+	private static final int BANKTYPE_ID = IBankTypes.NORDEA;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
diff --git src/com/liato/bankdroid/banking/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
index 9d9bbcb..96ed28f 100644
--- src/com/liato/bankdroid/banking/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -48,7 +49,7 @@ public class OKQ8 extends Bank {
 	private static final String NAME = "OKQ8 VISA";
 	private static final String NAME_SHORT = "okq8";
 	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
-	private static final int BANKTYPE_ID = Bank.OKQ8;
+	private static final int BANKTYPE_ID = IBankTypes.OKQ8;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
     private static final boolean STATIC_BALANCE = true;
diff --git src/com/liato/bankdroid/banking/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
index 8e9ef2e..7cec132 100644
--- src/com/liato/bankdroid/banking/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -45,7 +46,7 @@ public class PayPal extends Bank {
 	private static final String NAME = "PayPal";
 	private static final String NAME_SHORT = "paypal";
 	private static final String URL = "https://www.paypal.com/";
-	private static final int BANKTYPE_ID = Bank.PAYPAL;
+	private static final int BANKTYPE_ID = IBankTypes.PAYPAL;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 	private static final boolean STATIC_BALANCE = true;
 	
diff --git src/com/liato/bankdroid/banking/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
index efc967c..9fc95ae 100644
--- src/com/liato/bankdroid/banking/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -37,6 +37,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -45,7 +46,7 @@ public class Payson extends Bank {
 	private static final String NAME = "Payson";
 	private static final String NAME_SHORT = "payson";
 	private static final String URL = "https://www.payson.se/signin/";
-	private static final int BANKTYPE_ID = Bank.PAYSON;
+	private static final int BANKTYPE_ID = IBankTypes.PAYSON;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 	
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
index 685f1fc..c338d0c 100644
--- src/com/liato/bankdroid/banking/banks/Statoil.java
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -40,6 +40,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -48,7 +49,7 @@ public class Statoil extends Bank {
 	private static final String NAME = "Statoil";
 	private static final String NAME_SHORT = "statoil";
 	private static final String URL = "https://applications.sebkort.com/nis/external/stse/login.do";
-	private static final int BANKTYPE_ID = Bank.STATOIL;
+	private static final int BANKTYPE_ID = IBankTypes.STATOIL;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
     private static final boolean STATIC_BALANCE = true;
diff --git src/com/liato/bankdroid/banking/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
index 6e06b03..4ceba37 100644
--- src/com/liato/bankdroid/banking/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -42,6 +42,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -50,7 +51,7 @@ public class Steam extends Bank {
 	private static final String NAME = "Steam Wallet";
 	private static final String NAME_SHORT = "steam";
 	private static final String URL = "https://store.steampowered.com/login/?redir=account";
-	private static final int BANKTYPE_ID = Bank.STEAM;
+	private static final int BANKTYPE_ID = IBankTypes.STEAM;
 	private static final boolean STATIC_BALANCE = true;
 	
     private Pattern reBalance = Pattern.compile("accountBalance\">\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
diff --git src/com/liato/bankdroid/banking/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
index cb7ca2a..52237e6 100644
--- src/com/liato/bankdroid/banking/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -38,6 +38,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -46,7 +47,7 @@ public class Swedbank extends Bank {
 	private static final String NAME = "Swedbank";
 	private static final String NAME_SHORT = "swedbank";
 	private static final String URL = "https://mobilbank.swedbank.se/";
-	private static final int BANKTYPE_ID = Bank.SWEDBANK;
+	private static final int BANKTYPE_ID = IBankTypes.SWEDBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
     
diff --git src/com/liato/bankdroid/banking/banks/TestBank.java src/com/liato/bankdroid/banking/banks/TestBank.java
index c681c1f..2c48956 100644
--- src/com/liato/bankdroid/banking/banks/TestBank.java
+++ src/com/liato/bankdroid/banking/banks/TestBank.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -42,7 +43,7 @@ public class TestBank extends Bank {
 	private static final String NAME = "Testbank";
 	private static final String NAME_SHORT = "testbank";
 	private static final String URL = "http://www.nullbyte.eu/";
-	private static final int BANKTYPE_ID = Bank.TESTBANK;
+	private static final int BANKTYPE_ID = IBankTypes.TESTBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
diff --git src/com/liato/bankdroid/banking/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
index 6ec35d1..0304ec1 100644
--- src/com/liato/bankdroid/banking/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -36,6 +36,7 @@ import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.provider.IBankTypes;
 
 import eu.nullbyte.android.urllib.Urllib;
 
@@ -44,7 +45,7 @@ public class Villabanken extends Bank {
 	private static final String NAME = "Villabanken";
 	private static final String NAME_SHORT = "villabanken";
 	private static final String URL = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
-	private static final int BANKTYPE_ID = Bank.VILLABANKEN;
+	private static final int BANKTYPE_ID = IBankTypes.VILLABANKEN;
 	
 	private Pattern reAccounts = Pattern.compile("<td[^>]+>((?:utnyttjad|kvar)[^:]+)[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
 	private Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 7544636..b6324c2 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -42,26 +42,45 @@ import com.liato.bankdroid.db.DatabaseHelper;
 public class BankTransactionsProvider extends ContentProvider implements
 		IBankTransactionsProvider {
 
-	private final static int TRANSACTIONS = 1;
+	private final static int TRANSACTIONS = 0;
+	private static final int BANK_ACCOUNTS = 1;
+
+	private static final String BANK_ACCOUNT_TABLES = "banks, accounts";
 	private static final String TRANSACTIONS_TABLE = "transactions";
 
 	private DatabaseHelper dbHelper;
 	private final static UriMatcher uriMatcher;
+	private final static Map<String, String> bankAccountProjectionMap;
 	private final static Map<String, String> transProjectionMap;
 
 	static {
 		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-		uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/", TRANSACTIONS);
+		uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT, TRANSACTIONS);
+		uriMatcher.addURI(AUTHORITY, BANK_ACCOUNTS_CAT, BANK_ACCOUNTS);
+
+		// Projections are "Poor mans views" of the data.
+		bankAccountProjectionMap = new HashMap<String, String>();
+
+		// Must match bankAccountProjection in
+		// IBankTransactionsProvider#bankAccountProjection
+		bankAccountProjectionMap.put(BANK_ID, BANK_ID);
+		bankAccountProjectionMap.put(BANK_NAME, BANK_NAME);
+		bankAccountProjectionMap.put(BANK_TYPE, BANK_TYPE);
+		bankAccountProjectionMap.put(BANK_LAST_UPDATED, BANK_LAST_UPDATED);
+		bankAccountProjectionMap.put(ACC_ID, ACC_ID);
+		bankAccountProjectionMap.put(ACC_NAME, ACC_NAME);
+		bankAccountProjectionMap.put(ACC_TYPE, ACC_TYPE);
 
 		transProjectionMap = new HashMap<String, String>();
 
-		// Must match transactionProjectionMap in
-		// IBankTransactionsProvider#transactionProjectionMap
+		// Must match transactionProjection in
+		// IBankTransactionsProvider#transactionProjection
 		transProjectionMap.put(TRANS_ID, TRANS_ID);
 		transProjectionMap.put(TRANS_DATE, TRANS_DATE);
 		transProjectionMap.put(TRANS_DESC, TRANS_DESC);
 		transProjectionMap.put(TRANS_AMT, TRANS_AMT);
 		transProjectionMap.put(TRANS_CUR, TRANS_CUR);
+		transProjectionMap.put(TRANS_ACCNT, TRANS_ACCNT);
 	}
 
 	/**
@@ -80,10 +99,12 @@ public class BankTransactionsProvider extends ContentProvider implements
 	@Override
 	public String getType(final Uri uri) {
 		switch (uriMatcher.match(uri)) {
+		case BANK_ACCOUNTS:
+			return BANK_ACCOUNTS_MIME;
 		case TRANSACTIONS:
 			return TRANSACTIONS_MIME;
 		default:
-			throw new IllegalArgumentException("Unsupported URI:" + uri);
+			throw new IllegalArgumentException("Unsupported URI: " + uri);
 		}
 	}
 
@@ -113,24 +134,29 @@ public class BankTransactionsProvider extends ContentProvider implements
 			final String selection, final String[] selectionArgs,
 			final String sortOrder) {
 
-		// Only the chosen ones may enter
-		if (uriMatcher.match(uri) != TRANSACTIONS) {
-			throw new IllegalArgumentException("Unknown URI" + uri);
-		}
-
-		// TODO: Fetch the BANK_ACCOUNT_ID from the URI.
-
 		final SQLiteDatabase db = dbHelper.getReadableDatabase();
-		final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-		qb.setTables(TRANSACTIONS_TABLE);
-		qb.setProjectionMap(transProjectionMap);
-
-		// TODO: Add use the BANK_ACCOUNT_ID to limit hits.
+		SQLiteQueryBuilder qb;
+		if (BANK_ACCOUNTS_MIME.equals(getType(uri))) {
+			qb = new SQLiteQueryBuilder();
+			qb.setTables(BANK_ACCOUNT_TABLES);
+			qb.setProjectionMap(bankAccountProjectionMap);
+		} else if (TRANSACTIONS_MIME.equals(getType(uri))) {
+			qb = new SQLiteQueryBuilder();
+			qb.setTables(TRANSACTIONS_TABLE);
+			qb.setProjectionMap(transProjectionMap);
+		} else {
+			throw new IllegalArgumentException("Unsupported URI: " + uri);
+		}
+		/*
+		 * Select Statement to build: SELECT banks._id, banks.custname,
+		 * banks.banktype, banks.updated, accounts.id, accounts.name,
+		 * accounts.acctype FROM banks, accounts WHERE banks._id =
+		 * accounts.bankid AND accounts.hidden = 0;
+		 */
 		final Cursor cur = qb.query(db, projection, selection, selectionArgs,
 				null, null, sortOrder);
 
 		cur.setNotificationUri(getContext().getContentResolver(), uri);
-
 		return cur;
 	}
 
diff --git src/com/liato/bankdroid/provider/IAccountTypes.java src/com/liato/bankdroid/provider/IAccountTypes.java
new file mode 100644
index 0000000..92f1e5d
--- /dev/null
+++ src/com/liato/bankdroid/provider/IAccountTypes.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.provider;
+
+/**
+ * Defines what types of accounts are supported.
+ * 
+ * @since 8 jan 2011
+ */
+public interface IAccountTypes {
+	public final static int REGULAR = 1;
+	public final static int FUNDS = 2;
+	public final static int LOANS = 3;
+	public final static int CCARD = 4;
+	public final static int OTHER = 5;
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index 77067da..6fcc492 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -26,12 +26,27 @@ import java.math.BigDecimal;
  * <p>
  * Uri format for querying for all transaction of a given bank/account
  * combination:<br/>
- * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}/BANK_ACCOUNT_ID</code>
+ * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}</code>
  * </b>
  * </p>
  * 
+ * <p>
+ * <b>Example of reading transactions from a View that implements this
+ * interface:</b>
+ * 
+ * <pre>
+ * final Uri uri = Uri.parse(&quot;content://&quot; + AUTHORITY + &quot;/&quot; + TRANSACTIONS_CAT);
+ * final Cursor cur = managedQuery(uri, TRANSACTIONS_PROJECTION,
+ * 		ACCOUNT_SELECTION_FILTER, new String[] { currentAccountId }, null);
+ * startManagingCursor(cur);
+ * </pre>
+ * 
+ * Where <code>currentAccountId</code> is the account ID you wish to filter on.
+ * </p>
+ * 
  * @author Magnus Andersson
  * @since 8 jan 2011
+ * @version 1.0-RC1
  * @see BankTransactionsProvider
  */
 public interface IBankTransactionsProvider {
@@ -42,6 +57,7 @@ public interface IBankTransactionsProvider {
 	 */
 	String AUTHORITY = "com.liato.bankdroid.provider.BankTransactionsProvider";
 
+	// ====================================MIME-TYPES======================================
 	/**
 	 * <p>
 	 * MIME-type for Transactions. Not use today (no inserts) added for clarity.
@@ -49,6 +65,21 @@ public interface IBankTransactionsProvider {
 	 */
 	String TRANSACTIONS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.transactions";
 
+	/**
+	 * <p>
+	 * MIME-type for Bank/Account. Not use today (no inserts) added for clarity.
+	 * </p>
+	 */
+	String BANK_ACCOUNTS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.bankaccounts";
+
+	// ===================================CATEGORIES=======================================
+	/**
+	 * <p>
+	 * A category part of the URI.
+	 * </p>
+	 */
+	String BANK_ACCOUNTS_CAT = "banksaccounts";
+
 	/**
 	 * <p>
 	 * A category part of the URI.
@@ -56,6 +87,93 @@ public interface IBankTransactionsProvider {
 	 */
 	String TRANSACTIONS_CAT = "transactions";
 
+	// ===================================BANK/ACCOUNT_FIELDS==============================
+	/**
+	 * <p>
+	 * ID for Bank.
+	 * </p>
+	 * <b>PLEASE NOTE</b><br>
+	 * This is an BankDroid internal id, do not depend on this id for keeping
+	 * track between sessions.</p>
+	 */
+	String BANK_ID = "_id";
+
+	/**
+	 * <p>
+	 * User defined custom name for the Bank
+	 * </p>
+	 */
+	String BANK_NAME = "custname";
+
+	/**
+	 * <p>
+	 * Type of Bank.
+	 * </p>
+	 * 
+	 * @see IBankTypes
+	 */
+	String BANK_TYPE = "banktype";
+
+	/**
+	 * <p>
+	 * Last time the bank and the bank accounts were synchronized.
+	 * </p>
+	 */
+	String BANK_LAST_UPDATED = "updated";
+
+	/**
+	 * <p>
+	 * Account id, this is a composite key that
+	 * </p>
+	 * <b>PLEASE NOTE</b><br>
+	 * This is an BankDroid internal id, do not depend on this id for keeping
+	 * track between sessions.</p>
+	 * 
+	 * @See {@link #TRANS_ACCNT}, {@link #ACCOUNT_SELECTION_FILTER}
+	 * 
+	 */
+	String ACC_ID = "id";
+
+	/**
+	 * <p>
+	 * Name of the account.
+	 * </p>
+	 */
+	String ACC_NAME = "name";
+
+	/**
+	 * <p>
+	 * The account Type.
+	 * </p>
+	 * 
+	 * @See {@link IAccountTypes}
+	 */
+	String ACC_TYPE = "acctype";
+
+	/**
+	 * Defines if an account is hidden.
+	 */
+	String ACC_HIDDEN = "hidden";
+
+	/**
+	 * <p>
+	 * The projection (ie. db view) that works with the
+	 * {@link #BANK_ACCOUNTS_CAT} category.
+	 * </p>
+	 */
+	String[] BANK_ACCOUNT_PROJECTION = { BANK_ID, BANK_NAME, BANK_TYPE,
+			BANK_LAST_UPDATED, ACC_ID, ACC_NAME, ACC_TYPE };
+
+	/**
+	 * <p>
+	 * Use this filter to ignore hidden accounts (Hidden accounts only used for
+	 * debug purposes). Always use this filter or incorporate it into your own
+	 * filters.
+	 * </p>
+	 */
+	String NO_HIDDEN_ACCOUNTS_FILTER = ACC_HIDDEN + " = 0";
+
+	// ===================================TRANSACTION_FIELDS===============================
 	/**
 	 * <p>
 	 * Transaction ID.
@@ -101,10 +219,32 @@ public interface IBankTransactionsProvider {
 
 	/**
 	 * <p>
-	 * The projection (ie. 'view') that works with the {@link #TRANSACTIONS_CAT}
-	 * category.
+	 * The account a transaction belongs to.
+	 * </p>
+	 */
+	String TRANS_ACCNT = "account";
+
+	/**
+	 * <p>
+	 * The projection (ie. db view) that works with the
+	 * {@link #TRANSACTIONS_CAT} category.
 	 * </p>
 	 */
 	String[] TRANSACTIONS_PROJECTION = { TRANS_ID, TRANS_DATE, TRANS_DESC,
-			TRANS_AMT, TRANS_CUR };
+			TRANS_AMT, TRANS_CUR, TRANS_ACCNT };
+
+	/**
+	 * <p>
+	 * Use this filter to only return transactions belonging to a certain
+	 * account.
+	 * </p>
+	 * 
+	 * <p>
+	 * The format for the composite bank/account ID is {BANK_ID}_{ACCOUNT_ID}.<br>
+	 * <b>Example IDs:</b> 1_1 or 1_0
+	 * </p>
+	 * 
+	 * @See {@link #ACC_ID}
+	 */
+	String ACCOUNT_SELECTION_FILTER = TRANS_ACCNT + " = ?";
 }
diff --git src/com/liato/bankdroid/provider/IBankTypes.java src/com/liato/bankdroid/provider/IBankTypes.java
new file mode 100644
index 0000000..3c20a31
--- /dev/null
+++ src/com/liato/bankdroid/provider/IBankTypes.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.provider;
+
+/**
+ * Defines what types banks are supported.
+ * 
+ * @since 8 jan 2011
+ */
+public interface IBankTypes {
+
+	public final static int TESTBANK = 0;
+	public final static int SWEDBANK = 1;
+	public final static int NORDEA = 2;
+	public final static int ICABANKEN = 3;
+	public final static int LANSFORSAKRINGAR = 4;
+	public final static int HANDELSBANKEN = 5;
+	public final static int COOP = 6;
+	public final static int ICA = 7;
+	public final static int STATOIL = 8;
+	public final static int AVANZA = 9;
+	public final static int VILLABANKEN = 10;
+	public final static int AVANZAMINI = 11;
+	public final static int OKQ8 = 12;
+	public final static int EUROCARD = 13;
+	public final static int FIRSTCARD = 14;
+	public final static int PAYPAL = 15;
+	public final static int PAYSON = 16;
+	public final static int JOJO = 17;
+	public final static int IKANOBANK = 18;
+	public final static int STEAM = 19;
+	public final static int DINERSCLUB = 20;
+
+}
\ No newline at end of file

commit 02abe3593e7a8f029574787f22fd10934a542bf5
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 18:31:02 2011 +0100

    Uppercase for projection constant.
    
    Change-Id: Ibd9249af3804d20ed6bd9de28433de060165e9bb
    Signed-off-by: Magnus Andersson <magnus@magnusart.com>

diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index bd31a87..77067da 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -101,10 +101,10 @@ public interface IBankTransactionsProvider {
 
 	/**
 	 * <p>
-	 * The projection map that works with the {@link #TRANSACTIONS_CAT}
+	 * The projection (ie. 'view') that works with the {@link #TRANSACTIONS_CAT}
 	 * category.
 	 * </p>
 	 */
-	String[] transactionsProjectionMap = { TRANS_ID, TRANS_DATE, TRANS_DESC,
+	String[] TRANSACTIONS_PROJECTION = { TRANS_ID, TRANS_DATE, TRANS_DESC,
 			TRANS_AMT, TRANS_CUR };
 }

commit 112ef99d7eb43fa0443b3ee0ff1373b74d7a5e44
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 16:11:34 2011 +0100

    Added some information for the provider in the Manifest and another missed file.
    
    Change-Id: I70adac08c338ab9f9f47bbba3c36461281d19eb9

diff --git AndroidManifest.xml AndroidManifest.xml
index 0e572f8..942ad52 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -110,7 +110,9 @@
 					android:path="com.liato.bankdroid" />
 			</intent-filter>
 		</receiver>
-	</application>
+	<provider android:name=".provider.BankTransactionsProvider" android:syncable="false" android:authorities="com.liato.bankdroid.provider.BankTransactionsProvider">
+</provider>
+</application>
 	<uses-sdk
 		android:targetSdkVersion="4"
 		android:minSdkVersion="4" />
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
index d1fdacf..bd31a87 100644
--- src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -42,6 +42,13 @@ public interface IBankTransactionsProvider {
 	 */
 	String AUTHORITY = "com.liato.bankdroid.provider.BankTransactionsProvider";
 
+	/**
+	 * <p>
+	 * MIME-type for Transactions. Not use today (no inserts) added for clarity.
+	 * </p>
+	 */
+	String TRANSACTIONS_MIME = "vnd.android.cursor.dir/vnd.bankdroid.transactions";
+
 	/**
 	 * <p>
 	 * A category part of the URI.

commit ca19d5bd40872d5b69c73841ccad189dd6574b54
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 16:10:38 2011 +0100

    Forgot to commit the DBAdapter changes
    
    Change-Id: I7e1d9e3dc1ce065a829095cd5a6bff426f246341

diff --git src/com/liato/bankdroid/db/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
index f8fb80e..abb6753 100644
--- src/com/liato/bankdroid/db/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -30,66 +30,20 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.SQLException;
 import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
 import android.util.Log;
 
 
 public class DBAdapter {
 
-    private static final String TAG = "DBAdapter";
+    static final String TAG = "DBAdapter";
     private DatabaseHelper mDbHelper;
     private SQLiteDatabase mDb;
     
-    private static final String DATABASE_NAME = "data";
-    private static final int DATABASE_VERSION = 9;
+    static final String DATABASE_NAME = "data";
+    static final int DATABASE_VERSION = 9;
 
     private final Context mCtx;
 
-    private static class DatabaseHelper extends SQLiteOpenHelper {
-
-        DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("create table banks (_id integer primary key autoincrement, " +
-            		   "balance text not null, " +
-                       "banktype integer not null, " +
-                       "username text not null, " +
-                       "password text not null, " +
-                       "custname text, " +
-                       "updated text, " +
-                       "sortorder real, " +
-                       "currency text, " +
-                       "disabled integer);");
-            db.execSQL("create table accounts (bankid integer not null, " +
-            		   "id text not null, " +
-                       "balance text not null, " +
-                       "acctype integer not null, " +
-                       "hidden integer not null, " +
-                       "notify integer not null, " +
-                       "currency text, " +
-            		   "name text not null);");
-            db.execSQL("create table transactions (_id integer primary key autoincrement, " +
-            		   "transdate text not null, " +
-            		   "btransaction text not null, " +
-            		   "amount text not null, " +
-            		   "currency text, " +
-            		   "account text not null);");
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
-                    + newVersion + ", which will destroy all old data");
-            db.execSQL("DROP TABLE IF EXISTS banks;");
-            db.execSQL("DROP TABLE IF EXISTS accounts;");
-            db.execSQL("DROP TABLE IF EXISTS transactions;");
-            onCreate(db);
-        }
-    }
-
     /**
      * Constructor - takes the context to allow the database to be
      * opened/created
diff --git src/com/liato/bankdroid/db/DatabaseHelper.java src/com/liato/bankdroid/db/DatabaseHelper.java
index 957fddb..a3a3081 100644
--- src/com/liato/bankdroid/db/DatabaseHelper.java
+++ src/com/liato/bankdroid/db/DatabaseHelper.java
@@ -25,9 +25,9 @@ import android.util.Log;
  * 
  * @since 8 jan 2011
  */
-final class DatabaseHelper extends SQLiteOpenHelper {
+final public class DatabaseHelper extends SQLiteOpenHelper {
 
-	DatabaseHelper(final Context context) {
+	public DatabaseHelper(final Context context) {
 		super(context, DBAdapter.DATABASE_NAME, null,
 				DBAdapter.DATABASE_VERSION);
 	}

commit 3c548dd9fd598eec9ebe9e354652ca2f207ef645
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 12:19:36 2011 +0100

    Continued on the query  method for Transactions, ready for initial testing. Not using any specific account id to limit the query result set.
    
    Change-Id: Icd1848197fc75f987c964f7bd2a914096754ba80

diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
index 401bcc1..7544636 100644
--- src/com/liato/bankdroid/provider/BankTransactionsProvider.java
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -24,6 +24,7 @@ import android.content.ContentValues;
 import android.content.UriMatcher;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 
 import com.liato.bankdroid.db.DatabaseHelper;
@@ -42,6 +43,7 @@ public class BankTransactionsProvider extends ContentProvider implements
 		IBankTransactionsProvider {
 
 	private final static int TRANSACTIONS = 1;
+	private static final String TRANSACTIONS_TABLE = "transactions";
 
 	private DatabaseHelper dbHelper;
 	private final static UriMatcher uriMatcher;
@@ -77,8 +79,12 @@ public class BankTransactionsProvider extends ContentProvider implements
 	 */
 	@Override
 	public String getType(final Uri uri) {
-		// TODO Auto-generated method stub
-		return null;
+		switch (uriMatcher.match(uri)) {
+		case TRANSACTIONS:
+			return TRANSACTIONS_MIME;
+		default:
+			throw new IllegalArgumentException("Unsupported URI:" + uri);
+		}
 	}
 
 	/**
@@ -107,9 +113,25 @@ public class BankTransactionsProvider extends ContentProvider implements
 			final String selection, final String[] selectionArgs,
 			final String sortOrder) {
 
+		// Only the chosen ones may enter
+		if (uriMatcher.match(uri) != TRANSACTIONS) {
+			throw new IllegalArgumentException("Unknown URI" + uri);
+		}
+
+		// TODO: Fetch the BANK_ACCOUNT_ID from the URI.
+
 		final SQLiteDatabase db = dbHelper.getReadableDatabase();
+		final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+		qb.setTables(TRANSACTIONS_TABLE);
+		qb.setProjectionMap(transProjectionMap);
+
+		// TODO: Add use the BANK_ACCOUNT_ID to limit hits.
+		final Cursor cur = qb.query(db, projection, selection, selectionArgs,
+				null, null, sortOrder);
+
+		cur.setNotificationUri(getContext().getContentResolver(), uri);
 
-		return null;
+		return cur;
 	}
 
 	/**

commit 9d54579a2aa5543756daf95e8015c77bc148943f
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 12:08:08 2011 +0100

    Added a new package for providers where I created an Interface to be  used in client applications.
    Started fleshing out the Provider.
    
    Change-Id: I7136ffc158e328a0d61f20079d79b28d3127b8d9

diff --git src/com/liato/bankdroid/db/BankTransactionsProvider.java src/com/liato/bankdroid/db/BankTransactionsProvider.java
deleted file mode 100644
index 61f4694..0000000
--- src/com/liato/bankdroid/db/BankTransactionsProvider.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 Magnusart <http://www.magnusart.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.liato.bankdroid.db;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-/**
- * 
- * @author Magnus Andersson
- * @since 8 jan 2011
- */
-public class BankTransactionsProvider extends ContentProvider {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int delete(final Uri uri, final String selection,
-			final String[] selectionArgs) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public String getType(final Uri uri) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Uri insert(final Uri uri, final ContentValues values) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public boolean onCreate() {
-		// TODO Auto-generated method stub
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public Cursor query(final Uri uri, final String[] projection,
-			final String selection, final String[] selectionArgs,
-			final String sortOrder) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public int update(final Uri uri, final ContentValues values,
-			final String selection, final String[] selectionArgs) {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-}
diff --git src/com/liato/bankdroid/provider/BankTransactionsProvider.java src/com/liato/bankdroid/provider/BankTransactionsProvider.java
new file mode 100644
index 0000000..401bcc1
--- /dev/null
+++ src/com/liato/bankdroid/provider/BankTransactionsProvider.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2010 Magnusart <http://www.magnusart.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.provider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+
+import com.liato.bankdroid.db.DatabaseHelper;
+
+/**
+ * <p>
+ * This is the implementation of the BankTransactionsProvider. It provides
+ * access to the transaction data for specific banks.
+ * </p>
+ * 
+ * @author Magnus Andersson
+ * @since 8 jan 2011
+ * @see IBankTransactionsProvider
+ */
+public class BankTransactionsProvider extends ContentProvider implements
+		IBankTransactionsProvider {
+
+	private final static int TRANSACTIONS = 1;
+
+	private DatabaseHelper dbHelper;
+	private final static UriMatcher uriMatcher;
+	private final static Map<String, String> transProjectionMap;
+
+	static {
+		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+		uriMatcher.addURI(AUTHORITY, TRANSACTIONS_CAT + "/", TRANSACTIONS);
+
+		transProjectionMap = new HashMap<String, String>();
+
+		// Must match transactionProjectionMap in
+		// IBankTransactionsProvider#transactionProjectionMap
+		transProjectionMap.put(TRANS_ID, TRANS_ID);
+		transProjectionMap.put(TRANS_DATE, TRANS_DATE);
+		transProjectionMap.put(TRANS_DESC, TRANS_DESC);
+		transProjectionMap.put(TRANS_AMT, TRANS_AMT);
+		transProjectionMap.put(TRANS_CUR, TRANS_CUR);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int delete(final Uri uri, final String selection,
+			final String[] selectionArgs) {
+		throw new UnsupportedOperationException(
+				"This provider does not implement the delete method");
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String getType(final Uri uri) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Uri insert(final Uri uri, final ContentValues values) {
+		throw new UnsupportedOperationException(
+				"This provider does not implement the insert method");
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean onCreate() {
+		dbHelper = new DatabaseHelper(getContext());
+		return true;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Cursor query(final Uri uri, final String[] projection,
+			final String selection, final String[] selectionArgs,
+			final String sortOrder) {
+
+		final SQLiteDatabase db = dbHelper.getReadableDatabase();
+
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int update(final Uri uri, final ContentValues values,
+			final String selection, final String[] selectionArgs) {
+		throw new UnsupportedOperationException(
+				"This provider does not implement the update method");
+	}
+
+}
diff --git src/com/liato/bankdroid/provider/IBankTransactionsProvider.java src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
new file mode 100644
index 0000000..d1fdacf
--- /dev/null
+++ src/com/liato/bankdroid/provider/IBankTransactionsProvider.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Magnusart <http://www.magnusart.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.liato.bankdroid.provider;
+
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * This interface provides constants that can conveniently be used with the
+ * BankTransactionProvider. Copy this file and use it in your
+ * ContentProviderClient code.
+ * </p>
+ * <p>
+ * Uri format for querying for all transaction of a given bank/account
+ * combination:<br/>
+ * <code><b>content://{{@link #AUTHORITY}}/{{@link #TRANSACTIONS_CAT}}/BANK_ACCOUNT_ID</code>
+ * </b>
+ * </p>
+ * 
+ * @author Magnus Andersson
+ * @since 8 jan 2011
+ * @see BankTransactionsProvider
+ */
+public interface IBankTransactionsProvider {
+	/**
+	 * <p>
+	 * The authority part of the URI.
+	 * </p>
+	 */
+	String AUTHORITY = "com.liato.bankdroid.provider.BankTransactionsProvider";
+
+	/**
+	 * <p>
+	 * A category part of the URI.
+	 * </p>
+	 */
+	String TRANSACTIONS_CAT = "transactions";
+
+	/**
+	 * <p>
+	 * Transaction ID.
+	 * </p>
+	 * <p>
+	 * <b>PLEASE NOTE</b><br>
+	 * This is an BankDroid internal id, not the actual bank transaction id.
+	 * </p>
+	 */
+	String TRANS_ID = "_id";
+
+	/**
+	 * <p>
+	 * Date of Transaction.
+	 * </p>
+	 */
+	String TRANS_DATE = "transdate";
+
+	/**
+	 * <p>
+	 * Description text of Transaction.
+	 * </p>
+	 */
+	String TRANS_DESC = "btransaction";
+
+	/**
+	 * <p>
+	 * Amount of Transaction.
+	 * </p>
+	 * <p>
+	 * String representation of a {@link BigDecimal}. Positive for <i>Income</i>
+	 * and negative for <i>Expenses</i>.
+	 * </p>
+	 */
+	String TRANS_AMT = "amount";
+
+	/**
+	 * <p>
+	 * Currency of the Transaction. (Currently Only SEK)
+	 * </p>
+	 */
+	String TRANS_CUR = "currency";
+
+	/**
+	 * <p>
+	 * The projection map that works with the {@link #TRANSACTIONS_CAT}
+	 * category.
+	 * </p>
+	 */
+	String[] transactionsProjectionMap = { TRANS_ID, TRANS_DATE, TRANS_DESC,
+			TRANS_AMT, TRANS_CUR };
+}

commit 40d82092a4fb498800a756854e1a2c2a480b7dae
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 10:48:41 2011 +0100

    Refactoring out the DatabaseHelper as it's also needed by BankTransactionsProvider. Made it final default access so that no classes outside the package can use it or extend it.
    
    Change-Id: I66eae5dcfbcb4d3d4634478b0d8966c885954c05

diff --git src/com/liato/bankdroid/db/DatabaseHelper.java src/com/liato/bankdroid/db/DatabaseHelper.java
new file mode 100644
index 0000000..957fddb
--- /dev/null
+++ src/com/liato/bankdroid/db/DatabaseHelper.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.db;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+/**
+ * 
+ * @since 8 jan 2011
+ */
+final class DatabaseHelper extends SQLiteOpenHelper {
+
+	DatabaseHelper(final Context context) {
+		super(context, DBAdapter.DATABASE_NAME, null,
+				DBAdapter.DATABASE_VERSION);
+	}
+
+	@Override
+	public void onCreate(final SQLiteDatabase db) {
+		db.execSQL("create table banks (_id integer primary key autoincrement, "
+				+ "balance text not null, "
+				+ "banktype integer not null, "
+				+ "username text not null, "
+				+ "password text not null, "
+				+ "custname text, "
+				+ "updated text, "
+				+ "sortorder real, "
+				+ "currency text, " + "disabled integer);");
+		db.execSQL("create table accounts (bankid integer not null, "
+				+ "id text not null, " + "balance text not null, "
+				+ "acctype integer not null, " + "hidden integer not null, "
+				+ "notify integer not null, " + "currency text, "
+				+ "name text not null);");
+		db.execSQL("create table transactions (_id integer primary key autoincrement, "
+				+ "transdate text not null, "
+				+ "btransaction text not null, "
+				+ "amount text not null, "
+				+ "currency text, "
+				+ "account text not null);");
+	}
+
+	@Override
+	public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
+			final int newVersion) {
+		Log.w(DBAdapter.TAG, "Upgrading database from version " + oldVersion
+				+ " to " + newVersion + ", which will destroy all old data");
+		db.execSQL("DROP TABLE IF EXISTS banks;");
+		db.execSQL("DROP TABLE IF EXISTS accounts;");
+		db.execSQL("DROP TABLE IF EXISTS transactions;");
+		onCreate(db);
+	}
+}
\ No newline at end of file

commit a8919405cd899de25faec1ec70ffab93cbb9b5b7
Author: Magnus Andersson <magnus@magnusart.com>
Date:   Sat Jan 8 10:43:56 2011 +0100

    Adding skeleton for content provider.
    
    Change-Id: I10ab309c427ff9ce016e488d533ebe4aaab5a0b8

diff --git src/com/liato/bankdroid/db/BankTransactionsProvider.java src/com/liato/bankdroid/db/BankTransactionsProvider.java
new file mode 100644
index 0000000..61f4694
--- /dev/null
+++ src/com/liato/bankdroid/db/BankTransactionsProvider.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 Magnusart <http://www.magnusart.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.db;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * 
+ * @author Magnus Andersson
+ * @since 8 jan 2011
+ */
+public class BankTransactionsProvider extends ContentProvider {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int delete(final Uri uri, final String selection,
+			final String[] selectionArgs) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String getType(final Uri uri) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Uri insert(final Uri uri, final ContentValues values) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean onCreate() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Cursor query(final Uri uri, final String[] projection,
+			final String selection, final String[] selectionArgs,
+			final String sortOrder) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public int update(final Uri uri, final ContentValues values,
+			final String selection, final String[] selectionArgs) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+}

commit e86a926098c240f2cdb7427093da61b8a54afe4d
Author: Magnus Hagander <magnus@hagander.net>
Date:   Fri Dec 31 12:57:02 2010 +0100

    Implement transaction support for Diners Club

diff --git src/com/liato/bankdroid/banking/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
index 1a2f264..d08f270 100644
--- src/com/liato/bankdroid/banking/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -28,11 +28,13 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.util.Log;
 
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.R;
 import com.liato.bankdroid.banking.Account;
 import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
 import com.liato.bankdroid.banking.exceptions.BankException;
 import com.liato.bankdroid.banking.exceptions.LoginException;
 
@@ -48,7 +50,11 @@ public class DinersClub extends Bank {
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reBalance = Pattern.compile("class=\"card\"[^>]+>\\s*<div[^>]+>\\s*<b>([^<]+)</b>\\s*<br ?/>\\s*<span[^>]+>([^<]+)</span>\\s*</div>\\s*<div[^>]+>\\s*<strong[^>]+>[^<]+</strong>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
+	private Pattern reInvoices = Pattern.compile("<tr[^>]+>\\s*<td class=\"right\">\\s*<a href='((Invoice|Nonbilled).aspx\\?card=\\d+&bdate=[\\d-]+)'>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<tr[^>]+>\\s*<td>\\s*<a.*? href='Transact[^']+'>\\s*([\\d-]+)\\s*</a>\\s*</td><td>\\s*<a.*? href='Transact[^']+'>\\s*(.*?)\\s*</a>\\s*</td><td class=\"right\">\\s*(.*?)\\s*</td><td class=\"right\">\\s*<a.*? href='Transact[^']+'>\\s*(.*?)\\s*</a>\\s*</td>\\s*</tr>");
+
 	private String response = null;
+	private String invoiceUrl;
 	
 	public DinersClub(Context context) {
 		super(context);
@@ -145,7 +151,55 @@ public class DinersClub extends Bank {
 		}
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
-        }		
+        }
+
+        /* Detect invoice dates - needed to find the transactions */
+        matcher = reInvoices.matcher(response);
+        if (matcher.find()) {
+        	invoiceUrl = matcher.group(1);
+        }
+        else {
+        	invoiceUrl = null;
+        }
+
         super.updateComplete();
 	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		if (!urlopen.acceptsInvalidCertificates()) { //Should never happen, but we'll check it anyway.
+			urlopen = login();
+		}
+
+		String response = null;
+		Matcher matcher;
+		try {
+			/* We're going to look at all the pages until we find one that has transactions on it */
+			Log.d(TAG, String.format("Opening: https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
+			response = urlopen.open(String.format("https://www.dinersclub.se/dcs/eSaldo/%s", invoiceUrl));
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+
+			while (matcher.find()) {
+				/*
+				 * Capture groups:
+				 * GROUP				EXAMPLE DATA
+				 * 1: Trans. date		2010-10-06
+				 * 2: Specifications	Skyways Express Ab
+				 * 3: Foreign amount	30,30 EUR
+				 * 4: Amount			2.462,00 kr
+				 */
+
+				transactions.add(new Transaction(matcher.group(1), matcher.group(2), Helpers.parseBalance(matcher.group(4))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
 }

commit 38ca090a4813fbb5b91641c9b73fd5efb1395a4e
Author: Magnus Hagander <magnus@hagander.net>
Date:   Sat Jan 1 12:57:28 2011 +0100

    Add forgotten logo for ebmaster

diff --git res/drawable/logo_ebmaster.png res/drawable/logo_ebmaster.png
new file mode 100644
index 0000000..0354e55
Binary files /dev/null and res/drawable/logo_ebmaster.png differ

commit 7da06b613338559c60327cefd5ea58ae82f3fb38
Author: Magnus Hagander <magnus@hagander.net>
Date:   Fri Dec 31 11:47:35 2010 +0100

    Update comments about foreign currency fields

diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index a43f9b0..7aca4b7 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -185,8 +185,8 @@ public abstract class SEBKortBase extends Bank {
 				 * 2: Book. date		10-19
 				 * 3: Specification		ICA Kvantum
 				 * 4: Location			Stockholm
-				 * 5: Currency			always empty?
-				 * 6: Amount			always empty?
+				 * 5: Currency			currency code (e.g. EUR) for transactions in non-SEK
+				 * 6: Amount			local currency amount (in $currency) for transactions in non-SEK
 				 * 7: Amount in sek		5791,18
 				 * 
 				 */				

commit 02330d1c2d33f59452e4f27a246ec97b2c096df5
Author: Magnus Hagander <magnus@hagander.net>
Date:   Fri Dec 31 11:36:46 2010 +0100

    Add support for SAS EuroBonus Mastercard
    
    Provided by SEB kort, and supported by the common base class
    for such cards.

diff --git src/com/liato/bankdroid/banking/Bank.java src/com/liato/bankdroid/banking/Bank.java
index d1988b1..50cd765 100644
--- src/com/liato/bankdroid/banking/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -64,6 +64,7 @@ public abstract class Bank implements Comparable<Bank> {
     public final static int IKANOBANK = 18;
     public final static int STEAM = 19;
     public final static int DINERSCLUB = 20;
+    public final static int EUROBONUSMASTERCARD = 21;
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/banking/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
index 9fad560..f68b56e 100644
--- src/com/liato/bankdroid/banking/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -29,6 +29,7 @@ import com.liato.bankdroid.banking.banks.Avanza;
 import com.liato.bankdroid.banking.banks.AvanzaMini;
 import com.liato.bankdroid.banking.banks.Coop;
 import com.liato.bankdroid.banking.banks.DinersClub;
+import com.liato.bankdroid.banking.banks.EurobonusMastercard;
 import com.liato.bankdroid.banking.banks.Eurocard;
 import com.liato.bankdroid.banking.banks.FirstCard;
 import com.liato.bankdroid.banking.banks.Handelsbanken;
@@ -96,6 +97,8 @@ public class BankFactory {
             return new DinersClub(context);
         case Bank.IKANOBANK:
             return new IkanoBank(context);
+        case Bank.EUROBONUSMASTERCARD:
+        	return new EurobonusMastercard(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -124,6 +127,7 @@ public class BankFactory {
         banks.add(new Steam(context));
         banks.add(new DinersClub(context));
         banks.add(new IkanoBank(context));
+        banks.add(new EurobonusMastercard(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
new file mode 100644
index 0000000..63b5792
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/EurobonusMastercard.java
@@ -0,0 +1,28 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class EurobonusMastercard extends SEBKortBase {
+	private static final String TAG = "EurobonusMastercard";
+	private static final String NAME = "Eurobonus Mastercard";
+	private static final String NAME_SHORT = "ebmaster";
+	private static final int BANKTYPE_ID = Bank.EUROBONUSMASTERCARD;
+
+	public EurobonusMastercard(Context context) {
+		super(context, "sase", "0102");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public EurobonusMastercard(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "sase", "0102");
+	}
+
+}

commit 2349a17ec4bd8670ebae11439466e619861a89a6
Author: Magnus Hagander <magnus@hagander.net>
Date:   Thu Dec 30 19:06:25 2010 +0100

    Reimplement Statoil on top of common base class

diff --git src/com/liato/bankdroid/banking/banks/SEBKortBase.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
index 685f1fc..a43f9b0 100644
--- src/com/liato/bankdroid/banking/banks/SEBKortBase.java
+++ src/com/liato/bankdroid/banking/banks/SEBKortBase.java
@@ -43,12 +43,7 @@ import com.liato.bankdroid.banking.exceptions.LoginException;
 
 import eu.nullbyte.android.urllib.Urllib;
 
-public class Statoil extends Bank {
-	private static final String TAG = "Statoil";
-	private static final String NAME = "Statoil";
-	private static final String NAME_SHORT = "statoil";
-	private static final String URL = "https://applications.sebkort.com/nis/external/stse/login.do";
-	private static final int BANKTYPE_ID = Bank.STATOIL;
+public abstract class SEBKortBase extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
     private static final boolean STATIC_BALANCE = true;
@@ -56,42 +51,43 @@ public class Statoil extends Bank {
 	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunit(?:last(?:disposable|credit)amount|2rowcol2)\">([^<]+)</(?:div|td)>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*(?:<div[^>]+>\\s*)?<span>([^<]*)</span>\\s*(?:</div>\\s*)?</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
-	public Statoil(Context context) {
+	private String provider_part;
+	private String prodgroup;
+	public SEBKortBase(Context context, String provider_part, String prodgroup) {
 		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 		super.STATIC_BALANCE = STATIC_BALANCE;
+		this.provider_part = provider_part;
+		this.prodgroup = prodgroup;
+		super.URL = String.format("https://applications.sebkort.com/nis/external/%s/login.do", provider_part);
 	}
 
-	public Statoil(String username, String password, Context context) throws BankException, LoginException {
-		this(context);
+	public SEBKortBase(String username, String password, Context context, String url, String prodgroup) throws BankException, LoginException {
+		this(context, url, prodgroup);
 		this.update(username, password);
 	}
-
     
     @Override
     protected LoginPackage preLogin() throws BankException,
             ClientProtocolException, IOException {
         urlopen = new Urllib(true);
         List <NameValuePair> postData = new ArrayList <NameValuePair>();
-        response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
+        response = urlopen.open(String.format("https://applications.sebkort.com/nis/external/%s/login.do", provider_part));
         List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
-        parameters.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
+        parameters.add(new BasicNameValuePair("USERNAME", prodgroup+username.toUpperCase()));
         parameters.add(new BasicNameValuePair("referer", "login.jsp"));
         response = urlopen.open("https://applications.sebkort.com/nis/external/hidden.jsp", postData);
         
         postData.clear();
         postData.add(new BasicNameValuePair("choice", "PWD"));
+        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
+        postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
         postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
         postData.add(new BasicNameValuePair("PASSWORD", password));
-        postData.add(new BasicNameValuePair("target", "/nis/stse/main.do"));
-        postData.add(new BasicNameValuePair("prodgroup", "0122"));
-        postData.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
+        postData.add(new BasicNameValuePair("target", String.format("/nis/%s/main.do", provider_part)));
+        postData.add(new BasicNameValuePair("prodgroup", prodgroup));
+        postData.add(new BasicNameValuePair("USERNAME", prodgroup+username.toUpperCase()));
         postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
         postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
         return new LoginPackage(urlopen, postData, response, "https://applications.sebkort.com/siteminderagent/forms/generic.fcc");
@@ -124,8 +120,8 @@ public class Statoil extends Bank {
 		urlopen = login();
 		Matcher matcher;
 		try {
-			if (!"https://applications.sebkort.com/nis/stse/main.do".equals(urlopen.getCurrentURI())) {
-				response = urlopen.open("https://applications.sebkort.com/nis/stse/main.do");
+			if (!String.format("https://applications.sebkort.com/nis/%s/main.do", provider_part).equals(urlopen.getCurrentURI())) {
+				response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/main.do", provider_part));
 			}
 			matcher = reAccounts.matcher(response);
             /*
@@ -176,8 +172,8 @@ public class Statoil extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://applications.sebkort.com/nis/stse/getPendingTransactions.do");
-			response = urlopen.open("https://applications.sebkort.com/nis/stse/getPendingTransactions.do");
+			Log.d(TAG, String.format("Opening: https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
+			response = urlopen.open(String.format("https://applications.sebkort.com/nis/%s/getPendingTransactions.do", provider_part));
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			Calendar cal = Calendar.getInstance();
diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
new file mode 100644
index 0000000..af42be4
--- /dev/null
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -0,0 +1,28 @@
+package com.liato.bankdroid.banking.banks;
+
+import android.content.Context;
+
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+
+public class Statoil extends SEBKortBase {
+	private static final String TAG = "Statoil";
+	private static final String NAME = "Statoil";
+	private static final String NAME_SHORT = "statoil";
+	private static final int BANKTYPE_ID = Bank.STATOIL;
+
+	public Statoil(Context context) {
+		super(context, "stse", "0122");
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+	}
+	
+	public Statoil(String username, String password, Context context) throws BankException, LoginException {
+		super(username, password, context, "stse", "0122");
+	}
+
+}

commit 8d1b9dc7a270d8fe317af7cb8984c877f9aea1d5
Author: Magnus Hagander <magnus@hagander.net>
Date:   Thu Dec 30 18:53:34 2010 +0100

    Rename Statoil class to SEBKortBase
    
    In preparation for turning it into a baseclass shared between
    multiple providers.

diff --git src/com/liato/bankdroid/banking/banks/Statoil.java src/com/liato/bankdroid/banking/banks/SEBKortBase.java
similarity index 100%
rename from src/com/liato/bankdroid/banking/banks/Statoil.java
rename to src/com/liato/bankdroid/banking/banks/SEBKortBase.java

commit a50298cdbf13601dd649574306147651848b195a
Author: liato <x@x00.us>
Date:   Wed Dec 29 19:20:32 2010 +0100

    Increased hit box for logo/home button. Fixed FCs.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0281122..0e572f8 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="65" android:versionName="1.6.0">
+	android:versionCode="100" android:versionName="1.6.1">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/drawable/title_item_background.xml res/drawable/title_item_background.xml
index 902a6c6..37e7fbe 100644
--- res/drawable/title_item_background.xml
+++ res/drawable/title_item_background.xml
@@ -12,6 +12,8 @@
 	</item>
 
 	<item
-		android:drawable="@android:id/empty">
+		android:drawable="@android:color/transparent"
+		android:state_focused="false"
+		android:state_pressed="false">
 	</item>
 </selector>
diff --git res/layout-land/choose_lock_pattern.xml res/layout-land/choose_lock_pattern.xml
index 176efd8..b43796a 100644
--- res/layout-land/choose_lock_pattern.xml
+++ res/layout-land/choose_lock_pattern.xml
@@ -1,17 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
-	<!--
-		Copyright (C) 2008 The Android Open Source Project Licensed under the
-		Apache License, Version 2.0 (the "License"); you may not use this file
-		except in compliance with the License. You may obtain a copy of the
-		License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
-		by applicable law or agreed to in writing, software distributed under
-		the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-		CONDITIONS OF ANY KIND, either express or implied. See the License for
-		the specific language governing permissions and limitations under the
-		License.
-	-->
+<!-- Copyright (C) 2008 The Android Open Source Project Licensed under the 
+	Apache License, Version 2.0 (the "License"); you may not use this file except 
+	in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+	Unless required by applicable law or agreed to in writing, software distributed 
+	under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+	OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+	the specific language governing permissions and limitations under the License. -->
 
-<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+<com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:id="@+id/topLayout"
 	android:orientation="horizontal"
@@ -83,11 +79,11 @@
 		android:layout_width="2dip"
 		android:layout_height="fill_parent" />
 	<!-- right side: lock pattern -->
-	<com.liato.bankdroid.LockPatternView
+	<com.liato.bankdroid.lockpattern.LockPatternView
 		android:id="@+id/lockPattern"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content" />
 
 
-</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
+</com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient>
 
diff --git res/layout-land/confirm_lock_pattern.xml res/layout-land/confirm_lock_pattern.xml
index 4abb098..4dd5617 100644
--- res/layout-land/confirm_lock_pattern.xml
+++ res/layout-land/confirm_lock_pattern.xml
@@ -1,66 +1,60 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
-        xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/topLayout"
-    android:orientation="horizontal"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:background="@color/black">
-
-    <!-- left side: instructions and messages -->
-    <LinearLayout
-            android:orientation="vertical"
-            android:layout_width="0dip"
-            android:layout_height="fill_parent"
-            android:layout_weight="1.0"
-            >
-
-        <!-- header message -->
-        <TextView android:id="@+id/headerText"
-                  android:layout_width="fill_parent"
-                  android:layout_height="wrap_content"
-                  android:gravity="center"
-                  android:textSize="18sp"/>
-
-        <!-- fill space between header and button below -->
-        <View
-            android:layout_weight="1.0"
-            android:layout_width="fill_parent"
-            android:layout_height="0dip"
-            />
-
-        <!-- footer message -->
-        <TextView android:id="@+id/footerText"
-                  android:layout_width="fill_parent"
-                  android:layout_height="wrap_content"
-                  android:gravity="center"
-                  android:textSize="14sp"/>
-    </LinearLayout>
-
-    <View
-         android:background="@*android:drawable/code_lock_left"
-         android:layout_width="2dip"
-         android:layout_height="fill_parent" />
-    <!-- right side: lock pattern -->
-    <com.liato.bankdroid.LockPatternView android:id="@+id/lockPattern"
-         android:layout_width="wrap_content"
-         android:layout_height="wrap_content" />
-
-
-</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
+<!-- Copyright (C) 2008 The Android Open Source Project Licensed under the 
+	Apache License, Version 2.0 (the "License"); you may not use this file except 
+	in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
+	Unless required by applicable law or agreed to in writing, software distributed 
+	under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 
+	OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
+	the specific language governing permissions and limitations under the License. -->
+
+<com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/topLayout"
+	android:orientation="horizontal"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	android:background="@color/black">
+
+	<!-- left side: instructions and messages -->
+	<LinearLayout
+		android:orientation="vertical"
+		android:layout_width="0dip"
+		android:layout_height="fill_parent"
+		android:layout_weight="1.0">
+
+		<!-- header message -->
+		<TextView
+			android:id="@+id/headerText"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:gravity="center"
+			android:textSize="18sp" />
+
+		<!-- fill space between header and button below -->
+		<View
+			android:layout_weight="1.0"
+			android:layout_width="fill_parent"
+			android:layout_height="0dip" />
+
+		<!-- footer message -->
+		<TextView
+			android:id="@+id/footerText"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:gravity="center"
+			android:textSize="14sp" />
+	</LinearLayout>
+
+	<View
+		android:background="@*android:drawable/code_lock_left"
+		android:layout_width="2dip"
+		android:layout_height="fill_parent" />
+	<!-- right side: lock pattern -->
+	<com.liato.bankdroid.lockpattern.LockPatternView
+		android:id="@+id/lockPattern"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content" />
+
+
+</com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient>
 
diff --git res/layout/title.xml res/layout/title.xml
index 1ba33b0..15d7895 100644
--- res/layout/title.xml
+++ res/layout/title.xml
@@ -7,7 +7,7 @@
 	<LinearLayout
 		android:layout_width="wrap_content"
 		android:id="@+id/layLogoContainer"
-		android:layout_height="fill_parent">
+		android:layout_height="fill_parent" android:layout_toLeftOf="@+id/layTitleButtons" android:layout_alignParentLeft="true" android:clickable="true" android:focusable="true">
 		<ImageView
 			android:layout_height="wrap_content"
 			android:layout_width="wrap_content"
@@ -26,7 +26,7 @@
 			android:adjustViewBounds="true"
 			android:id="@+id/imgTitle"
 			android:layout_gravity="center_vertical"
-			android:maxHeight="17dp" android:paddingLeft="6dp"></ImageView>
+			android:maxHeight="17dp" android:paddingLeft="6dp" android:duplicateParentState="true"></ImageView>
 	</LinearLayout>
 	<LinearLayout
 		android:layout_width="wrap_content"
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 5facf11..673b928 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -60,15 +60,19 @@ public class LockableActivity extends Activity {
         mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
         ImageView homeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
+        View homeButtonCont = titlebar.findViewById(R.id.layLogoContainer);
         OnClickListener listener = new View.OnClickListener() {
             public void onClick(View v) {
                 Intent intent = new Intent(LockableActivity.this, MainActivity.class);
                 startActivity(intent);
             }
-        };        
+        };
         homeButton.setOnClickListener(listener);
         homeButton.setFocusable(true);
         homeButton.setClickable(true);
+        homeButtonCont.setOnClickListener(listener);
+        homeButtonCont.setFocusable(true);
+        homeButtonCont.setClickable(true);
     }
 
     protected void addTitleButton(int imageResourceId, String tag, OnClickListener listener) {

commit 00cb21e8f2e039aae5d553c955c985636b0ed442
Author: liato <x@x00.us>
Date:   Wed Dec 29 00:42:24 2010 +0100

    Bump version to 1.6.0. Market release.

diff --git AndroidManifest.xml AndroidManifest.xml
index f6b55ea..0281122 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="64" android:versionName="1.6.0-RC2">
+	android:versionCode="65" android:versionName="1.6.0">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 9b6b10395ad51bd1469ce4ac24af01c1dd5099ac
Author: liato <x@x00.us>
Date:   Tue Dec 28 23:05:38 2010 +0100

    Widgets should be working again.

diff --git .gitignore .gitignore
index 71d027d..29beabd 100644
--- .gitignore
+++ .gitignore
@@ -15,5 +15,5 @@ gen
 local.properties
 *.jar
 dev/
-src/com/liato/bankdroid/db/Crypto.java
+src/com/liato/bankdroid/db/Crypto.*
 src/com/liato/bankdroid/db/Crypto.java.dev
diff --git AndroidManifest.xml AndroidManifest.xml
index 71e6d18..f6b55ea 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,20 +2,11 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.6.0-RC1" android:versionCode="63">
+	android:versionCode="64" android:versionName="1.6.0-RC2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
 		android:debuggable="false">
-		<!--
-			<activity android:label="@string/app_name"
-			android:multiprocess="false" android:name=".MainActivity"
-			android:alwaysRetainTaskState="false"
-			android:theme="@android:style/Theme.Dialog"> <intent-filter> <action
-			android:name="android.intent.action.MAIN" /> <category
-			android:name="android.intent.category.LAUNCHER" /> </intent-filter>
-			</activity>
-		-->
 		<activity
 			android:name=".MainActivity"
 			android:label="@string/app_name"
@@ -87,7 +78,7 @@
 		</receiver>
 
 		<receiver
-			android:label="@string/widget_name_large" android:name=".appwidget.BankdroidWidgetProvider_2x1">
+			android:label="@string/widget_name_large" android:name=".appwidget.BankdroidWidgetProvider_4x1">
 			<intent-filter>
 				<action
 					android:name="android.appwidget.action.APPWIDGET_UPDATE" />
diff --git res/layout/choose_lock_pattern.xml res/layout/choose_lock_pattern.xml
index 3b06f0c..665599e 100644
--- res/layout/choose_lock_pattern.xml
+++ res/layout/choose_lock_pattern.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+<com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient
         xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/topLayout"
     android:orientation="vertical"
@@ -32,7 +32,7 @@
          android:background="@*android:drawable/code_lock_top"
          android:layout_width="fill_parent"
          android:layout_height="2dip" />
-    <com.liato.bankdroid.LockPatternView android:id="@+id/lockPattern"
+    <com.liato.bankdroid.lockpattern.LockPatternView android:id="@+id/lockPattern"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />
     <View
@@ -80,4 +80,4 @@
 
     </LinearLayout>
 
-</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
+</com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient>
diff --git res/layout/confirm_lock_pattern.xml res/layout/confirm_lock_pattern.xml
index 22880bf..828d7e7 100644
--- res/layout/confirm_lock_pattern.xml
+++ res/layout/confirm_lock_pattern.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+<com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient
         xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/topLayout"
     android:orientation="vertical"
@@ -32,7 +32,7 @@
          android:background="@*android:drawable/code_lock_top"
          android:layout_width="fill_parent"
          android:layout_height="2dip" />
-    <com.liato.bankdroid.LockPatternView android:id="@+id/lockPattern"
+    <com.liato.bankdroid.lockpattern.LockPatternView android:id="@+id/lockPattern"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />
     <View
@@ -48,4 +48,4 @@
         android:textSize="14sp"/>
 
 
-</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
+</com.liato.bankdroid.lockpattern.LinearLayoutWithDefaultTouchRecepient>
diff --git res/xml/appwidget_info.xml res/xml/appwidget_info.xml
index 1729ee9..bb5ed18 100644
--- res/xml/appwidget_info.xml
+++ res/xml/appwidget_info.xml
@@ -4,5 +4,5 @@
     android:minHeight="72dp"
     android:updatePeriodMillis="0"
     android:initialLayout="@layout/widget"
-    android:configure="com.liato.bankdroid.WidgetConfigureActivity" >
+    android:configure="com.liato.bankdroid.appwidget.WidgetConfigureActivity" >
 </appwidget-provider>
\ No newline at end of file
diff --git res/xml/appwidget_info_large.xml res/xml/appwidget_info_large.xml
index 564461a..d46fc4f 100644
--- res/xml/appwidget_info_large.xml
+++ res/xml/appwidget_info_large.xml
@@ -4,5 +4,5 @@
     android:minHeight="72dp"
     android:updatePeriodMillis="0"
     android:initialLayout="@layout/widget_large"
-    android:configure="com.liato.bankdroid.WidgetConfigureActivity" >
+    android:configure="com.liato.bankdroid.appwidget.WidgetConfigureActivity" >
 </appwidget-provider>
\ No newline at end of file

commit dc5d5a2f9e7a8cd0db2a7ed386672210bf9cfeb0
Author: liato <x@x00.us>
Date:   Tue Dec 28 13:41:00 2010 +0100

    Manifest fixes. Bump version to 1.6.0-rc1.

diff --git .gitignore .gitignore
index 01d0b95..71d027d 100644
--- .gitignore
+++ .gitignore
@@ -15,5 +15,5 @@ gen
 local.properties
 *.jar
 dev/
-src/com/liato/bankdroid/Crypto.java
-src/com/liato/bankdroid/Crypto.java.dev
+src/com/liato/bankdroid/db/Crypto.java
+src/com/liato/bankdroid/db/Crypto.java.dev
diff --git AndroidManifest.xml AndroidManifest.xml
index 57d4551..71e6d18 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.5.4-RC1" android:versionCode="61">
+	android:versionName="1.6.0-RC1" android:versionCode="63">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
@@ -52,35 +52,29 @@
 			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
-			android:name=".ChooseLockPattern"
 			android:label="@string/app_name"
-			android:theme="@style/BankdroidTheme">
+			android:theme="@style/BankdroidTheme" android:name=".lockpattern.ChooseLockPattern">
 		</activity>
 		<activity
-			android:name=".ChooseLockPatternExample"
 			android:label="@string/app_name"
-			android:theme="@style/BankdroidTheme">
+			android:theme="@style/BankdroidTheme" android:name=".lockpattern.ChooseLockPatternExample">
 		</activity>
 		<activity
-			android:name=".ChooseLockPatternTutorial"
 			android:label="@string/app_name"
-			android:theme="@style/BankdroidTheme">
+			android:theme="@style/BankdroidTheme" android:name=".lockpattern.ChooseLockPatternTutorial">
 		</activity>
 		<activity
-			android:name=".ConfirmLockPattern"
-			android:label="@string/app_name">
+			android:label="@string/app_name" android:name=".lockpattern.ConfirmLockPattern">
 		</activity>
 		<activity
-			android:name=".WidgetConfigureActivity"
-			android:theme="@android:style/Theme.Dialog">
+			android:theme="@android:style/Theme.Dialog" android:name=".appwidget.WidgetConfigureActivity">
 			<intent-filter>
 				<action
 					android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
 			</intent-filter>
 		</activity>
 		<receiver
-			android:name="BankdroidWidgetProvider_2x1"
-			android:label="@string/widget_name_small">
+			android:label="@string/widget_name_small" android:name=".appwidget.BankdroidWidgetProvider_2x1">
 			<intent-filter>
 				<action
 					android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -93,8 +87,7 @@
 		</receiver>
 
 		<receiver
-			android:name="BankdroidWidgetProvider_4x1"
-			android:label="@string/widget_name_large">
+			android:label="@string/widget_name_large" android:name=".appwidget.BankdroidWidgetProvider_2x1">
 			<intent-filter>
 				<action
 					android:name="android.appwidget.action.APPWIDGET_UPDATE" />
@@ -107,11 +100,9 @@
 		</receiver>
 
 		<service
-			android:enabled="true"
-			android:name=".AutoRefreshService" />
+			android:enabled="true" android:name=".appwidget.AutoRefreshService"/>
 		<service
-			android:enabled="true"
-			android:name=".BankdroidWidgetProvider$WidgetService" />
+			android:enabled="true" android:name=".appwidget.BankdroidWidgetProvider$WidgetService"/>
 		<receiver
 			android:name="StartupReceiver">
 			<intent-filter>
diff --git src/com/liato/bankdroid/Crypto.java src/com/liato/bankdroid/Crypto.java
deleted file mode 100644
index 42ae0f7..0000000
--- src/com/liato/bankdroid/Crypto.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.liato.bankdroid;
-public class Crypto {
-	/*
-	 * The key used to encrypt all the account passwords before storing them in the database.
-	 * This key is not used in the market app.
-	 * 
-	 */
-	private final static String KEY = "KGLRqraqThYniEtasoCqfbjFDwctomjmiY4rvSJThyyU4qUTIPXNLhPxkivpFLgr";
-
-	public final static String getKey() {
-		/*
-		 * Manipulate the key before returning it.
-		 * 
-		 * ...
-		 * 
-		 * Code omitted.
-		 * 
-		 * ...
-		 * 
-		 */
-
-		return KEY;
-	}
-}

commit e4754e36359b363be23ccc4308e7ed1b797b99b6
Author: liato <x@x00.us>
Date:   Tue Dec 28 13:19:24 2010 +0100

    Reorganized projekt a bit.

diff --git res/layout/about.xml res/layout/about.xml
index 5e27d8b..3955db6 100644
--- res/layout/about.xml
+++ res/layout/about.xml
@@ -3,22 +3,83 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:orientation="vertical"
 	android:layout_height="fill_parent"
-	android:layout_width="fill_parent" android:paddingBottom="20dp">
+	android:layout_width="fill_parent"
+	android:paddingBottom="20dp">
 	<ScrollView
 		android:fillViewport="true"
-		android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1">
-		<LinearLayout android:id="@+id/LinearLayout03" android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="wrap_content" android:paddingLeft="20dp" android:paddingRight="20dp"><TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:typeface="sans" android:gravity="center_horizontal" android:text="BANKDROID" android:layout_width="fill_parent" android:visibility="visible" android:textColor="#fff" android:textSize="42dp" android:ellipsize="none" android:inputType="none" android:layout_gravity="center_horizontal"></TextView><LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent">
-			<ImageView android:id="@+id/ImageView01" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:visibility="visible" android:src="@drawable/icon_large" android:maxHeight="100dp" android:maxWidth="100dp" android:minHeight="100dp" android:minWidth="100dp" android:scaleType="fitXY"></ImageView>
-			<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
-				<TextView android:layout_height="wrap_content" android:id="@+id/txtVersion" android:layout_width="fill_parent" android:textSize="17dp" android:text="@string/version"></TextView>
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:layout_weight="1">
+		<LinearLayout
+			android:id="@+id/LinearLayout03"
+			android:orientation="vertical"
+			android:layout_height="fill_parent"
+			android:layout_width="wrap_content"
+			android:paddingLeft="20dp"
+			android:paddingRight="20dp">
+			
+			<ImageView android:id="@+id/ImageView02" android:layout_height="wrap_content" android:src="@drawable/logo_text_big" android:adjustViewBounds="true" android:layout_width="fill_parent" android:scaleType="fitXY"></ImageView><LinearLayout
+				android:id="@+id/LinearLayout01"
+				android:layout_height="wrap_content"
+				android:orientation="horizontal"
+				android:layout_width="fill_parent">
+				<ImageView
+					android:id="@+id/ImageView01"
+					android:layout_width="100dp"
+					android:layout_height="100dp"
+					android:layout_gravity="center_horizontal"
+					android:visibility="visible"
+					android:src="@drawable/icon_large"
+					android:maxHeight="100dp"
+					android:maxWidth="100dp"
+					android:minHeight="100dp"
+					android:minWidth="100dp"
+					android:scaleType="fitXY"></ImageView>
+				<LinearLayout
+					android:id="@+id/LinearLayout02"
+					android:layout_height="wrap_content"
+					android:orientation="vertical"
+					android:layout_width="fill_parent">
+					<TextView
+						android:layout_height="wrap_content"
+						android:id="@+id/txtVersion"
+						android:layout_width="fill_parent"
+						android:textSize="17dp"
+						android:text="@string/version"></TextView>
 
 
-				<TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="http://liato.github.com/android-bankdroid/" android:autoLink="web" android:fitsSystemWindows="false"></TextView>
-			</LinearLayout>
+					<TextView
+						android:id="@+id/TextView02"
+						android:layout_width="wrap_content"
+						android:layout_height="wrap_content"
+						android:text="http://liato.github.com/android-bankdroid/"
+						android:autoLink="web"
+						android:fitsSystemWindows="false"></TextView>
+				</LinearLayout>
 
 
-		</LinearLayout><TextView android:id="@+id/TextView04" android:layout_height="wrap_content" android:text="@string/thanks_to" android:textSize="20sp" android:textStyle="bold" android:layout_marginTop="10dp" android:layout_width="fill_parent"></TextView><TextView android:id="@+id/TextView03" android:layout_height="wrap_content" android:text="@string/thanks" android:layout_width="fill_parent" android:paddingLeft="10dp" android:typeface="serif" android:textSize="12sp"></TextView></LinearLayout>
+			</LinearLayout>
+			<TextView
+				android:id="@+id/TextView04"
+				android:layout_height="wrap_content"
+				android:text="@string/thanks_to"
+				android:textSize="20sp"
+				android:textStyle="bold"
+				android:layout_marginTop="10dp"
+				android:layout_width="fill_parent"></TextView>
+			<TextView
+				android:id="@+id/TextView03"
+				android:layout_height="wrap_content"
+				android:text="@string/thanks"
+				android:layout_width="fill_parent"
+				android:paddingLeft="10dp"
+				android:typeface="serif"
+				android:textSize="12sp"></TextView>
 		
+</LinearLayout>
+
+
+
 
 
 
@@ -27,8 +88,6 @@
 
 
 
-		
-		
 
 
 	</ScrollView>
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 3001624..1939fb6 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -20,6 +20,12 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index e6facb7..0be3b68 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -18,6 +18,12 @@ package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.DialogInterface;
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index c589ad4..5facf11 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -16,6 +16,9 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index d1dbb4f..cd5de32 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -16,6 +16,9 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 791a202..43f9d86 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -18,6 +18,13 @@ package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
+import com.liato.bankdroid.adapters.AccountsAdapter;
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.db.DBAdapter;
+
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 43cc10a..d413e92 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -16,6 +16,11 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+import com.liato.bankdroid.lockpattern.ChooseLockPattern;
+import com.liato.bankdroid.lockpattern.ConfirmLockPattern;
+import com.liato.bankdroid.lockpattern.LockPatternUtils;
+
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 9a04762..178bc12 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -16,6 +16,8 @@
 
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.appwidget.AutoRefreshService;
+
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index 724942e..a2671f9 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -19,6 +19,11 @@ package com.liato.bankdroid;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.Transaction;
+
 import android.content.Context;
 import android.os.Bundle;
 import android.util.Log;
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index 0b18ac2..58323db 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -34,8 +34,11 @@ import android.webkit.CookieSyncManager;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 
-import com.liato.bankdroid.Bank.SessionPackage;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.Bank.SessionPackage;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class WebViewActivity extends LockableActivity implements OnClickListener {
     private final static String TAG = "WebViewActivity";
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/adapters/AccountsAdapter.java
similarity index 95%
rename from src/com/liato/bankdroid/AccountsAdapter.java
rename to src/com/liato/bankdroid/adapters/AccountsAdapter.java
index 7785d35..016af0d 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/adapters/AccountsAdapter.java
@@ -14,10 +14,17 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.adapters;
 
 import java.util.ArrayList;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+
 import android.content.Context;
 import android.graphics.Color;
 import android.view.LayoutInflater;
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/appwidget/AutoRefreshService.java
similarity index 89%
rename from src/com/liato/bankdroid/AutoRefreshService.java
rename to src/com/liato/bankdroid/appwidget/AutoRefreshService.java
index e0259f1..7036a4c 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/appwidget/AutoRefreshService.java
@@ -14,12 +14,24 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.appwidget;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.string;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -37,12 +49,12 @@ import android.util.Log;
 
 public class AutoRefreshService extends Service {
 	private final static String TAG = "AutoRefreshService";
-	final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
-	final static String BROADCAST_MAIN_REFRESH = "com.liato.bankdroid.MAIN_REFRESH";
-    final static String BROADCAST_REMOTE_NOTIFIER = "org.damazio.notifier.service.UserReceiver.USER_MESSAGE";
-    final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
-    final static String BROADCAST_OPENWATCH_VIBRATE = "com.smartmadsoft.openwatch.action.VIBRATE";
-    final static String ACTION_MAIN_SHOW_TRANSACTIONS = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
+	public final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
+	public final static String BROADCAST_MAIN_REFRESH = "com.liato.bankdroid.MAIN_REFRESH";
+	public final static String BROADCAST_REMOTE_NOTIFIER = "org.damazio.notifier.service.UserReceiver.USER_MESSAGE";
+	public final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
+	public final static String BROADCAST_OPENWATCH_VIBRATE = "com.smartmadsoft.openwatch.action.VIBRATE";
+	public final static String ACTION_MAIN_SHOW_TRANSACTIONS = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
     
     NotificationManager notificationManager;
 
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
similarity index 96%
rename from src/com/liato/bankdroid/BankdroidWidgetProvider.java
rename to src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
index 04aa45a..3d6506e 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider.java
@@ -14,7 +14,19 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.appwidget;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.MainActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.drawable;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
 
 import android.app.PendingIntent;
 import android.app.Service;
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
similarity index 94%
rename from src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
rename to src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
index ecdaef7..84794bf 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_2x1.java
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.appwidget;
+
 
 public class BankdroidWidgetProvider_2x1 extends BankdroidWidgetProvider {
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
similarity index 94%
rename from src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
rename to src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
index e2f5751..b6c480c 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
+++ src/com/liato/bankdroid/appwidget/BankdroidWidgetProvider_4x1.java
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.appwidget;
+
 
 
 public class BankdroidWidgetProvider_4x1 extends BankdroidWidgetProvider {
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
similarity index 92%
rename from src/com/liato/bankdroid/WidgetConfigureActivity.java
rename to src/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
index 363bd70..fbc4dd5 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/appwidget/WidgetConfigureActivity.java
@@ -14,10 +14,20 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.appwidget;
 
 import java.util.ArrayList;
 
+import com.liato.bankdroid.LockableActivity;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
+import com.liato.bankdroid.R.string;
+import com.liato.bankdroid.adapters.AccountsAdapter;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.BankFactory;
+
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/banking/Account.java
similarity index 98%
rename from src/com/liato/bankdroid/Account.java
rename to src/com/liato/bankdroid/banking/Account.java
index ad037d3..60ede1a 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/banking/Account.java
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.banking;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
 
+
 public class Account {
 	public final static int REGULAR = 1;
 	public final static int FUNDS = 2;
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/banking/Bank.java
similarity index 96%
rename from src/com/liato/bankdroid/Bank.java
rename to src/com/liato/bankdroid/banking/Bank.java
index 19acaa8..d1988b1 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/banking/Bank.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.banking;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -27,13 +27,20 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.CookieStore;
 
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.raw;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+import com.liato.bankdroid.db.DBAdapter;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.urllib.Urllib;
+import eu.nullbyte.android.urllib.Urllib;
 
 public abstract class Bank implements Comparable<Bank> {
     public final static int TESTBANK = 0;
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/banking/BankFactory.java
similarity index 88%
rename from src/com/liato/bankdroid/BankFactory.java
rename to src/com/liato/bankdroid/banking/BankFactory.java
index d26db9b..9fad560 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/banking/BankFactory.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.banking;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -24,29 +24,31 @@ import android.content.Context;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
-import android.util.Log;
 
-import com.liato.bankdroid.banks.Avanza;
-import com.liato.bankdroid.banks.AvanzaMini;
-import com.liato.bankdroid.banks.Coop;
-import com.liato.bankdroid.banks.DinersClub;
-import com.liato.bankdroid.banks.Eurocard;
-import com.liato.bankdroid.banks.FirstCard;
-import com.liato.bankdroid.banks.Handelsbanken;
-import com.liato.bankdroid.banks.ICA;
-import com.liato.bankdroid.banks.ICABanken;
-import com.liato.bankdroid.banks.IkanoBank;
-import com.liato.bankdroid.banks.Jojo;
-import com.liato.bankdroid.banks.Lansforsakringar;
-import com.liato.bankdroid.banks.Nordea;
-import com.liato.bankdroid.banks.OKQ8;
-import com.liato.bankdroid.banks.PayPal;
-import com.liato.bankdroid.banks.Payson;
-import com.liato.bankdroid.banks.Statoil;
-import com.liato.bankdroid.banks.Steam;
-import com.liato.bankdroid.banks.Swedbank;
-import com.liato.bankdroid.banks.TestBank;
-import com.liato.bankdroid.banks.Villabanken;
+import com.liato.bankdroid.banking.banks.Avanza;
+import com.liato.bankdroid.banking.banks.AvanzaMini;
+import com.liato.bankdroid.banking.banks.Coop;
+import com.liato.bankdroid.banking.banks.DinersClub;
+import com.liato.bankdroid.banking.banks.Eurocard;
+import com.liato.bankdroid.banking.banks.FirstCard;
+import com.liato.bankdroid.banking.banks.Handelsbanken;
+import com.liato.bankdroid.banking.banks.ICA;
+import com.liato.bankdroid.banking.banks.ICABanken;
+import com.liato.bankdroid.banking.banks.IkanoBank;
+import com.liato.bankdroid.banking.banks.Jojo;
+import com.liato.bankdroid.banking.banks.Lansforsakringar;
+import com.liato.bankdroid.banking.banks.Nordea;
+import com.liato.bankdroid.banking.banks.OKQ8;
+import com.liato.bankdroid.banking.banks.PayPal;
+import com.liato.bankdroid.banking.banks.Payson;
+import com.liato.bankdroid.banking.banks.Statoil;
+import com.liato.bankdroid.banking.banks.Steam;
+import com.liato.bankdroid.banking.banks.Swedbank;
+import com.liato.bankdroid.banking.banks.TestBank;
+import com.liato.bankdroid.banking.banks.Villabanken;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.db.Crypto;
+import com.liato.bankdroid.db.DBAdapter;
 
 public class BankFactory {
 
diff --git src/com/liato/bankdroid/Transaction.java src/com/liato/bankdroid/banking/Transaction.java
similarity index 98%
rename from src/com/liato/bankdroid/Transaction.java
rename to src/com/liato/bankdroid/banking/Transaction.java
index 8c67cce..34d2503 100644
--- src/com/liato/bankdroid/Transaction.java
+++ src/com/liato/bankdroid/banking/Transaction.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.banking;
 
 import java.math.BigDecimal;
 
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banking/banks/Avanza.java
similarity index 94%
rename from src/com/liato/bankdroid/banks/Avanza.java
rename to src/com/liato/bankdroid/banking/banks/Avanza.java
index b495db7..b2cddb9 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banking/banks/Avanza.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.text.SimpleDateFormat;
@@ -31,14 +31,15 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Avanza extends Bank {
 	private static final String TAG = "Avanza";
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banking/banks/AvanzaMini.java
similarity index 93%
rename from src/com/liato/bankdroid/banks/AvanzaMini.java
rename to src/com/liato/bankdroid/banking/banks/AvanzaMini.java
index 14bd8c3..c2fcc8f 100644
--- src/com/liato/bankdroid/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banking/banks/AvanzaMini.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -29,13 +29,14 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class AvanzaMini extends Bank {
 	private static final String TAG = "AvanzaMini";
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banking/banks/Coop.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/Coop.java
rename to src/com/liato/bankdroid/banking/banks/Coop.java
index c92f643..257ddbc 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banking/banks/Coop.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -32,14 +32,15 @@ import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 import android.text.Html;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Coop extends Bank {
     private static final String TAG = "Coop";
diff --git src/com/liato/bankdroid/banks/DinersClub.java src/com/liato/bankdroid/banking/banks/DinersClub.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/DinersClub.java
rename to src/com/liato/bankdroid/banking/banks/DinersClub.java
index 6ee4f44..1a2f264 100644
--- src/com/liato/bankdroid/banks/DinersClub.java
+++ src/com/liato/bankdroid/banking/banks/DinersClub.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -29,13 +29,14 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class DinersClub extends Bank {
 	private static final String TAG = "DinersClub";
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banking/banks/Eurocard.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/Eurocard.java
rename to src/com/liato/bankdroid/banking/banks/Eurocard.java
index 8f2a6ca..5932112 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banking/banks/Eurocard.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -33,14 +33,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Eurocard extends Bank {
 	private static final String TAG = "Eurocard";
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banking/banks/FirstCard.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/FirstCard.java
rename to src/com/liato/bankdroid/banking/banks/FirstCard.java
index 1be4e13..50994ff 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banking/banks/FirstCard.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,14 +31,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class FirstCard extends Bank {
 	private static final String TAG = "FirstCard";
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banking/banks/Handelsbanken.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/Handelsbanken.java
rename to src/com/liato/bankdroid/banking/banks/Handelsbanken.java
index 3c5ef1b..4b5e93b 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banking/banks/Handelsbanken.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -32,14 +32,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Handelsbanken extends Bank {
 	private static final String TAG = "Handelsbanken";
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banking/banks/ICA.java
similarity index 94%
rename from src/com/liato/bankdroid/banks/ICA.java
rename to src/com/liato/bankdroid/banking/banks/ICA.java
index 485bb20..1b5a6f5 100644
--- src/com/liato/bankdroid/banks/ICA.java
+++ src/com/liato/bankdroid/banking/banks/ICA.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -30,14 +30,15 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class ICA extends Bank {
 	private static final String TAG = "ICA";
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banking/banks/ICABanken.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/ICABanken.java
rename to src/com/liato/bankdroid/banking/banks/ICABanken.java
index 57d8a85..347ca41 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banking/banks/ICABanken.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,14 +31,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class ICABanken extends Bank {
 	private static final String TAG = "ICABanken";
diff --git src/com/liato/bankdroid/banks/IkanoBank.java src/com/liato/bankdroid/banking/banks/IkanoBank.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/IkanoBank.java
rename to src/com/liato/bankdroid/banking/banks/IkanoBank.java
index d86bbb2..64740e6 100644
--- src/com/liato/bankdroid/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banking/banks/IkanoBank.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,14 +31,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class IkanoBank extends Bank {
     private static final String TAG = "IkanoBank";
diff --git src/com/liato/bankdroid/banks/Jojo.java src/com/liato/bankdroid/banking/banks/Jojo.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/Jojo.java
rename to src/com/liato/bankdroid/banking/banks/Jojo.java
index 8a7ee3d..2837fb2 100644
--- src/com/liato/bankdroid/banks/Jojo.java
+++ src/com/liato/bankdroid/banking/banks/Jojo.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -29,13 +29,14 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.text.Html;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Jojo extends Bank {
     private static final String TAG = "Jojo";
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
similarity index 97%
rename from src/com/liato/bankdroid/banks/Lansforsakringar.java
rename to src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
index 6aca12f..bcc39ee 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banking/banks/Lansforsakringar.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,14 +31,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Lansforsakringar extends Bank {
     private static final String TAG = "Lansforsakringar";
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banking/banks/Nordea.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/Nordea.java
rename to src/com/liato/bankdroid/banking/banks/Nordea.java
index f526afb..6456ee2 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banking/banks/Nordea.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,14 +31,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Nordea extends Bank {
 	private static final String TAG = "Nordea";
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banking/banks/OKQ8.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/OKQ8.java
rename to src/com/liato/bankdroid/banking/banks/OKQ8.java
index 503b8df..9d9bbcb 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banking/banks/OKQ8.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -33,14 +33,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class OKQ8 extends Bank {
 	private static final String TAG = "OKQ8";
diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banking/banks/PayPal.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/PayPal.java
rename to src/com/liato/bankdroid/banking/banks/PayPal.java
index 606c6d8..8e9ef2e 100644
--- src/com/liato/bankdroid/banks/PayPal.java
+++ src/com/liato/bankdroid/banking/banks/PayPal.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,13 +31,14 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class PayPal extends Bank {
 	private static final String TAG = "PayPal";
diff --git src/com/liato/bankdroid/banks/Payson.java src/com/liato/bankdroid/banking/banks/Payson.java
similarity index 94%
rename from src/com/liato/bankdroid/banks/Payson.java
rename to src/com/liato/bankdroid/banking/banks/Payson.java
index 73b60b6..efc967c 100644
--- src/com/liato/bankdroid/banks/Payson.java
+++ src/com/liato/bankdroid/banking/banks/Payson.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -30,14 +30,15 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Payson extends Bank {
 	private static final String TAG = "Payson";
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banking/banks/Statoil.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/Statoil.java
rename to src/com/liato/bankdroid/banking/banks/Statoil.java
index bec78ec..685f1fc 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banking/banks/Statoil.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -33,14 +33,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Statoil extends Bank {
 	private static final String TAG = "Statoil";
diff --git src/com/liato/bankdroid/banks/Steam.java src/com/liato/bankdroid/banking/banks/Steam.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/Steam.java
rename to src/com/liato/bankdroid/banking/banks/Steam.java
index 61d2f7a..6e06b03 100644
--- src/com/liato/bankdroid/banks/Steam.java
+++ src/com/liato/bankdroid/banking/banks/Steam.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -35,14 +35,15 @@ import android.content.Context;
 import android.text.Html;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Steam extends Bank {
 	private static final String TAG = "Steam";
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banking/banks/Swedbank.java
similarity index 95%
rename from src/com/liato/bankdroid/banks/Swedbank.java
rename to src/com/liato/bankdroid/banking/banks/Swedbank.java
index 1732636..cb7ca2a 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banking/banks/Swedbank.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,14 +31,15 @@ import android.text.Html;
 import android.text.InputType;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Swedbank extends Bank {
 	private static final String TAG = "Swedbank";
diff --git src/com/liato/bankdroid/banks/TestBank.java src/com/liato/bankdroid/banking/banks/TestBank.java
similarity index 94%
rename from src/com/liato/bankdroid/banks/TestBank.java
rename to src/com/liato/bankdroid/banking/banks/TestBank.java
index cb5ea94..c681c1f 100644
--- src/com/liato/bankdroid/banks/TestBank.java
+++ src/com/liato/bankdroid/banking/banks/TestBank.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -27,14 +27,15 @@ import android.content.Context;
 import android.text.Html;
 import android.text.InputType;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.bankdroid.Transaction;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class TestBank extends Bank {
 	private static final String TAG = "TestBank";
diff --git src/com/liato/bankdroid/banks/Villabanken.java src/com/liato/bankdroid/banking/banks/Villabanken.java
similarity index 96%
rename from src/com/liato/bankdroid/banks/Villabanken.java
rename to src/com/liato/bankdroid/banking/banks/Villabanken.java
index 20d1872..6ec35d1 100644
--- src/com/liato/bankdroid/banks/Villabanken.java
+++ src/com/liato/bankdroid/banking/banks/Villabanken.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid.banks;
+package com.liato.bankdroid.banking.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -30,13 +30,14 @@ import android.content.Context;
 import android.text.Html;
 import android.util.Log;
 
-import com.liato.bankdroid.Account;
-import com.liato.bankdroid.Bank;
-import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
-import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
-import com.liato.urllib.Urllib;
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.exceptions.BankException;
+import com.liato.bankdroid.banking.exceptions.LoginException;
+
+import eu.nullbyte.android.urllib.Urllib;
 
 public class Villabanken extends Bank {
 	private static final String TAG = "Villabanken";
diff --git src/com/liato/bankdroid/BankException.java src/com/liato/bankdroid/banking/exceptions/BankException.java
similarity index 94%
rename from src/com/liato/bankdroid/BankException.java
rename to src/com/liato/bankdroid/banking/exceptions/BankException.java
index 212e4cd..b057b2b 100644
--- src/com/liato/bankdroid/BankException.java
+++ src/com/liato/bankdroid/banking/exceptions/BankException.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.banking.exceptions;
 
 public class BankException extends Exception {
 	private static final long serialVersionUID = 1L;
diff --git src/com/liato/bankdroid/LoginException.java src/com/liato/bankdroid/banking/exceptions/LoginException.java
similarity index 94%
rename from src/com/liato/bankdroid/LoginException.java
rename to src/com/liato/bankdroid/banking/exceptions/LoginException.java
index a6fcdc4..df810ef 100644
--- src/com/liato/bankdroid/LoginException.java
+++ src/com/liato/bankdroid/banking/exceptions/LoginException.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.banking.exceptions;
 
 public class LoginException extends Exception {
 	private static final long serialVersionUID = 1L;
diff --git src/com/liato/bankdroid/db/Crypto.java src/com/liato/bankdroid/db/Crypto.java
new file mode 100644
index 0000000..29b2ac7
--- /dev/null
+++ src/com/liato/bankdroid/db/Crypto.java
@@ -0,0 +1,24 @@
+package com.liato.bankdroid.db;
+public class Crypto {
+	/*
+	 * The key used to encrypt all the account passwords before storing them in the database.
+	 * This key is not used in the market app.
+	 * 
+	 */
+	private final static String KEY = "KGLRqraqThYniEtasoCqfbjFDwctomjmiY4rvSJThyyU4qUTIPXNLhPxkivpFLgr";
+
+	public final static String getKey() {
+		/*
+		 * Manipulate the key before returning it.
+		 * 
+		 * ...
+		 * 
+		 * Code omitted.
+		 * 
+		 * ...
+		 * 
+		 */
+
+		return KEY;
+	}
+}
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/db/DBAdapter.java
similarity index 98%
rename from src/com/liato/bankdroid/DBAdapter.java
rename to src/com/liato/bankdroid/db/DBAdapter.java
index 8622845..f8fb80e 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/db/DBAdapter.java
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.db;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 
+import com.liato.bankdroid.banking.Account;
+import com.liato.bankdroid.banking.Bank;
+import com.liato.bankdroid.banking.Transaction;
+
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.ContentValues;
 import android.content.Context;
diff --git src/com/liato/bankdroid/ChooseLockPattern.java src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
similarity index 97%
rename from src/com/liato/bankdroid/ChooseLockPattern.java
rename to src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
index 1d92f5b..60b54de 100644
--- src/com/liato/bankdroid/ChooseLockPattern.java
+++ src/com/liato/bankdroid/lockpattern/ChooseLockPattern.java
@@ -14,14 +14,17 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.lockpattern;
 
 import com.google.common.collect.Lists;
 
-import com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient;
-import com.liato.bankdroid.LockPatternUtils;
-import com.liato.bankdroid.LockPatternView;
-import static com.liato.bankdroid.LockPatternView.DisplayMode;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
+import com.liato.bankdroid.R.string;
+import com.liato.bankdroid.lockpattern.LockPatternView.Cell;
+import com.liato.bankdroid.lockpattern.LockPatternView.DisplayMode;
+import com.liato.bankdroid.lockpattern.LockPatternView.OnPatternListener;
 
 import android.app.Activity;
 import android.content.Intent;
diff --git src/com/liato/bankdroid/ChooseLockPatternExample.java src/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
similarity index 94%
rename from src/com/liato/bankdroid/ChooseLockPatternExample.java
rename to src/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
index bc149cf..61865f1 100644
--- src/com/liato/bankdroid/ChooseLockPatternExample.java
+++ src/com/liato/bankdroid/lockpattern/ChooseLockPatternExample.java
@@ -14,7 +14,12 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.lockpattern;
+
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.drawable;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
 
 import android.app.Activity;
 import android.content.Intent;
diff --git src/com/liato/bankdroid/ChooseLockPatternTutorial.java src/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
similarity index 94%
rename from src/com/liato/bankdroid/ChooseLockPatternTutorial.java
rename to src/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
index dfaeb9b..ead0f85 100644
--- src/com/liato/bankdroid/ChooseLockPatternTutorial.java
+++ src/com/liato/bankdroid/lockpattern/ChooseLockPatternTutorial.java
@@ -14,9 +14,11 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.lockpattern;
 
-import com.liato.bankdroid.LockPatternUtils;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
 
 import android.app.Activity;
 import android.content.Intent;
diff --git src/com/liato/bankdroid/ConfirmLockPattern.java src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
similarity index 95%
rename from src/com/liato/bankdroid/ConfirmLockPattern.java
rename to src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
index e50df89..a76e58f 100644
--- src/com/liato/bankdroid/ConfirmLockPattern.java
+++ src/com/liato/bankdroid/lockpattern/ConfirmLockPattern.java
@@ -14,11 +14,17 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
-
-import com.liato.bankdroid.LockPatternUtils;
-import com.liato.bankdroid.LockPatternView;
-import com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient;
+package com.liato.bankdroid.lockpattern;
+
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.R.anim;
+import com.liato.bankdroid.R.id;
+import com.liato.bankdroid.R.layout;
+import com.liato.bankdroid.R.string;
+import com.liato.bankdroid.lockpattern.LockPatternView.Cell;
+import com.liato.bankdroid.lockpattern.LockPatternView.DisplayMode;
+import com.liato.bankdroid.lockpattern.LockPatternView.OnPatternListener;
 
 import android.app.Activity;
 import android.content.Intent;
diff --git src/com/liato/bankdroid/LinearLayoutWithDefaultTouchRecepient.java src/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
similarity index 98%
rename from src/com/liato/bankdroid/LinearLayoutWithDefaultTouchRecepient.java
rename to src/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
index ac3d3ab..0350369 100644
--- src/com/liato/bankdroid/LinearLayoutWithDefaultTouchRecepient.java
+++ src/com/liato/bankdroid/lockpattern/LinearLayoutWithDefaultTouchRecepient.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.lockpattern;
 
 import android.content.Context;
 import android.graphics.Rect;
diff --git src/com/liato/bankdroid/LockPatternUtils.java src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
similarity index 99%
rename from src/com/liato/bankdroid/LockPatternUtils.java
rename to src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
index 687ded6..39125ee 100644
--- src/com/liato/bankdroid/LockPatternUtils.java
+++ src/com/liato/bankdroid/lockpattern/LockPatternUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.lockpattern;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -35,6 +35,7 @@ import android.text.TextUtils;
 import android.util.Log;
 
 import com.google.common.collect.Lists;
+import com.liato.bankdroid.lockpattern.LockPatternView.Cell;
 
 /**
  * Utilities for the lock patten and its settings.
diff --git src/com/liato/bankdroid/LockPatternView.java src/com/liato/bankdroid/lockpattern/LockPatternView.java
similarity index 99%
rename from src/com/liato/bankdroid/LockPatternView.java
rename to src/com/liato/bankdroid/lockpattern/LockPatternView.java
index da6db20..b79ed01 100644
--- src/com/liato/bankdroid/LockPatternView.java
+++ src/com/liato/bankdroid/lockpattern/LockPatternView.java
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package com.liato.bankdroid;
+package com.liato.bankdroid.lockpattern;
 
 
 import java.util.ArrayList;
 import java.util.List;
 
+
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
diff --git src/com/liato/urllib/EasySSLSocketFactory.java src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
similarity index 99%
rename from src/com/liato/urllib/EasySSLSocketFactory.java
rename to src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
index 61d2d15..936876d 100644
--- src/com/liato/urllib/EasySSLSocketFactory.java
+++ src/eu/nullbyte/android/urllib/EasySSLSocketFactory.java
@@ -1,4 +1,4 @@
-package com.liato.urllib;
+package eu.nullbyte.android.urllib;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
diff --git src/com/liato/urllib/TrivialTrustManager.java src/eu/nullbyte/android/urllib/TrivialTrustManager.java
similarity index 94%
rename from src/com/liato/urllib/TrivialTrustManager.java
rename to src/eu/nullbyte/android/urllib/TrivialTrustManager.java
index be57bc9..e2c2e74 100644
--- src/com/liato/urllib/TrivialTrustManager.java
+++ src/eu/nullbyte/android/urllib/TrivialTrustManager.java
@@ -1,4 +1,4 @@
-package com.liato.urllib;
+package eu.nullbyte.android.urllib;
 
 public class TrivialTrustManager implements javax.net.ssl.X509TrustManager {
     public java.security.cert.X509Certificate[] getAcceptedIssuers() {
diff --git src/com/liato/urllib/Urllib.java src/eu/nullbyte/android/urllib/Urllib.java
similarity index 99%
rename from src/com/liato/urllib/Urllib.java
rename to src/eu/nullbyte/android/urllib/Urllib.java
index c95a42e..93a2f56 100644
--- src/com/liato/urllib/Urllib.java
+++ src/eu/nullbyte/android/urllib/Urllib.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.liato.urllib;
+package eu.nullbyte.android.urllib;
 
 import java.io.IOException;
 import java.util.ArrayList;

commit 9381f9f6506680872a273b02832baf8aa9598a6f
Author: liato <x@x00.us>
Date:   Mon Dec 27 22:36:34 2010 +0100

    New loading page for automatic logins.

diff --git .classpath .classpath
index 6d8bf51..e7b211d 100644
--- .classpath
+++ .classpath
@@ -4,5 +4,6 @@
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
+	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/commons-io-2.0.1/commons-io-2.0.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index e9d361f..57d4551 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -21,7 +21,8 @@
 			android:label="@string/app_name"
 			android:multiprocess="false"
 			android:alwaysRetainTaskState="false"
-			android:configChanges="keyboardHidden|orientation">
+			android:configChanges="keyboardHidden|orientation"
+			android:theme="@style/BankdroidTheme">
 			<intent-filter>
 				<action
 					android:name="android.intent.action.MAIN" />
@@ -31,32 +32,39 @@
 		</activity>
 		<activity
 			android:name=".TransactionsActivity"
-			android:label="@string/app_name">
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".WebViewActivity"
-			android:label="@string/app_name">
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".BankEditActivity"
 			android:label="@string/app_name"
-			android:configChanges="keyboardHidden|orientation">
+			android:configChanges="keyboardHidden|orientation"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".SettingsActivity"
-			android:label="@string/app_name">
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".ChooseLockPattern"
-			android:label="@string/app_name">
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".ChooseLockPatternExample"
-			android:label="@string/app_name">
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".ChooseLockPatternTutorial"
-			android:label="@string/app_name">
+			android:label="@string/app_name"
+			android:theme="@style/BankdroidTheme">
 		</activity>
 		<activity
 			android:name=".ConfirmLockPattern"
diff --git assets/background_repeat.png assets/background_repeat.png
new file mode 100644
index 0000000..5cf48ae
Binary files /dev/null and assets/background_repeat.png differ
diff --git assets/logo_text_big.png assets/logo_text_big.png
new file mode 100644
index 0000000..ccb77b9
Binary files /dev/null and assets/logo_text_big.png differ
diff --git res/drawable-hdpi-v4/background_repeat.png res/drawable-hdpi-v4/background_repeat.png
new file mode 100644
index 0000000..5cf48ae
Binary files /dev/null and res/drawable-hdpi-v4/background_repeat.png differ
diff --git res/drawable-hdpi-v4/logo_text_big.png res/drawable-hdpi-v4/logo_text_big.png
new file mode 100644
index 0000000..ccb77b9
Binary files /dev/null and res/drawable-hdpi-v4/logo_text_big.png differ
diff --git res/drawable-hdpi-v4/title_icon_add.png res/drawable-hdpi-v4/title_icon_add.png
new file mode 100644
index 0000000..415ee04
Binary files /dev/null and res/drawable-hdpi-v4/title_icon_add.png differ
diff --git res/drawable-hdpi-v4/title_icon_back.png res/drawable-hdpi-v4/title_icon_back.png
new file mode 100644
index 0000000..2e45562
Binary files /dev/null and res/drawable-hdpi-v4/title_icon_back.png differ
diff --git res/drawable-hdpi-v4/title_icon_forward.png res/drawable-hdpi-v4/title_icon_forward.png
new file mode 100644
index 0000000..f6fa1d8
Binary files /dev/null and res/drawable-hdpi-v4/title_icon_forward.png differ
diff --git res/drawable-hdpi-v4/title_icon_refresh.png res/drawable-hdpi-v4/title_icon_refresh.png
new file mode 100644
index 0000000..27df0b0
Binary files /dev/null and res/drawable-hdpi-v4/title_icon_refresh.png differ
diff --git res/drawable-hdpi-v4/title_logo_focused.png res/drawable-hdpi-v4/title_logo_focused.png
new file mode 100644
index 0000000..4c7e999
Binary files /dev/null and res/drawable-hdpi-v4/title_logo_focused.png differ
diff --git res/drawable-hdpi-v4/title_logo_normal.png res/drawable-hdpi-v4/title_logo_normal.png
new file mode 100644
index 0000000..9248894
Binary files /dev/null and res/drawable-hdpi-v4/title_logo_normal.png differ
diff --git res/drawable/background_repeat.xml res/drawable/background_repeats.xml
similarity index 100%
rename from res/drawable/background_repeat.xml
rename to res/drawable/background_repeats.xml
diff --git res/drawable/logo_moneybookers.png res/drawable/logo_moneybookers.png
new file mode 100644
index 0000000..4f4e123
Binary files /dev/null and res/drawable/logo_moneybookers.png differ
diff --git res/drawable/menu_button.xml res/drawable/menu_button.xml
index 6d60713..e3ea269 100644
--- res/drawable/menu_button.xml
+++ res/drawable/menu_button.xml
@@ -1,14 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true"
-        android:drawable="@drawable/button_bg_pressed" >
-    </item>
+<selector
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<item
+		android:state_pressed="true"
+		android:drawable="@drawable/button_bg_pressed">
+	</item>
 
-    <item android:state_focused="true"
-        android:drawable="@drawable/button_bg_pressed" >
-    </item>
+	<item
+		android:state_focused="true"
+		android:drawable="@drawable/button_bg_pressed">
+	</item>
 
-    <item 
-        android:drawable="@drawable/button_bg" >
-    </item>
+	<item
+		android:drawable="@drawable/button_bg">
+	</item>
 </selector>
diff --git res/drawable/title_background.xml res/drawable/title_background.xml
new file mode 100644
index 0000000..0e30069
--- /dev/null
+++ res/drawable/title_background.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#3a3838"
+        android:endColor="#020202"
+        android:angle="-90" />
+</shape>
\ No newline at end of file
diff --git res/drawable/title_item_background.xml res/drawable/title_item_background.xml
new file mode 100644
index 0000000..902a6c6
--- /dev/null
+++ res/drawable/title_item_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<item
+		android:state_pressed="true"
+		android:drawable="@drawable/title_item_background_focused">
+	</item>
+
+	<item
+		android:state_focused="true"
+		android:drawable="@drawable/title_item_background_focused">
+	</item>
+
+	<item
+		android:drawable="@android:id/empty">
+	</item>
+</selector>
diff --git res/drawable/title_item_background_focused.xml res/drawable/title_item_background_focused.xml
new file mode 100644
index 0000000..213d1a7
--- /dev/null
+++ res/drawable/title_item_background_focused.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#589bd4"
+        android:endColor="#2b5b83"
+        android:angle="-90" />
+</shape>
\ No newline at end of file
diff --git res/drawable/title_logo.xml res/drawable/title_logo.xml
new file mode 100644
index 0000000..442b4ad
--- /dev/null
+++ res/drawable/title_logo.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<item
+		android:state_pressed="true"
+		android:drawable="@drawable/title_logo_focused">
+	</item>
+
+	<item
+		android:state_focused="true"
+		android:drawable="@drawable/title_logo_focused">
+	</item>
+
+	<item
+		android:drawable="@drawable/title_logo_normal">
+	</item>
+</selector>
\ No newline at end of file
diff --git res/drawable/title_separator.xml res/drawable/title_separator.xml
new file mode 100644
index 0000000..26450b1
--- /dev/null
+++ res/drawable/title_separator.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#4d4c4c"
+        android:endColor="#4d4c4c"
+        android:angle="-90" />
+</shape>
\ No newline at end of file
diff --git res/layout/main.xml res/layout/main.xml
index ceb48ca..82d716e 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -33,7 +33,7 @@
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentRight="true"
 		android:layout_width="wrap_content"
-		android:id="@+id/layMainMenu">
+		android:id="@+id/layMainMenu" android:visibility="gone">
 		<TableRow
 			android:id="@+id/TableRow01"
 			android:layout_height="wrap_content"
diff --git res/layout/title.xml res/layout/title.xml
new file mode 100644
index 0000000..1ba33b0
--- /dev/null
+++ res/layout/title.xml
@@ -0,0 +1,36 @@
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	android:background="@drawable/title_background"
+	android:id="@+id/layTitle">
+	<LinearLayout
+		android:layout_width="wrap_content"
+		android:id="@+id/layLogoContainer"
+		android:layout_height="fill_parent">
+		<ImageView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:src="@drawable/icon"
+			android:scaleType="fitXY"
+			android:adjustViewBounds="true"
+			android:id="@+id/imgLogoIcon"
+			android:layout_gravity="center_vertical"
+			android:paddingLeft="2dp"
+			android:maxHeight="20dp" android:visibility="gone"></ImageView>
+		<ImageView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:src="@drawable/title_logo"
+			android:scaleType="fitXY"
+			android:adjustViewBounds="true"
+			android:id="@+id/imgTitle"
+			android:layout_gravity="center_vertical"
+			android:maxHeight="17dp" android:paddingLeft="6dp"></ImageView>
+	</LinearLayout>
+	<LinearLayout
+		android:layout_width="wrap_content"
+		android:id="@+id/layTitleButtons"
+		android:layout_height="fill_parent"
+		android:layout_alignParentRight="true"></LinearLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/title_item.xml res/layout/title_item.xml
new file mode 100644
index 0000000..6596cc9
--- /dev/null
+++ res/layout/title_item.xml
@@ -0,0 +1,25 @@
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="wrap_content"
+	android:id="@+id/layTitleItem"
+	android:layout_height="fill_parent"
+	android:layout_gravity="right">
+	<ImageView
+		android:layout_width="wrap_content"
+		android:background="@drawable/title_separator"
+		android:layout_height="fill_parent"
+		android:maxWidth="1dp"
+		android:minWidth="1dp"></ImageView>
+	<ImageButton
+		android:layout_width="wrap_content"
+		android:adjustViewBounds="true"
+		android:id="@+id/imgItemIcon"
+		android:paddingLeft="5dp"
+		android:src="@drawable/title_icon_add"
+		android:paddingRight="5dp"
+		android:layout_height="fill_parent"
+		android:layout_gravity="center_vertical|center"
+		android:background="@drawable/title_item_background"
+		android:paddingBottom="0dp"></ImageButton>
+
+</LinearLayout>
\ No newline at end of file
diff --git res/layout/webview.xml res/layout/webview.xml
index 199f115..d46671d 100644
--- res/layout/webview.xml
+++ res/layout/webview.xml
@@ -6,5 +6,6 @@
 	<WebView
 		android:id="@+id/wvBank"
 		android:layout_height="fill_parent"
-		android:layout_width="fill_parent" />
+		android:layout_width="fill_parent"
+		android:scrollbarAlwaysDrawHorizontalTrack="false" android:scrollbarAlwaysDrawVerticalTrack="false" android:background="@drawable/background_repeat"/>
 </FrameLayout>
diff --git res/raw/loading.html res/raw/loading.html
new file mode 100644
index 0000000..69655b6
--- /dev/null
+++ res/raw/loading.html
@@ -0,0 +1,73 @@
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
+		<style type="text/css">
+			body {
+				/*background: #1a1a1a url(file:///android_asset/background_repeat.png) no-repeat;*/
+				background: transparent;
+				background-size: 100%%;
+				margin: 0;
+				padding: 0;
+				height: 100%%;
+			}
+			#content {
+				margin-left: 12%%;
+				width: 76%%;
+				position: absolute;
+				top: 45%%;
+			}
+			#logo {
+				width: 100%%;
+				display: block;
+			}
+			#loading {
+			        float:right;
+			}
+			.c {
+			    background-color: #59b1f9; /*Preload: #CCC; Presubmit: #59b1f9*/
+			    float:left;
+			    height:6px;
+			    margin-left:5px;
+			    width:6px;
+			    -webkit-animation-name: bounce_circle;
+			    -webkit-border-radius:3px;
+			    -webkit-animation-duration: 2.5s;
+			    -webkit-animation-iteration-count: infinite;
+			    -webkit-animation-direction: linear;
+			    opacity:0.3;
+			}
+			#c1{
+			    -webkit-animation-delay: .0s;
+			 }
+			#c2{
+			    -webkit-animation-delay: .4s;
+			}
+			#c3{
+			    -webkit-animation-delay: .8s;
+			}
+			#c4{
+			    -webkit-animation-delay: 1.2s;
+			}
+			@-webkit-keyframes bounce_circle{
+			    0%%{opacity:0.3;}
+			    50%%{opacity:1;background-color:#111}
+			    100%%{opacity:0.3;}
+			}
+		</style>
+		<script type="text/javascript">
+		%s
+		</script>
+	</head>
+	<body>
+		<div id="content">
+			<img id="logo" src="file:///android_asset/logo_text_big.png" alt="Bankdroid" />
+			<div id="loading">
+				<div id="c1" class="c"></div>
+				<div id="c2" class="c"></div>
+				<div id="c3" class="c"></div>
+				<div id="c4" class="c"></div>
+			</div>
+		</div>
+		%s
+	</body>
+</html> 
\ No newline at end of file
diff --git res/values/strings.xml res/values/strings.xml
index 3e6e423..9397845 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -199,6 +199,5 @@
     </string>
 	<string name="lock_cancel">Cancel</string>
 	<string name="lock_ok">Ok</string>
-	
          
 </resources>
diff --git res/values/styles.xml res/values/styles.xml
index 321aeaf..7751164 100644
--- res/values/styles.xml
+++ res/values/styles.xml
@@ -58,5 +58,9 @@
 	<style name="Animations.PopDownMenu">
 		<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
 		<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
-	</style>  
+	</style>
+    <style name="WindowTitleBackground" parent="android:WindowTitleBackground">    
+        <item name="android:background">@android:color/transparent</item>        
+    </style>    
+ 	
 </resources>
diff --git res/values/themes.xml res/values/themes.xml
new file mode 100644
index 0000000..e606b55
--- /dev/null
+++ res/values/themes.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<style
+		name="BankdroidTheme"
+		parent="android:Theme">
+		<item
+			name="android:windowTitleSize">40dp</item>
+		<item
+			name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item>
+	</style>
+</resources>
\ No newline at end of file
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 77367db..19acaa8 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -22,12 +22,14 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.CookieStore;
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.text.InputType;
 import android.util.Log;
 
@@ -297,32 +299,32 @@ public abstract class Bank implements Comparable<Bank> {
         }
     }
     
-    public SessionPackage getSessionPackage() {
-        String loginHtmlTemplate = "<html><head>" +
-                                    "<script type=\"text/javascript\">" +
-                                    "function go(){document.getElementById('submitform').submit(); }" +
-                                    "</script>" +
-                                    "</head><body>" +
-                                    "Bankdroid..." +
-                                    "%s" +
-                                    "<script type=\"text/javascript\">" +
-                                    "go();" +
-                                    "</script></body></html>";
-        String redirectHtmlTemplate = "<html><head>" +
-                                        "<script type=\"text/javascript\">" +
-                                        "function go(){window.location=\"%s\" }" +
-                                        "</script></head><body>" +
-                                        "Bankdroid..." +
-                                        "<script type=\"text/javascript\">" +
-                                        "go();" +
-                                        "</script></body></html>";        
+    public SessionPackage getSessionPackage(Context context) {
+        String preloader = "Error...";
+        try {
+            preloader = IOUtils.toString(context.getResources().openRawResource(R.raw.loading));
+        }
+        catch (NotFoundException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
+        catch (IOException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
+ 
         try {
             LoginPackage lp = preLogin();
             if (lp == null) {
-                throw new BankException("No automatic login for this bank. preLogin() is not implemented.");
+                throw new BankException("No automatic login for this bank. preLogin() is not implemented or has failed.");
             }
+            String html = String.format(preloader,
+                                        "function go(){document.getElementById('submitform').submit(); }", // Javascript function
+                                        Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())+"<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
+                                        );        
+            
             CookieStore cookies = urlopen.getHttpclient().getCookieStore();
-            return new SessionPackage(String.format(loginHtmlTemplate, Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())), cookies);
+            return new SessionPackage(html, cookies);
         }
         catch (ClientProtocolException e) {
             Log.d(TAG, e.getMessage());
@@ -333,8 +335,11 @@ public abstract class Bank implements Comparable<Bank> {
         catch (BankException e) {
             Log.d(TAG, e.getMessage());
         }
-        
-        return new SessionPackage(String.format(redirectHtmlTemplate, this.URL), null);
+        String html = String.format(preloader,
+                String.format("function go(){window.location=\"%s\" }", this.URL), // Javascript function
+                "<script type=\"text/javascript\">setTimeout('go()', 1000);</script>" // HTML
+                );          
+        return new SessionPackage(html, null);
     }
 
     protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 5bded7f..c589ad4 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -17,26 +17,82 @@
 package com.liato.bankdroid;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.Window;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 
 public class LockableActivity extends Activity {
     private static int PATTERNLOCK_UNLOCK = 42;
 	private SharedPreferences prefs;
 	private Editor editor;
 	private LockPatternUtils mLockPatternUtils;
+	
+	private LinearLayout mTitlebarButtons;
+	private LayoutInflater mInflater;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		mLockPatternUtils = new LockPatternUtils(this);		
+        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+    }
+	
+	@Override
+    public void setContentView(int layoutResID) {
+        super.setContentView(layoutResID);
+        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);
+        View titlebar = findViewById(R.id.layTitle);
+        mTitlebarButtons = (LinearLayout)titlebar.findViewById(R.id.layTitleButtons);
+        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        ImageView homeButton = (ImageView)titlebar.findViewById(R.id.imgTitle);
+        OnClickListener listener = new View.OnClickListener() {
+            public void onClick(View v) {
+                Intent intent = new Intent(LockableActivity.this, MainActivity.class);
+                startActivity(intent);
+            }
+        };        
+        homeButton.setOnClickListener(listener);
+        homeButton.setFocusable(true);
+        homeButton.setClickable(true);
+    }
+
+    protected void addTitleButton(int imageResourceId, String tag, OnClickListener listener) {
+        View child = mInflater.inflate(R.layout.title_item, mTitlebarButtons, false);
+        ImageButton button = (ImageButton)child.findViewById(R.id.imgItemIcon);
+        button.setImageResource(imageResourceId);
+        button.setTag(tag);
+        child.setTag("item_"+tag);
+        button.setOnClickListener(listener);
+        mTitlebarButtons.addView(child);
 	}
 
-	@Override
+    protected void hideTitleButton(String tag) {
+        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
+        if (v != null) {
+            v.setVisibility(View.GONE);
+        }
+    }
+    
+    protected void showTitleButton(String tag) {
+        View v = mTitlebarButtons.findViewWithTag("item_"+tag);
+        if (v != null) {
+            v.setVisibility(View.VISIBLE);
+        }
+    }
+
+    @Override
 	protected void onPause() {
 		super.onPause();
 		// Don't do anything if not lock pattern is set
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 1beaa95..791a202 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -28,7 +28,6 @@ import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -36,14 +35,14 @@ import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.Button;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
 
 public class MainActivity extends LockableActivity {
 	private final static String TAG = "MainActivity";
@@ -56,23 +55,22 @@ public class MainActivity extends LockableActivity {
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
-
-		setContentView(R.layout.main);
-        Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
-		btnRefresh.setOnClickListener(new View.OnClickListener() {
+        
+        setContentView(R.layout.main);
+        OnClickListener listener = new View.OnClickListener() {
+            public void onClick(View v) {
+                Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
+                startActivity(intentAccount);
+            }
+        };
+		OnClickListener listener2 = new View.OnClickListener() {
 			public void onClick(View v) {
 				new DataRetrieverTask(MainActivity.this).execute();
 			}
-		});		
-		Button btnAddBank = (Button)findViewById(R.id.btnAddBank);
-		btnAddBank.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
-				startActivity(intentAccount);
-			}
-		});
+		};
+        this.addTitleButton(R.drawable.title_icon_add, "add", listener);
+		this.addTitleButton(R.drawable.title_icon_refresh, "refresh", listener2);
 
-		//ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 		adapter = new AccountsAdapter(this, showHidden);
 		ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
 		adapter.setGroups(banks);
@@ -139,10 +137,12 @@ public class MainActivity extends LockableActivity {
 		Log.d(TAG, "Bank count: "+banks.size());
 		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
+            showTitleButton("refresh");
 			//findViewById(R.id.btnAccountsRefresh).setClickable(true);
 		}
 		else {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
+            hideTitleButton("refresh");
 			//findViewById(R.id.btnAccountsRefresh).setClickable(false);
 		}
 
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
index f052d1d..0b18ac2 100644
--- src/com/liato/bankdroid/WebViewActivity.java
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -16,13 +16,19 @@
 
 package com.liato.bankdroid;
 
+import java.io.IOException;
+
+import org.apache.commons.io.IOUtils;
 import org.apache.http.client.CookieStore;
 import org.apache.http.cookie.Cookie;
 
+import android.content.res.Resources.NotFoundException;
 import android.os.Bundle;
 import android.os.Message;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
 import android.webkit.CookieManager;
 import android.webkit.CookieSyncManager;
 import android.webkit.WebView;
@@ -31,7 +37,7 @@ import android.webkit.WebViewClient;
 import com.liato.bankdroid.Bank.SessionPackage;
 import com.liato.urllib.Urllib;
 
-public class WebViewActivity extends LockableActivity {
+public class WebViewActivity extends LockableActivity implements OnClickListener {
     private final static String TAG = "WebViewActivity";
     private static WebView mWebView;
     private boolean mFirstPageLoaded = false;
@@ -40,24 +46,44 @@ public class WebViewActivity extends LockableActivity {
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.webview);
+        this.addTitleButton(R.drawable.title_icon_back, "back", this);
+        this.addTitleButton(R.drawable.title_icon_forward, "forward", this);
+        this.addTitleButton(R.drawable.title_icon_refresh, "refresh", this);
+
         final CookieSyncManager csm = CookieSyncManager.createInstance(this);
         mWebView = (WebView)findViewById(R.id.wvBank);
+        mWebView.setBackgroundColor(0);
         mWebView.getSettings().setJavaScriptEnabled(true);
         mWebView.getSettings().setBuiltInZoomControls(true); 
         mWebView.getSettings().setUserAgentString(Urllib.USER_AGENT);
+        mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
         mWebView.setWebViewClient(new BankWebViewClient());
-        String preloader = "<html><head></head><body>" +
-                            "Bankdroid..." +
-                            "</body></html>";
-        mWebView.loadData(preloader, "text/html", "utf-8");
+        String preloader = "Error...";
+        try {
+            preloader = IOUtils.toString(getResources().openRawResource(R.raw.loading));
+            preloader = String.format(preloader,
+                                    "", // Javascript function
+                                    "" // HTML
+                                    );
+        }
+        catch (NotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", preloader, "text/html", "utf-8", null);
 
         Bundle extras = getIntent().getExtras();
         final long bankId = extras.getLong("bankid", -1);
+        //final long bankId = -1;
         if (bankId >= 0) {
             Runnable generateLoginPage = new Runnable() {
                 public void run() {
                     Bank bank = BankFactory.bankFromDb(bankId, WebViewActivity.this, false);
-                    SessionPackage loginPackage = bank.getSessionPackage();
+                    SessionPackage loginPackage = bank.getSessionPackage(WebViewActivity.this);
                     CookieStore cookieStore = loginPackage.getCookiestore();
                     if ((cookieStore != null) && !cookieStore.getCookies().isEmpty()) {
                         CookieManager cookieManager = CookieManager.getInstance();
@@ -73,7 +99,8 @@ public class WebViewActivity extends LockableActivity {
                         }
                         csm.sync();
                     }
-                    mWebView.loadData(loginPackage.getHtml(), "text/html", "utf-8");
+                    Log.d("HTML", loginPackage.getHtml());
+                    mWebView.loadDataWithBaseURL("what://is/this/i/dont/even", loginPackage.getHtml(), "text/html", "utf-8", null);
                 }
               };
               new Thread(generateLoginPage).start();
@@ -88,10 +115,11 @@ public class WebViewActivity extends LockableActivity {
     private class BankWebViewClient extends WebViewClient {
         @Override
         public void onPageFinished(WebView view, String url) {
+            Log.d(TAG, "Finished loading: "+url);
             super.onPageFinished(view, url);
             if (!mFirstPageLoaded) {
                 //This is the generated POST page.
-                if (url.startsWith("data:text")) return;
+                if (url.startsWith("what:")) return;
                 
                 //This is the first real page.
                 //Remove the generated page from history.
@@ -128,4 +156,18 @@ public class WebViewActivity extends LockableActivity {
         }
         return super.onKeyDown(keyCode, event);
     }
+
+    @Override
+    public void onClick(View v) {
+        String tag = (String)v.getTag();
+        if ("refresh".equals(tag)) {
+            mWebView.reload();
+        }
+        else if ("back".equals(tag)) {
+            mWebView.goBack();
+        }
+        else if ("forward".equals(tag)) {
+            mWebView.goForward();
+        }
+    }
 }
\ No newline at end of file
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index 71841ce..c95a42e 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -29,9 +29,11 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.ClientConnectionManager;
 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.ssl.SSLSocketFactory;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
@@ -69,11 +71,15 @@ public class Urllib {
 	        SchemeRegistry registry = new SchemeRegistry();
 	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
 	        registry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
-	        ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
+	        ClientConnectionManager manager = new ThreadSafeClientConnManager(params, registry);
 	        httpclient = new DefaultHttpClient(manager, params);
 		}
 		else {
-			httpclient = new DefaultHttpClient();
+            SchemeRegistry registry = new SchemeRegistry();
+            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+            registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+            ClientConnectionManager  manager = new ThreadSafeClientConnManager(params, registry);
+			httpclient = new DefaultHttpClient(manager, params);
 		}
     	context = new BasicHttpContext();
     }

commit 65ec1c79246c51f21bbfe989c47607345910adc1
Author: liato <x@x00.us>
Date:   Sat Dec 25 22:21:49 2010 +0100

    Autologin won't work without the webview activity so here it is.

diff --git res/layout/webview.xml res/layout/webview.xml
new file mode 100644
index 0000000..199f115
--- /dev/null
+++ res/layout/webview.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<WebView
+		android:id="@+id/wvBank"
+		android:layout_height="fill_parent"
+		android:layout_width="fill_parent" />
+</FrameLayout>
diff --git src/com/liato/bankdroid/WebViewActivity.java src/com/liato/bankdroid/WebViewActivity.java
new file mode 100644
index 0000000..f052d1d
--- /dev/null
+++ src/com/liato/bankdroid/WebViewActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import org.apache.http.client.CookieStore;
+import org.apache.http.cookie.Cookie;
+
+import android.os.Bundle;
+import android.os.Message;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import com.liato.bankdroid.Bank.SessionPackage;
+import com.liato.urllib.Urllib;
+
+public class WebViewActivity extends LockableActivity {
+    private final static String TAG = "WebViewActivity";
+    private static WebView mWebView;
+    private boolean mFirstPageLoaded = false;
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.webview);
+        final CookieSyncManager csm = CookieSyncManager.createInstance(this);
+        mWebView = (WebView)findViewById(R.id.wvBank);
+        mWebView.getSettings().setJavaScriptEnabled(true);
+        mWebView.getSettings().setBuiltInZoomControls(true); 
+        mWebView.getSettings().setUserAgentString(Urllib.USER_AGENT);
+        mWebView.setWebViewClient(new BankWebViewClient());
+        String preloader = "<html><head></head><body>" +
+                            "Bankdroid..." +
+                            "</body></html>";
+        mWebView.loadData(preloader, "text/html", "utf-8");
+
+        Bundle extras = getIntent().getExtras();
+        final long bankId = extras.getLong("bankid", -1);
+        if (bankId >= 0) {
+            Runnable generateLoginPage = new Runnable() {
+                public void run() {
+                    Bank bank = BankFactory.bankFromDb(bankId, WebViewActivity.this, false);
+                    SessionPackage loginPackage = bank.getSessionPackage();
+                    CookieStore cookieStore = loginPackage.getCookiestore();
+                    if ((cookieStore != null) && !cookieStore.getCookies().isEmpty()) {
+                        CookieManager cookieManager = CookieManager.getInstance();
+                        String cookieString;
+                        for (Cookie cookie : cookieStore.getCookies()) {
+                            cookieString = String.format("%s=%s;%spath=%s; domain=%s;",
+                                    cookie.getName(), cookie.getValue(),
+                                    cookie.getExpiryDate() == null ? "" : "expires="+cookie.getExpiryDate()+"; ",
+                                    cookie.getPath() == null ? "/" : cookie.getPath(),
+                                    cookie.getDomain());
+                            Log.d(TAG, "Cookiestring: " + cookieString);
+                            cookieManager.setCookie(cookie.getDomain(), cookieString);
+                        }
+                        csm.sync();
+                    }
+                    mWebView.loadData(loginPackage.getHtml(), "text/html", "utf-8");
+                }
+              };
+              new Thread(generateLoginPage).start();
+        }
+    }
+
+    public void onResume() {
+        super.onResume();
+    }
+
+    // Make sure clicked links are loaded in our webview.
+    private class BankWebViewClient extends WebViewClient {
+        @Override
+        public void onPageFinished(WebView view, String url) {
+            super.onPageFinished(view, url);
+            if (!mFirstPageLoaded) {
+                //This is the generated POST page.
+                if (url.startsWith("data:text")) return;
+                
+                //This is the first real page.
+                //Remove the generated page from history.
+                mWebView.clearHistory();
+                mFirstPageLoaded = true;
+                return;
+            }
+        }
+        
+
+        @Override
+        public void onFormResubmission(WebView view, Message dontResend,
+                Message resend) {
+            // TODO Auto-generated method stub
+            //super.onFormResubmission(view, dontResend, resend);
+            resend.sendToTarget();
+        }
+
+        @Override
+        public boolean shouldOverrideUrlLoading(WebView view, String url) {
+            view.loadUrl(url);
+            return true;
+        }
+    }	
+
+    //Handle the back key
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (mWebView != null) {
+            if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
+                mWebView.goBack();
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+}
\ No newline at end of file

commit 5670c23ec1a5ce2a9e94bcf508c4378faf23cfd2
Author: liato <x@x00.us>
Date:   Sat Dec 25 12:07:08 2010 +0100

    Automatic login for all banks when clicing the WWW button.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8fdd642..e9d361f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -33,6 +33,10 @@
 			android:name=".TransactionsActivity"
 			android:label="@string/app_name">
 		</activity>
+		<activity
+			android:name=".WebViewActivity"
+			android:label="@string/app_name">
+		</activity>
 		<activity
 			android:name=".BankEditActivity"
 			android:label="@string/app_name"
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index a261258..77367db 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -16,13 +16,20 @@
 
 package com.liato.bankdroid;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.CookieStore;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.text.InputType;
+import android.util.Log;
 
 import com.liato.urllib.Urllib;
 
@@ -62,7 +69,6 @@ public abstract class Bank implements Comparable<Bank> {
 
 	protected Context context;
 	protected Resources res;
-
 	
 	protected String username;
 	protected String password;
@@ -75,7 +81,6 @@ public abstract class Bank implements Comparable<Bank> {
 	protected String customName;
 	protected String currency = "SEK";
 
-
 	public Urllib getUrlopen() {
 		return urlopen;
 	}
@@ -290,6 +295,90 @@ public abstract class Bank implements Comparable<Bank> {
             }
             a.setBank(this);
         }
-    }	
-	
+    }
+    
+    public SessionPackage getSessionPackage() {
+        String loginHtmlTemplate = "<html><head>" +
+                                    "<script type=\"text/javascript\">" +
+                                    "function go(){document.getElementById('submitform').submit(); }" +
+                                    "</script>" +
+                                    "</head><body>" +
+                                    "Bankdroid..." +
+                                    "%s" +
+                                    "<script type=\"text/javascript\">" +
+                                    "go();" +
+                                    "</script></body></html>";
+        String redirectHtmlTemplate = "<html><head>" +
+                                        "<script type=\"text/javascript\">" +
+                                        "function go(){window.location=\"%s\" }" +
+                                        "</script></head><body>" +
+                                        "Bankdroid..." +
+                                        "<script type=\"text/javascript\">" +
+                                        "go();" +
+                                        "</script></body></html>";        
+        try {
+            LoginPackage lp = preLogin();
+            if (lp == null) {
+                throw new BankException("No automatic login for this bank. preLogin() is not implemented.");
+            }
+            CookieStore cookies = urlopen.getHttpclient().getCookieStore();
+            return new SessionPackage(String.format(loginHtmlTemplate, Helpers.renderForm(lp.getLoginTarget(), lp.getPostData())), cookies);
+        }
+        catch (ClientProtocolException e) {
+            Log.d(TAG, e.getMessage());
+        }
+        catch (IOException e) {
+            Log.d(TAG, e.getMessage());
+        }
+        catch (BankException e) {
+            Log.d(TAG, e.getMessage());
+        }
+        
+        return new SessionPackage(String.format(redirectHtmlTemplate, this.URL), null);
+    }
+
+    protected LoginPackage preLogin() throws BankException, ClientProtocolException, IOException {
+        return null;
+    }
+
+    public static class SessionPackage {
+        private String html;
+        private CookieStore cookiestore;
+        public SessionPackage(String html, CookieStore cookiestore) {
+            this.html = html;
+            this.cookiestore = cookiestore;
+        }
+        public String getHtml() {
+            return html;
+        }
+        public CookieStore getCookiestore() {
+            return cookiestore;
+        }
+    }    
+
+    public static class LoginPackage {
+        private String response;
+        private Urllib urllib;
+        private List<NameValuePair> postData;
+        private String loginTarget;
+        public LoginPackage(Urllib urllib, List<NameValuePair> postData, String response, String loginTarget) {
+            this.urllib = urllib;
+            this.postData = postData;
+            this.response = response;
+            this.loginTarget = loginTarget;
+        }
+        public String getResponse() {
+            return response;
+        }
+        public Urllib getUrllib() {
+            return urllib;
+        }
+        public List<NameValuePair> getPostData() {
+            return postData;
+        }
+        public String getLoginTarget() {
+            return loginTarget;
+        }
+    }    
+
 }
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 90e4e5d..202f0fe 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -20,6 +20,9 @@ import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
+import java.util.List;
+
+import org.apache.http.NameValuePair;
 
 import android.app.Activity;
 import android.util.Log;
@@ -141,5 +144,22 @@ public class Helpers {
         }
         return def;
     }
+    
+    public static String renderForm(String action, List <NameValuePair> postData) {
+        StringBuilder form = new StringBuilder();
+        form.append("<form id=\"submitform\" method=\"POST\" action=\"")
+        .append(action)
+        .append("\">");
+        for (NameValuePair p : postData) {
+            form.append("<input type=\"hidden\" name=\"")
+            .append(p.getName())
+            .append("\" value=\"")
+            .append(p.getValue())
+            .append("\" />");
+        }
+        form.append("</form>");
+        return form.toString();
+        
+    }
 
 }
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 666fcd0..1beaa95 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -245,8 +245,10 @@ public class MainActivity extends LockableActivity {
 			switch (id) {
 			case R.id.btnWWW:
 				if (selected_bank != null) {
-					Uri uri = Uri.parse(selected_bank.getURL());
-					Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+					//Uri uri = Uri.parse(selected_bank.getURL());
+					//Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+				    Intent intent = new Intent(context, WebViewActivity.class);
+	                intent.putExtra("bankid", selected_bank.getDbId());
 					context.startActivity(intent);
 				}
 				this.dismiss();
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 44f8b7f..b495db7 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -30,7 +30,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.util.Log;
 
 import com.liato.bankdroid.Account;
 import com.liato.bankdroid.Bank;
@@ -65,18 +64,22 @@ public class Avanza extends Bank {
 	}
 
 	
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true, true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        return new LoginPackage(urlopen, postData, null, "https://www.avanza.se/aza/login/login.jsp");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true, true);
 		String response = null;
 		try {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("username", username));
-			postData.add(new BasicNameValuePair("password", password));
-
-			Log.d("BankAvanza", "Posting to https://www.avanza.se/aza/login/login.jsp");
-			response = urlopen.open("https://www.avanza.se/aza/login/login.jsp", postData);
-			Log.d("BankAvanza", "Url after post: "+urlopen.getCurrentURI());
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -99,7 +102,6 @@ public class Avanza extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d("BankAvanza", "Opening: https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
 			response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
 						
 			matcher = reAccounts.matcher(response);
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banks/AvanzaMini.java
index 6e0f98c..14bd8c3 100644
--- src/com/liato/bankdroid/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banks/AvanzaMini.java
@@ -28,7 +28,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.util.Log;
 
 import com.liato.bankdroid.Account;
 import com.liato.bankdroid.Bank;
@@ -61,18 +60,22 @@ public class AvanzaMini extends Bank {
 		this.update(username, password);
 	}
 
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true, true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        return new LoginPackage(urlopen, postData, null, "https://www.avanza.se/aza/login/login.jsp");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true, true);
 		String response = null;
 		try {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("username", username));
-			postData.add(new BasicNameValuePair("password", password));
-
-			Log.d("BankAvanza", "Posting to https://www.avanza.se/aza/login/login.jsp");
-			response = urlopen.open("https://www.avanza.se/aza/login/login.jsp", postData);
-			Log.d("BankAvanza", "Url after post: "+urlopen.getCurrentURI());
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -94,7 +97,6 @@ public class AvanzaMini extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d("BankAvanza", "Opening: https://www.avanza.se/mini/mitt_konto/index.html");
 			response = urlopen.open("https://www.avanza.se/mini/mitt_konto/index.html");
 			matcher = reAvanzaMini.matcher(response);
 	        if (matcher.find()) {
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index e4bdd38..c92f643 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -31,7 +31,6 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 import android.text.Html;
-import android.util.Log;
 
 import com.liato.bankdroid.Account;
 import com.liato.bankdroid.Bank;
@@ -69,25 +68,31 @@ public class Coop extends Bank {
     }
 
     @Override
-    public Urllib login() throws LoginException, BankException {
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
         urlopen = new Urllib();
-        Matcher matcher;
+        response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+        }
+        String strViewState = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
+        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
+        postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$ButtonLogin", "Logga in"));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        return new LoginPackage(urlopen, postData, response, "https://www.coop.se/Mina-sidor/Oversikt/");
+    }
+
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
         try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
-            matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
-            }
-            String strViewState = matcher.group(1);
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
-            postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
-            postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$ButtonLogin", "Logga in"));
-            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/", postData);
-            Log.d(TAG, urlopen.getCurrentURI());
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("forfarande logga in med ditt personnummer")) {
                 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
                 if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_coop_sendmail", false)) {
diff --git src/com/liato/bankdroid/banks/DinersClub.java src/com/liato/bankdroid/banks/DinersClub.java
index 89b3326..6ee4f44 100644
--- src/com/liato/bankdroid/banks/DinersClub.java
+++ src/com/liato/bankdroid/banks/DinersClub.java
@@ -63,32 +63,40 @@ public class DinersClub extends Bank {
 		this.update(username, password);
 	}
 
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
-		try {
-            response = urlopen.open("https://www.dinersclub.se/dcs/login.aspx");
-            Matcher matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }
-            String viewState = matcher.group(1);
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        response = urlopen.open("https://www.dinersclub.se/dcs/login.aspx");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String viewState = matcher.group(1);
 
-            matcher = reEventValidation.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-            }
-            String eventValidation = matcher.group(1);            
-            
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-            postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-            postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-            postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$UserName", username));
-            postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", password));
-            postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String eventValidation = matcher.group(1);            
+        
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$UserName", username));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", password));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
 
-            response = urlopen.open("https://www.dinersclub.se/dcs/login.aspx", postData);		    
+        return new LoginPackage(urlopen, postData, response, "https://www.dinersclub.se/dcs/login.aspx");
+    }
+
+	public Urllib login() throws LoginException, BankException {
+		try {
+		    LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());		    
 			if (response.contains("Har du glömt ditt lösenord")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 9fd2dba..8f2a6ca 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -72,23 +72,27 @@ public class Eurocard extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));                
+        postData.add(new BasicNameValuePair("prodgroup", "0005"));              
+        postData.add(new BasicNameValuePair("USERNAME", "0005"+username));              
+        postData.add(new BasicNameValuePair("METHOD", "LOGIN"));                
+        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));              
+        postData.add(new BasicNameValuePair("uname", username));
+        postData.add(new BasicNameValuePair("PASSWORD", password));
+        return new LoginPackage(urlopen, postData, response, "https://e-saldo.eurocard.se/siteminderagent/forms/generic.fcc");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
 		try {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));				
-			postData.add(new BasicNameValuePair("prodgroup", "0005"));				
-			postData.add(new BasicNameValuePair("USERNAME", "0005"+username));				
-			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));				
-			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));				
-			postData.add(new BasicNameValuePair("uname", username));
-			postData.add(new BasicNameValuePair("PASSWORD", password));
-			
-			Log.d(TAG, "Posting to https://e-saldo.eurocard.se/siteminderagent/forms/generic.fcc");
-			response = urlopen.open("https://e-saldo.eurocard.se/siteminderagent/forms/generic.fcc", postData);
-			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
-			
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("Felaktig kombination")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
index 826a151..1be4e13 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -68,22 +68,26 @@ public class FirstCard extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("op", "login"));                
+        postData.add(new BasicNameValuePair("searchIndex", ""));                
+        postData.add(new BasicNameValuePair("country", "0"));               
+        postData.add(new BasicNameValuePair("soktext", "Skriv sökord här"));                
+        postData.add(new BasicNameValuePair("pnr", username));
+        postData.add(new BasicNameValuePair("intpwd", password));
+        return new LoginPackage(urlopen, postData, null, "https://www.firstcard.se/valkom.jsp");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
 		try {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("op", "login"));				
-			postData.add(new BasicNameValuePair("searchIndex", ""));				
-			postData.add(new BasicNameValuePair("country", "0"));				
-			postData.add(new BasicNameValuePair("soktext", "Skriv sökord här"));				
-			postData.add(new BasicNameValuePair("pnr", username));
-			postData.add(new BasicNameValuePair("intpwd", password));
-			
-			Log.d(TAG, "Posting to https://www.firstcard.se/valkom.jsp");
-			response = urlopen.open("https://www.firstcard.se/valkom.jsp", postData);
-			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
-			
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("felaktig identitet") || response.contains("obligatoriskt") || response.contains("ange en internetkod")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index cc76fb5..3c5ef1b 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -75,23 +75,29 @@ public class Handelsbanken extends Bank {
 	}
 
 	
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        response = urlopen.open("https://m.handelsbanken.se/primary/");
+        Matcher matcher = reLoginUrl.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" login url.");
+        }
+        String strLoginUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("pin", password));
+        postData.add(new BasicNameValuePair("execute", "true"));
+        return new LoginPackage(urlopen, postData, response, strLoginUrl);
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		Matcher matcher;
 		try {
-			response = urlopen.open("https://m.handelsbanken.se/primary/");
-			matcher = reLoginUrl.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" login url.");
-			}
-			String strLoginUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("username", username));
-			postData.add(new BasicNameValuePair("pin", password));
-			postData.add(new BasicNameValuePair("execute", "true"));
-			response = urlopen.open(strLoginUrl, postData);
-
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("ontrollera dina uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banks/ICA.java
index c56aa65..485bb20 100644
--- src/com/liato/bankdroid/banks/ICA.java
+++ src/com/liato/bankdroid/banks/ICA.java
@@ -68,35 +68,40 @@ public class ICA extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String response = urlopen.open("https://www.ica.se/Logga-in/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+        }
+        String strViewState = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("ctl00$fakie", ""));
+        postData.add(new BasicNameValuePair("q", "Sök"));
+        postData.add(new BasicNameValuePair("appendUrlString", ""));
+        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$btnLogin", "Logga in"));
+        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$chbRememberMe", "on"));
+        postData.add(new BasicNameValuePair("footer-q", "Sök"));
+        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPersno", username));
+        postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPasswd", password));
+
+        return new LoginPackage(urlopen, postData, response, "https://www.ica.se/Logga-in/");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
 		try {
-			response = urlopen.open("https://www.ica.se/Logga-in/");
-			matcher = reViewState.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
-			}
-			String strViewState = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-			postData.add(new BasicNameValuePair("ctl00$fakie", ""));
-			postData.add(new BasicNameValuePair("q", "Sök"));
-			postData.add(new BasicNameValuePair("appendUrlString", ""));
-			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$btnLogin", "Logga in"));
-			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$chbRememberMe", "on"));
-			postData.add(new BasicNameValuePair("footer-q", "Sök"));
-			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPersno", username));
-			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPasswd", password));
-			
-			response = urlopen.open("https://www.ica.se/Logga-in/", postData);
-			
-			matcher = reLoginError.matcher(response);
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reLoginError.matcher(response);
 			if (matcher.find()) {
 				throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
 			}
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index 58300a3..57d8a85 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -74,30 +74,36 @@ public class ICABanken extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String response = urlopen.open("https://mobil2.icabanken.se/login/login.aspx");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+        }
+        String strViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
+        }
+        String strEventValidation = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("pnr_phone", username));
+        postData.add(new BasicNameValuePair("pwd_phone", password));
+        postData.add(new BasicNameValuePair("btnLogin", "Logga in"));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        return new LoginPackage(urlopen, postData, response, "https://mobil2.icabanken.se/login/login.aspx");
+    }
+
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil2.icabanken.se/login/login.aspx");
-			matcher = reViewState.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
-			}
-			String strViewState = matcher.group(1);
-			matcher = reEventValidation.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
-			}
-			String strEventValidation = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("pnr_phone", username));
-			postData.add(new BasicNameValuePair("pwd_phone", password));
-			postData.add(new BasicNameValuePair("btnLogin", "Logga in"));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-			response = urlopen.open("https://mobil2.icabanken.se/login/login.aspx", postData);
-			matcher = reError.matcher(response);
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+			Matcher matcher = reError.matcher(response);
 			if (matcher.find()) {
 				throw new LoginException(Html.fromHtml(matcher.group(1).trim()).toString());
 			}
diff --git src/com/liato/bankdroid/banks/IkanoBank.java src/com/liato/bankdroid/banks/IkanoBank.java
index 0c1a71c..d86bbb2 100644
--- src/com/liato/bankdroid/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banks/IkanoBank.java
@@ -74,33 +74,38 @@ public class IkanoBank extends Bank {
     }
 
 
-    public Urllib login() throws LoginException, BankException {
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
         urlopen = new Urllib(true);
-        String response = null;
-        Matcher matcher;
-        try {
-            response = urlopen.open("https://secure.ikanobank.se/login");
-            matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }
-            String strViewState = matcher.group(1);
-            matcher = reEventValidation.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-            }
-            String strEventValidation = matcher.group(1);
-
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-            postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl02$lbLogin"));
-            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-            postData.add(new BasicNameValuePair("ctl02$txtSocialSecurityNumber", username));
-            postData.add(new BasicNameValuePair("ctl02$txtPinCode", password));
-            postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-            response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1895", postData);
+        response = urlopen.open("https://secure.ikanobank.se/login");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String strViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String strEventValidation = matcher.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl02$lbLogin"));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("ctl02$txtSocialSecurityNumber", username));
+        postData.add(new BasicNameValuePair("ctl02$txtPinCode", password));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        return new LoginPackage(urlopen, postData, response, "https://secure.ikanobank.se/engines/page.aspx?structid=1895");
+    }
 
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("Ogiltigt personnummer eller")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
diff --git src/com/liato/bankdroid/banks/Jojo.java src/com/liato/bankdroid/banks/Jojo.java
index c7a1366..8a7ee3d 100644
--- src/com/liato/bankdroid/banks/Jojo.java
+++ src/com/liato/bankdroid/banks/Jojo.java
@@ -38,85 +38,89 @@ import com.liato.bankdroid.R;
 import com.liato.urllib.Urllib;
 
 public class Jojo extends Bank {
-	private static final String TAG = "Jojo";
-	private static final String NAME = "Jojo Reskassa";
-	private static final String NAME_SHORT = "jojo";
-	private static final String URL = "https://www.skanetrafiken.se/templates/MSRootPage.aspx?id=2935&epslanguage=SV";
-	private static final int BANKTYPE_ID = Bank.JOJO;
-	
+    private static final String TAG = "Jojo";
+    private static final String NAME = "Jojo Reskassa";
+    private static final String NAME_SHORT = "jojo";
+    private static final String URL = "https://www.skanetrafiken.se/templates/MSRootPage.aspx?id=2935&epslanguage=SV";
+    private static final int BANKTYPE_ID = Bank.JOJO;
+
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
     private Pattern reAccounts = Pattern.compile("1_mRepeaterMyCards_ctl(\\d{2,3})_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>\\s*</td>\\s*<td[^>]+>\\s*<a\\s*id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl\\d{2,3}_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>", Pattern.CASE_INSENSITIVE);
     private Pattern reBalance = Pattern.compile("labelsaldoinfo\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private String response = null;
-	
-	public Jojo(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
-
-	public Jojo(String username, String password, Context context) throws BankException, LoginException {
-		this(context);
-		this.update(username, password);
-	}
-
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
-		Matcher matcher;
-		
-		try {
-			response = urlopen.open("http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
+    private String response = null;
+
+    public Jojo(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
+
+    public Jojo(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+    ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        response = urlopen.open("http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String strViewState = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Username", username));
+        postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Password", password));
+        postData.add(new BasicNameValuePair("ctl00$LoginBlob1$LoginButton", "Logga in"));
+
+        return new LoginPackage(urlopen, postData, response, "https://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
+    }
+
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
+            if (response.contains("Inloggningen misslyckades")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+        urlopen = login();
+        try {
+            response = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV");
+            Matcher matcher;
+            Matcher matcher_b;
             matcher = reViewState.matcher(response);
             if (!matcher.find()) {
                 throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }
-            String strViewState = matcher.group(1);
-
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-            postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Username", username));
-            postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Password", password));
-            postData.add(new BasicNameValuePair("ctl00$LoginBlob1$LoginButton", "Logga in"));
-           
-			response = urlopen.open("https://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV", postData);
-
-			if (response.contains("Inloggningen misslyckades")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-
-	@Override
-	public void update() throws BankException, LoginException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-		urlopen = login();
-		try {
-		    response = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV");
-			Matcher matcher;
-			Matcher matcher_b;
-			matcher = reViewState.matcher(response);
-			if (!matcher.find()) {
-			    throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-			}			
+            }			
             String strViewState = matcher.group(1);
 
             matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                EXAMPLE DATA
@@ -125,14 +129,14 @@ public class Jojo extends Bank {
                  * 3: Card number       1111111111
                  * 
                  */
-			    
-	            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-	            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-	            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-	            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-	            postData.add(new BasicNameValuePair("ctl00$fullRegion$mainRegion$CardInformation1$mRepeaterMyCards$ctl" + matcher.group(1) + "$Button", "Kortinfo"));
+
+                List <NameValuePair> postData = new ArrayList <NameValuePair>();
+                postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+                postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+                postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+                postData.add(new BasicNameValuePair("ctl00$fullRegion$mainRegion$CardInformation1$mRepeaterMyCards$ctl" + matcher.group(1) + "$Button", "Kortinfo"));
                 String accinfo = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV", postData);
-			    
+
                 matcher_b = reBalance.matcher(accinfo);
                 if (matcher_b.find()) {
                     /*
@@ -141,16 +145,16 @@ public class Jojo extends Bank {
                      * 1: Amount            592,80 kr
                      * 
                      */
-                    
+
                     accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() , Helpers.parseBalance(matcher_b.group(1)), matcher.group(1)));
                     balance = balance.add(Helpers.parseBalance(matcher_b.group(1)));
                 }
-			}
-			
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
+            }
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
         catch (ClientProtocolException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
@@ -162,5 +166,5 @@ public class Jojo extends Bank {
         finally {
             super.updateComplete();
         }
-	}
+    }
 }
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index d9362b7..6aca12f 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -82,41 +82,46 @@ public class Lansforsakringar extends Bank {
     }
 
 
-    public Urllib login() throws LoginException, BankException {
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
         urlopen = new Urllib();
-        String response = null;
-        Matcher matcher;
-        try {
-            response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
-            matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }
-            mViewState = matcher.group(1);
-            matcher = reEventValidation.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-            }
-            String strEventValidation = matcher.group(1);
+        String response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        mViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String strEventValidation = matcher.group(1);
 
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-            postData.add(new BasicNameValuePair("inputPersonalNumber", username));
-            postData.add(new BasicNameValuePair("inputPinCode", password));
-            postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
-            postData.add(new BasicNameValuePair("__VIEWSTATE", mViewState));
-            postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-            postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-            postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
-            postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-            response = urlopen.open(urlopen.getCurrentURI(), postData);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("inputPersonalNumber", username));
+        postData.add(new BasicNameValuePair("inputPinCode", password));
+        postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", mViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
+        postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
+        return new LoginPackage(urlopen, postData, response, urlopen.getCurrentURI());
+    }
 
+    public Urllib login() throws LoginException, BankException {
+        try {
+            LoginPackage lp = preLogin();
+            String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("Felaktig inloggning")) {
                 throw new LoginException(res.getText(R.string.invalid_username_password).toString());
             }
 
-            matcher = reToken.matcher(response);
+            Matcher matcher = reToken.matcher(response);
             if (!matcher.find()) {
                 throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
             }
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 90b6c20..f526afb 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -73,24 +73,32 @@ public class Nordea extends Bank {
 		this.update(username, password);
 	}
 
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        Matcher matcher;
+        String response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+        matcher = reCSRF.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+        }
+        String csrftoken = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("xyz", username));
+        postData.add(new BasicNameValuePair("zyx", password));
+        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+        return new LoginPackage(urlopen, postData, response, "https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib();
 		String response = null;
-		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-			matcher = reCSRF.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-			}
-			String csrftoken = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("xyz", username));
-			postData.add(new BasicNameValuePair("zyx", password));
-			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+		    LoginPackage lp = preLogin();
 			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html", postData);
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
 			
 			if (response.contains("felaktiga uppgifter")) {
@@ -194,6 +202,5 @@ public class Nordea extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-	}
-	
+	}	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index 9bd6add..503b8df 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -74,30 +74,31 @@ public class OKQ8 extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        Date d = new Date();
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        response = urlopen.open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
+        //p_tranid is the epoch time in milliseconds
+        postData.add(new BasicNameValuePair("p_tranid", Long.toString(d.getTime())));
+        postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
+        postData.add(new BasicNameValuePair("n_bank", ""));
+        postData.add(new BasicNameValuePair("empty_pwd", ""));
+        postData.add(new BasicNameValuePair("user_id", username.toUpperCase()));
+        postData.add(new BasicNameValuePair("password", password));
+        return new LoginPackage(urlopen, postData, response, "https://nettbank.edb.com/Logon/logon/step1");
+    }
+
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
-		Matcher matcher;
-		Date d = new Date();
-		String value = null;
-		
+        Matcher matcher;
+        String value = null;
 		try {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			
-			response = urlopen.open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
-			
-			/*
-			 * Post the login information to the login page.
-			 */
-			postData.clear();
-			//p_tranid is the epoch time in milliseconds
-			postData.add(new BasicNameValuePair("p_tranid", Long.toString(d.getTime())));
-			postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
-			postData.add(new BasicNameValuePair("n_bank", ""));
-			postData.add(new BasicNameValuePair("empty_pwd", ""));
-			postData.add(new BasicNameValuePair("user_id", username.toUpperCase()));
-			postData.add(new BasicNameValuePair("password", password));
-			response = urlopen.open("https://nettbank.edb.com/Logon/logon/step1", postData);
-			
+			LoginPackage lp = preLogin();
+			List <NameValuePair> postData = lp.getPostData();
+			response = urlopen.open(lp.getLoginTarget(), postData);
 			if (!response.contains("LOGON_OK")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banks/PayPal.java
index bd03671..606c6d8 100644
--- src/com/liato/bankdroid/banks/PayPal.java
+++ src/com/liato/bankdroid/banks/PayPal.java
@@ -68,48 +68,51 @@ public class PayPal extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        //Get cookies and url to post to
+        response = urlopen.open("https://www.paypal.com/en");
+        Matcher matcher = reFormAction.matcher(response);
+        String strPostUrl;
+        if (matcher.find()) {
+            strPostUrl = Html.fromHtml(matcher.group(1)).toString();
+            Log.d(TAG, "Found post url: "+strPostUrl);
+        }
+        else {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
+        }
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("login_email", username));
+        postData.add(new BasicNameValuePair("login_password", password));
+        postData.add(new BasicNameValuePair("target_page", "0"));
+        postData.add(new BasicNameValuePair("submit.x", "Log In"));
+        postData.add(new BasicNameValuePair("form_charset", "UTF-8"));
+        postData.add(new BasicNameValuePair("browser_name", "undefined"));
+        postData.add(new BasicNameValuePair("browser_version", "undefined"));
+        postData.add(new BasicNameValuePair("operating_system", "Windows"));
+        postData.add(new BasicNameValuePair("bp_mid", "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
+        postData.add(new BasicNameValuePair("bp_ks1", "v=1;l=16;Di0:2663Di1:48Ui0:15Ui1:81Di2:176Di3:48Ui2:32Ui3:96Di4:384Ui4:48Di5:352Ui5:48Di6:128Ui6:80Di7:112Ui7:48Di8:113Ui8:79Di9:125Ui9:51Di10:98Ui10:72Di11:227Ui11:51Di12:80Ui12:80Di13:128Ui13:64Di14:48Ui14:80Di15:416Ui15:80"));
+        postData.add(new BasicNameValuePair("bp_ks2", ""));
+        postData.add(new BasicNameValuePair("bp_ks3", ""));
+        postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
+        postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
+        return new LoginPackage(urlopen, postData, response, strPostUrl);
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
 		try {
-		    //Get cookies and url to post to
-		    response = urlopen.open("https://www.paypal.com/en");
-		    Matcher matcher = reFormAction.matcher(response);
-		    String strPostUrl;
-		    if (matcher.find()) {
-		        strPostUrl = Html.fromHtml(matcher.group(1)).toString();
-		        Log.d(TAG, "Found post url: "+strPostUrl);
-		    }
-		    else {
-		        throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
-		    }
-		    List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("login_email", username));
-			postData.add(new BasicNameValuePair("login_password", password));
-			postData.add(new BasicNameValuePair("target_page", "0"));
-			postData.add(new BasicNameValuePair("submit.x", "Log In"));
-			postData.add(new BasicNameValuePair("form_charset", "UTF-8"));
-			postData.add(new BasicNameValuePair("browser_name", "undefined"));
-			postData.add(new BasicNameValuePair("browser_version", "undefined"));
-			postData.add(new BasicNameValuePair("operating_system", "Windows"));
-			postData.add(new BasicNameValuePair("bp_mid", "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
-			postData.add(new BasicNameValuePair("bp_ks1", "v=1;l=16;Di0:2663Di1:48Ui0:15Ui1:81Di2:176Di3:48Ui2:32Ui3:96Di4:384Ui4:48Di5:352Ui5:48Di6:128Ui6:80Di7:112Ui7:48Di8:113Ui8:79Di9:125Ui9:51Di10:98Ui10:72Di11:227Ui11:51Di12:80Ui12:80Di13:128Ui13:64Di14:48Ui14:80Di15:416Ui15:80"));
-			postData.add(new BasicNameValuePair("bp_ks2", ""));
-			postData.add(new BasicNameValuePair("bp_ks3", ""));
-			postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
-			postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
-			
-			Log.d(TAG, "Posting to " + strPostUrl);
-			response = urlopen.open(strPostUrl, postData);
-			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 			if (response.contains("your last action could not be completed")) {
 			    throw new BankException("Error: PPL92");
 			}
-
-			
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
diff --git src/com/liato/bankdroid/banks/Payson.java src/com/liato/bankdroid/banks/Payson.java
index 0754911..73b60b6 100644
--- src/com/liato/bankdroid/banks/Payson.java
+++ src/com/liato/bankdroid/banks/Payson.java
@@ -68,35 +68,40 @@ public class Payson extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        response = urlopen.open("https://www.payson.se/signin/");
+        Matcher matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+        }
+        String strViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+        }
+        String strEventValidation = matcher.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtEmail", username));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtPassword", password));
+        postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$btnLogin", "Logga in"));
+        return new LoginPackage(urlopen, postData, response, "https://www.payson.se/signin/");
+    }
+
+    @Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
-		Matcher matcher;
-		
 		try {
-			response = urlopen.open("https://www.payson.se/signin/");
-            matcher = reViewState.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-            }
-            String strViewState = matcher.group(1);
-            matcher = reEventValidation.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-            }
-            String strEventValidation = matcher.group(1);
-
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-            postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtEmail", username));
-            postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtPassword", password));
-            postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$btnLogin", "Logga in"));
-			response = urlopen.open("https://www.payson.se/signin/", postData);
-			//Helpers.slowDebug(TAG, response);
-			
+            LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("Felaktig E-postadress") || response.contains("Lösenord saknas") ||
 			        response.contains("E-postadress saknas"))  {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index ec0a6b1..bec78ec 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -72,27 +72,35 @@ public class Statoil extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
+        List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
+        parameters.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
+        parameters.add(new BasicNameValuePair("referer", "login.jsp"));
+        response = urlopen.open("https://applications.sebkort.com/nis/external/hidden.jsp", postData);
+        
+        postData.clear();
+        postData.add(new BasicNameValuePair("choice", "PWD"));
+        postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
+        postData.add(new BasicNameValuePair("PASSWORD", password));
+        postData.add(new BasicNameValuePair("target", "/nis/stse/main.do"));
+        postData.add(new BasicNameValuePair("prodgroup", "0122"));
+        postData.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
+        postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
+        postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
+        return new LoginPackage(urlopen, postData, response, "https://applications.sebkort.com/siteminderagent/forms/generic.fcc");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
 		try {
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
-			List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
-            parameters.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
-            parameters.add(new BasicNameValuePair("referer", "login.jsp"));
-            response = urlopen.open("https://applications.sebkort.com/nis/external/hidden.jsp", postData);
-            
-			postData.clear();
-			postData.add(new BasicNameValuePair("choice", "PWD"));
-			postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
-			postData.add(new BasicNameValuePair("PASSWORD", password));
-			postData.add(new BasicNameValuePair("target", "/nis/stse/main.do"));
-			postData.add(new BasicNameValuePair("prodgroup", "0122"));
-			postData.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
-			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
-			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-			response = urlopen.open("https://applications.sebkort.com/siteminderagent/forms/generic.fcc", postData);
+			LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("elaktig kombination")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/bankdroid/banks/Steam.java src/com/liato/bankdroid/banks/Steam.java
index feb7138..61d2f7a 100644
--- src/com/liato/bankdroid/banks/Steam.java
+++ src/com/liato/bankdroid/banks/Steam.java
@@ -71,14 +71,23 @@ public class Steam extends Bank {
 		this.update(username, password);
 	}
 
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib(true);
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib(true);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("redir", "account"));
+        postData.add(new BasicNameValuePair("username", username));
+        postData.add(new BasicNameValuePair("password", password));
+        return new LoginPackage(urlopen, postData, null, "https://store.steampowered.com/login/");
+    }
+
+    @Override
+    public Urllib login() throws LoginException, BankException {
 		try {
-            List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("redir", "account"));
-            postData.add(new BasicNameValuePair("username", username));
-            postData.add(new BasicNameValuePair("password", password));
-			response = urlopen.open("https://store.steampowered.com/login/", postData);
+		    LoginPackage lp = preLogin();
+			response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
             if (response.contains("Enter the characters above")) {
                 throw new BankException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
             }
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 42877d9..1732636 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -48,7 +48,7 @@ public class Swedbank extends Bank {
 	private static final int BANKTYPE_ID = Bank.SWEDBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
-
+    
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
 	private Pattern reLinklessAccounts = Pattern.compile("<li>\\s*([^<]+)<br/?><span\\sclass=\"secondary\">([^<]+)</span>\\s*</li>", Pattern.CASE_INSENSITIVE);
@@ -70,22 +70,29 @@ public class Swedbank extends Bank {
 	}
 
 	@Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        Matcher matcher;
+        String response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
+        matcher = reCSRF.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+        }
+        String csrftoken = matcher.group(1);
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("xyz", username));
+        postData.add(new BasicNameValuePair("zyx", password));
+        postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+        return new LoginPackage(urlopen, postData, response, "https://mobilbank.swedbank.se/banking/swedbank/login.html");
+    }
+
+    @Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
-			matcher = reCSRF.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-			}
-			String csrftoken = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("xyz", username));
-			postData.add(new BasicNameValuePair("zyx", password));
-			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
+	    
+	    try {
+	        LoginPackage lp = preLogin();
+	        String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 
 			if (response.contains("misslyckats")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -111,7 +118,6 @@ public class Swedbank extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
-			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim() == "loan" ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
@@ -172,5 +178,5 @@ public class Swedbank extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-	}	
+	}
 }
diff --git src/com/liato/bankdroid/banks/Villabanken.java src/com/liato/bankdroid/banks/Villabanken.java
index 602df3c..20d1872 100644
--- src/com/liato/bankdroid/banks/Villabanken.java
+++ src/com/liato/bankdroid/banks/Villabanken.java
@@ -65,69 +65,72 @@ public class Villabanken extends Bank {
 		this.update(username, password);
 	}
 
+    
+    @Override
+    protected LoginPackage preLogin() throws BankException,
+            ClientProtocolException, IOException {
+        urlopen = new Urllib();
+        String response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
+        Matcher matcher = reRequestDigest.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" request digest.");
+        }
+        String requestDigest = matcher.group(1);
+        
+        matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" view state.");
+        }
+        String viewState = matcher.group(1);
+        
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" event validation.");
+        }
+        String eventValidation = matcher.group(1);
+
+        matcher = rePageHashCode.matcher(response);
+        if (!matcher.find()) {
+            throw new BankException(res.getText(R.string.unable_to_find).toString()+" page hash code.");
+        }
+        String pageHashCode = matcher.group(1);
+
+        List <NameValuePair> postData = new ArrayList <NameValuePair>();
+        postData.add(new BasicNameValuePair("__spDummyText1", ""));
+        postData.add(new BasicNameValuePair("__spDummyText2", ""));
+        postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
+        postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
+        postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
+        postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
+        postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
+        postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
+        postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
+        postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+        postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+        postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
+        postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
+        postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
+        postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
+        postData.add(new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
+        postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$ctl00", "Logga in"));
+        
+        postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
+        postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+        postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+        postData.add(new BasicNameValuePair("MSO_PageHashCode", pageHashCode));
+        postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$accountNumber", username));
+        postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$password", password));
+        
+        return new LoginPackage(urlopen, postData, response, "https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
+    }
+
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
 		try {
-			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
-			matcher = reRequestDigest.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" request digest.");
-			}
-			String requestDigest = matcher.group(1);
-			
-			matcher = reViewState.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" view state.");
-			}
-			String viewState = matcher.group(1);
-			
-			matcher = reEventValidation.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" event validation.");
-			}
-			String eventValidation = matcher.group(1);
-
-			matcher = rePageHashCode.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" page hash code.");
-			}
-			String pageHashCode = matcher.group(1);
-
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("__spDummyText1", ""));
-			postData.add(new BasicNameValuePair("__spDummyText2", ""));
-			postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
-			postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
-			postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
-			postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
-			postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
-			postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
-			postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
-			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-			postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
-			postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
-			postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
-			postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
-			postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
-			postData.add(new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
-			postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$ctl00", "Logga in"));
-			
-			postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
-			postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
-			postData.add(new BasicNameValuePair("MSO_PageHashCode", pageHashCode));
-			postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$accountNumber", username));
-			postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$password", password));
-			
-			Log.d(TAG, "Posting to https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
-			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/default.aspx", postData);
-			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
-			
+			LoginPackage lp = preLogin();
+			String response = urlopen.open(lp.getLoginTarget(), lp.getPostData());
 			if (response.contains("misslyckades")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index f956938..71841ce 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -44,10 +44,11 @@ import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 
 public class Urllib {
-	private DefaultHttpClient httpclient;
+    public final static String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+
+    private DefaultHttpClient httpclient;
 	private HttpContext context;
 	private String currentURI;
-	private final static String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
 	private boolean acceptInvalidCertificates = false;
 	
 	public Urllib() {

commit 1aae889a0edd99ccd0f4f2721f99a5ce0d313d2a
Author: liato <x@x00.us>
Date:   Wed Dec 22 23:28:33 2010 +0100

    Bump version to 1.5.4-rc1.

diff --git AndroidManifest.xml AndroidManifest.xml
index c2d1d73..8fdd642 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.5.3" android:versionCode="60">
+	android:versionName="1.5.4-RC1" android:versionCode="61">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 21c7f6bee14fe587b64cc73bfa2a690bd77fe00d
Author: liato <x@x00.us>
Date:   Wed Dec 22 23:27:41 2010 +0100

    Use the right value when calculating balance for IkanoBank.

diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 5be151c..d26db9b 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -24,6 +24,7 @@ import android.content.Context;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.preference.PreferenceManager;
+import android.util.Log;
 
 import com.liato.bankdroid.banks.Avanza;
 import com.liato.bankdroid.banks.AvanzaMini;
@@ -213,6 +214,7 @@ public class BankFactory {
 		DBAdapter db = new DBAdapter(context);
 		db.open();
 		Cursor c = db.getAccount(accountId);
+       
 		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
 			db.close();
 			return null;
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index 61d2d8c..e6facb7 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -70,10 +70,15 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 			}
 			Log.d("AA", "Refreshing "+bank.getName()+" ("+bank.getUsername()+").");
 			try {
-				bank.update();
-				bank.updateAllTransactions();
-				bank.closeConnection();
-				bank.save();
+                //Log.d("AA", "bank.update()");
+                bank.update();
+                //Log.d("AA", "bank.updateAllTransactions()");
+                bank.updateAllTransactions();
+                //Log.d("AA", "bank.closeConnction()");
+                bank.closeConnection();
+                //Log.d("AA", "bank.save()");
+                bank.save();
+                //Log.d("AA", "DONE!");
 				i++;
 			} 
 			catch (BankException e) {
diff --git src/com/liato/bankdroid/banks/IkanoBank.java src/com/liato/bankdroid/banks/IkanoBank.java
index a132036..0c1a71c 100644
--- src/com/liato/bankdroid/banks/IkanoBank.java
+++ src/com/liato/bankdroid/banks/IkanoBank.java
@@ -134,7 +134,7 @@ public class IkanoBank extends Bank {
              * 
              */    
             accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()), matcher.group(1).trim()));
-            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+            balance = balance.add(Helpers.parseBalance(matcher.group(4)));
         }
 
         if (accounts.isEmpty()) {

commit 97ee608a921f9271d625dc505217346866fdd0dd
Author: liato <x@x00.us>
Date:   Wed Dec 22 23:11:34 2010 +0100

    Fixed Eurocard widget bug.

diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 774998d..9fd2dba 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -54,6 +54,7 @@ public class Eurocard extends Bank {
 	private Pattern reAccounts = Pattern.compile("Welcomepagecardimagecontainer\">\\s*[^<]+<br>[^>]+<br>([^>]+)</div>\\s*</div>\\s*</div>.*?indentationwrapper\">\\s*<a\\s*href=\"getPendingTransactions\\.do\\?id=([^\"]+)\">.*?billedamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reSaldo = Pattern.compile("Billingunitbalanceamount\">\\s*([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+    private ArrayList<String> accountIds = new ArrayList<String>();
 	private String response = null;
 	public Eurocard(Context context) {
 		super(context);
@@ -108,28 +109,25 @@ public class Eurocard extends Bank {
 		}
 		urlopen = login();
 		Matcher matcher = reAccounts.matcher(response);
+        Integer accountId = 0;
 		while (matcher.find()) {
             /*
              * Capture groups:
-             * GROUP                     EXAMPLE DATA
+             * GROUP                     EXAMPLE DATA           NOTES
              * 1: account number         **** **** **** 1234
-             * 2: id                     a1c2d3d4e5f6s7b8c9d0
+             * 2: id                     a1c2d3d4e5f6s7b8c9d0   Changes when session expires
              * 3: ofakturerat amount     &nbsp;2 988,96
              * 
              */
 
 		    // Create a separate account for "Ofakturerat".
 		    // Set the balance for the main account to 0 and update it later
-			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), new BigDecimal(0), matcher.group(2).trim()));
-			accounts.add(new Account("Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak:"+matcher.group(2).trim(), Account.OTHER));
-		}
-		if (accounts.size() > 2) {
-		    boolean s = true;
-		    for (Account a : accounts) {
-		        a.setName(s ? "┌ " : "└ "+ a.getName());
-		        s = !s;
-		    }
+			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), new BigDecimal(0), accountId.toString()));
+			accounts.add(new Account("└ " + "Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak:"+accountId.toString(), Account.OTHER));
+            accountIds.add(matcher.group(2).trim());
+            accountId += 1;			
 		}
+
 		try {
             response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getBillingUnits.do");
             matcher = reSaldo.matcher(response);
@@ -169,8 +167,9 @@ public class Eurocard extends Bank {
 		// If the account is of type "other" it's the fake "Ofakturerat" account.
 		if (account.getType() == Account.OTHER) return;
 		try {
-			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+account.getId());
-			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+account.getId());
+		    String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
+			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
+			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			String strDate = null;

commit 202c4a3882eb4e0803fd0e87490953a1b727e879
Author: liato <x@x00.us>
Date:   Tue Dec 21 15:29:22 2010 +0100

    Bump version to 1.5.3.

diff --git AndroidManifest.xml AndroidManifest.xml
index e89dcd4..c2d1d73 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.5.3-RC1" android:versionCode="59">
+	android:versionName="1.5.3" android:versionCode="60">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit c468e04e4ac92a2d293f9c4189cc653a9fec647c
Author: liato <x@x00.us>
Date:   Tue Dec 21 14:07:04 2010 +0100

    Found the missing IkanoBank class!

diff --git src/com/liato/bankdroid/banks/IkanoBank.java src/com/liato/bankdroid/banks/IkanoBank.java
new file mode 100644
index 0000000..a132036
--- /dev/null
+++ src/com/liato/bankdroid/banks/IkanoBank.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class IkanoBank extends Bank {
+    private static final String TAG = "IkanoBank";
+    private static final String NAME = "Ikano Bank";
+    private static final String NAME_SHORT = "ikanobank";
+    private static final String URL = "https://secure.ikanobank.se/engines/page.aspx?structid=1895";
+    private static final int BANKTYPE_ID = Bank.IKANOBANK;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccounts = Pattern.compile("(ctl\\d{1,}_rptAccountList_ctl\\d{1,}_RowLink)[^>]+>([^<]+)</a>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]+</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private String response = null;
+
+    public IkanoBank(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public IkanoBank(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib(true);
+        String response = null;
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://secure.ikanobank.se/login");
+            matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            }
+            String strViewState = matcher.group(1);
+            matcher = reEventValidation.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            }
+            String strEventValidation = matcher.group(1);
+
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+            postData.add(new BasicNameValuePair("__EVENTTARGET", "ctl02$lbLogin"));
+            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+            postData.add(new BasicNameValuePair("ctl02$txtSocialSecurityNumber", username));
+            postData.add(new BasicNameValuePair("ctl02$txtPinCode", password));
+            postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+            response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1895", postData);
+
+            if (response.contains("Ogiltigt personnummer eller")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
+
+    @Override
+    public void update() throws BankException, LoginException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher = reAccounts.matcher(response);
+        while (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                    EXAMPLE DATA
+             * 1: ID                    ctl07_rptAccountList_ctl00_RowLink
+             * 2: Name                  Kontonamn1
+             * 3: Account number        123456
+             * 4: Balance               316 000,39
+             * 
+             */    
+            accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()), matcher.group(1).trim()));
+            balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+        }
+
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }
+        super.updateComplete();
+    }
+
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+
+        // Find viewstate and eventvalidation from last page.
+        Matcher matcher;
+        matcher = reViewState.matcher(response);
+        if (!matcher.find()) {
+            Log.d(TAG, "Unable to find ViewState. L156.");
+        }
+        String strViewState = matcher.group(1);
+        matcher = reEventValidation.matcher(response);
+        if (!matcher.find()) {
+            Log.d(TAG, "Unable to find EventValidation. L161.");
+        }
+        String strEventValidation = matcher.group(1);       
+
+        try {
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            postData.add(new BasicNameValuePair("__EVENTTARGET", account.getId().replace("_", "$")));
+            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));            
+            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));            
+            postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));            
+            response = urlopen.open("https://secure.ikanobank.se/engines/page.aspx?structid=1787", postData);
+
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Date              2010-10-27
+                 * 2: Specification     ÍVERFÍRING
+                 * 3: Amount            50
+                 *   
+                 */                    
+                transactions.add(new Transaction(matcher.group(1).trim(),
+                        Html.fromHtml(matcher.group(2)).toString().trim(),
+                        Helpers.parseBalance(matcher.group(3))));
+            }
+            account.setTransactions(transactions);
+
+        } catch (ClientProtocolException e) {
+            Log.e(TAG, e.getMessage());
+        } catch (IOException e) {
+            Log.e(TAG, e.getMessage());
+        }
+        finally {
+            super.updateComplete();
+        }
+    }       	
+}
\ No newline at end of file

commit 954f133b901ec6ec0b6f4e39a84958510ccb4aa3
Author: liato <x@x00.us>
Date:   Sun Dec 19 17:22:01 2010 +0100

    Updated "thanks to".

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 6979b85..43a69e7 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -112,6 +112,7 @@
 	\nbernard (Diners Club)
 	\npilang (Länsförsäkringar)
 	\nMidde (Ikano Bank)
+	\nweppe (Coop)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index 42323f3..3e6e423 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -113,6 +113,7 @@
 	\nbernard (Diners Club)
 	\npilang (Länsförsäkringar)
 	\nMidde (Ikano Bank)
+	\nweppe (Coop)
      </string>
      
      

commit c0ba832c8e4a5baf11846ada80d1ce269a8c6b9a
Author: liato <x@x00.us>
Date:   Sun Dec 19 17:20:40 2010 +0100

    Added support for Ikano Bank. Bump version to 1.5.3-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 69067d8..e89dcd4 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="58" android:versionName="1.5.2">
+	android:versionName="1.5.3-RC1" android:versionCode="59">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/drawable/logo_ikanobank.png res/drawable/logo_ikanobank.png
new file mode 100644
index 0000000..5a709ad
Binary files /dev/null and res/drawable/logo_ikanobank.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 47f324d..6979b85 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -111,6 +111,7 @@
 	\ngust (Handelsbanken)
 	\nbernard (Diners Club)
 	\npilang (Länsförsäkringar)
+	\nMidde (Ikano Bank)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index b51dfbc..42323f3 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -112,6 +112,7 @@
 	\ngust (Handelsbanken)
 	\nbernard (Diners Club)
 	\npilang (Länsförsäkringar)
+	\nMidde (Ikano Bank)
      </string>
      
      
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 2ddb107..a261258 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -45,7 +45,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int PAYPAL = 15;
     public final static int PAYSON = 16;
     public final static int JOJO = 17;
-    public final static int IKANO = 18;
+    public final static int IKANOBANK = 18;
     public final static int STEAM = 19;
     public final static int DINERSCLUB = 20;
 
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 5578b0c..5be151c 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -34,6 +34,7 @@ import com.liato.bankdroid.banks.FirstCard;
 import com.liato.bankdroid.banks.Handelsbanken;
 import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
+import com.liato.bankdroid.banks.IkanoBank;
 import com.liato.bankdroid.banks.Jojo;
 import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
@@ -90,6 +91,8 @@ public class BankFactory {
             return new Steam(context);
         case Bank.DINERSCLUB:
             return new DinersClub(context);
+        case Bank.IKANOBANK:
+            return new IkanoBank(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -117,6 +120,7 @@ public class BankFactory {
         banks.add(new Jojo(context));
         banks.add(new Steam(context));
         banks.add(new DinersClub(context));
+        banks.add(new IkanoBank(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));

commit a7a526cf8ce7d7df887bfaf070ad0c5546767274
Author: liato <x@x00.us>
Date:   Sun Dec 19 15:37:26 2010 +0100

    Support for multiple Eurocard accounts.

diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
index 311be75..ad037d3 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/Account.java
@@ -95,7 +95,11 @@ public class Account {
 		return name;
 	}
 	
-	public String getId() {
+	public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getId() {
 		return id;
 	}
 	
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index ea0ee97..774998d 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -108,7 +108,7 @@ public class Eurocard extends Bank {
 		}
 		urlopen = login();
 		Matcher matcher = reAccounts.matcher(response);
-		if (matcher.find()) {
+		while (matcher.find()) {
             /*
              * Capture groups:
              * GROUP                     EXAMPLE DATA
@@ -121,12 +121,20 @@ public class Eurocard extends Bank {
 		    // Create a separate account for "Ofakturerat".
 		    // Set the balance for the main account to 0 and update it later
 			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), new BigDecimal(0), matcher.group(2).trim()));
-			accounts.add(new Account("Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak", Account.OTHER));
+			accounts.add(new Account("Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak:"+matcher.group(2).trim(), Account.OTHER));
+		}
+		if (accounts.size() > 2) {
+		    boolean s = true;
+		    for (Account a : accounts) {
+		        a.setName(s ? "┌ " : "└ "+ a.getName());
+		        s = !s;
+		    }
 		}
 		try {
             response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getBillingUnits.do");
             matcher = reSaldo.matcher(response);
-            if (matcher.find()) {
+            int i = 0;
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                     EXAMPLE DATA
@@ -135,8 +143,8 @@ public class Eurocard extends Bank {
                  */ 
                 
                 // Update the main account balance
-                if (!accounts.isEmpty()) {
-                    accounts.get(0).setBalance(Helpers.parseBalance(matcher.group(1)));
+                if (accounts.size() >= i*2+1) {
+                    accounts.get(i*2).setBalance(Helpers.parseBalance(matcher.group(1)));
                 }
             }
 		}
@@ -158,7 +166,7 @@ public class Eurocard extends Bank {
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
 		Matcher matcher;
-		// If the account is of type "other" it's probably the fake "Ofakturerat" account.
+		// If the account is of type "other" it's the fake "Ofakturerat" account.
 		if (account.getType() == Account.OTHER) return;
 		try {
 			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+account.getId());

commit b24779a55250b052dd615701cd4e978a5c8eafe7
Author: liato <x@x00.us>
Date:   Sun Dec 19 15:05:36 2010 +0100

    Added MedMera Faktura to Coop.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 50705e4..e4bdd38 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -50,7 +50,6 @@ public class Coop extends Bank {
     private static final int BANKTYPE_ID = Bank.COOP;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    //private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
     private String response;
@@ -134,6 +133,7 @@ public class Coop extends Bank {
         ArrayList<RequestDetails> arrRD = new ArrayList<RequestDetails>();
         arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/", "MedMera Visa", "1"));
         arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/", "MedMera Konto", "2"));
+        arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Faktura/", "MedMera Faktura", "3"));
 
         for (RequestDetails rd : arrRD) {
             try {

commit ed2c4840e704abc72fe29c4f73115440681b92bb
Author: liato <x@x00.us>
Date:   Sat Dec 18 11:39:17 2010 +0100

    Bump version to 1.5.2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 1f1d95b..69067d8 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="57" android:versionName="1.5.2-RC3">
+	android:versionCode="58" android:versionName="1.5.2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit c74ed9e4d6c8864e930ec7e7c353224ac0929a85
Author: liato <x@x00.us>
Date:   Fri Dec 17 17:30:37 2010 +0100

    Fixed transaction history for lansforsakringar.

diff --git AndroidManifest.xml AndroidManifest.xml
index 81aa22e..1f1d95b 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="7" android:versionName="1.5.2-RC2">
+	android:versionCode="57" android:versionName="1.5.2-RC3">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git logos.psd logos.psd
index 88cf055..e5c4859 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_lansforsakringar.png res/drawable/logo_lansforsakringar.png
index 8498a63..137dee5 100644
Binary files res/drawable/logo_lansforsakringar.png and res/drawable/logo_lansforsakringar.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 3a99406..47f324d 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -110,6 +110,7 @@
 	\nLibodido (Coop)
 	\ngust (Handelsbanken)
 	\nbernard (Diners Club)
+	\npilang (Länsförsäkringar)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index 48673fe..b51dfbc 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -111,6 +111,7 @@
 	\nLibodido (Coop)
 	\ngust (Handelsbanken)
 	\nbernard (Diners Club)
+	\npilang (Länsförsäkringar)
      </string>
      
      
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index 4b8b6c6..d9362b7 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -51,13 +51,13 @@ public class Lansforsakringar extends Bank {
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
     private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("(?:__|javax\\.faces\\.)VIEWSTATE\"\\s+.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa.*?internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_(?:[^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
     private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+>(?:<a[^>]+>)?<span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>(?:</a>)?\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
     private String accountsUrl = null;
     private String mRequestToken = null;
     private String mViewState = null;
@@ -220,4 +220,107 @@ public class Lansforsakringar extends Bank {
         }
     }
 
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        // No transaction history for funds and loans
+        if (account.getType() != Account.REGULAR) return;
+        String response = null;
+        Matcher matcher;
+
+        if (mFirstTransactionPage) {
+            try {
+                response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&AccountNumber=" + account.getId() + "&_token=" + mRequestToken);
+                matcher = reViewState.matcher(response);
+                if (!matcher.find()) {
+                    Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" ViewState. L237.");
+                    return;
+                }
+                mViewState = matcher.group(1);
+
+                matcher = reToken.matcher(response);
+                if (!matcher.find()) {
+                    Log.d(TAG,res.getText(R.string.unable_to_find).toString()+" token. L244.");
+                    return;
+                }
+                mRequestToken = matcher.group(1);                  
+            }
+            catch (ClientProtocolException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }            
+        }
+
+        try {
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            if (mFirstTransactionPage) {
+                postData.add(new BasicNameValuePair("dialog-account_viewAccountTransactions", "Submit Query"));            
+                postData.add(new BasicNameValuePair("_token", mRequestToken));            
+                postData.add(new BasicNameValuePair("loginForm_SUBMIT", "1"));            
+                postData.add(new BasicNameValuePair("loginForm:_idcl", ""));            
+                postData.add(new BasicNameValuePair("loginForm:_link_hidden_", ""));            
+                postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
+                response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Findex_account.faces", postData);
+                mFirstTransactionPage = false;
+            }
+            else {
+                postData.add(new BasicNameValuePair("_token", mRequestToken));            
+                postData.add(new BasicNameValuePair("viewAccountListTransactionsForm_SUBMIT", "1"));            
+                postData.add(new BasicNameValuePair("viewAccountListTransactionsForm:_idcl", ""));            
+                postData.add(new BasicNameValuePair("viewAccountListTransactionsForm:_link_hidden_", ""));            
+                postData.add(new BasicNameValuePair("javax.faces.ViewState", mViewState));            
+                postData.add(new BasicNameValuePair("accountList", account.getId()));
+                response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_windowLabel=account_1&_nffvid=%2Flfportal%2Fjsp%2Faccount%2Fview%2FviewAccountTransactions.faces", postData);
+            }
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Book. date        2009-05-03
+                 * 2: Trans. date       2009-05-03
+                 * 3: Specification     &Ouml;verf&ouml;ring internet ...
+                 * 4: Note              829909945928712
+                 * 5: Amount            -54,00
+                 * 6: Remaining         0,00
+                 *   
+                 */                    
+                transactions.add(new Transaction(matcher.group(2).trim(),
+                        Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " (" + Html.fromHtml(matcher.group(4)).toString().trim() + ")" : ""),
+                        Helpers.parseBalance(matcher.group(5))));
+            }
+            account.setTransactions(transactions);
+
+            // Save token and viewstate for next request
+            matcher = reViewState.matcher(response);
+            // We need the second match, disregard the first one.
+            matcher.find();
+            if (!matcher.find()) {
+                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" ViewState. L304.");
+                return;
+            }
+            mViewState = matcher.group(1);
+
+
+            matcher = reToken.matcher(response);
+            if (!matcher.find()) {
+                Log.d(TAG, res.getText(R.string.unable_to_find).toString()+" token. L312.");
+                return;
+            }
+            mRequestToken = matcher.group(1);            
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        finally {
+            super.updateComplete();
+        }
+    }       	
 }
\ No newline at end of file

commit a47d842eeae40645535953dfbe7c280496129b40
Author: liato <x@x00.us>
Date:   Fri Dec 17 01:36:51 2010 +0100

    Added support for Diners Club. v1.5.2-rc2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 4b009c3..81aa22e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.5.2-RC1" android:versionCode="56">
+	android:versionCode="7" android:versionName="1.5.2-RC2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git logos.psd logos.psd
index 9bfcc0d..88cf055 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_dinersclub.png res/drawable/logo_dinersclub.png
new file mode 100644
index 0000000..3b3d916
Binary files /dev/null and res/drawable/logo_dinersclub.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index f0573b7..3a99406 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -109,6 +109,7 @@
 	\nRadioman62 (Handelsbanken)
 	\nLibodido (Coop)
 	\ngust (Handelsbanken)
+	\nbernard (Diners Club)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index dd31228..48673fe 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -110,6 +110,7 @@
 	\nRadioman62 (Handelsbanken)
 	\nLibodido (Coop)
 	\ngust (Handelsbanken)
+	\nbernard (Diners Club)
      </string>
      
      
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 6d90fcf..2ddb107 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -47,6 +47,7 @@ public abstract class Bank implements Comparable<Bank> {
     public final static int JOJO = 17;
     public final static int IKANO = 18;
     public final static int STEAM = 19;
+    public final static int DINERSCLUB = 20;
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index c229a6a..5578b0c 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -28,6 +28,7 @@ import android.preference.PreferenceManager;
 import com.liato.bankdroid.banks.Avanza;
 import com.liato.bankdroid.banks.AvanzaMini;
 import com.liato.bankdroid.banks.Coop;
+import com.liato.bankdroid.banks.DinersClub;
 import com.liato.bankdroid.banks.Eurocard;
 import com.liato.bankdroid.banks.FirstCard;
 import com.liato.bankdroid.banks.Handelsbanken;
@@ -87,6 +88,8 @@ public class BankFactory {
             return new Jojo(context);
         case Bank.STEAM:
             return new Steam(context);
+        case Bank.DINERSCLUB:
+            return new DinersClub(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -113,6 +116,7 @@ public class BankFactory {
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
         banks.add(new Steam(context));
+        banks.add(new DinersClub(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banks/DinersClub.java src/com/liato/bankdroid/banks/DinersClub.java
new file mode 100644
index 0000000..89b3326
--- /dev/null
+++ src/com/liato/bankdroid/banks/DinersClub.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class DinersClub extends Bank {
+	private static final String TAG = "DinersClub";
+	private static final String NAME = "Diners Club";
+	private static final String NAME_SHORT = "dinersclub";
+	private static final String URL = "https://www.dinersclub.se/dcs/login.aspx";
+	private static final int BANKTYPE_ID = Bank.DINERSCLUB;
+	
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+	private Pattern reBalance = Pattern.compile("class=\"card\"[^>]+>\\s*<div[^>]+>\\s*<b>([^<]+)</b>\\s*<br ?/>\\s*<span[^>]+>([^<]+)</span>\\s*</div>\\s*<div[^>]+>\\s*<strong[^>]+>[^<]+</strong>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	
+	public DinersClub(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public DinersClub(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		try {
+            response = urlopen.open("https://www.dinersclub.se/dcs/login.aspx");
+            Matcher matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            }
+            String viewState = matcher.group(1);
+
+            matcher = reEventValidation.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            }
+            String eventValidation = matcher.group(1);            
+            
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+            postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+            postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+            postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$UserName", username));
+            postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$Password", password));
+            postData.add(new BasicNameValuePair("ctl00$MainContent$Login1$LoginButton", "Logga in"));
+
+            response = urlopen.open("https://www.dinersclub.se/dcs/login.aspx", postData);		    
+			if (response.contains("Har du glömt ditt lösenord")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		if (!"https://www.dinersclub.se/dcs/eSaldo/Default.aspx".equalsIgnoreCase(urlopen.getCurrentURI())) {
+		    try {
+                response = urlopen.open("https://www.dinersclub.se/dcs/eSaldo/Default.aspx");
+            }
+            catch (ClientProtocolException e) {
+                throw new BankException(e.getMessage());
+            }
+            catch (IOException e) {
+                throw new BankException(e.getMessage());
+            }
+		}
+
+		Matcher matcher = reBalance.matcher(response);
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Name              Privatkort
+             * 2: Card number       1234 789456 741
+             * 3: Balance           3.331,79 kr
+             * 
+             */
+		    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "1"));
+		    balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }		
+        super.updateComplete();
+	}
+}

commit ead1995100c9e1cc69c3ee07f8f01233889b1719
Author: liato <x@x00.us>
Date:   Fri Dec 17 00:11:12 2010 +0100

    Lansforsakringar: Show debt for loans. Bump version to 1.5.1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 875c82e..4b009c3 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.5.1-RC1" android:versionCode="54">
+	android:versionName="1.5.2-RC1" android:versionCode="56">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index 355a681..4b8b6c6 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -41,124 +41,126 @@ import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 public class Lansforsakringar extends Bank {
-	private static final String TAG = "Lansforsakringar";
-	private static final String NAME = "Länsförsäkringar";
-	private static final String NAME_SHORT = "lansforsakringar";
-	private static final String URL = "https://secure246.lansforsakringar.se/lfportal/login/privat";
-	private static final int BANKTYPE_ID = Bank.LANSFORSAKRINGAR;
+    private static final String TAG = "Lansforsakringar";
+    private static final String NAME = "Länsförsäkringar";
+    private static final String NAME_SHORT = "lansforsakringar";
+    private static final String URL = "https://secure246.lansforsakringar.se/lfportal/login/privat";
+    private static final int BANKTYPE_ID = Bank.LANSFORSAKRINGAR;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
-	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
-	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
+    private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa.*?internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_(?:[^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
     private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private String accountsUrl = null;
-	private String token = null;
-	private String host = null;
-	
-	public Lansforsakringar(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
-		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
-		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
-	}
-
-	public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException {
-		this(context);
-		this.update(username, password);
-	}
-
-	
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
-			matcher = reViewState.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
-			}
-			String strViewState = matcher.group(1);
-			matcher = reEventValidation.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
-			}
-			String strEventValidation = matcher.group(1);
+    private String accountsUrl = null;
+    private String mRequestToken = null;
+    private String mViewState = null;
+    private String host = null;
+    private boolean mFirstTransactionPage = true;
+
+    public Lansforsakringar(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+    }
+
+    public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
+
+
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib();
+        String response = null;
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
+            matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            }
+            mViewState = matcher.group(1);
+            matcher = reEventValidation.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            }
+            String strEventValidation = matcher.group(1);
+
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            postData.add(new BasicNameValuePair("inputPersonalNumber", username));
+            postData.add(new BasicNameValuePair("inputPinCode", password));
+            postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
+            postData.add(new BasicNameValuePair("__VIEWSTATE", mViewState));
+            postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+            postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+            postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
+            postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
+            response = urlopen.open(urlopen.getCurrentURI(), postData);
+
+            if (response.contains("Felaktig inloggning")) {
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
 
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("inputPersonalNumber", username));
-			postData.add(new BasicNameValuePair("inputPinCode", password));
-			postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
-			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
-			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-			response = urlopen.open(urlopen.getCurrentURI(), postData);
+            matcher = reToken.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+            }
+            mRequestToken = matcher.group(1);
 
-			if (response.contains("Felaktig inloggning")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
+            matcher = reUrl.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
+            }
 
-			matcher = reToken.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
-			}
-			token = matcher.group(1);
+            host = urlopen.getCurrentURI().split("/")[2];
+            accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + mRequestToken;
+            if (!accountsUrl.contains("https://")) {
+                accountsUrl = "https://" + host + accountsUrl;
+            }
 
-			matcher = reUrl.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
-			}
-			
-			host = urlopen.getCurrentURI().split("/")[2];
-			accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + token;
-			if (!accountsUrl.contains("https://")) {
-			    accountsUrl = "https://" + host + accountsUrl;
-			}
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;
+    }
 
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+    @Override
+    public void update() throws BankException, LoginException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
 
-		urlopen = login();
-		String response = null;
-		Matcher matcher;
-		try {
-			if (accountsUrl == null) {
-				Log.d(TAG, "accountsUrl is null, unable to update.");
-				return;
-			}
-			response = urlopen.open(accountsUrl);
-			matcher = reAccountsReg.matcher(response);
-			while (matcher.find()) {
+        urlopen = login();
+        String response = null;
+        Matcher matcher;
+        try {
+            if (accountsUrl == null) {
+                Log.d(TAG, "accountsUrl is null, unable to update.");
+                return;
+            }
+            response = urlopen.open(accountsUrl);
+            matcher = reAccountsReg.matcher(response);
+            while (matcher.find()) {
                 /*
                  * Capture groups:
                  * GROUP                    EXAMPLE DATA
@@ -167,9 +169,9 @@ public class Lansforsakringar extends Bank {
                  * 3: Amount                25 000 000
                  * 
                  */    
-			    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
+                accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+                balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+            }
             matcher = reAccountsFunds.matcher(response);
             while (matcher.find()) {
                 /*
@@ -190,9 +192,10 @@ public class Lansforsakringar extends Bank {
                  * 1: Name                  Privatl&#229;n
                  * 2: ID                    idJsp207
                  * 3: Amount                25 000 000
+                 * 4: Debt                  1,00
                  * 
                  */                
-                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim(), Account.LOANS));
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4).trim()), matcher.group(2).trim(), Account.LOANS));
             }
 
             // Save token for next request
@@ -200,67 +203,21 @@ public class Lansforsakringar extends Bank {
             if (!matcher.find()) {
                 throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
             }
-            token = matcher.group(1);
-            
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-        finally {
-            super.updateComplete();
-        }
-	}
-	
-    @Override
-    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-        super.updateTransactions(account, urlopen);
-        // No transaction history for funds and loans
-        if (account.getType() != Account.REGULAR) return;
-        String response = null;
-        Matcher matcher;
-        try {
-            response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&AccountNumber=" + account.getId() + "&_token=" + token);
-            matcher = reTransactions.matcher(response);
-            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-            while (matcher.find()) {
-                /*
-                 * Capture groups:
-                 * GROUP                EXAMPLE DATA
-                 * 1: Book. date        2009-05-03
-                 * 2: Trans. date       2009-05-03
-                 * 3: Specification     &Ouml;verf&ouml;ring internet ...
-                 * 4: Note              829909945928712
-                 * 5: Amount            -54,00
-                 * 6: Remaining         0,00
-                 *   
-                 */                    
-                transactions.add(new Transaction(matcher.group(2).trim().substring(8),
-                                    Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " (" + Html.fromHtml(matcher.group(3)).toString().trim() + ")" : ""),
-                                    Helpers.parseBalance(matcher.group(5))));
-            }
-            account.setTransactions(transactions);
-            
-            // Save token for next request
-            matcher = reToken.matcher(response);
-            if (!matcher.find()) {
-                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+            mRequestToken = matcher.group(1);
+
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
             }
-            token = matcher.group(1);            
-        } catch (ClientProtocolException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        } catch (IOException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
         }
         finally {
             super.updateComplete();
         }
-    }       	
+    }
+
 }
\ No newline at end of file

commit 9f692910ea9acbbf2042f1a482e291882b7f9b9c
Author: liato <x@x00.us>
Date:   Thu Dec 16 16:33:32 2010 +0100

    Added license headers.

diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
index 8f55f7d..311be75 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/Account.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index f332353..7785d35 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -1,10 +1,25 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
 import android.content.Context;
 import android.graphics.Color;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index f6e4cc6..e0259f1 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 3b39a7a..6d90fcf 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index c75307e..3001624 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
@@ -12,19 +28,18 @@ import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.text.InputType;
 import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.Spinner;
 import android.widget.TextView;
-import android.widget.AdapterView.OnItemSelectedListener;
 
 public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private final static String TAG = "AccountActivity";
diff --git src/com/liato/bankdroid/BankException.java src/com/liato/bankdroid/BankException.java
index 9dce865..212e4cd 100644
--- src/com/liato/bankdroid/BankException.java
+++ src/com/liato/bankdroid/BankException.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 public class BankException extends Exception {
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 21ad09a..c229a6a 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 337d1b3..04aa45a 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import android.app.PendingIntent;
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
index 89fadd2..ecdaef7 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 public class BankdroidWidgetProvider_2x1 extends BankdroidWidgetProvider {
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
index 2b2d478..e2f5751 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 
diff --git src/com/liato/bankdroid/BetterPopupWindow.java src/com/liato/bankdroid/BetterPopupWindow.java
index 609910c..9335936 100644
--- src/com/liato/bankdroid/BetterPopupWindow.java
+++ src/com/liato/bankdroid/BetterPopupWindow.java
@@ -4,14 +4,13 @@ import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.WindowManager;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
 import android.widget.PopupWindow;
 
 /**
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index 53570a1..8622845 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.text.SimpleDateFormat;
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index e46c143..61d2d8c 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index c3911f4..90e4e5d 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.lang.reflect.Method;
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 0aa959c..5bded7f 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -1,6 +1,20 @@
-package com.liato.bankdroid;
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-import com.liato.bankdroid.LockPatternUtils;
+package com.liato.bankdroid;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -8,10 +22,8 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.util.Log;
 
 public class LockableActivity extends Activity {
-    private static String TAG = "LockableActivity";
     private static int PATTERNLOCK_UNLOCK = 42;
 	private SharedPreferences prefs;
 	private Editor editor;
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index c246f8b..d1dbb4f 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import android.content.Intent;
@@ -8,7 +24,6 @@ import android.preference.PreferenceActivity;
 import android.preference.PreferenceManager;
 
 public class LockablePreferenceActivity extends PreferenceActivity {
-    private static String TAG = "LockablePreferenceActivity";
     private static int PATTERNLOCK_UNLOCK = 42;
 	private SharedPreferences prefs;
 	private Editor editor;
diff --git src/com/liato/bankdroid/LoginException.java src/com/liato/bankdroid/LoginException.java
index 6f7b550..a6fcdc4 100644
--- src/com/liato/bankdroid/LoginException.java
+++ src/com/liato/bankdroid/LoginException.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 public class LoginException extends Exception {
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 46bf503..666fcd0 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index d82ae64..43cc10a 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import android.content.Intent;
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 2f5fc44..9a04762 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import android.app.AlarmManager;
diff --git src/com/liato/bankdroid/Transaction.java src/com/liato/bankdroid/Transaction.java
index 6a5535e..8c67cce 100644
--- src/com/liato/bankdroid/Transaction.java
+++ src/com/liato/bankdroid/Transaction.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index 8f389b1..724942e 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.lang.reflect.Method;
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index c31121f..363bd70 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -1,19 +1,33 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
-import android.app.Activity;
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.View;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
 import android.widget.CheckBox;
 import android.widget.ListView;
-import android.widget.AdapterView.OnItemClickListener;
 
 public class WidgetConfigureActivity extends LockableActivity {
     private static final String WIDGET_PREFIX = "widget_";
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 8f7074e..44f8b7f 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banks/AvanzaMini.java
index c20579f..6e0f98c 100644
--- src/com/liato/bankdroid/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banks/AvanzaMini.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 59c6bfc..50705e4 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 225d89b..ea0ee97 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
index bdb72ea..826a151 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index e6ad97a..cc76fb5 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: DEGE
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
@@ -24,10 +41,6 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
-/**
- * @author DEGE
- *
- */
 public class Handelsbanken extends Bank {
 	private static final String TAG = "Handelsbanken";
 	private static final String NAME = "Handelsbanken";
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banks/ICA.java
index 5363a20..c56aa65 100644
--- src/com/liato/bankdroid/banks/ICA.java
+++ src/com/liato/bankdroid/banks/ICA.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index 8164cc0..58300a3 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Jojo.java src/com/liato/bankdroid/banks/Jojo.java
index c6a785a..c7a1366 100644
--- src/com/liato/bankdroid/banks/Jojo.java
+++ src/com/liato/bankdroid/banks/Jojo.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index b2c1864..355a681 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 20f7088..90b6c20 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index 97d029b..9bd6add 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ * Contributors: COLA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
@@ -25,10 +42,6 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
-/**
- * @author COLA
- */
-
 public class OKQ8 extends Bank {
 	private static final String TAG = "OKQ8";
 	private static final String NAME = "OKQ8 VISA";
diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banks/PayPal.java
index 1fe54a4..bd03671 100644
--- src/com/liato/bankdroid/banks/PayPal.java
+++ src/com/liato/bankdroid/banks/PayPal.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Payson.java src/com/liato/bankdroid/banks/Payson.java
index cb4eac4..0754911 100644
--- src/com/liato/bankdroid/banks/Payson.java
+++ src/com/liato/bankdroid/banks/Payson.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index 67c0d0f..ec0a6b1 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Steam.java src/com/liato/bankdroid/banks/Steam.java
index b57a9ba..feb7138 100644
--- src/com/liato/bankdroid/banks/Steam.java
+++ src/com/liato/bankdroid/banks/Steam.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 2694ee2..42877d9 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/TestBank.java src/com/liato/bankdroid/banks/TestBank.java
index de8b956..cb5ea94 100644
--- src/com/liato/bankdroid/banks/TestBank.java
+++ src/com/liato/bankdroid/banks/TestBank.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/bankdroid/banks/Villabanken.java src/com/liato/bankdroid/banks/Villabanken.java
index 4442a61..602df3c 100644
--- src/com/liato/bankdroid/banks/Villabanken.java
+++ src/com/liato/bankdroid/banks/Villabanken.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index 6294c27..f956938 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 Nullbyte <http://nullbyte.eu>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.liato.urllib;
 
 import java.io.IOException;
diff --git src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
index ca45b90..4c067f6 100644
--- src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
+++ src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -1,24 +1,8 @@
-/*******************************************************************************
+/*
  * Copyright (c) 2009 Ferenc Hechler - ferenc_hechler@users.sourceforge.net
- * 
- * This file is part of the Android Hotspot Login
- *
- * The Android Hotspot Login 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.
- * 
- * The Android Hotspot Login 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 the Android Hotspot Login;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *  
- *******************************************************************************/
+ * http://www.androidsnippets.org/snippets/39/index.html
+ */
+
 package net.sf.andhsli.hotspotlogin;
 
 import java.security.SecureRandom;

commit 24f89af1d2f8f119247e9db3cf573cba97821e2e
Author: liato <x@x00.us>
Date:   Wed Dec 15 10:54:46 2010 +0100

    Bump version to 1.5.1-RC1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8a9e323..875c82e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="53" android:versionName="1.5.0">
+	android:versionName="1.5.1-RC1" android:versionCode="54">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 0ffd32b..f0573b7 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -104,6 +104,11 @@
 	\nDaniel (Avanza)
 	\nRadioman62 (Coop)
 	\ns3 (Steam Wallet)
+	\nVarazir (Jojo Reskassa)
+	\nJohan (Länsförsäkringar)
+	\nRadioman62 (Handelsbanken)
+	\nLibodido (Coop)
+	\ngust (Handelsbanken)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index 4b28f36..dd31228 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -105,6 +105,11 @@
 	\nDaniel (Avanza)
 	\nRadioman62 (Coop)
 	\ns3 (Steam Wallet)
+	\nVarazir (Jojo Reskassa)
+	\nJohan (Länsförsäkringar)
+	\nRadioman62 (Handelsbanken)
+	\nLibodido (Coop)
+	\ngust (Handelsbanken)
      </string>
      
      

commit cdc89ee0ca545cda76b90c46caac19e30b639fbb
Author: liato <x@x00.us>
Date:   Wed Dec 15 10:54:11 2010 +0100

    Inputtype phone+password is working. Yey.

diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 8b6ddcb..3b39a7a 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -38,7 +38,7 @@ public abstract class Bank implements Comparable<Bank> {
 	protected int BANKTYPE_ID = 0;
 	protected String URL;
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
-    protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
     protected String INPUT_HINT_USERNAME = null;
     protected boolean STATIC_BALANCE = false;
     protected boolean BROKEN = false;
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index 4426805..c75307e 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -9,6 +9,7 @@ import android.app.ProgressDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.Resources;
+import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.text.InputType;
@@ -96,7 +97,10 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
 		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
         //Not possible to set a textfield to both PHONE and PASSWORD :\
-        //((EditText)findViewById(R.id.edtBankeditPassword)).setInputType(SELECTED_BANK.getInputTypePassword());
+		EditText edtPassword = (EditText)findViewById(R.id.edtBankeditPassword);
+		edtPassword.setInputType(SELECTED_BANK.getInputTypePassword());
+		edtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+		edtPassword.setTypeface(Typeface.MONOSPACE);
         
 	}
 

commit 3cf0c5f0687ea9fc12b54c57282aed36aa8dffa2
Author: liato <x@x00.us>
Date:   Wed Dec 15 09:35:11 2010 +0100

    Fix for Handelsbanken.

diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 1d2d251..e6ad97a 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -37,12 +37,14 @@ public class Handelsbanken extends Bank {
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
-	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
-	private Pattern reLoginUrl = Pattern.compile("_-([^\"]+)\"><img[^>]*><img[^>]*><span[^>]*>Logga",Pattern.CASE_INSENSITIVE);
+	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"[^\"]*?/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK(?:&nbsp;|\\s*)?([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
+	private Pattern reLoginUrl = Pattern.compile("_-([^\"]+)\">(?:<img[^>]+>)?<img[^>]+><span[^>]+>Logga",Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE);
 
-	private ArrayList<String> accountIds = new ArrayList<String>(); 
+	private ArrayList<String> accountIds = new ArrayList<String>();
+	private String response = null;
+	
 	public Handelsbanken(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -63,7 +65,6 @@ public class Handelsbanken extends Bank {
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib();
-		String response = null;
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://m.handelsbanken.se/primary/");
@@ -76,13 +77,7 @@ public class Handelsbanken extends Bank {
 			postData.add(new BasicNameValuePair("username", username));
 			postData.add(new BasicNameValuePair("pin", password));
 			postData.add(new BasicNameValuePair("execute", "true"));
-			Log.d(TAG, "Posting data to: " + strLoginUrl);
 			response = urlopen.open(strLoginUrl, postData);
-			/*
-			for (String s : response.split("<span")) {
-				Log.d(TAG, s);
-			}
-			*/
 
 			if (response.contains("ontrollera dina uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -107,17 +102,13 @@ public class Handelsbanken extends Bank {
 		}
 
 		urlopen = login();
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open(urlopen.getCurrentURI());
-			//Successful login, find accounts url and retrieve account info.
 			matcher = reAccountsUrl.matcher(response);
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
 			}
 			String strAccountsUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);			
-			Log.d("TAG", "Accounts url: "+strAccountsUrl);
 			response = urlopen.open(strAccountsUrl);
 			matcher = reBalance.matcher(response);
 			Integer accountId = 0;
@@ -145,7 +136,6 @@ public class Handelsbanken extends Bank {
 
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		String response = null;
 		Matcher matcher;
 		try {
 			String accountWebId = accountIds.get(Integer.parseInt(account.getId()));

commit 18039f1ed373616ee92efdd0bc8eb7b60f569686
Author: liato <x@x00.us>
Date:   Wed Dec 15 02:01:01 2010 +0100

    Display medmera visa for coop.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 27a19d4..59c6bfc 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -34,10 +34,9 @@ public class Coop extends Bank {
     private static final int BANKTYPE_ID = Bank.COOP;
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-    private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reBalanceKonto = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactionsKonto = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    //private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reBalance = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>(?:\\s*<a[^>]+>)?([^<]+)(?:</a>\\s*)?</td>", Pattern.CASE_INSENSITIVE);
     private String response;
 
     public Coop(Context context) {
@@ -106,64 +105,60 @@ public class Coop extends Bank {
         urlopen = login();
         Matcher matcher;
         Account account;
-        matcher = reBalanceVisa.matcher(response);
-        if (matcher.find()) {
-            account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
-            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+
+
+        class RequestDetails {
+            public String url, name, id;
+            public RequestDetails(String url, String name, String id) {
+                this.url = url;
+                this.name = name;
+                this.id = id;
+            }
+        }    
+        ArrayList<RequestDetails> arrRD = new ArrayList<RequestDetails>();
+        arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/", "MedMera Visa", "1"));
+        arrRD.add(new RequestDetails("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/", "MedMera Konto", "2"));
+
+        for (RequestDetails rd : arrRD) {
             try {
-                response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
-                matcher = reTransactionsVisa.matcher(response);
-                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                while (matcher.find()) {
-                    String title = matcher.group(4).length() > 0 ? matcher.group(4).trim() + " (" + matcher.group(3).trim() + ")" : matcher.group(2);
-                    transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(5))));
+                response = urlopen.open(rd.url);
+                matcher = reBalance.matcher(response);
+                if (matcher.find()) {
+                    account = new Account(rd.name, Helpers.parseBalance(matcher.group(1).trim()), rd.id);
+                    balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+                    matcher = reTransactions.matcher(response);
+                    ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                    while (matcher.find()) {
+                        /*
+                         * Capture groups:
+                         * GROUP                EXAMPLE DATA
+                         * 1: Date              2010-11-04
+                         * 2: Activity          Köp
+                         * 3: User              John Doe
+                         * 4: Place             Coop Extra Stenungsund
+                         * 5: Amount            -809,37 kr
+                         *                      * 
+                         */
+
+                        String title = Html.fromHtml(matcher.group(4)).toString().trim().length() > 0 ? Html.fromHtml(matcher.group(4)).toString().trim() : Html.fromHtml(matcher.group(2)).toString().trim();
+                        if (Html.fromHtml(matcher.group(3)).toString().trim().length() > 0) {
+                            title = title + " (" + Html.fromHtml(matcher.group(3)).toString().trim() + ")";
+                        }
+                        transactions.add(new Transaction(matcher.group(1).trim(),
+                                title,
+                                Helpers.parseBalance(matcher.group(5))));
+                    }
+                    account.setTransactions(transactions);
+                    accounts.add(account);
                 }
-                account.setTransactions(transactions);
-                accounts.add(account);
             }
             catch (ClientProtocolException e) {
                 //404 or 500 response
             }
             catch (IOException e) {
-                throw new BankException(e.getMessage());
-            }                
+            }                        
         }
-        try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/");
-            matcher = reBalanceKonto.matcher(response);
-            if (matcher.find()) {
-                account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
-                balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-                matcher = reTransactionsKonto.matcher(response);
-                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-                while (matcher.find()) {
-                    /*
-                     * Capture groups:
-                     * GROUP                EXAMPLE DATA
-                     * 1: Date              2010-11-04
-                     * 2: Activity          Köp
-                     * 3: User              John Doe
-                     * 4: Place             Coop Extra Stenungsund
-                     * 5: Amount            -809,37 kr
-                     *                      * 
-                     */
-
-                    String title = Html.fromHtml(matcher.group(4)).toString().trim().length() > 0 ? Html.fromHtml(matcher.group(4)).toString().trim() : Html.fromHtml(matcher.group(2)).toString().trim();
-                    if (Html.fromHtml(matcher.group(3)).toString().trim().length() > 0) {
-                        title = title + " (" + Html.fromHtml(matcher.group(3)).toString().trim() + ")";
-                    }
-                    transactions.add(new Transaction(matcher.group(1).trim(),
-                            title,
-                            Helpers.parseBalance(matcher.group(5))));
-                }
-                account.setTransactions(transactions);
-                accounts.add(account);
-            }        }
-        catch (ClientProtocolException e) {
-            //404 or 500 response
-        }
-        catch (IOException e) {
-        }            
+
         if (accounts.isEmpty()) {
             throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }

commit ab0df0bbe7dd39c84c599e46340377f6105535a1
Author: liato <x@x00.us>
Date:   Wed Dec 15 01:00:19 2010 +0100

    Display funds and loans for lansforsakringar and also, maybe, transactions.

diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index b65b7d6..b2c1864 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -36,12 +36,15 @@ public class Lansforsakringar extends Bank {
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalance = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccountsReg = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountsFunds = Pattern.compile("fundsDataTable[^>]+>([^<]+)</span></a></td><td[^>]+></td><td[^>]+><span\\sid=\"fundsDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reAccountsLoans = Pattern.compile("internalLoanDataTable[^>]+>([^<]+)</span></a></span></td><td[^>]+><span[^>]+>[^<]+</span></td><td[^>]+><span\\sid=\"internalLoanDataTable:\\d{1,}:bankoverview_\\d{1,}_([^\"]+)\">([0-9 .,-]+)</spa", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
     private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private String accountsUrl = null;
 	private String token = null;
+	private String host = null;
 	
 	public Lansforsakringar(Context context) {
 		super(context);
@@ -105,9 +108,11 @@ public class Lansforsakringar extends Bank {
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
 			}
+			
+			host = urlopen.getCurrentURI().split("/")[2];
 			accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + token;
 			if (!accountsUrl.contains("https://")) {
-			    accountsUrl = "https://" + urlopen.getCurrentURI().split("/")[2] + accountsUrl;
+			    accountsUrl = "https://" + host + accountsUrl;
 			}
 
 		}
@@ -136,11 +141,51 @@ public class Lansforsakringar extends Bank {
 				return;
 			}
 			response = urlopen.open(accountsUrl);
-			matcher = reBalance.matcher(response);
+			matcher = reAccountsReg.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Account number        125486547
+                 * 2: Name                  Personkonto
+                 * 3: Amount                25 000 000
+                 * 
+                 */    
+			    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
+            matcher = reAccountsFunds.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Name                  Fonder
+                 * 2: ID                    idJsp165
+                 * 3: Amount                0,00
+                 * 
+                 */
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim(), Account.FUNDS));
+            }
+            matcher = reAccountsLoans.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                    EXAMPLE DATA
+                 * 1: Name                  Privatl&#229;n
+                 * 2: ID                    idJsp207
+                 * 3: Amount                25 000 000
+                 * 
+                 */                
+                accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(2).trim(), Account.LOANS));
+            }
+
+            // Save token for next request
+            matcher = reToken.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+            }
+            token = matcher.group(1);
+            
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
@@ -159,11 +204,12 @@ public class Lansforsakringar extends Bank {
     @Override
     public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
         super.updateTransactions(account, urlopen);
+        // No transaction history for funds and loans
+        if (account.getType() != Account.REGULAR) return;
         String response = null;
         Matcher matcher;
         try {
- 
-            response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&AccountNumber=" + account.getId() + "&_token=" + token);
+            response = urlopen.open("https://" + host + "/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&AccountNumber=" + account.getId() + "&_token=" + token);
             matcher = reTransactions.matcher(response);
             ArrayList<Transaction> transactions = new ArrayList<Transaction>();
             while (matcher.find()) {
@@ -183,6 +229,13 @@ public class Lansforsakringar extends Bank {
                                     Helpers.parseBalance(matcher.group(5))));
             }
             account.setTransactions(transactions);
+            
+            // Save token for next request
+            matcher = reToken.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+            }
+            token = matcher.group(1);            
         } catch (ClientProtocolException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();

commit 19152ea60a87529ac10bcd803a5a33a304f174ea
Author: liato <x@x00.us>
Date:   Sun Dec 12 12:40:27 2010 +0100

    Bump version to 1.5.0

diff --git AndroidManifest.xml AndroidManifest.xml
index ac09bfb..8a9e323 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="49" android:versionName="1.5.0-RC2">
+	android:versionCode="53" android:versionName="1.5.0">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 6e82b79..0ffd32b 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -103,6 +103,7 @@
 	\nnihplod (Eurocard)
 	\nDaniel (Avanza)
 	\nRadioman62 (Coop)
+	\ns3 (Steam Wallet)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index b54e472..4b28f36 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -104,6 +104,7 @@
 	\nNihplod (Eurocard)
 	\nDaniel (Avanza)
 	\nRadioman62 (Coop)
+	\ns3 (Steam Wallet)
      </string>
      
      
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 4039e87..c3911f4 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -56,9 +56,6 @@ public class Helpers {
     }; 
 
     public static BigDecimal parseBalance(String balance) {
-        //balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
-        //balance = balance.replaceAll("[a-zA-Z]*", "");
-        //balance = balance.replaceAll("\\s*", "");
         balance = balance.replaceAll("[^0-9,.-]*", "");
         balance = balance.replace(",", ".");
         if (balance.indexOf(".") != balance.lastIndexOf(".")) {

commit c2d7117eb816f0158e438ec15c0edccb1eac0512
Author: liato <x@x00.us>
Date:   Sun Dec 12 12:40:03 2010 +0100

    Display subitem text on steam transactions.

diff --git src/com/liato/bankdroid/banks/Steam.java src/com/liato/bankdroid/banks/Steam.java
index 582d8af..b57a9ba 100644
--- src/com/liato/bankdroid/banks/Steam.java
+++ src/com/liato/bankdroid/banks/Steam.java
@@ -1,9 +1,11 @@
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -35,7 +37,7 @@ public class Steam extends Bank {
 	private static final boolean STATIC_BALANCE = true;
 	
     private Pattern reBalance = Pattern.compile("accountBalance\">\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
-    private Pattern reTransactions = Pattern.compile("(?:even|odd)\">\\s*<div\\s*class=\"transactionRowDate\">([^<]+)</div>\\s*<div.*?RowPrice\">([^<]+)</div>\\s*<div.*?RowEvent\">([^<]+)</div>.*?RowTitle\">([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactions = Pattern.compile("(?:even|odd)\">\\s*<div\\s*class=\"transactionRowDate\">([^<]+)</div>\\s*<div.*?RowPrice\">([^<]+)</div>\\s*<div.*?RowEvent\">([^<]+)</div>.*?RowTitle\">([^<]+)</div>\\s*<span[^>]+>([^<]*)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private String response = null;
 	
 	public Steam(Context context) {
@@ -92,7 +94,7 @@ public class Steam extends Bank {
              * 1: Amount            0,--&#8364;
              * 
              */
-		    String amount = Html.fromHtml(matcher.group(1)).toString().trim();
+		    String amount = Html.fromHtml(matcher.group(1)).toString().trim().replace("--", "00");
 		    Account account = new Account("Wallet", Helpers.parseBalance(amount), "1");
 		    String currency = Helpers.parseCurrency(amount, "USD");
 		    this.setCurrency(currency);
@@ -105,9 +107,10 @@ public class Steam extends Bank {
 	             * Capture groups:
 	             * GROUP                EXAMPLE DATA
 	             * 1: Date              18 Oct 2007
-	             * 2: Amount            &#36;62.44
+	             * 2: Amount            0,99&#8364;
 	             * 3: Event             Purchase
-	             * 4: Item              The Orange Box
+	             * 4: Item              Team Fortress 2&nbsp;
+	             * 5: Sub item          Mann Co. Supply Crate Key
 	             * 
 	             */
                 SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
@@ -116,15 +119,21 @@ public class Steam extends Bank {
                 try {
                     transactionDate = sdfFrom.parse(matcher.group(1).trim());
                     String strDate = sdfTo.format(transactionDate);
+                    BigDecimal price = Helpers.parseBalance(Html.fromHtml(matcher.group(2)).toString().trim().replace("--", "00"));
+                    if ("Purchase".equalsIgnoreCase(matcher.group(3).trim())) {
+                        price = price.negate();
+                    }
                     transactions.add(new Transaction(strDate,
-                                                     Html.fromHtml(matcher.group(4)).toString().trim(),
-                                                     Helpers.parseBalance(Html.fromHtml(matcher.group(2)).toString().trim()),
+                                                     Html.fromHtml(matcher.group(4)).toString().trim() + (Html.fromHtml(matcher.group(5)).toString().trim().length() > 1 ? " (" + Html.fromHtml(matcher.group(5)).toString().trim() + ")" : ""),
+                                                     price,
                                                      Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(), "USD")));
                 }
                 catch (ParseException e) {
                     Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
                 }
 		    }
+		    Collections.sort(transactions);
+		    Collections.reverse(transactions);
 		    account.setTransactions(transactions);
 		    accounts.add(account);
 		}

commit 036951be0f6dc43e6395d4bfad3f124659b79bfa
Author: liato <x@x00.us>
Date:   Sun Dec 12 12:39:06 2010 +0100

    Use the correct url for Coop's medmera kort.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index deac1ee..27a19d4 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -129,7 +129,7 @@ public class Coop extends Bank {
             }                
         }
         try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/Kontoutdrag/");
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/");
             matcher = reBalanceKonto.matcher(response);
             if (matcher.find()) {
                 account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");

commit 7c5d36c6b2df2bf74332ce7db71d5428fdae4dc2
Author: liato <x@x00.us>
Date:   Sat Dec 11 23:36:59 2010 +0100

    Don't skip avanza banks from db.

diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 55fa3c8..21ad09a 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -156,9 +156,6 @@ public class BankFactory {
 			c.moveToNext();
 			//Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
 			try {
-			    if (c.getInt(c.getColumnIndex("banktype")) == Bank.AVANZA) {
-			        continue;
-			    }
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
 				
 	            String password = "";

commit a16f68e52e4550a03bf62470d54268134f0acf51
Author: liato <x@x00.us>
Date:   Sat Dec 11 23:32:53 2010 +0100

    Bump version to 1.5.0-RC2

diff --git AndroidManifest.xml AndroidManifest.xml
index 93a3292..ac09bfb 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.5.0-RC1" android:versionCode="48">
+	android:versionCode="49" android:versionName="1.5.0-RC2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 45a1542..6e82b79 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -102,6 +102,7 @@
 	\nRikko (FirstCard)
 	\nnihplod (Eurocard)
 	\nDaniel (Avanza)
+	\nRadioman62 (Coop)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index 720abea..b54e472 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -103,6 +103,7 @@
 	\nRikko (FirstCard)
 	\nNihplod (Eurocard)
 	\nDaniel (Avanza)
+	\nRadioman62 (Coop)
      </string>
      
      

commit 11108803553c159df840bebed59a91379ba3a024
Author: liato <x@x00.us>
Date:   Sat Dec 11 23:32:23 2010 +0100

    Fix for Coop.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index c3a8292..deac1ee 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -35,8 +35,8 @@ public class Coop extends Bank {
 
     private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
     private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-    private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reBalanceKonto = Pattern.compile("saldo\">([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactionsKonto = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
     private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
     private String response;
 
@@ -129,7 +129,7 @@ public class Coop extends Bank {
             }                
         }
         try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/");
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/Kontoutdrag/");
             matcher = reBalanceKonto.matcher(response);
             if (matcher.find()) {
                 account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
@@ -137,8 +137,24 @@ public class Coop extends Bank {
                 matcher = reTransactionsKonto.matcher(response);
                 ArrayList<Transaction> transactions = new ArrayList<Transaction>();
                 while (matcher.find()) {
-                    String title = matcher.group(4).length() > 0 ? matcher.group(4) : matcher.group(3);
-                    transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(4))));
+                    /*
+                     * Capture groups:
+                     * GROUP                EXAMPLE DATA
+                     * 1: Date              2010-11-04
+                     * 2: Activity          Köp
+                     * 3: User              John Doe
+                     * 4: Place             Coop Extra Stenungsund
+                     * 5: Amount            -809,37 kr
+                     *                      * 
+                     */
+
+                    String title = Html.fromHtml(matcher.group(4)).toString().trim().length() > 0 ? Html.fromHtml(matcher.group(4)).toString().trim() : Html.fromHtml(matcher.group(2)).toString().trim();
+                    if (Html.fromHtml(matcher.group(3)).toString().trim().length() > 0) {
+                        title = title + " (" + Html.fromHtml(matcher.group(3)).toString().trim() + ")";
+                    }
+                    transactions.add(new Transaction(matcher.group(1).trim(),
+                            title,
+                            Helpers.parseBalance(matcher.group(5))));
                 }
                 account.setTransactions(transactions);
                 accounts.add(account);

commit 73e505f0cb107f47aebab8f989a17271a6c86537
Author: liato <x@x00.us>
Date:   Sat Dec 11 23:31:53 2010 +0100

    Fix for Avanza.

diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index e1e5bc8..8b6ddcb 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -247,7 +247,8 @@ public abstract class Bank implements Comparable<Bank> {
     public String getInputHintUsername() {
         return INPUT_HINT_USERNAME;
     }
-    
+
+    // Returns true if the current implementation of this bank is broken.
     public boolean isBroken() {
         return BROKEN;
     }
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index e38f1eb..8f7074e 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -31,7 +31,6 @@ public class Avanza extends Bank {
 	private static final String NAME_SHORT = "avanza";
 	private static final String URL = "https://www.avanza.se/";
     private static final int BANKTYPE_ID = Bank.AVANZA;
-    private static final boolean BROKEN = true;
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>([^<]+)<.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -42,7 +41,6 @@ public class Avanza extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.BROKEN = BROKEN;
 	}
 
 	public Avanza(String username, String password, Context context) throws BankException, LoginException {

commit 07973beed733b0b31943acf8661057732d5aa968
Author: liato <x@x00.us>
Date:   Sat Dec 11 23:30:56 2010 +0100

    Added option to round balance on widgets.

diff --git res/xml-sv/settings.xml res/xml-sv/settings.xml
index f297c11..5611d6a 100644
--- res/xml-sv/settings.xml
+++ res/xml-sv/settings.xml
@@ -26,6 +26,14 @@
 			android:summary="Dölj saldot igen efter angiven tid"
 			android:dependency="widget_blur_balance" />
 	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Utseende">
+		<CheckBoxPreference
+			android:key="round_widget_balance"
+			android:defaultValue="false"
+			android:title="Avrunda saldo på widgets"
+			android:summary="Visa saldot på widgets utan decimaler" />
+	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="Automatiska Uppdateringar">
 		<CheckBoxPreference
diff --git res/xml/settings.xml res/xml/settings.xml
index 7a6dbdf..027f3f8 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -46,6 +46,14 @@
 			android:title="Update transaction history"
 			android:summary="Update transaction history when updating automatically" />
 	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Appearance">
+		<CheckBoxPreference
+			android:key="round_widget_balance"
+			android:defaultValue="false"
+			android:title="Round widget balance"
+			android:summary="Display the balance on widgets without decimals" />
+	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="Notifications">
 		<CheckBoxPreference
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 5a3a9b0..337d1b3 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -109,6 +109,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
+        SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
 		if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) {
 			if (providerInfo.initialLayout == R.layout.widget_large) {
 				layoutId = R.layout.widget_large_transparent;
@@ -121,7 +122,12 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
         views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
         views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
-		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        if (defprefs.getBoolean("round_widget_balance", false)) {
+            views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), true));
+        }
+        else {
+            views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+        }
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
 		Log.d("Disabled", ""+bank.isDisabled());
 		if (bank.isDisabled()) {
@@ -152,7 +158,6 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
         views.setOnClickPendingIntent(R.id.imgBalanceblur, pendingIntent);
         
-        SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (defprefs.getBoolean("widget_blur_balance", false) && !prefs.getBoolean("widget_unblurred_" + appWidgetId, false)) {
             views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE);
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 8e15b4b..4039e87 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -10,114 +10,123 @@ import android.util.Log;
 
 public class Helpers {
     private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD",
-                                         "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
-                                         "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
-                                         "BZD", "CAD", "CDF", "CHF", "CLP", "CNY", "COP", "CRC",
-                                         "CUP", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD",
-                                         "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP",
-                                         "GEL", "GGP", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
-                                         "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "IMP",
-                                         "INR", "IQD", "IRR", "ISK", "JEP", "JMD", "JOD", "JPY",
-                                         "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD",
-                                         "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL",
-                                         "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP",
-                                         "MRO", "MTL", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN",
-                                         "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB",
-                                         "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON",
-                                         "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK",
-                                         "SGD", "SHP", "SLL", "SOS", "SPL", "SRD", "STD", "SVC",
-                                         "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TOP", "TRY",
-                                         "TTD", "TVD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU",
-                                         "UZS", "VEB", "VEF", "VND", "VUV", "WST", "XAF", "XAG",
-                                         "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER",
-                                         "ZAR", "ZMK", "ZWD"};
+        "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
+        "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
+        "BZD", "CAD", "CDF", "CHF", "CLP", "CNY", "COP", "CRC",
+        "CUP", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD",
+        "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP",
+        "GEL", "GGP", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
+        "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "IMP",
+        "INR", "IQD", "IRR", "ISK", "JEP", "JMD", "JOD", "JPY",
+        "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD",
+        "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL",
+        "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP",
+        "MRO", "MTL", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN",
+        "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB",
+        "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON",
+        "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK",
+        "SGD", "SHP", "SLL", "SOS", "SPL", "SRD", "STD", "SVC",
+        "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TOP", "TRY",
+        "TTD", "TVD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU",
+        "UZS", "VEB", "VEF", "VND", "VUV", "WST", "XAF", "XAG",
+        "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER",
+        "ZAR", "ZMK", "ZWD"};
 
     private final static String[][] symMappings = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"},
-                                            {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"},
-                                            {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"},
-                                            {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"},
-                                            {"Bs", "VEF"}, {"Ft", "HUF"}, {"Gs", "PYG"},
-                                            {"KM", "BAM"}, {"Kč", "CZK"}, {"Lek", "ALL"},
-                                            {"S/.", "PEN"}, {"Ls", "LVL"}, {"Lt", "LTL"},
-                                            {"MT", "MZN"}, {"Php", "PHP"}, {"RM", "MYR"},
-                                            {"Rp", "IDR"}, {"TL", "TRY"}, {"kn", "HRK"},
-                                            {"kr", "SEK"}, {"lei", "RON"}, {"p.", "BYR"},
-                                            {"L", "HNL"}, {"S", "SOS"}, {"P", "BWP"},
-                                            {"Q", "GTQ"}, {"R", "ZAR"}, {"zł", "PLN"},
-                                            {"¢", "GHC"}, {"£", "GBP"}, {"¥", "JPY"},
-                                            {"ƒ", "ANG"}, {"Дин.", "RSD"}, {"ден", "MKD"},
-                                            {"лв", "BGN"}, {"ман", "AZN"}, {"руб", "RUB"},
-                                            {"؋", "AFN"}, {"฿", "THB"}, {"៛", "KHR"},
-                                            {"₡", "CRC"}, {"₤", "TRL"}, {"₦", "NGN"},
-                                            {"₨", "PKR"}, {"₩", "KRW"}, {"₪", "ILS"},
-                                            {"₫", "VND"}, {"€", "EUR"}, {"₭", "LAK"},
-                                            {"₮", "MNT"}, {"₱", "CUP"}, {"₴", "UAH"},
-                                            {"﷼", "SAR"}, 
-}; 
-    
-	public static BigDecimal parseBalance(String balance) {
-		//balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
-		//balance = balance.replaceAll("[a-zA-Z]*", "");
-		//balance = balance.replaceAll("\\s*", "");
-		balance = balance.replaceAll("[^0-9,.-]*", "");
-		balance = balance.replace(",", ".");
-		if (balance.indexOf(".") != balance.lastIndexOf(".")) {
-			String b = balance.substring(balance.lastIndexOf("."));
-			balance = balance.substring(0, balance.lastIndexOf("."));
-			balance = balance.replace(".", "");
-			balance = balance+b;
-		}
-		BigDecimal ret;
-		try {
-			ret = new BigDecimal(balance);
-		}
-		catch (NumberFormatException e) {
-			ret = new BigDecimal(0);
-		}
-		return ret;
-	}
-	public static String formatBalance(BigDecimal balance, String curr) {
-		DecimalFormatSymbols dfs = new DecimalFormatSymbols();
-		dfs.setDecimalSeparator(',');
-		dfs.setGroupingSeparator(' ');
-		DecimalFormat currency = new DecimalFormat("#,##0.00 ");
-		currency.setDecimalFormatSymbols(dfs);
-		return currency.format(balance.doubleValue())+curr;
-	}
-	public static String formatBalance(Double balance, String curr) {
-		return formatBalance(new BigDecimal(balance), curr);
-	}
-	
-	public static void slowDebug(String TAG, String text) {
-	    for (String s : text.split("\n")) {
-	        Log.d(TAG, s);
-	        try {
+        {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"},
+        {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"},
+        {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"},
+        {"Bs", "VEF"}, {"Ft", "HUF"}, {"Gs", "PYG"},
+        {"KM", "BAM"}, {"Kč", "CZK"}, {"Lek", "ALL"},
+        {"S/.", "PEN"}, {"Ls", "LVL"}, {"Lt", "LTL"},
+        {"MT", "MZN"}, {"Php", "PHP"}, {"RM", "MYR"},
+        {"Rp", "IDR"}, {"TL", "TRY"}, {"kn", "HRK"},
+        {"kr", "SEK"}, {"lei", "RON"}, {"p.", "BYR"},
+        {"L", "HNL"}, {"S", "SOS"}, {"P", "BWP"},
+        {"Q", "GTQ"}, {"R", "ZAR"}, {"zł", "PLN"},
+        {"¢", "GHC"}, {"£", "GBP"}, {"¥", "JPY"},
+        {"ƒ", "ANG"}, {"Дин.", "RSD"}, {"ден", "MKD"},
+        {"лв", "BGN"}, {"ман", "AZN"}, {"руб", "RUB"},
+        {"؋", "AFN"}, {"฿", "THB"}, {"៛", "KHR"},
+        {"₡", "CRC"}, {"₤", "TRL"}, {"₦", "NGN"},
+        {"₨", "PKR"}, {"₩", "KRW"}, {"₪", "ILS"},
+        {"₫", "VND"}, {"€", "EUR"}, {"₭", "LAK"},
+        {"₮", "MNT"}, {"₱", "CUP"}, {"₴", "UAH"},
+        {"﷼", "SAR"}, 
+    }; 
+
+    public static BigDecimal parseBalance(String balance) {
+        //balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
+        //balance = balance.replaceAll("[a-zA-Z]*", "");
+        //balance = balance.replaceAll("\\s*", "");
+        balance = balance.replaceAll("[^0-9,.-]*", "");
+        balance = balance.replace(",", ".");
+        if (balance.indexOf(".") != balance.lastIndexOf(".")) {
+            String b = balance.substring(balance.lastIndexOf("."));
+            balance = balance.substring(0, balance.lastIndexOf("."));
+            balance = balance.replace(".", "");
+            balance = balance+b;
+        }
+        BigDecimal ret;
+        try {
+            ret = new BigDecimal(balance);
+        }
+        catch (NumberFormatException e) {
+            ret = new BigDecimal(0);
+        }
+        return ret;
+    }
+    public static String formatBalance(BigDecimal balance, String curr, boolean round) {
+        DecimalFormatSymbols dfs = new DecimalFormatSymbols();
+        dfs.setDecimalSeparator(',');
+        dfs.setGroupingSeparator(' ');
+        DecimalFormat currency;
+        if (!round) {
+            currency = new DecimalFormat("#,##0.00 ");
+        }
+        else {
+            currency = new DecimalFormat("#,##0 ");  
+        }
+        currency.setDecimalFormatSymbols(dfs);
+        return currency.format(balance.doubleValue())+curr;
+    }
+    public static String formatBalance(BigDecimal balance, String curr) {
+        return formatBalance(balance, curr, false);
+    }
+    public static String formatBalance(Double balance, String curr) {
+        return formatBalance(new BigDecimal(balance), curr);
+    }
+
+    public static void slowDebug(String TAG, String text) {
+        for (String s : text.split("\n")) {
+            Log.d(TAG, s);
+            try {
                 Thread.sleep(100);
             }
             catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
-	    }
-	}
-	
-	static public void setActivityAnimation(Activity activity, int in, int out) {
-	    try {
-	        Method method = Activity.class.getMethod("overridePendingTransition", new Class[]{int.class, int.class});
-	        method.invoke(activity, in, out);
-	    } catch (Exception e) {
-	        // Can't change animation, so do nothing
-	    }
-	}
-	
-	public static String parseCurrency(String text, String def) {
-	    for (String currency : currencies) {
-	        if (text.contains(currency)) return currency;
-	    }
+        }
+    }
+
+    static public void setActivityAnimation(Activity activity, int in, int out) {
+        try {
+            Method method = Activity.class.getMethod("overridePendingTransition", new Class[]{int.class, int.class});
+            method.invoke(activity, in, out);
+        } catch (Exception e) {
+            // Can't change animation, so do nothing
+        }
+    }
+
+    public static String parseCurrency(String text, String def) {
+        for (String currency : currencies) {
+            if (text.contains(currency)) return currency;
+        }
         for (String[] symCur : symMappings) {
             if (text.contains(symCur[0])) return symCur[1];
         }
-	    return def;
-	}
-	
+        return def;
+    }
+
 }

commit a6c6512f7d2c5fc27d4a623d239e907ca038f2f4
Author: liato <x@x00.us>
Date:   Fri Dec 10 15:23:30 2010 +0100

    Added support for Steam Wallet.

diff --git res/drawable/logo_steam.png res/drawable/logo_steam.png
new file mode 100644
index 0000000..5dac35c
Binary files /dev/null and res/drawable/logo_steam.png differ
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index aee2d90..55fa3c8 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -24,6 +24,7 @@ import com.liato.bankdroid.banks.OKQ8;
 import com.liato.bankdroid.banks.PayPal;
 import com.liato.bankdroid.banks.Payson;
 import com.liato.bankdroid.banks.Statoil;
+import com.liato.bankdroid.banks.Steam;
 import com.liato.bankdroid.banks.Swedbank;
 import com.liato.bankdroid.banks.TestBank;
 import com.liato.bankdroid.banks.Villabanken;
@@ -68,6 +69,8 @@ public class BankFactory {
             return new Payson(context);
         case Bank.JOJO:
             return new Jojo(context);
+        case Bank.STEAM:
+            return new Steam(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -93,6 +96,7 @@ public class BankFactory {
         banks.add(new PayPal(context));
         banks.add(new Payson(context));
         banks.add(new Jojo(context));
+        banks.add(new Steam(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banks/Steam.java src/com/liato/bankdroid/banks/Steam.java
new file mode 100644
index 0000000..582d8af
--- /dev/null
+++ src/com/liato/bankdroid/banks/Steam.java
@@ -0,0 +1,136 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class Steam extends Bank {
+	private static final String TAG = "Steam";
+	private static final String NAME = "Steam Wallet";
+	private static final String NAME_SHORT = "steam";
+	private static final String URL = "https://store.steampowered.com/login/?redir=account";
+	private static final int BANKTYPE_ID = Bank.STEAM;
+	private static final boolean STATIC_BALANCE = true;
+	
+    private Pattern reBalance = Pattern.compile("accountBalance\">\\s*<div[^>]+>([^<]+)</div>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("(?:even|odd)\">\\s*<div\\s*class=\"transactionRowDate\">([^<]+)</div>\\s*<div.*?RowPrice\">([^<]+)</div>\\s*<div.*?RowEvent\">([^<]+)</div>.*?RowTitle\">([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private String response = null;
+	
+	public Steam(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.STATIC_BALANCE = STATIC_BALANCE;
+	}
+
+	public Steam(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		try {
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("redir", "account"));
+            postData.add(new BasicNameValuePair("username", username));
+            postData.add(new BasicNameValuePair("password", password));
+			response = urlopen.open("https://store.steampowered.com/login/", postData);
+            if (response.contains("Enter the characters above")) {
+                throw new BankException("You have entered the wrong username/password too many times and Steam now requires you to enter a CAPTCHA.\nPlease wait 10 minutes before logging in again.");
+            }
+			if (response.contains("Incorrect login.")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		Matcher matcher = reBalance.matcher(response);
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: Amount            0,--&#8364;
+             * 
+             */
+		    String amount = Html.fromHtml(matcher.group(1)).toString().trim();
+		    Account account = new Account("Wallet", Helpers.parseBalance(amount), "1");
+		    String currency = Helpers.parseCurrency(amount, "USD");
+		    this.setCurrency(currency);
+		    account.setCurrency(currency);
+		    balance = balance.add(Helpers.parseBalance(amount));
+		    ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+		    matcher = reTransactions.matcher(response);
+		    while (matcher.find()) {
+	            /*
+	             * Capture groups:
+	             * GROUP                EXAMPLE DATA
+	             * 1: Date              18 Oct 2007
+	             * 2: Amount            &#36;62.44
+	             * 3: Event             Purchase
+	             * 4: Item              The Orange Box
+	             * 
+	             */
+                SimpleDateFormat sdfFrom = new SimpleDateFormat("d MMM yyyy");
+                SimpleDateFormat sdfTo = new SimpleDateFormat("yyyy-MM-dd");
+		        Date transactionDate;
+                try {
+                    transactionDate = sdfFrom.parse(matcher.group(1).trim());
+                    String strDate = sdfTo.format(transactionDate);
+                    transactions.add(new Transaction(strDate,
+                                                     Html.fromHtml(matcher.group(4)).toString().trim(),
+                                                     Helpers.parseBalance(Html.fromHtml(matcher.group(2)).toString().trim()),
+                                                     Helpers.parseCurrency(Html.fromHtml(matcher.group(2)).toString().trim(), "USD")));
+                }
+                catch (ParseException e) {
+                    Log.d(TAG, "Unable to parse date: " + matcher.group(1).trim());
+                }
+		    }
+		    account.setTransactions(transactions);
+		    accounts.add(account);
+		}
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
+        }		
+        super.updateComplete();
+	}
+}

commit 9a44db6b4530f5faa5a14045b553fc90cc4e2ff4
Author: liato <x@x00.us>
Date:   Fri Dec 10 15:22:43 2010 +0100

    Added currency parser.

diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 376333b..8e15b4b 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -9,6 +9,52 @@ import android.app.Activity;
 import android.util.Log;
 
 public class Helpers {
+    private final static String[] currencies = {"AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD",
+                                         "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF",
+                                         "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYR",
+                                         "BZD", "CAD", "CDF", "CHF", "CLP", "CNY", "COP", "CRC",
+                                         "CUP", "CVE", "CYP", "CZK", "DJF", "DKK", "DOP", "DZD",
+                                         "EEK", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP",
+                                         "GEL", "GGP", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
+                                         "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "IMP",
+                                         "INR", "IQD", "IRR", "ISK", "JEP", "JMD", "JOD", "JPY",
+                                         "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD",
+                                         "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LVL",
+                                         "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP",
+                                         "MRO", "MTL", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN",
+                                         "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB",
+                                         "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON",
+                                         "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK",
+                                         "SGD", "SHP", "SLL", "SOS", "SPL", "SRD", "STD", "SVC",
+                                         "SYP", "SZL", "THB", "TJS", "TMM", "TND", "TOP", "TRY",
+                                         "TTD", "TVD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU",
+                                         "UZS", "VEB", "VEF", "VND", "VUV", "WST", "XAF", "XAG",
+                                         "XAU", "XCD", "XDR", "XOF", "XPD", "XPF", "XPT", "YER",
+                                         "ZAR", "ZMK", "ZWD"};
+
+    private final static String[][] symMappings = {{"$U", "UYU"}, {"$b", "BOB"}, {"BZ$", "BZD"},
+                                            {"C$", "NIO"}, {"J$", "JMD"}, {"NT$", "TWD"},
+                                            {"R$", "BRL"}, {"RD$", "DOP"}, {"TT$", "TTD"},
+                                            {"Z$", "ZWD"}, {"$", "USD"}, {"B/.", "PAB"},
+                                            {"Bs", "VEF"}, {"Ft", "HUF"}, {"Gs", "PYG"},
+                                            {"KM", "BAM"}, {"Kč", "CZK"}, {"Lek", "ALL"},
+                                            {"S/.", "PEN"}, {"Ls", "LVL"}, {"Lt", "LTL"},
+                                            {"MT", "MZN"}, {"Php", "PHP"}, {"RM", "MYR"},
+                                            {"Rp", "IDR"}, {"TL", "TRY"}, {"kn", "HRK"},
+                                            {"kr", "SEK"}, {"lei", "RON"}, {"p.", "BYR"},
+                                            {"L", "HNL"}, {"S", "SOS"}, {"P", "BWP"},
+                                            {"Q", "GTQ"}, {"R", "ZAR"}, {"zł", "PLN"},
+                                            {"¢", "GHC"}, {"£", "GBP"}, {"¥", "JPY"},
+                                            {"ƒ", "ANG"}, {"Дин.", "RSD"}, {"ден", "MKD"},
+                                            {"лв", "BGN"}, {"ман", "AZN"}, {"руб", "RUB"},
+                                            {"؋", "AFN"}, {"฿", "THB"}, {"៛", "KHR"},
+                                            {"₡", "CRC"}, {"₤", "TRL"}, {"₦", "NGN"},
+                                            {"₨", "PKR"}, {"₩", "KRW"}, {"₪", "ILS"},
+                                            {"₫", "VND"}, {"€", "EUR"}, {"₭", "LAK"},
+                                            {"₮", "MNT"}, {"₱", "CUP"}, {"₴", "UAH"},
+                                            {"﷼", "SAR"}, 
+}; 
+    
 	public static BigDecimal parseBalance(String balance) {
 		//balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
 		//balance = balance.replaceAll("[a-zA-Z]*", "");
@@ -64,4 +110,14 @@ public class Helpers {
 	    }
 	}
 	
+	public static String parseCurrency(String text, String def) {
+	    for (String currency : currencies) {
+	        if (text.contains(currency)) return currency;
+	    }
+        for (String[] symCur : symMappings) {
+            if (text.contains(symCur[0])) return symCur[1];
+        }
+	    return def;
+	}
+	
 }

commit f8eca563a2f661c28b6ed35f61c13f86edc66233
Author: liato <x@x00.us>
Date:   Fri Dec 10 12:14:35 2010 +0100

    Version 1.5.0-RC1

diff --git AndroidManifest.xml AndroidManifest.xml
index 57529e2..93a3292 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="18" android:versionName="1.5.0">
+	android:versionName="1.5.0-RC1" android:versionCode="48">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"

commit 5f5963670f95c341d789e02265c42cda28263155
Author: liato <x@x00.us>
Date:   Fri Dec 10 12:12:25 2010 +0100

    Added support for Jojo Reskassa. Bump version to 1.5.0.

diff --git AndroidManifest.xml AndroidManifest.xml
index cd324e4..57529e2 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.4.4" android:versionCode="47">
+	android:versionCode="18" android:versionName="1.5.0">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/drawable/logo_jojo.png res/drawable/logo_jojo.png
new file mode 100644
index 0000000..a232ae2
Binary files /dev/null and res/drawable/logo_jojo.png differ
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index d0458ac..e1e5bc8 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -27,8 +27,10 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int EUROCARD = 13;
 	public final static int FIRSTCARD = 14;
 	public final static int PAYPAL = 15;
-	public final static int PAYSON = 16;
-
+    public final static int PAYSON = 16;
+    public final static int JOJO = 17;
+    public final static int IKANO = 18;
+    public final static int STEAM = 19;
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index f70a647..aee2d90 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -17,6 +17,7 @@ import com.liato.bankdroid.banks.FirstCard;
 import com.liato.bankdroid.banks.Handelsbanken;
 import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
+import com.liato.bankdroid.banks.Jojo;
 import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
 import com.liato.bankdroid.banks.OKQ8;
@@ -65,6 +66,8 @@ public class BankFactory {
             return new PayPal(context);
         case Bank.PAYSON:
             return new Payson(context);
+        case Bank.JOJO:
+            return new Jojo(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -89,6 +92,7 @@ public class BankFactory {
         banks.add(new FirstCard(context));
         banks.add(new PayPal(context));
         banks.add(new Payson(context));
+        banks.add(new Jojo(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 620cc2d..1d2d251 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -35,7 +35,7 @@ public class Handelsbanken extends Bank {
 	private static final String URL = "https://m.handelsbanken.se/";
 	private static final int BANKTYPE_ID = Bank.HANDELSBANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
-    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
 	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
@@ -50,7 +50,7 @@ public class Handelsbanken extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		//super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
diff --git src/com/liato/bankdroid/banks/Jojo.java src/com/liato/bankdroid/banks/Jojo.java
new file mode 100644
index 0000000..c6a785a
--- /dev/null
+++ src/com/liato/bankdroid/banks/Jojo.java
@@ -0,0 +1,150 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class Jojo extends Bank {
+	private static final String TAG = "Jojo";
+	private static final String NAME = "Jojo Reskassa";
+	private static final String NAME_SHORT = "jojo";
+	private static final String URL = "https://www.skanetrafiken.se/templates/MSRootPage.aspx?id=2935&epslanguage=SV";
+	private static final int BANKTYPE_ID = Bank.JOJO;
+	
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reAccounts = Pattern.compile("1_mRepeaterMyCards_ctl(\\d{2,3})_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>\\s*</td>\\s*<td[^>]+>\\s*<a\\s*id=\"ctl00_fullRegion_mainRegion_CardInformation1_mRepeaterMyCards_ctl\\d{2,3}_LinkButton\\d{1,3}\"[^>]+>([^<]+)</a>", Pattern.CASE_INSENSITIVE);
+    private Pattern reBalance = Pattern.compile("labelsaldoinfo\">([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	
+	public Jojo(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Jojo(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		Matcher matcher;
+		
+		try {
+			response = urlopen.open("http://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV");
+            matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            }
+            String strViewState = matcher.group(1);
+
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+            postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Username", username));
+            postData.add(new BasicNameValuePair("ctl00$LoginBlob1$Password", password));
+            postData.add(new BasicNameValuePair("ctl00$LoginBlob1$LoginButton", "Logga in"));
+           
+			response = urlopen.open("https://www.skanetrafiken.se/templates/StartPage.aspx?id=2182&epslanguage=SV", postData);
+
+			if (response.contains("Inloggningen misslyckades")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+		    response = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV");
+			Matcher matcher;
+			Matcher matcher_b;
+			matcher = reViewState.matcher(response);
+			if (!matcher.find()) {
+			    throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+			}			
+            String strViewState = matcher.group(1);
+
+            matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: ID                01
+                 * 2: Name              Nytt
+                 * 3: Card number       1111111111
+                 * 
+                 */
+			    
+	            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+	            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+	            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+	            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+	            postData.add(new BasicNameValuePair("ctl00$fullRegion$mainRegion$CardInformation1$mRepeaterMyCards$ctl" + matcher.group(1) + "$Button", "Kortinfo"));
+                String accinfo = urlopen.open("https://www.skanetrafiken.se/templates/CardInformation.aspx?id=26957&epslanguage=SV", postData);
+			    
+                matcher_b = reBalance.matcher(accinfo);
+                if (matcher_b.find()) {
+                    /*
+                     * Capture groups:
+                     * GROUP                EXAMPLE DATA
+                     * 1: Amount            592,80 kr
+                     * 
+                     */
+                    
+                    accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim() , Helpers.parseBalance(matcher_b.group(1)), matcher.group(1)));
+                    balance = balance.add(Helpers.parseBalance(matcher_b.group(1)));
+                }
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+        catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }		
+        finally {
+            super.updateComplete();
+        }
+	}
+}

commit f9ac58311b4191051d7a691eb46724f9ff1927a4
Author: liato <x@x00.us>
Date:   Fri Dec 10 10:45:40 2010 +0100

    Display more account info for Statoil.

diff --git logos.psd logos.psd
index 4dc9df1..9bfcc0d 100644
Binary files logos.psd and logos.psd differ
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 92336ac..620cc2d 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -50,7 +50,7 @@ public class Handelsbanken extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		//super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index f33e37e..67c0d0f 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid.banks;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -33,8 +34,9 @@ public class Statoil extends Bank {
 	private static final int BANKTYPE_ID = Bank.STATOIL;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final boolean STATIC_BALANCE = true;
 
-	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunitlastdisposableamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunit(?:last(?:disposable|credit)amount|2rowcol2)\">([^<]+)</(?:div|td)>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*(?:<div[^>]+>\\s*)?<span>([^<]*)</span>\\s*(?:</div>\\s*)?</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	public Statoil(Context context) {
@@ -46,6 +48,7 @@ public class Statoil extends Bank {
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
 	public Statoil(String username, String password, Context context) throws BankException, LoginException {
@@ -100,18 +103,29 @@ public class Statoil extends Bank {
 				response = urlopen.open("https://applications.sebkort.com/nis/stse/main.do");
 			}
 			matcher = reAccounts.matcher(response);
+            /*
+             * Capture groups:
+             * GROUP                EXAMPLE DATA
+             * 1: amount            10 579,43
+             * 
+             */
 			if (matcher.find()) {
-				/*
-				 * Capture groups:
-				 * GROUP				EXAMPLE DATA
-				 * 1: amount			10 579,43
-				 * 
-				 */
-			    Account account = new Account("Statoil MasterCard" , Helpers.parseBalance(matcher.group(1)), "1");
-			    account.setType(Account.CCARD);
-				accounts.add(account);
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			    Account account = new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3");
+			    account.setType(Account.OTHER);
+			    accounts.add(account);
 			}
+            if (matcher.find()) {
+                Account account = new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2");
+                account.setType(Account.OTHER);
+                accounts.add(account);
+            }
+            if (matcher.find()) {
+                Account account = new Account("Disponibelt belopp" , Helpers.parseBalance(matcher.group(1)), "1");
+                account.setType(Account.CCARD);
+                accounts.add(account);
+                balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+            }
+            Collections.reverse(accounts);
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
@@ -133,6 +147,7 @@ public class Statoil extends Bank {
 		if (!urlopen.acceptsInvalidCertificates()) { //Should never happen, but we'll check it anyway.
 			urlopen = login();
 		}
+		if (account.getType() != Account.CCARD) return;
 		String response = null;
 		Matcher matcher;
 		try {
@@ -145,8 +160,8 @@ public class Statoil extends Bank {
 				/*
 				 * Capture groups:
 				 * GROUP				EXAMPLE DATA
-				 * 1: Date				10-18
-				 * 2: Date				10-19
+				 * 1: Trans. date		10-18
+				 * 2: Book. date		10-19
 				 * 3: Specification		ICA Kvantum
 				 * 4: Location			Stockholm
 				 * 5: Currency			always empty?

commit dd9498f2a7a2633f0ca9655f02a3bc397bf5ee32
Author: liato <x@x00.us>
Date:   Fri Dec 10 10:42:27 2010 +0100

    Correct url for medmera konto hopefully.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index e17753a..c3a8292 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -129,7 +129,7 @@ public class Coop extends Bank {
             }                
         }
         try {
-            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/MedMera-Konto/");
             matcher = reBalanceKonto.matcher(response);
             if (matcher.find()) {
                 account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");

commit f3b9a868b7db8c9093f69189f5cbec0b6a68f8ba
Author: liato <x@x00.us>
Date:   Wed Dec 8 05:57:56 2010 +0100

    Improved handling of widget clicks when blurred. Open transaction history for selected account on widget click.

diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index 18a8e92..f6e4cc6 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -26,6 +26,8 @@ public class AutoRefreshService extends Service {
     final static String BROADCAST_REMOTE_NOTIFIER = "org.damazio.notifier.service.UserReceiver.USER_MESSAGE";
     final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
     final static String BROADCAST_OPENWATCH_VIBRATE = "com.smartmadsoft.openwatch.action.VIBRATE";
+    final static String ACTION_MAIN_SHOW_TRANSACTIONS = "com.liato.bankdroid.action.MAIN_SHOW_TRANSACTIONS";
+    
     NotificationManager notificationManager;
 
     @Override
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index e9b5cb6..5a3a9b0 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -1,6 +1,5 @@
 package com.liato.bankdroid;
 
-import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.appwidget.AppWidgetManager;
@@ -14,8 +13,6 @@ import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Message;
-import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
 import android.view.View;
@@ -134,9 +131,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			views.setViewVisibility(R.id.frmWarning, View.INVISIBLE);
 		}
 		Intent intent = new Intent(context, MainActivity.class);
-		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
-		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
+		PendingIntent pendingIntent;
 
 		//intent = new Intent(context, AccountsActivity.class);
 		pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
@@ -162,13 +157,23 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
             views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE);
-            views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE);          
+            views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE);
+            views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
         }
         else {
             views.setViewVisibility(R.id.imgBalanceblur, View.GONE);
             views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.GONE);
             views.setViewVisibility(R.id.txtWidgetAccountbalance, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE);            
+
+            intent = new Intent(context, MainActivity.class);
+            intent.setAction(AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS);
+            intent.setData(Uri.parse("rofl://copter/showtransactions/"+appWidgetId+"/"+System.currentTimeMillis()));
+            intent.putExtra("bank", bank.getDbId());
+            intent.putExtra("account", account.getId());
+            pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+            views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
+            views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);        
         }
 
 		return views;
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 741e3f5..46bf503 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -39,9 +39,9 @@ public class MainActivity extends LockableActivity {
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-        //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
 
-        setContentView(R.layout.main);
+
+		setContentView(R.layout.main);
         Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
 		btnRefresh.setOnClickListener(new View.OnClickListener() {
 			public void onClick(View v) {
@@ -91,6 +91,16 @@ public class MainActivity extends LockableActivity {
 				}
 			}
 		});
+		
+		Bundle extras = getIntent().getExtras();
+		// Clicking on widgets opens their transaction history through MainActivity so that
+		// the user can back out to the main window.
+		if (AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS.equals(getIntent().getAction())) {
+            Intent intent = new Intent(this, TransactionsActivity.class);
+            intent.putExtra("account", extras.getString("account"));
+            intent.putExtra("bank", extras.getLong("bank"));
+            startActivity(intent);		    
+		}
 	}
 	
 	public void onResume() {

commit 4c565d04829c741180b95ea74716fb3a395c3f3a
Author: liato <x@x00.us>
Date:   Wed Dec 8 05:19:59 2010 +0100

    Updated thanks.

diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 08b47fb..45a1542 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -101,6 +101,7 @@
 	\ncola (OKQ8)
 	\nRikko (FirstCard)
 	\nnihplod (Eurocard)
+	\nDaniel (Avanza)
     </string>
     
 
diff --git res/values/strings.xml res/values/strings.xml
index f73756f..720abea 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -102,6 +102,7 @@
 	\ncola (OKQ8)
 	\nRikko (FirstCard)
 	\nNihplod (Eurocard)
+	\nDaniel (Avanza)
      </string>
      
      

commit a2fdaedda8275d3f37bbc54078415790867754ea
Author: liato <x@x00.us>
Date:   Wed Dec 8 05:19:18 2010 +0100

    Fix for Avanza, forgot the new regex last time.

diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index ba3dcec..e38f1eb 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -33,7 +33,7 @@ public class Avanza extends Bank {
     private static final int BANKTYPE_ID = Bank.AVANZA;
     private static final boolean BROKEN = true;
 	
-	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=([^\"]+)[^>]+>[^<]+</a>\\s*</td>\\s*<td[^>]+>([^<]+)<.*?<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	public Avanza(Context context) {
 		super(context);

commit 73583e24c2c2c1d4e0f69730e05d2fa98d90eed7
Author: liato <x@x00.us>
Date:   Wed Dec 8 05:18:57 2010 +0100

    Fix for Avanza.

diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 092c638..ba3dcec 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -50,14 +50,12 @@ public class Avanza extends Bank {
 		this.update(username, password);
 	}
 
-	/*
+	
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib(true, true);
 		String response = null;
 		try {
-			//response = urlopen.open("https://www.avanza.se/aza/login/logout.jsp");
-
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			postData.add(new BasicNameValuePair("username", username));
 			postData.add(new BasicNameValuePair("password", password));
@@ -75,16 +73,11 @@ public class Avanza extends Bank {
 		}
 		return urlopen;
 	}
-	*/
+	
 	
 	@Override
 	public void update() throws BankException, LoginException {
 		super.update();
-		throw new BankException("The implementation of this bank is currently broken.\n" +
-				                "To fix this problem help is needed from you, Avanza users. " +
-				                "Please read the first post at\n" +
-				                "http://j.mp/9GRlt1 for instructions on how you can help.");
-		/*
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
@@ -97,7 +90,16 @@ public class Avanza extends Bank {
 						
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: ID                3505060
+                 * 2: Type              Aktie- och fondkonto Premium Silver
+                 * 3: % since purchase  1,90
+                 * 4: Amount in SEK     820
+                 *    
+                 */    
+			    accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
 			if (accounts.isEmpty()) {
@@ -113,11 +115,9 @@ public class Avanza extends Bank {
         finally {
             super.updateComplete();
         }
-        */
 	}
 
 	
-	/*
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
@@ -134,7 +134,6 @@ public class Avanza extends Bank {
 			strDate = sdf.format(cal.getTime());
 
 			while (matcher.find()) {
-				//Log.d(TAG, "Date: "+strDate+"; Trans: "+Html.fromHtml(matcher.group(2)).toString().trim()+"; Amount: "+Helpers.parseBalance(matcher.group(3)).toString());
 				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2))));
 			}
 			account.setTransactions(transactions);
@@ -146,5 +145,4 @@ public class Avanza extends Bank {
 			e.printStackTrace();
 		}
 	}
-	*/
 }
\ No newline at end of file

commit edfe1de7f4dd4af2840dee9eb5d100a81ac05a70
Author: liato <x@x00.us>
Date:   Wed Dec 8 04:26:16 2010 +0100

    Coop half-fixed, transactions history url for "medmera konto" is still missing.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 252b517..e17753a 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -79,7 +79,7 @@ public class Coop extends Bank {
                 if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_coop_sendmail", false)) {
                     Intent i = new Intent(android.content.Intent.ACTION_SEND);
                     i.setType("plain/text");
-                    i.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"android@x00.us"});
+                    i.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"android@nullbyte.eu"});
                     i.putExtra(android.content.Intent.EXTRA_SUBJECT, "Bankdroid - Coop Error");
                     i.putExtra(android.content.Intent.EXTRA_TEXT, response);
                     context.startActivity(i);
@@ -105,12 +105,12 @@ public class Coop extends Bank {
 
         urlopen = login();
         Matcher matcher;
-        try {
-            Account account;
-            matcher = reBalanceVisa.matcher(response);
-            if (matcher.find()) {
-                account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
-                balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+        Account account;
+        matcher = reBalanceVisa.matcher(response);
+        if (matcher.find()) {
+            account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
+            balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+            try {
                 response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
                 matcher = reTransactionsVisa.matcher(response);
                 ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -121,6 +121,14 @@ public class Coop extends Bank {
                 account.setTransactions(transactions);
                 accounts.add(account);
             }
+            catch (ClientProtocolException e) {
+                //404 or 500 response
+            }
+            catch (IOException e) {
+                throw new BankException(e.getMessage());
+            }                
+        }
+        try {
             response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
             matcher = reBalanceKonto.matcher(response);
             if (matcher.find()) {
@@ -134,19 +142,15 @@ public class Coop extends Bank {
                 }
                 account.setTransactions(transactions);
                 accounts.add(account);
-            }
-            if (accounts.isEmpty()) {
-                throw new BankException(res.getText(R.string.no_accounts_found).toString());
-            }
-        }
+            }        }
         catch (ClientProtocolException e) {
-            throw new BankException(e.getMessage());
+            //404 or 500 response
         }
         catch (IOException e) {
-            throw new BankException(e.getMessage());
-        }
-        finally {
-            super.updateComplete();
+        }            
+        if (accounts.isEmpty()) {
+            throw new BankException(res.getText(R.string.no_accounts_found).toString());
         }
+        super.updateComplete();
     }
 }
\ No newline at end of file

commit b6c39cc7cac09205451dcd83703eb35e3dc0dc33
Author: liato <x@x00.us>
Date:   Wed Dec 8 04:15:47 2010 +0100

    Improved account display for OKQ8.

diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index 575e72d..97d029b 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -31,12 +31,13 @@ import com.liato.urllib.Urllib;
 
 public class OKQ8 extends Bank {
 	private static final String TAG = "OKQ8";
-	private static final String NAME = "OKQ8";
+	private static final String NAME = "OKQ8 VISA";
 	private static final String NAME_SHORT = "okq8";
 	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
 	private static final int BANKTYPE_ID = Bank.OKQ8;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
+    private static final boolean STATIC_BALANCE = true;
 	
 	private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
 	private Pattern reBalance = Pattern.compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
@@ -52,6 +53,7 @@ public class OKQ8 extends Bank {
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
 	public OKQ8(String username, String password, Context context) throws BankException, LoginException {
@@ -158,10 +160,31 @@ public class OKQ8 extends Bank {
 			 */
 			Matcher matcher;
 			matcher = reBalance.matcher(response);
-			if (matcher.find()) {
-				accounts.add(new Account("OKQ8 VISA" , Helpers.parseBalance(matcher.group(1)), "1"));
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			
+			/*
+			 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
+			 * The balance is the first value (of three) that are matched by reBalance expression.
+			 */
+			matcher = reBalance.matcher(response);
+			if(matcher.find())
+			{
+			    accounts.add(new Account("Kvar att utnyttja" , Helpers.parseBalance(matcher.group(1)), "1"));
+			    balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 			}
+			/*
+			 * Find the next value that is "Saldo". Add a new account but don't add to the balance.
+			 */
+			if(matcher.find())
+			{
+			    accounts.add(new Account("Saldo" , Helpers.parseBalance(matcher.group(1)), "2"));
+			}
+			/*
+			 * Find the next value that is "Köpgräns". Add a new account but don't add to the balance.
+			 */
+			if(matcher.find())
+			{
+			    accounts.add(new Account("Köpgräns" , Helpers.parseBalance(matcher.group(1)), "3"));
+			}			
 			
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());

commit 3bb5a9d734cff6523bb7b933cfd6ce8c736b7682
Author: liato <x@x00.us>
Date:   Wed Dec 8 04:15:16 2010 +0100

    Added transaction history to lansforsakringar that probably wont work.

diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index 64abdca..b65b7d6 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -2,7 +2,6 @@ package com.liato.bankdroid.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -22,6 +21,7 @@ import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 public class Lansforsakringar extends Bank {
@@ -38,8 +38,11 @@ public class Lansforsakringar extends Bank {
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reBalance = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
-	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactions = Pattern.compile("td\\s*class=\"leftpadding\"[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span>\\s*<a.*?</a></td><td[^>]+><span[^>]+>(\\d{4}-\\d{2}-\\d{2})</span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+><span[^>]+>([^<]*)</span></span></td><td[^>]+><span[^>]+>([^<]+)</span></td><td[^>]+><span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private String accountsUrl = null;
+	private String token = null;
+	
 	public Lansforsakringar(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -86,9 +89,7 @@ public class Lansforsakringar extends Bank {
 			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
 			postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
 			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
-			Log.d("Bankdroid", "Posting data to: " + urlopen.getCurrentURI());
 			response = urlopen.open(urlopen.getCurrentURI(), postData);
-			String a = "https://secure246.lansforsakringar.se:443/lfportal/appmanager/privat/main?_nfpb=true&amp;_pageLabel=bank&newUc=true&isTopLevel=true";
 
 			if (response.contains("Felaktig inloggning")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -98,7 +99,7 @@ public class Lansforsakringar extends Bank {
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
 			}
-			String token = matcher.group(1);
+			token = matcher.group(1);
 
 			matcher = reUrl.matcher(response);
 			if (!matcher.find()) {
@@ -108,7 +109,7 @@ public class Lansforsakringar extends Bank {
 			if (!accountsUrl.contains("https://")) {
 			    accountsUrl = "https://" + urlopen.getCurrentURI().split("/")[2] + accountsUrl;
 			}
-			Log.d("Bankdroid", "Accounts url: " + accountsUrl);
+
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
@@ -154,4 +155,43 @@ public class Lansforsakringar extends Bank {
             super.updateComplete();
         }
 	}
+	
+    @Override
+    public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+        super.updateTransactions(account, urlopen);
+        String response = null;
+        Matcher matcher;
+        try {
+ 
+            response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&dialog=dialog:account.viewAccountTransactions&webapp=edb-account-web&stickyMenu=false&newUc=true&AccountNumber=" + account.getId() + "&_token=" + token);
+            matcher = reTransactions.matcher(response);
+            ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Book. date        2009-05-03
+                 * 2: Trans. date       2009-05-03
+                 * 3: Specification     &Ouml;verf&ouml;ring internet ...
+                 * 4: Note              829909945928712
+                 * 5: Amount            -54,00
+                 * 6: Remaining         0,00
+                 *   
+                 */                    
+                transactions.add(new Transaction(matcher.group(2).trim().substring(8),
+                                    Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " (" + Html.fromHtml(matcher.group(3)).toString().trim() + ")" : ""),
+                                    Helpers.parseBalance(matcher.group(5))));
+            }
+            account.setTransactions(transactions);
+        } catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        finally {
+            super.updateComplete();
+        }
+    }       	
 }
\ No newline at end of file

commit c04eab7520f414cf5ae7440e7e446c089b5fec93
Author: liato <x@x00.us>
Date:   Wed Dec 8 02:49:00 2010 +0100

    Changed request urls for ICABanken, should be working again.

diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index 82ebfe3..8164cc0 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -63,7 +63,7 @@ public class ICABanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx");
+			response = urlopen.open("https://mobil2.icabanken.se/login/login.aspx");
 			matcher = reViewState.matcher(response);
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
@@ -80,8 +80,7 @@ public class ICABanken extends Bank {
 			postData.add(new BasicNameValuePair("btnLogin", "Logga in"));
 			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
 			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx", postData);
-			Log.d("BankICA", urlopen.getCurrentURI());
+			response = urlopen.open("https://mobil2.icabanken.se/login/login.aspx", postData);
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
 				throw new LoginException(Html.fromHtml(matcher.group(1).trim()).toString());
@@ -109,8 +108,7 @@ public class ICABanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
-			Log.d("BankICA", urlopen.getCurrentURI());
+			response = urlopen.open("https://mobil2.icabanken.se/account/overview.aspx");
 			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_oversikt.htm");
 			matcher = reBalanceSald.matcher(response);
 			while (matcher.find()) {
@@ -140,9 +138,7 @@ public class ICABanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://mobil.icabanken.se/account/account.aspx?id="+account.getId());
-			response = urlopen.open("https://mobil.icabanken.se/account/account.aspx?id="+account.getId());
-			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_kontoutdrag.htm");
+			response = urlopen.open("https://mobil2.icabanken.se/account/account.aspx?id="+account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit b9ebb52aa9117368ee6a4ee2cc6ddc7386fce8d5
Author: liato <x@x00.us>
Date:   Tue Dec 7 04:27:08 2010 +0100

    Payson url was incorrect.

diff --git AndroidManifest.xml AndroidManifest.xml
index a66eaba..cd324e4 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="46" android:versionName="1.4.4-RC1">
+	android:versionName="1.4.4" android:versionCode="47">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/banks/Payson.java src/com/liato/bankdroid/banks/Payson.java
index c2c4133..cb4eac4 100644
--- src/com/liato/bankdroid/banks/Payson.java
+++ src/com/liato/bankdroid/banks/Payson.java
@@ -27,7 +27,7 @@ public class Payson extends Bank {
 	private static final String TAG = "Payson";
 	private static final String NAME = "Payson";
 	private static final String NAME_SHORT = "payson";
-	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
+	private static final String URL = "https://www.payson.se/signin/";
 	private static final int BANKTYPE_ID = Bank.PAYSON;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 	

commit ef5b42317b154ed000306cac8446d96b2d2721eb
Author: liato <x@x00.us>
Date:   Fri Nov 26 03:09:21 2010 +0100

    Swedish translation for widget blur settings.

diff --git AndroidManifest.xml AndroidManifest.xml
index 85fbb9f..a66eaba 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.4.3" android:versionCode="45">
+	android:versionCode="46" android:versionName="1.4.4-RC1">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/xml-sv/settings.xml res/xml-sv/settings.xml
index 145fb8a..f297c11 100644
--- res/xml-sv/settings.xml
+++ res/xml-sv/settings.xml
@@ -12,6 +12,19 @@
 			android:summary="Ändra ditt nuvarande grafiska lösenord"
 			android:key="patternlock_change"
 			android:dependency="patternlock_enabled" />
+		<CheckBoxPreference
+			android:key="widget_blur_balance"
+			android:defaultValue="false"
+			android:title="Dölj widgetsaldo"
+			android:summary="Saldot på widgeten visas endast då du klickat på den" />
+		<ListPreference
+			android:title="Dölj saldot efter"
+			android:key="widget_blur_balance_timeout"
+			android:defaultValue="5"
+			android:entries="@array/unblurTimeoutNames"
+			android:entryValues="@array/unblurTimeoutValues"
+			android:summary="Dölj saldot igen efter angiven tid"
+			android:dependency="widget_blur_balance" />
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="Automatiska Uppdateringar">
@@ -54,7 +67,7 @@
 			android:ringtoneType="notification"
 			android:showDefault="true"
 			android:showSilent="true"
-			
+
 			android:dependency="notify_on_change" />
 		<PreferenceScreen
 			android:key="account_types_screen"
@@ -148,8 +161,8 @@
 					android:defaultValue="false"
 					android:title="Coop - Mail on error"
 					android:summary="Open your email client with the html response when Bankdroid fails to login to your Coop account."
-					android:dependency="debug_mode" />					
+					android:dependency="debug_mode" />
 			</PreferenceScreen>
 		</PreferenceScreen>
-	</PreferenceCategory>	
+	</PreferenceCategory>
 </PreferenceScreen>
\ No newline at end of file
diff --git res/xml/settings.xml res/xml/settings.xml
index cb59399..7a6dbdf 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -16,14 +16,14 @@
 			android:key="widget_blur_balance"
 			android:defaultValue="false"
 			android:title="Blur widget balance"
-			android:summary="Blur the balance on the widget, click widget to unblur for a few seconds." />
+			android:summary="Blur the balance on the widget, click widget to unblur for a few seconds" />
 		<ListPreference
 			android:title="Unblur timeout"
 			android:key="widget_blur_balance_timeout"
 			android:defaultValue="5"
 			android:entries="@array/unblurTimeoutNames"
 			android:entryValues="@array/unblurTimeoutValues"
-			android:summary="Blur the balance again after this many seconds."
+			android:summary="Blur the balance again after this many seconds"
 			android:dependency="widget_blur_balance" />
 	</PreferenceCategory>
 	<PreferenceCategory

commit f632817da2409bc2adf06a825de7639148da5bb2
Author: liato <x@x00.us>
Date:   Fri Nov 26 02:50:18 2010 +0100

    Added support for Payson.

diff --git res/drawable-hdpi-v4/widget_large_balance_blured.png res/drawable-hdpi-v4/widget_large_balance_blurred.png
similarity index 100%
rename from res/drawable-hdpi-v4/widget_large_balance_blured.png
rename to res/drawable-hdpi-v4/widget_large_balance_blurred.png
diff --git res/drawable-hdpi-v4/widget_small_balance_blured.png res/drawable-hdpi-v4/widget_small_balance_blurred.png
similarity index 100%
rename from res/drawable-hdpi-v4/widget_small_balance_blured.png
rename to res/drawable-hdpi-v4/widget_small_balance_blurred.png
diff --git res/drawable/logo_payson.png res/drawable/logo_payson.png
new file mode 100644
index 0000000..e188f50
Binary files /dev/null and res/drawable/logo_payson.png differ
diff --git res/layout/widget.xml res/layout/widget.xml
index b5b143f..d42b09a 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -56,7 +56,7 @@
 		android:layout_marginTop="7dp">
 		<ImageView
 			android:id="@+id/imgBalanceblur"
-			android:src="@drawable/widget_small_balance_blured"
+			android:src="@drawable/widget_small_balance_blurred"
 			android:layout_gravity="center_vertical|center_horizontal"
 			android:layout_height="fill_parent"
 			android:layout_width="fill_parent"
diff --git res/layout/widget_large.xml res/layout/widget_large.xml
index 3221ad6..2fa6ca4 100644
--- res/layout/widget_large.xml
+++ res/layout/widget_large.xml
@@ -36,7 +36,7 @@
 				android:layout_toLeftOf="@+id/txtWidgetAccountbalance"
 				android:layout_width="wrap_content"
 				android:id="@+id/imgBalanceblur"
-				android:src="@drawable/widget_large_balance_blured"
+				android:src="@drawable/widget_large_balance_blurred"
 				android:paddingTop="8dp"
 				android:paddingRight="1dp"
 				android:adjustViewBounds="true"
diff --git res/layout/widget_large_transparent.xml res/layout/widget_large_transparent.xml
index 3078cb8..4d3253c 100644
--- res/layout/widget_large_transparent.xml
+++ res/layout/widget_large_transparent.xml
@@ -35,7 +35,7 @@
 				android:layout_toLeftOf="@+id/txtWidgetAccountbalance"
 				android:layout_width="wrap_content"
 				android:id="@+id/imgBalanceblur"
-				android:src="@drawable/widget_large_balance_blured"
+				android:src="@drawable/widget_large_balance_blurred"
 				android:paddingTop="8dp"
 				android:paddingRight="1dp"
 				android:adjustViewBounds="true"
diff --git res/layout/widget_transparent.xml res/layout/widget_transparent.xml
index b0466f4..1a8e3de 100644
--- res/layout/widget_transparent.xml
+++ res/layout/widget_transparent.xml
@@ -60,7 +60,7 @@
 		android:layout_marginTop="7dp">
 		<ImageView
 			android:id="@+id/imgBalanceblur"
-			android:src="@drawable/widget_small_balance_blured"
+			android:src="@drawable/widget_small_balance_blurred"
 			android:layout_gravity="center_vertical|center_horizontal"
 			android:layout_height="fill_parent"
 			android:layout_width="fill_parent"
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index f4f8952..d0458ac 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -27,7 +27,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int EUROCARD = 13;
 	public final static int FIRSTCARD = 14;
 	public final static int PAYPAL = 15;
-	public final static int Payson = 16;
+	public final static int PAYSON = 16;
 
 
 	protected String TAG = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index c4b6bcf..f70a647 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -21,6 +21,7 @@ import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
 import com.liato.bankdroid.banks.OKQ8;
 import com.liato.bankdroid.banks.PayPal;
+import com.liato.bankdroid.banks.Payson;
 import com.liato.bankdroid.banks.Statoil;
 import com.liato.bankdroid.banks.Swedbank;
 import com.liato.bankdroid.banks.TestBank;
@@ -62,6 +63,8 @@ public class BankFactory {
             return new FirstCard(context);
         case Bank.PAYPAL:
             return new PayPal(context);
+        case Bank.PAYSON:
+            return new Payson(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -85,6 +88,7 @@ public class BankFactory {
 		banks.add(new Eurocard(context));
         banks.add(new FirstCard(context));
         banks.add(new PayPal(context));
+        banks.add(new Payson(context));
         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
         if (prefs.getBoolean("debug_mode", false)) { 
             banks.add(new TestBank(context));
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index ee52b98..e9b5cb6 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -42,7 +42,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
             int appWidgetId) {
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);  
         Editor e = prefs.edit();
-        e.putBoolean("widget_unblured_"+appWidgetId, true);
+        e.putBoolean("widget_unblurred_"+appWidgetId, true);
         e.commit();
 
         RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
@@ -59,7 +59,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
             int appWidgetId) {
         SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);  
         Editor e = prefs.edit();
-        e.remove("widget_unblured_"+appWidgetId);
+        e.remove("widget_unblurred_"+appWidgetId);
         e.commit();
         RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
         if (views != null) {
@@ -158,7 +158,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
         views.setOnClickPendingIntent(R.id.imgBalanceblur, pendingIntent);
         
         SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
-        if (defprefs.getBoolean("widget_blur_balance", false) && !prefs.getBoolean("widget_unblured_" + appWidgetId, false)) {
+        if (defprefs.getBoolean("widget_blur_balance", false) && !prefs.getBoolean("widget_unblurred_" + appWidgetId, false)) {
             views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE);
             views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE);
diff --git src/com/liato/bankdroid/banks/Payson.java src/com/liato/bankdroid/banks/Payson.java
new file mode 100644
index 0000000..c2c4133
--- /dev/null
+++ src/com/liato/bankdroid/banks/Payson.java
@@ -0,0 +1,143 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class Payson extends Bank {
+	private static final String TAG = "Payson";
+	private static final String NAME = "Payson";
+	private static final String NAME_SHORT = "payson";
+	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
+	private static final int BANKTYPE_ID = Bank.PAYSON;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+	
+    private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reBalance = Pattern.compile("Saldo:\\s*<strong>([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("href=\"details/Default\\.aspx\\?\\d{1,}\">\\s*<span\\s*title=\"(\\d{4}-\\d{2}-\\d{2})[^\"]+\">.*?Grid1_0_3_\\d{1,}_Hy[^>]+>([^<]+)<.*?Grid1_0_5_\\d{1,}_Hy[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private String response = null;
+	
+	public Payson(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+	}
+
+	public Payson(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		Matcher matcher;
+		
+		try {
+			response = urlopen.open("https://www.payson.se/signin/");
+            matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
+            }
+            String strViewState = matcher.group(1);
+            matcher = reEventValidation.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
+            }
+            String strEventValidation = matcher.group(1);
+
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+            postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtEmail", username));
+            postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$txtPassword", password));
+            postData.add(new BasicNameValuePair("ctl00$MainContent$SignIn1$btnLogin", "Logga in"));
+			response = urlopen.open("https://www.payson.se/signin/", postData);
+			//Helpers.slowDebug(TAG, response);
+			
+			if (response.contains("Felaktig E-postadress") || response.contains("Lösenord saknas") ||
+			        response.contains("E-postadress saknas"))  {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+			Matcher matcher;
+			matcher = reBalance.matcher(response);
+			if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Balance           0,00 kr
+                 *  
+                 */			    
+				accounts.add(new Account("Konto" , Helpers.parseBalance(matcher.group(1)), "1"));
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+	
+	
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Date              2010-06-03
+                 * 2: Specification     Best&#228;llning fr&#229;n SPELKONTROLL.SE
+                 * 3: Amount            -228,00 kr
+                 *   
+                 */     
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			accounts.get(0).setTransactions(transactions);
+		}		
+        finally {
+            super.updateComplete();
+        }
+	}
+}

commit 0a067c43c4169790ab750634fab5a418cd2f2cec
Author: liato <x@x00.us>
Date:   Fri Nov 26 01:09:13 2010 +0100

    Added option to blur balance on widgets.

diff --git res/drawable-hdpi-v4/widget_large_balance_blured.png res/drawable-hdpi-v4/widget_large_balance_blured.png
new file mode 100644
index 0000000..d24d46e
Binary files /dev/null and res/drawable-hdpi-v4/widget_large_balance_blured.png differ
diff --git res/drawable-hdpi-v4/widget_small_balance_blured.png res/drawable-hdpi-v4/widget_small_balance_blured.png
new file mode 100644
index 0000000..33c9e28
Binary files /dev/null and res/drawable-hdpi-v4/widget_small_balance_blured.png differ
diff --git res/layout/widget.xml res/layout/widget.xml
index 883e9b2..b5b143f 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -4,9 +4,15 @@
 	android:layout_gravity="center_horizontal"
 	android:background="@drawable/widget_2x1"
 	android:layout_height="100dp"
-	android:layout_width="160dp" android:id="@+id/layWidgetContainer">
+	android:layout_width="160dp"
+	android:id="@+id/layWidgetContainer">
 
-	<FrameLayout android:layout_height="22dp" android:layout_width="fill_parent" android:id="@+id/hitBox" android:focusable="true"></FrameLayout><LinearLayout
+	<FrameLayout
+		android:layout_height="22dp"
+		android:layout_width="fill_parent"
+		android:id="@+id/hitBox"
+		android:focusable="true"></FrameLayout>
+	<LinearLayout
 		android:layout_height="wrap_content"
 		android:layout_width="wrap_content"
 		android:id="@+id/layWidgetRow01"
@@ -28,7 +34,19 @@
 			android:textColor="#a8a3a3"
 			android:textSize="11dp"
 			android:inputType="none"
-			android:layout_marginLeft="2dp" android:text="Bankdroid"></TextView>
+			android:layout_marginLeft="2dp"
+			android:text="Bankdroid"></TextView>
+		<TextView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:id="@+id/txtWidgetAccountnameBlur"
+			android:layout_gravity="center_vertical"
+			android:textColor="#a8a3a3"
+			android:textSize="11dp"
+			android:inputType="none"
+			android:layout_marginLeft="2dp"
+			android:text="Bankdroid"
+			android:visibility="gone"></TextView>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -36,6 +54,16 @@
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
 		android:layout_marginTop="7dp">
+		<ImageView
+			android:id="@+id/imgBalanceblur"
+			android:src="@drawable/widget_small_balance_blured"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_height="fill_parent"
+			android:layout_width="fill_parent"
+			android:scaleType="centerInside"
+			android:adjustViewBounds="false"
+			android:paddingTop="5dp"
+			android:visibility="gone"></ImageView>
 		<TextView
 			android:textColor="#fff"
 			android:inputType="none"
@@ -45,7 +73,8 @@
 			android:gravity="center_vertical|center_horizontal"
 			android:textSize="15dp"
 			android:id="@+id/txtWidgetAccountbalance"
-			android:layout_height="fill_parent" android:text="Loading..."/>
+			android:layout_height="fill_parent"
+			android:text="Loading..." />
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow03"
@@ -55,8 +84,25 @@
 		android:gravity="bottom"
 		android:layout_alignParentBottom="true"
 		android:visibility="visible">
-		
-		<FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:maxHeight="2dp" android:minHeight="2dp" android:minWidth="17dp" android:visibility="visible"></ProgressBar></FrameLayout>
+
+		<FrameLayout
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:id="@+id/frmProgress"
+			android:visibility="invisible">
+			<ProgressBar
+				android:layout_width="wrap_content"
+				android:indeterminateOnly="true"
+				android:indeterminateBehavior="repeat"
+				android:indeterminate="true"
+				android:layout_height="wrap_content"
+				style="@style/Widget_Progress"
+				android:id="@+id/prgProgress"
+				android:maxHeight="2dp"
+				android:minHeight="2dp"
+				android:minWidth="17dp"
+				android:visibility="visible"></ProgressBar>
+		</FrameLayout>
 
 
 		<FrameLayout
@@ -74,7 +120,4 @@
 				android:layout_width="wrap_content"></ImageView>
 		</FrameLayout>
 	</LinearLayout>
-	
-
-
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/widget_large.xml res/layout/widget_large.xml
index 13d4fe0..3221ad6 100644
--- res/layout/widget_large.xml
+++ res/layout/widget_large.xml
@@ -3,17 +3,138 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_gravity="center_horizontal"
 	android:layout_height="100dp"
-	android:id="@+id/layWidgetContainer" android:layout_width="320dp" android:background="@drawable/widget_4x1">
-
-	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp" android:paddingTop="8dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="37dp"></TextView></RelativeLayout>
-</RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="15dp" android:paddingRight="11dp"><FrameLayout android:layout_height="wrap_content" android:id="@+id/frmWarning" android:layout_width="wrap_content" android:visibility="invisible">
-			<ImageView android:id="@+id/imgWarning" android:adjustViewBounds="true" android:layout_height="fill_parent" android:src="@drawable/indicator_input_error" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_gravity="top|right" android:maxWidth="17dp" android:maxHeight="17dp" android:minHeight="17dp" android:minWidth="17dp"></ImageView>
-		</FrameLayout></RelativeLayout><RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp" android:id="@+id/hitBox"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
-	
-	
-	
-
-
-
+	android:id="@+id/layWidgetContainer"
+	android:layout_width="320dp"
+	android:background="@drawable/widget_4x1">
 
+	<RelativeLayout
+		android:id="@+id/RelativeLayout02"
+		android:paddingLeft="17dp"
+		android:paddingTop="24dp"
+		android:layout_height="wrap_content"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentTop="true"
+		android:layout_width="fill_parent"
+		android:paddingRight="28dp">
+		<ImageView
+			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+			android:id="@+id/imgWidgetIcon"
+			android:layout_gravity="center_vertical"
+			android:baselineAlignBottom="true"
+			android:scaleType="fitXY"
+			android:layout_height="52dp"
+			android:layout_width="52dp"
+			android:src="@drawable/icon_large"></ImageView>
+		<RelativeLayout
+			android:id="@+id/RelativeLayout01"
+			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+			android:layout_toRightOf="@+id/imgWidgetIcon"
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent">
+			<ImageView
+				android:layout_height="wrap_content"
+				android:layout_toLeftOf="@+id/txtWidgetAccountbalance"
+				android:layout_width="wrap_content"
+				android:id="@+id/imgBalanceblur"
+				android:src="@drawable/widget_large_balance_blured"
+				android:paddingTop="8dp"
+				android:paddingRight="1dp"
+				android:adjustViewBounds="true"
+				android:layout_centerInParent="true"
+				android:visibility="gone"></ImageView>
+			<TextView
+				android:layout_height="wrap_content"
+				android:layout_width="wrap_content"
+				android:textColor="#a8a3a3"
+				android:textSize="11dp"
+				android:inputType="none"
+				android:gravity="right"
+				android:paddingTop="37dp"
+				android:id="@+id/txtWidgetAccountnameBlur"
+				android:layout_alignRight="@+id/imgBalanceblur"
+				android:layout_alignTop="@+id/imgBalanceblur"
+				android:visibility="gone"></TextView>
+			<TextView
+				android:textColor="#fff"
+				android:inputType="none"
+				android:layout_gravity="center_vertical|center_horizontal"
+				android:ellipsize="none"
+				android:gravity="center_vertical|center_horizontal"
+				android:id="@+id/txtWidgetAccountbalance"
+				android:layout_height="wrap_content"
+				android:layout_toRightOf="@+id/imgWidgetIcon"
+				android:layout_width="wrap_content"
+				android:layout_centerInParent="false"
+				android:layout_centerHorizontal="true"
+				android:text="Loading..."
+				android:textSize="27dp"
+				android:paddingRight="1dp"
+				android:paddingTop="8dp" />
+			<TextView
+				android:layout_height="wrap_content"
+				android:layout_width="wrap_content"
+				android:id="@+id/txtWidgetAccountname"
+				android:textColor="#a8a3a3"
+				android:textSize="11dp"
+				android:inputType="none"
+				android:layout_alignRight="@+id/txtWidgetAccountbalance"
+				android:gravity="right"
+				android:layout_alignTop="@+id/txtWidgetAccountbalance"
+				android:paddingTop="37dp"></TextView>
+		
+</RelativeLayout>
+	</RelativeLayout>
+	<RelativeLayout
+		android:id="@+id/RelativeLayout03"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_alignParentRight="true"
+		android:paddingTop="15dp"
+		android:paddingRight="11dp">
+		<FrameLayout
+			android:layout_height="wrap_content"
+			android:id="@+id/frmWarning"
+			android:layout_width="wrap_content"
+			android:visibility="invisible">
+			<ImageView
+				android:id="@+id/imgWarning"
+				android:adjustViewBounds="true"
+				android:layout_height="fill_parent"
+				android:src="@drawable/indicator_input_error"
+				android:scaleType="fitXY"
+				android:layout_width="wrap_content"
+				android:layout_gravity="top|right"
+				android:maxWidth="17dp"
+				android:maxHeight="17dp"
+				android:minHeight="17dp"
+				android:minWidth="17dp"></ImageView>
+		</FrameLayout>
+	</RelativeLayout>
+	<RelativeLayout
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_alignTop="@+id/RelativeLayout02"
+		android:paddingTop="75dp"
+		android:paddingLeft="34dp"
+		android:id="@+id/hitBox">
+		<FrameLayout
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:id="@+id/frmProgress"
+			android:visibility="invisible">
+			<ProgressBar
+				android:layout_width="wrap_content"
+				android:indeterminateOnly="true"
+				android:indeterminateBehavior="repeat"
+				android:indeterminate="true"
+				android:layout_height="wrap_content"
+				style="@style/Widget_Progress"
+				android:id="@+id/prgProgress"
+				android:minWidth="17dp"
+				android:visibility="visible"
+				android:minHeight="6dp"
+				android:maxHeight="6dp"
+				android:layout_gravity="top|center_horizontal"></ProgressBar>
+		</FrameLayout>
+	</RelativeLayout>
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/widget_large_transparent.xml res/layout/widget_large_transparent.xml
index fcc3838..3078cb8 100644
--- res/layout/widget_large_transparent.xml
+++ res/layout/widget_large_transparent.xml
@@ -3,17 +3,136 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_gravity="center_horizontal"
 	android:layout_height="100dp"
-	android:id="@+id/layWidgetContainer" android:layout_width="320dp" >
-
-	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp" android:paddingTop="8dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="37dp"></TextView></RelativeLayout>
-</RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="15dp" android:paddingRight="11dp"><FrameLayout android:layout_height="wrap_content" android:id="@+id/frmWarning" android:layout_width="wrap_content" android:visibility="invisible">
-			<ImageView android:id="@+id/imgWarning" android:adjustViewBounds="true" android:layout_height="fill_parent" android:src="@drawable/indicator_input_error" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_gravity="top|right" android:maxWidth="17dp" android:maxHeight="17dp" android:minHeight="17dp" android:minWidth="17dp"></ImageView>
-		</FrameLayout></RelativeLayout><RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp" android:id="@+id/hitBox"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
-	
-	
-	
-
-
-
+	android:id="@+id/layWidgetContainer"
+	android:layout_width="320dp">
 
+	<RelativeLayout
+		android:id="@+id/RelativeLayout02"
+		android:paddingLeft="17dp"
+		android:paddingTop="24dp"
+		android:layout_height="wrap_content"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentTop="true"
+		android:layout_width="fill_parent"
+		android:paddingRight="28dp">
+		<ImageView
+			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+			android:id="@+id/imgWidgetIcon"
+			android:layout_gravity="center_vertical"
+			android:baselineAlignBottom="true"
+			android:scaleType="fitXY"
+			android:layout_height="52dp"
+			android:layout_width="52dp"
+			android:src="@drawable/icon_large"></ImageView>
+		<RelativeLayout
+			android:id="@+id/RelativeLayout01"
+			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+			android:layout_toRightOf="@+id/imgWidgetIcon"
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent">
+			<ImageView
+				android:layout_height="wrap_content"
+				android:layout_toLeftOf="@+id/txtWidgetAccountbalance"
+				android:layout_width="wrap_content"
+				android:id="@+id/imgBalanceblur"
+				android:src="@drawable/widget_large_balance_blured"
+				android:paddingTop="8dp"
+				android:paddingRight="1dp"
+				android:adjustViewBounds="true"
+				android:layout_centerInParent="true"
+				android:visibility="gone"></ImageView>
+			<TextView
+				android:layout_height="wrap_content"
+				android:layout_width="wrap_content"
+				android:textColor="#a8a3a3"
+				android:textSize="11dp"
+				android:inputType="none"
+				android:gravity="right"
+				android:paddingTop="37dp"
+				android:id="@+id/txtWidgetAccountnameBlur"
+				android:layout_alignRight="@+id/imgBalanceblur"
+				android:layout_alignTop="@+id/imgBalanceblur"
+				android:visibility="gone"></TextView>			
+			<TextView
+				android:textColor="#fff"
+				android:inputType="none"
+				android:layout_gravity="center_vertical|center_horizontal"
+				android:ellipsize="none"
+				android:gravity="center_vertical|center_horizontal"
+				android:id="@+id/txtWidgetAccountbalance"
+				android:layout_height="wrap_content"
+				android:layout_toRightOf="@+id/imgWidgetIcon"
+				android:layout_width="wrap_content"
+				android:layout_centerInParent="false"
+				android:layout_centerHorizontal="true"
+				android:text="Loading..."
+				android:textSize="27dp"
+				android:paddingRight="1dp"
+				android:paddingTop="8dp" />
+			<TextView
+				android:layout_height="wrap_content"
+				android:layout_width="wrap_content"
+				android:id="@+id/txtWidgetAccountname"
+				android:textColor="#a8a3a3"
+				android:textSize="11dp"
+				android:inputType="none"
+				android:layout_alignRight="@+id/txtWidgetAccountbalance"
+				android:gravity="right"
+				android:layout_alignTop="@+id/txtWidgetAccountbalance"
+				android:paddingTop="37dp"></TextView>
+		</RelativeLayout>
+	</RelativeLayout>
+	<RelativeLayout
+		android:id="@+id/RelativeLayout03"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_alignParentRight="true"
+		android:paddingTop="15dp"
+		android:paddingRight="11dp">
+		<FrameLayout
+			android:layout_height="wrap_content"
+			android:id="@+id/frmWarning"
+			android:layout_width="wrap_content"
+			android:visibility="invisible">
+			<ImageView
+				android:id="@+id/imgWarning"
+				android:adjustViewBounds="true"
+				android:layout_height="fill_parent"
+				android:src="@drawable/indicator_input_error"
+				android:scaleType="fitXY"
+				android:layout_width="wrap_content"
+				android:layout_gravity="top|right"
+				android:maxWidth="17dp"
+				android:maxHeight="17dp"
+				android:minHeight="17dp"
+				android:minWidth="17dp"></ImageView>
+		</FrameLayout>
+	</RelativeLayout>
+	<RelativeLayout
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_alignTop="@+id/RelativeLayout02"
+		android:paddingTop="75dp"
+		android:paddingLeft="34dp"
+		android:id="@+id/hitBox">
+		<FrameLayout
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:id="@+id/frmProgress"
+			android:visibility="invisible">
+			<ProgressBar
+				android:layout_width="wrap_content"
+				android:indeterminateOnly="true"
+				android:indeterminateBehavior="repeat"
+				android:indeterminate="true"
+				android:layout_height="wrap_content"
+				style="@style/Widget_Progress"
+				android:id="@+id/prgProgress"
+				android:minWidth="17dp"
+				android:visibility="visible"
+				android:minHeight="6dp"
+				android:maxHeight="6dp"
+				android:layout_gravity="top|center_horizontal"></ProgressBar>
+		</FrameLayout>
+	</RelativeLayout>
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/widget_transparent.xml res/layout/widget_transparent.xml
index c3a18bb..b0466f4 100644
--- res/layout/widget_transparent.xml
+++ res/layout/widget_transparent.xml
@@ -2,11 +2,21 @@
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_gravity="center_horizontal"
-	
+
 	android:layout_height="100dp"
-	android:layout_width="160dp" android:id="@+id/layWidgetContainer" android:paddingTop="22dp" android:paddingLeft="19dp" android:paddingRight="18dp" android:paddingBottom="20dp">
+	android:layout_width="160dp"
+	android:id="@+id/layWidgetContainer"
+	android:paddingTop="22dp"
+	android:paddingLeft="19dp"
+	android:paddingRight="18dp"
+	android:paddingBottom="20dp">
 
-	<FrameLayout android:layout_height="22dp" android:layout_width="fill_parent" android:id="@+id/hitBox" android:focusable="true"></FrameLayout><LinearLayout
+	<FrameLayout
+		android:layout_height="22dp"
+		android:layout_width="fill_parent"
+		android:id="@+id/hitBox"
+		android:focusable="true"></FrameLayout>
+	<LinearLayout
 		android:layout_height="wrap_content"
 		android:layout_width="wrap_content"
 		android:id="@+id/layWidgetRow01"
@@ -28,7 +38,19 @@
 			android:textColor="#a8a3a3"
 			android:textSize="11dp"
 			android:inputType="none"
-			android:layout_marginLeft="2dp" android:text="Bankdroid"></TextView>
+			android:layout_marginLeft="2dp"
+			android:text="Bankdroid"></TextView>
+		<TextView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:id="@+id/txtWidgetAccountnameBlur"
+			android:layout_gravity="center_vertical"
+			android:textColor="#a8a3a3"
+			android:textSize="11dp"
+			android:inputType="none"
+			android:layout_marginLeft="2dp"
+			android:text="Bankdroid"
+			android:visibility="gone"></TextView>			
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -36,6 +58,16 @@
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
 		android:layout_marginTop="7dp">
+		<ImageView
+			android:id="@+id/imgBalanceblur"
+			android:src="@drawable/widget_small_balance_blured"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_height="fill_parent"
+			android:layout_width="fill_parent"
+			android:scaleType="centerInside"
+			android:adjustViewBounds="false"
+			android:paddingTop="5dp"
+			android:visibility="gone"></ImageView>
 		<TextView
 			android:textColor="#fff"
 			android:inputType="none"
@@ -45,7 +77,8 @@
 			android:gravity="center_vertical|center_horizontal"
 			android:textSize="15dp"
 			android:id="@+id/txtWidgetAccountbalance"
-			android:layout_height="fill_parent" android:text="Loading..."/>
+			android:layout_height="fill_parent"
+			android:text="Loading..." />
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow03"
@@ -55,8 +88,25 @@
 		android:gravity="bottom"
 		android:layout_alignParentBottom="true"
 		android:visibility="visible">
-		
-		<FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:maxHeight="2dp" android:minHeight="2dp" android:minWidth="17dp" android:visibility="visible"></ProgressBar></FrameLayout>
+
+		<FrameLayout
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:id="@+id/frmProgress"
+			android:visibility="invisible">
+			<ProgressBar
+				android:layout_width="wrap_content"
+				android:indeterminateOnly="true"
+				android:indeterminateBehavior="repeat"
+				android:indeterminate="true"
+				android:layout_height="wrap_content"
+				style="@style/Widget_Progress"
+				android:id="@+id/prgProgress"
+				android:maxHeight="2dp"
+				android:minHeight="2dp"
+				android:minWidth="17dp"
+				android:visibility="visible"></ProgressBar>
+		</FrameLayout>
 
 
 		<FrameLayout
@@ -74,7 +124,7 @@
 				android:layout_width="wrap_content"></ImageView>
 		</FrameLayout>
 	</LinearLayout>
-	
+
 
 
 </RelativeLayout>
\ No newline at end of file
diff --git res/values-sv/array.xml res/values-sv/array.xml
index 255a855..c0c6314 100644
--- res/values-sv/array.xml
+++ res/values-sv/array.xml
@@ -11,4 +11,15 @@
 		<item>16 timmar</item>
 		<item>Dagligen</item>
 	</string-array>
+	<string-array
+		name="unblurTimeoutNames">
+		<item>1 sekund</item>
+		<item>2 sekunder</item>
+		<item>3 sekunder</item>
+		<item>4 sekunder</item>
+		<item>5 sekunder</item>
+		<item>10 sekunder</item>
+		<item>15 sekunder</item>
+		<item>20 sekunder</item>
+	</string-array>	
 </resources>
diff --git res/values/array.xml res/values/array.xml
index 3be9c89..2f542db 100644
--- res/values/array.xml
+++ res/values/array.xml
@@ -22,4 +22,26 @@
 		<item>960</item>
 		<item>1440</item>
 	</string-array>
+	<string-array
+		name="unblurTimeoutNames">
+		<item>1 second</item>
+		<item>2 seconds</item>
+		<item>3 seconds</item>
+		<item>4 seconds</item>
+		<item>5 seconds</item>
+		<item>10 seconds</item>
+		<item>15 seconds</item>
+		<item>20 seconds</item>
+	</string-array>
+	<string-array
+		name="unblurTimeoutValues">
+		<item>1</item>
+		<item>2</item>
+		<item>3</item>
+		<item>4</item>
+		<item>5</item>
+		<item>10</item>
+		<item>15</item>
+		<item>20</item>
+	</string-array>
 </resources>
diff --git res/xml/settings.xml res/xml/settings.xml
index 7b5bfa5..cb59399 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -1,7 +1,7 @@
 <PreferenceScreen
 	xmlns:android="http://schemas.android.com/apk/res/android">
 	<PreferenceCategory
-		android:title="Security">
+		android:title="Security and Privacy">
 		<CheckBoxPreference
 			android:key="patternlock_enabled"
 			android:defaultValue="false"
@@ -12,6 +12,19 @@
 			android:summary="Change your current lock pattern"
 			android:key="patternlock_change"
 			android:dependency="patternlock_enabled" />
+		<CheckBoxPreference
+			android:key="widget_blur_balance"
+			android:defaultValue="false"
+			android:title="Blur widget balance"
+			android:summary="Blur the balance on the widget, click widget to unblur for a few seconds." />
+		<ListPreference
+			android:title="Unblur timeout"
+			android:key="widget_blur_balance_timeout"
+			android:defaultValue="5"
+			android:entries="@array/unblurTimeoutNames"
+			android:entryValues="@array/unblurTimeoutValues"
+			android:summary="Blur the balance again after this many seconds."
+			android:dependency="widget_blur_balance" />
 	</PreferenceCategory>
 	<PreferenceCategory
 		android:title="Automatic Updates">
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index f91ed81..ee52b98 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -1,5 +1,6 @@
 package com.liato.bankdroid;
 
+import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.appwidget.AppWidgetManager;
@@ -8,15 +9,22 @@ import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
 import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 	private final static String TAG = "BankdroidWidgetProvider";
+    private final static String ACTION_WIDGET_BLUR = "com.liato.bankdroid.action.WIDGET_BLUR";
+    private final static String ACTION_WIDGET_UNBLUR = "com.liato.bankdroid.action.WIDGET_UNBLUR";
 	
 	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId, Account account) {
@@ -29,8 +37,42 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
 		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
 	}
+	
+    static void unblurAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId) {
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);  
+        Editor e = prefs.edit();
+        e.putBoolean("widget_unblured_"+appWidgetId, true);
+        e.commit();
 
-	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
+        RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+        if (views != null) {
+            views.setViewVisibility(R.id.imgBalanceblur, View.GONE);
+            views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.GONE);
+            views.setViewVisibility(R.id.txtWidgetAccountbalance, View.VISIBLE);
+            views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE);
+            appWidgetManager.updateAppWidget(appWidgetId, views);
+        }
+    }	
+
+    static void blurAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId) {
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);  
+        Editor e = prefs.edit();
+        e.remove("widget_unblured_"+appWidgetId);
+        e.commit();
+        RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+        if (views != null) {
+            views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
+            views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE);
+            views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE);
+            views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE);
+            appWidgetManager.updateAppWidget(appWidgetId, views);
+        }
+    }   
+
+    
+    static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
 		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
 		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
@@ -80,7 +122,8 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Bank bank = account.getBank();
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
-		views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
+        views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
+        views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase());
 		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
 		Log.d("Disabled", ""+bank.isDisabled());
@@ -106,8 +149,28 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 		views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent);
 		views.setOnClickPendingIntent(R.id.hitBox, pendingIntent);
+		
+        intent = new Intent(context, WidgetService.class);
+        intent.setAction(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+        intent.setData(Uri.parse("rofl://copter/widgetunblur/"+appWidgetId+"/"+System.currentTimeMillis()));
+        pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+        views.setOnClickPendingIntent(R.id.imgBalanceblur, pendingIntent);
+        
+        SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (defprefs.getBoolean("widget_blur_balance", false) && !prefs.getBoolean("widget_unblured_" + appWidgetId, false)) {
+            views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE);
+            views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE);
+            views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE);
+            views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE);          
+        }
+        else {
+            views.setViewVisibility(R.id.imgBalanceblur, View.GONE);
+            views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.GONE);
+            views.setViewVisibility(R.id.txtWidgetAccountbalance, View.VISIBLE);
+            views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE);            
+        }
 
-		//appWidgetManager.updateAppWidget(appWidgetId, views); 
 		return views;
 	}
 	
@@ -179,16 +242,44 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 	}
 
 	public static class WidgetService extends Service {
+
 		@Override
 		public void onStart(Intent intent, int startId) {
 			int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
 			Log.d("WidgetService", "Updating widget: " + appWidgetId);
-
+			Context context = getApplicationContext();
 			String action = intent.getAction();
+			if (action == null) return; 
 			if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) {
-				Context context = getApplicationContext();
 				new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId).execute();
 			}
+	        else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR)) {
+                unblurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId);
+                
+                Handler blurHandler = new Handler();
+                class BlurRunnable implements Runnable {
+                    private int mAppWidgetId;
+                    
+                    public BlurRunnable(int appWidgetId) {
+                        this.mAppWidgetId = appWidgetId;
+                    }
+    
+                    @Override
+                    public void run() {
+                        Context context = getApplicationContext();
+                        blurAppWidget(context, AppWidgetManager.getInstance(context), mAppWidgetId);
+                    }
+                     
+                 }
+                
+
+                SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context);
+                Integer unblurTimeout = 1000*Integer.parseInt(defprefs.getString("widget_blur_balance_timeout", "5"));                 
+                blurHandler.postDelayed(new BlurRunnable(appWidgetId), unblurTimeout);
+	        }
+            else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_BLUR)) {
+                blurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId);
+            }
 		}
 
 		@Override
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 27b2f9b..d82ae64 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -117,6 +117,8 @@ public class SettingsActivity extends LockablePreferenceActivity implements OnPr
     protected void onPause() {
         super.onPause();
         StartupReceiver.setAlarm(this);
+        // Blur/unblur the widget balance
+        AutoRefreshService.sendWidgetRefresh(this);
     }
     
 }
\ No newline at end of file

commit aa664eb936433e852830b5b3186b61e43729a951
Author: liato <x@x00.us>
Date:   Thu Nov 25 17:26:06 2010 +0100

    Prevent FC when loading accounts without id.

diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 793a7e7..c4b6bcf 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -226,15 +226,20 @@ public class BankFactory {
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
 			c.moveToNext();
-			Account account = new Account(c.getString(c.getColumnIndex("name")),
-                                          new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                          c.getString(c.getColumnIndex("id")).split("_", 2)[1],
-                                          c.getLong(c.getColumnIndex("bankid")),
-                                          c.getInt(c.getColumnIndex("acctype")));
-	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
-	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
-	        account.setCurrency(c.getString(c.getColumnIndex("currency")));
-			accounts.add(account);
+			try {
+    			Account account = new Account(c.getString(c.getColumnIndex("name")),
+                                              new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                                              c.getString(c.getColumnIndex("id")).split("_", 2)[1],
+                                              c.getLong(c.getColumnIndex("bankid")),
+                                              c.getInt(c.getColumnIndex("acctype")));
+    	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
+    	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
+    	        account.setCurrency(c.getString(c.getColumnIndex("currency")));
+    			accounts.add(account);
+			}
+			catch (ArrayIndexOutOfBoundsException e) {
+			    // Attempted to load an account without and ID, probably an old Avanza account.
+			}
 		}
 		c.close();
 		db.close();

commit 164ef857ef0f38603b551412c13b7a6824e7f7db
Author: liato <x@x00.us>
Date:   Thu Nov 25 17:25:12 2010 +0100

    Fixed LF bug where accounts url was returned as a relative url.

diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index a0d560a..64abdca 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -2,6 +2,7 @@ package com.liato.bankdroid.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -87,6 +88,7 @@ public class Lansforsakringar extends Bank {
 			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
 			Log.d("Bankdroid", "Posting data to: " + urlopen.getCurrentURI());
 			response = urlopen.open(urlopen.getCurrentURI(), postData);
+			String a = "https://secure246.lansforsakringar.se:443/lfportal/appmanager/privat/main?_nfpb=true&amp;_pageLabel=bank&newUc=true&isTopLevel=true";
 
 			if (response.contains("Felaktig inloggning")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -103,6 +105,9 @@ public class Lansforsakringar extends Bank {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
 			}
 			accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + token;
+			if (!accountsUrl.contains("https://")) {
+			    accountsUrl = "https://" + urlopen.getCurrentURI().split("/")[2] + accountsUrl;
+			}
 			Log.d("Bankdroid", "Accounts url: " + accountsUrl);
 		}
 		catch (ClientProtocolException e) {

commit 39e153f56d3d469716aa9e9bf92ac9242c37c1e2
Author: liato <x@x00.us>
Date:   Wed Nov 24 17:30:50 2010 +0100

    Brake lol

diff --git res/xml-sv/settings.xml res/xml-sv/settings.xml
index e222090..145fb8a 100644
--- res/xml-sv/settings.xml
+++ res/xml-sv/settings.xml
@@ -125,7 +125,7 @@
 			<PreferenceScreen
 				android:key="debug_screen"
 				android:title="Seriously"
-				android:summary="You might brake things">
+				android:summary="You might break things">
 				<CheckBoxPreference
 					android:key="debug_mode"
 					android:defaultValue="false"
diff --git res/xml/settings.xml res/xml/settings.xml
index 3455379..7b5bfa5 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -124,7 +124,7 @@
 			<PreferenceScreen
 				android:key="debug_screen"
 				android:title="Seriously"
-				android:summary="You might brake things">
+				android:summary="You might break things">
 				<CheckBoxPreference
 					android:key="debug_mode"
 					android:defaultValue="false"

commit e8ac807cb5727713328ac92e5c8c4e06ecee8330
Author: liato <x@x00.us>
Date:   Sat Nov 20 01:14:41 2010 +0100

    Fixed bug where an account would get the wrong id when loading from db if the id contained "_". Changed LoginError detection string for Coop.

diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 48cdfb4..793a7e7 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -187,7 +187,7 @@ public class BankFactory {
 
 		Account account = new Account(c.getString(c.getColumnIndex("name")),
                                       new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                      c.getString(c.getColumnIndex("id")).split("_")[1],
+                                      c.getString(c.getColumnIndex("id")).split("_", 2)[1],
                                       c.getLong(c.getColumnIndex("bankid")),
                                       c.getInt(c.getColumnIndex("acctype")));
         account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
@@ -228,7 +228,7 @@ public class BankFactory {
 			c.moveToNext();
 			Account account = new Account(c.getString(c.getColumnIndex("name")),
                                           new BigDecimal(c.getString(c.getColumnIndex("balance"))),
-                                          c.getString(c.getColumnIndex("id")).split("_")[1],
+                                          c.getString(c.getColumnIndex("id")).split("_", 2)[1],
                                           c.getLong(c.getColumnIndex("bankid")),
                                           c.getInt(c.getColumnIndex("acctype")));
 	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index 4f06884..8f389b1 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -22,7 +22,7 @@ public class TransactionsActivity extends LockableActivity {
     @Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-        //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
+
 		//Use HtcListView if available
 		try {
 		    setContentView(R.layout.transactions_htc);
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 91c11cb..252b517 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -74,7 +74,7 @@ public class Coop extends Bank {
             postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
             response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/", postData);
             Log.d(TAG, urlopen.getCurrentURI());
-            if (response.contains("Felmeddelande")) {
+            if (response.contains("forfarande logga in med ditt personnummer")) {
                 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
                 if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_coop_sendmail", false)) {
                     Intent i = new Intent(android.content.Intent.ACTION_SEND);

commit d46fa8f6d3942b5933f574192d24bd9d4943b745
Author: liato <x@x00.us>
Date:   Fri Nov 19 10:30:45 2010 +0100

    Bump version to 1.4.3

diff --git AndroidManifest.xml AndroidManifest.xml
index b834ca1..85fbb9f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.4.3-RC2" android:versionCode="44">
+	android:versionName="1.4.3" android:versionCode="45">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/layout/main.xml res/layout/main.xml
index 88cd44b..ceb48ca 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -25,7 +25,7 @@
 		android:layout_height="wrap_content"
 		android:cacheColorHint="#00000000"
 		android:layout_above="@+id/layMainMenu"
-		android:layout_below="@+id/chkTransperantBackground" android:layout_alignWithParentIfMissing="true" android:dividerHeight="0dp"/>
+		android:layout_below="@+id/chkTransperantBackground" android:layout_alignWithParentIfMissing="true" android:dividerHeight="0dp" android:fadingEdge="vertical"/>
 	<TableLayout
 		android:stretchColumns="0,2"
 		android:layout_height="wrap_content"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index dd8f9df..08b47fb 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -94,7 +94,7 @@
     \nDustin (ICA)
     \ndimaZ (Statoil)
     \nOxygen (Statoil)
-    \nNiclas Ljungstrand (Nordea)
+    \nOxygen (Nordea)
 	\nOzzy (Avanza)
 	\nasperon (Transparent widget)
 	\nDEGE (Handelsbanken)
diff --git res/values/strings.xml res/values/strings.xml
index f741cbb..f73756f 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -95,7 +95,7 @@
     \nDustin (ICA)
     \ndimaZ (Statoil)
     \nOxygen (Statoil)
-    \nNiclas Ljungstrand (Nordea)
+    \nOxygen (Nordea)
 	\nOzzy (Avanza)
 	\nasperon (Transparent widget)
 	\nDEGE (Handelsbanken)
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index 3e7a7ee..f332353 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -65,7 +65,6 @@ public class AccountsAdapter extends BaseAdapter {
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(bank.getBalance(), bank.getCurrency()));
 		icon.setImageResource(bank.getImageResource());
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
-		Log.d("AccountsAdapter", ""+bank.isDisabled());
 		if (bank.isDisabled()) {
 			warning.setVisibility(View.VISIBLE);
 		}
@@ -87,7 +86,6 @@ public class AccountsAdapter extends BaseAdapter {
         TextView txtBalance = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance));
 		txtAccountName.setText(account.getName());
 		txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
-		Log.d("ACCADDAPTER", "Account: "+account.getName()+"; hidden: "+account.isHidden());
 		if (account.isHidden()) {
             txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
             txtBalance.setTextColor(Color.argb(255, 191, 191, 191));		    
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index fae5824..18a8e92 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -86,10 +86,10 @@ public class AutoRefreshService extends Service {
         if (prefs.getBoolean("notify_openwatch", false)) {
             Intent i;
             if (prefs.getBoolean("notify_openwatch_vibrate", false)) {
-                i = new Intent(BROADCAST_OPENWATCH_TEXT);
+                i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
             }
             else {
-                i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
+                i = new Intent(BROADCAST_OPENWATCH_TEXT);
             }
             i.putExtra("line1", String.format("%s (%s)", bank, title));
             i.putExtra("line2", text);

commit ee63d09917cae5c2fa28a04656de523d4085a4d7
Author: liato <x@x00.us>
Date:   Wed Nov 17 11:37:50 2010 +0100

    Custom animation from lock pattern on supported devices.

diff --git AndroidManifest.xml AndroidManifest.xml
index 72ed454..b834ca1 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.4.3-RC1" android:versionCode="43">
+	android:versionName="1.4.3-RC2" android:versionCode="44">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/anim/zoom_enter.xml res/anim/zoom_enter.xml
new file mode 100644
index 0000000..7c29852
--- /dev/null
+++ res/anim/zoom_enter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<!-- Special window zoom animation: this is the element that enters the screen,
+     it starts at 200% and scales down.  Goes with zoom_exit.xml. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@android:anim/decelerate_interpolator">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git res/anim/zoom_exit.xml res/anim/zoom_exit.xml
new file mode 100644
index 0000000..29dfe99
--- /dev/null
+++ res/anim/zoom_exit.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<!-- Special window zoom animation: this is the element that exits the
+     screen, it is forced above the entering element and starts at its
+     normal size (filling the screen) and scales down while fading out.
+     This goes with zoom_enter.xml. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@android:anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+           android:fromYScale="1.0" android:toYScale=".5"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git src/com/liato/bankdroid/ConfirmLockPattern.java src/com/liato/bankdroid/ConfirmLockPattern.java
index 6faee30..e50df89 100644
--- src/com/liato/bankdroid/ConfirmLockPattern.java
+++ src/com/liato/bankdroid/ConfirmLockPattern.java
@@ -268,4 +268,10 @@ public class ConfirmLockPattern extends Activity {
             }
         }.start();
     }
+
+    @Override
+    public void finish() {
+        super.finish();
+        Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
+    }
 }

commit bde6293521bf10f4dbbdaf3115d1bd45e07bfa23
Author: liato <x@x00.us>
Date:   Wed Nov 17 08:55:26 2010 +0100

    Fixed eurocard balance parsing.

diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index a320fd2..225d89b 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -108,17 +108,18 @@ public class Eurocard extends Bank {
 			accounts.add(new Account("Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak", Account.OTHER));
 		}
 		try {
-            /*
-             * Capture groups:
-             * GROUP                     EXAMPLE DATA
-             * 1: balance                &nbsp;40 988,96
-             * 
-             */		    
             response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getBillingUnits.do");
             matcher = reSaldo.matcher(response);
             if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                     EXAMPLE DATA
+                 * 1: balance                &nbsp;40 988,96
+                 * 
+                 */ 
+                
                 // Update the main account balance
-                if (accounts.isEmpty()) {
+                if (!accounts.isEmpty()) {
                     accounts.get(0).setBalance(Helpers.parseBalance(matcher.group(1)));
                 }
             }

commit a8747b2a1d57fbf7882178ef2070020cfd39da55
Author: liato <x@x00.us>
Date:   Wed Nov 17 08:54:33 2010 +0100

    Fixed transactions regex.

diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index 86e9a01..f33e37e 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -35,7 +35,7 @@ public class Statoil extends Bank {
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
 	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunitlastdisposableamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]+>\\s*<span>([^<]*)</span>\\s*</div>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*(?:<div[^>]+>\\s*)?<span>([^<]*)</span>\\s*(?:</div>\\s*)?</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	public Statoil(Context context) {
 		super(context);

commit f4fbbfd966a25a9c2e4b0a5aca381b47c2f36ac1
Author: liato <x@x00.us>
Date:   Mon Nov 15 04:54:58 2010 +0100

    Added debug mode.

diff --git AndroidManifest.xml AndroidManifest.xml
index 0bff922..72ed454 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,8 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.4.2"
-	android:versionCode="42">
+	android:versionName="1.4.3-RC1" android:versionCode="43">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 79647ce..dd8f9df 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -105,6 +105,8 @@
     
 
 	<!-- Lock Pattern settings -->
+    <!-- Unlock header -->
+    <string name="patternlock_header">Rita ditt grafiska lösenord för att låsa upp Bankdroid</string>
     <!-- Security & location settings screen, header -->
     <string name="lock_settings_title">Lås för SIM-kort</string>
     <!-- Security & location settings screen, setting option name -->
diff --git res/values/strings.xml res/values/strings.xml
index c147fd3..f741cbb 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -106,6 +106,8 @@
      
      
     <!-- Lock Pattern settings -->
+    <!-- Unlock header -->
+    <string name="patternlock_header">Draw pattern to unlock Bankdroid</string>
     <!-- Security & location settings screen, header -->
     <string name="lock_settings_title">Screen unlock pattern</string>
     <!-- Security & location settings screen, setting option name -->
diff --git res/xml-sv/settings.xml res/xml-sv/settings.xml
index 5f53c6a..e222090 100644
--- res/xml-sv/settings.xml
+++ res/xml-sv/settings.xml
@@ -116,4 +116,40 @@
 				android:key="openwatch_help" />
 		</PreferenceScreen>
 	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Debug">
+		<PreferenceScreen
+			android:key="debug_screen_pre"
+			android:title="Debug Settings"
+			android:summary="Don't touch if you don't know what you're doing">
+			<PreferenceScreen
+				android:key="debug_screen"
+				android:title="Seriously"
+				android:summary="You might brake things">
+				<CheckBoxPreference
+					android:key="debug_mode"
+					android:defaultValue="false"
+					android:title="Enable"
+					android:summary="Enable debug mode" />
+				<CheckBoxPreference
+					android:key="debug_refreshrate_in_seconds"
+					android:defaultValue="false"
+					android:title="Update freq. in sec."
+					android:summary="Update frequenzy is given in seconds instead of minutes"
+					android:dependency="debug_mode" />
+				<CheckBoxPreference
+					android:key="debug_only_testbank"
+					android:defaultValue="false"
+					android:title="Testbank only"
+					android:summary="Only auto update 'Testbank' banks"
+					android:dependency="debug_mode" />
+				<CheckBoxPreference
+					android:key="debug_coop_sendmail"
+					android:defaultValue="false"
+					android:title="Coop - Mail on error"
+					android:summary="Open your email client with the html response when Bankdroid fails to login to your Coop account."
+					android:dependency="debug_mode" />					
+			</PreferenceScreen>
+		</PreferenceScreen>
+	</PreferenceCategory>	
 </PreferenceScreen>
\ No newline at end of file
diff --git res/xml/settings.xml res/xml/settings.xml
index ad40abc..3455379 100644
--- res/xml/settings.xml
+++ res/xml/settings.xml
@@ -54,7 +54,6 @@
 			android:ringtoneType="notification"
 			android:showDefault="true"
 			android:showSilent="true"
-			
 			android:dependency="notify_on_change" />
 		<PreferenceScreen
 			android:key="account_types_screen"
@@ -116,4 +115,40 @@
 				android:key="openwatch_help" />
 		</PreferenceScreen>
 	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Debug">
+		<PreferenceScreen
+			android:key="debug_screen_pre"
+			android:title="Debug Settings"
+			android:summary="Don't touch if you don't know what you're doing">
+			<PreferenceScreen
+				android:key="debug_screen"
+				android:title="Seriously"
+				android:summary="You might brake things">
+				<CheckBoxPreference
+					android:key="debug_mode"
+					android:defaultValue="false"
+					android:title="Enable"
+					android:summary="Enable debug mode" />
+				<CheckBoxPreference
+					android:key="debug_refreshrate_in_seconds"
+					android:defaultValue="false"
+					android:title="Update freq. in sec."
+					android:summary="Update frequenzy is given in seconds instead of minutes"
+					android:dependency="debug_mode" />
+				<CheckBoxPreference
+					android:key="debug_only_testbank"
+					android:defaultValue="false"
+					android:title="Testbank only"
+					android:summary="Only auto update 'Testbank' banks"
+					android:dependency="debug_mode" />
+				<CheckBoxPreference
+					android:key="debug_coop_sendmail"
+					android:defaultValue="false"
+					android:title="Coop - Mail on error"
+					android:summary="Open your email client with the html response when Bankdroid fails to login to your Coop account."
+					android:dependency="debug_mode" />					
+			</PreferenceScreen>
+		</PreferenceScreen>
+	</PreferenceCategory>
 </PreferenceScreen>
\ No newline at end of file
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index a8fc404..fae5824 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -57,7 +57,9 @@ public class AutoRefreshService extends Service {
         //http://www.freesound.org/samplesViewSingle.php?id=75235
         //http://www.freesound.org/samplesViewSingle.php?id=91924
         Log.d(TAG, "Notification sound: "+prefs.getString("notification_sound", "none"));
-        notification.sound = Uri.parse(prefs.getString("notification_sound", null));
+        if (prefs.getString("notification_sound", null) != null) {
+            notification.sound = Uri.parse(prefs.getString("notification_sound", null));
+        }
 		if (prefs.getBoolean("notify_with_vibration", true)) {
 			long[] vib = {0, 90, 130, 80, 350, 190, 20, 380};
 			notification.vibrate = vib;
@@ -121,6 +123,10 @@ public class AutoRefreshService extends Service {
     		HashMap<String, Account> accounts = new HashMap<String, Account>();
     		
     		for (Bank bank : banks) {
+                if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_only_testbank", false)) {
+                    Log.d(TAG, "Debug::Only_Testbank is ON. Skipping update for "+bank.getName());
+                    continue;
+                }
     			if (bank.isDisabled()) {
     				Log.d(TAG, bank.getName()+" ("+bank.getDisplayName()+") is disabled. Skipping refresh.");
     				continue;
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index b86b3cb..48cdfb4 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -5,7 +5,9 @@ import java.util.ArrayList;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.database.Cursor;
+import android.preference.PreferenceManager;
 
 import com.liato.bankdroid.banks.Avanza;
 import com.liato.bankdroid.banks.AvanzaMini;
@@ -83,7 +85,10 @@ public class BankFactory {
 		banks.add(new Eurocard(context));
         banks.add(new FirstCard(context));
         banks.add(new PayPal(context));
-        banks.add(new TestBank(context));
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        if (prefs.getBoolean("debug_mode", false)) { 
+            banks.add(new TestBank(context));
+        }
 		return banks;
 	}
 
@@ -139,7 +144,11 @@ public class BankFactory {
 			c.moveToNext();
 			//Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
 			try {
+			    if (c.getInt(c.getColumnIndex("banktype")) == Bank.AVANZA) {
+			        continue;
+			    }
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+				
 	            String password = "";
                 try {
                     password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
@@ -197,6 +206,7 @@ public class BankFactory {
                                      new BigDecimal(c.getString(c.getColumnIndex("amount"))),
                                      c.getString(c.getColumnIndex("currency"))));
 				}
+				c.close();
 			}
 			account.setTransactions(transactions);
 		}
diff --git src/com/liato/bankdroid/BetterPopupWindow.java src/com/liato/bankdroid/BetterPopupWindow.java
index 1ea3e8d..609910c 100644
--- src/com/liato/bankdroid/BetterPopupWindow.java
+++ src/com/liato/bankdroid/BetterPopupWindow.java
@@ -42,7 +42,6 @@ public class BetterPopupWindow {
 		this.window.setTouchInterceptor(new OnTouchListener() {
 			@Override
 			public boolean onTouch(View v, MotionEvent event) {
-			    Log.d("TOCUH", "TOUCH!");
 				if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
 					BetterPopupWindow.this.window.dismiss();
 					return true;
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 97cf5ab..0aa959c 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -27,7 +27,6 @@ public class LockableActivity extends Activity {
 	@Override
 	protected void onPause() {
 		super.onPause();
-        Log.d(TAG, "Pausing...");
 		// Don't do anything if not lock pattern is set
 		if (!mLockPatternUtils.isLockPatternEnabled()) return;
         // Save the current time If a lock pattern has been set
@@ -55,7 +54,7 @@ public class LockableActivity extends Activity {
 	private void launchPatternLock() {
         Intent intent = new Intent(this, ConfirmLockPattern.class);
         intent.putExtra(ConfirmLockPattern.DISABLE_BACK_KEY, true);
-        intent.putExtra(ConfirmLockPattern.HEADER_TEXT, "Draw pattern to unlock Bankdroid");
+        intent.putExtra(ConfirmLockPattern.HEADER_TEXT, getText(R.string.patternlock_header));
         startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
 	}
 	
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
index 6ce018f..c246f8b 100644
--- src/com/liato/bankdroid/LockablePreferenceActivity.java
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -51,7 +51,7 @@ public class LockablePreferenceActivity extends PreferenceActivity {
 	private void launchPatternLock() {
         Intent intent = new Intent(this, ConfirmLockPattern.class);
         intent.putExtra(ConfirmLockPattern.DISABLE_BACK_KEY, true);
-        intent.putExtra(ConfirmLockPattern.HEADER_TEXT, "Draw pattern to unlock Bankdroid");
+        intent.putExtra(ConfirmLockPattern.HEADER_TEXT, getText(R.string.patternlock_header));
         startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
 	}
 	
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index e0664d3..2f5fc44 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -32,7 +32,11 @@ public class StartupReceiver extends BroadcastReceiver{
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*60*1000, refreshRate*60*1000, alarmSender);
+	        int secondsInMinute = 60;
+	        if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_refreshrate_in_seconds", false)) {
+	            secondsInMinute = 1;
+	        }
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*secondsInMinute*1000, refreshRate*secondsInMinute*1000, alarmSender);
         	Log.d(TAG,"Automatic updates set to "+refreshRate.toString()+" minutes.");
         }
 	
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index a1a213d..092c638 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -50,6 +50,7 @@ public class Avanza extends Bank {
 		this.update(username, password);
 	}
 
+	/*
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib(true, true);
@@ -74,9 +75,16 @@ public class Avanza extends Bank {
 		}
 		return urlopen;
 	}
+	*/
+	
 	@Override
 	public void update() throws BankException, LoginException {
 		super.update();
+		throw new BankException("The implementation of this bank is currently broken.\n" +
+				                "To fix this problem help is needed from you, Avanza users. " +
+				                "Please read the first post at\n" +
+				                "http://j.mp/9GRlt1 for instructions on how you can help.");
+		/*
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
@@ -105,12 +113,15 @@ public class Avanza extends Bank {
         finally {
             super.updateComplete();
         }
+        */
 	}
 
+	
+	/*
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-
+		
 		String response = null;
 		Matcher matcher;
 		try {						
@@ -135,5 +146,5 @@ public class Avanza extends Bank {
 			e.printStackTrace();
 		}
 	}
-	
+	*/
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 9117da7..91c11cb 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -11,6 +11,9 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
 import android.text.Html;
 import android.util.Log;
 
@@ -24,117 +27,126 @@ import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 public class Coop extends Bank {
-	private static final String TAG = "Coop";
-	private static final String NAME = "Coop";
-	private static final String NAME_SHORT = "coop";
-	private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
-	private static final int BANKTYPE_ID = Bank.COOP;
+    private static final String TAG = "Coop";
+    private static final String NAME = "Coop";
+    private static final String NAME_SHORT = "coop";
+    private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
+    private static final int BANKTYPE_ID = Bank.COOP;
 
-	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-	private String response;
-	
-	public Coop(Context context) {
-		super(context);
-		super.TAG = TAG;
-		super.NAME = NAME;
-		super.NAME_SHORT = NAME_SHORT;
-		super.BANKTYPE_ID = BANKTYPE_ID;
-		super.URL = URL;
-	}
+    private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+    private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+    private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+    private String response;
 
-	public Coop(String username, String password, Context context) throws BankException, LoginException {
-		this(context);
-		this.update(username, password);
-	}
+    public Coop(Context context) {
+        super(context);
+        super.TAG = TAG;
+        super.NAME = NAME;
+        super.NAME_SHORT = NAME_SHORT;
+        super.BANKTYPE_ID = BANKTYPE_ID;
+        super.URL = URL;
+    }
 
-	@Override
-	public Urllib login() throws LoginException, BankException {
-		urlopen = new Urllib();
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
-			matcher = reViewState.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
-			}
-			String strViewState = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
-			postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
-			postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$ButtonLogin", "Logga in"));
-			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
-			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
-			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/", postData);
-			Log.d(TAG, urlopen.getCurrentURI());
-			if (response.contains("Felmeddelande")) {
-				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		return urlopen;		
-	}
-	
-	@Override
-	public void update() throws BankException, LoginException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
+    public Coop(String username, String password, Context context) throws BankException, LoginException {
+        this(context);
+        this.update(username, password);
+    }
 
-		urlopen = login();
-		Matcher matcher;
-		try {
-			Account account;
-			matcher = reBalanceVisa.matcher(response);
-			if (matcher.find()) {
-				account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-	            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
-				matcher = reTransactionsVisa.matcher(response);
-				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-				while (matcher.find()) {
-					String title = matcher.group(4).length() > 0 ? matcher.group(4).trim() + " (" + matcher.group(3).trim() + ")" : matcher.group(2);
-					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(5))));
-				}
-				account.setTransactions(transactions);
-				accounts.add(account);
-			}
-			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
-			matcher = reBalanceKonto.matcher(response);
-			if (matcher.find()) {
-				account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
-				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-				matcher = reTransactionsKonto.matcher(response);
-				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-				while (matcher.find()) {
-					String title = matcher.group(4).length() > 0 ? matcher.group(4) : matcher.group(3);
-					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(4))));
-				}
-				account.setTransactions(transactions);
-				accounts.add(account);
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
+    @Override
+    public Urllib login() throws LoginException, BankException {
+        urlopen = new Urllib();
+        Matcher matcher;
+        try {
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
+            matcher = reViewState.matcher(response);
+            if (!matcher.find()) {
+                throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+            }
+            String strViewState = matcher.group(1);
+            List <NameValuePair> postData = new ArrayList <NameValuePair>();
+            postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
+            postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
+            postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$ButtonLogin", "Logga in"));
+            postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+            postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+            postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/", postData);
+            Log.d(TAG, urlopen.getCurrentURI());
+            if (response.contains("Felmeddelande")) {
+                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+                if (prefs.getBoolean("debug_mode", false) && prefs.getBoolean("debug_coop_sendmail", false)) {
+                    Intent i = new Intent(android.content.Intent.ACTION_SEND);
+                    i.setType("plain/text");
+                    i.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"android@x00.us"});
+                    i.putExtra(android.content.Intent.EXTRA_SUBJECT, "Bankdroid - Coop Error");
+                    i.putExtra(android.content.Intent.EXTRA_TEXT, response);
+                    context.startActivity(i);
+                }
+                throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
+        return urlopen;		
+    }
+
+    @Override
+    public void update() throws BankException, LoginException {
+        super.update();
+        if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+            throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+        }
+
+        urlopen = login();
+        Matcher matcher;
+        try {
+            Account account;
+            matcher = reBalanceVisa.matcher(response);
+            if (matcher.find()) {
+                account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
+                balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+                response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
+                matcher = reTransactionsVisa.matcher(response);
+                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                while (matcher.find()) {
+                    String title = matcher.group(4).length() > 0 ? matcher.group(4).trim() + " (" + matcher.group(3).trim() + ")" : matcher.group(2);
+                    transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(5))));
+                }
+                account.setTransactions(transactions);
+                accounts.add(account);
+            }
+            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
+            matcher = reBalanceKonto.matcher(response);
+            if (matcher.find()) {
+                account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
+                balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+                matcher = reTransactionsKonto.matcher(response);
+                ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+                while (matcher.find()) {
+                    String title = matcher.group(4).length() > 0 ? matcher.group(4) : matcher.group(3);
+                    transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(4))));
+                }
+                account.setTransactions(transactions);
+                accounts.add(account);
+            }
+            if (accounts.isEmpty()) {
+                throw new BankException(res.getText(R.string.no_accounts_found).toString());
+            }
+        }
+        catch (ClientProtocolException e) {
+            throw new BankException(e.getMessage());
+        }
+        catch (IOException e) {
+            throw new BankException(e.getMessage());
+        }
         finally {
             super.updateComplete();
         }
-	}
+    }
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/TestBank.java src/com/liato/bankdroid/banks/TestBank.java
index 0651263..de8b956 100644
--- src/com/liato/bankdroid/banks/TestBank.java
+++ src/com/liato/bankdroid/banks/TestBank.java
@@ -62,7 +62,7 @@ public class TestBank extends Bank {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		urlopen = new Urllib();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {

commit 1747b81da807e5ea03f2e2e26b890e013b80e3a7
Author: liato <x@x00.us>
Date:   Mon Nov 15 00:44:00 2010 +0100

    Added TestBank for testing.

diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index bff868b..f4f8952 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -11,7 +11,8 @@ import android.text.InputType;
 import com.liato.urllib.Urllib;
 
 public abstract class Bank implements Comparable<Bank> {
-	public final static int SWEDBANK = 1;
+    public final static int TESTBANK = 0;
+    public final static int SWEDBANK = 1;
 	public final static int NORDEA = 2;
 	public final static int ICABANKEN = 3;
 	public final static int LANSFORSAKRINGAR = 4;
@@ -27,7 +28,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int FIRSTCARD = 14;
 	public final static int PAYPAL = 15;
 	public final static int Payson = 16;
-	
+
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
@@ -38,6 +39,7 @@ public abstract class Bank implements Comparable<Bank> {
     protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
     protected String INPUT_HINT_USERNAME = null;
     protected boolean STATIC_BALANCE = false;
+    protected boolean BROKEN = false;
 
 	protected Context context;
 	protected Resources res;
@@ -243,6 +245,10 @@ public abstract class Bank implements Comparable<Bank> {
     public String getInputHintUsername() {
         return INPUT_HINT_USERNAME;
     }
+    
+    public boolean isBroken() {
+        return BROKEN;
+    }
 
     public int getImageResource() {
 		return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index f1dab83..b86b3cb 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -21,14 +21,17 @@ import com.liato.bankdroid.banks.OKQ8;
 import com.liato.bankdroid.banks.PayPal;
 import com.liato.bankdroid.banks.Statoil;
 import com.liato.bankdroid.banks.Swedbank;
+import com.liato.bankdroid.banks.TestBank;
 import com.liato.bankdroid.banks.Villabanken;
 
 public class BankFactory {
 
 	public static Bank fromBanktypeId(int id, Context context) throws BankException {
 		switch (id) {
-		case Bank.SWEDBANK:
-			return new Swedbank(context);
+        case Bank.TESTBANK:
+            return new TestBank(context);
+        case Bank.SWEDBANK:
+            return new Swedbank(context);
 		case Bank.NORDEA:
 			return new Nordea(context);
 		case Bank.LANSFORSAKRINGAR:
@@ -80,6 +83,7 @@ public class BankFactory {
 		banks.add(new Eurocard(context));
         banks.add(new FirstCard(context));
         banks.add(new PayPal(context));
+        banks.add(new TestBank(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 7137406..741e3f5 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -1,6 +1,5 @@
 package com.liato.bankdroid;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 import android.app.AlertDialog;
@@ -16,7 +15,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
-import android.view.InflateException;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -24,7 +22,6 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.OnClickListener;
-import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.ListView;
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 2301d20..a1a213d 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -30,7 +30,8 @@ public class Avanza extends Bank {
 	private static final String NAME = "Avanza";
 	private static final String NAME_SHORT = "avanza";
 	private static final String URL = "https://www.avanza.se/";
-	private static final int BANKTYPE_ID = Bank.AVANZA;
+    private static final int BANKTYPE_ID = Bank.AVANZA;
+    private static final boolean BROKEN = true;
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -41,6 +42,7 @@ public class Avanza extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.BROKEN = BROKEN;
 	}
 
 	public Avanza(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 4c45600..20f7088 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -99,7 +99,8 @@ public class Nordea extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+		    
+		    Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
 			
 			matcher = reAccounts.matcher(response);
@@ -130,6 +131,7 @@ public class Nordea extends Bank {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c:"+matcher.group(1).trim(), -1L, Account.CCARD));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
+
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
diff --git src/com/liato/bankdroid/banks/TestBank.java src/com/liato/bankdroid/banks/TestBank.java
new file mode 100644
index 0000000..0651263
--- /dev/null
+++ src/com/liato/bankdroid/banks/TestBank.java
@@ -0,0 +1,138 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.client.ClientProtocolException;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class TestBank extends Bank {
+	private static final String TAG = "TestBank";
+	private static final String NAME = "Testbank";
+	private static final String NAME_SHORT = "testbank";
+	private static final String URL = "http://www.nullbyte.eu/";
+	private static final int BANKTYPE_ID = Bank.TESTBANK;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
+	
+	private Pattern reAccounts = Pattern.compile("<div>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</span>\\s*<span>([^<]+)</", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+	public TestBank(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
+	}
+
+	public TestBank(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib();
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+		    
+            response = urlopen.open("http://www.nullbyte.eu/static/bankdroid/tests/testbank/accounts.htm");
+            matcher = reAccounts.matcher(response);
+            while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: Name              Sparkonto
+                 * 2: Amount            83553,70
+                 * 3: ID                1
+                 * 4: Type              trans|fund
+                 *  
+                 */
+                Account acc = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ("fund".equals(matcher.group(4)) ? "f:" : "")+matcher.group(3).trim());
+                if ("fund".equals(matcher.group(4))) {
+                    acc.setType(Account.FUNDS);
+                }
+                else {
+                    balance = balance.add(Helpers.parseBalance(matcher.group(3)));    
+                }
+                accounts.add(acc);
+            }		        
+
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		    super.updateComplete();
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
+		//No transaction history for loans, funds and credit cards.
+		int accType = account.getType();
+		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
+
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("http://www.nullbyte.eu/static/bankdroid/tests/testbank/transactions_"+account.getId()+".htm");
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+    @Override
+    public int getImageResource() {
+        return res.getIdentifier("icon_large", "drawable", context.getPackageName()); 
+    }
+}
\ No newline at end of file

commit 1778cec33dc6445b3029d562ba5bf0fe128833aa
Author: liato <x@x00.us>
Date:   Sun Nov 14 23:35:41 2010 +0100

    Improved Statoil regex. Should now get all transactions.

diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index e787f8f..86e9a01 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -145,13 +145,13 @@ public class Statoil extends Bank {
 				/*
 				 * Capture groups:
 				 * GROUP				EXAMPLE DATA
-				 * 1: date				10-18
-				 * 2: date				10-19
-				 * 3: specification		ICA Kvantum
-				 * 4: location			Stockholm
-				 * 5: currency			always empty?
-				 * 6: amount			always empty?
-				 * 7: amount in sek		5791,18
+				 * 1: Date				10-18
+				 * 2: Date				10-19
+				 * 3: Specification		ICA Kvantum
+				 * 4: Location			Stockholm
+				 * 5: Currency			always empty?
+				 * 6: Amount			always empty?
+				 * 7: Amount in sek		5791,18
 				 * 
 				 */				
 				transactions.add(new Transaction(""+cal.get(Calendar.YEAR)+"-"+matcher.group(1).trim(), Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(7)).negate()));

commit cdb1dbdc5c7a1121deeb4db891aa64aac128081b
Author: liato <x@x00.us>
Date:   Sun Nov 14 23:17:19 2010 +0100

    Possible fix for FirstCard.

diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
index 9a37116..bdb72ea 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -140,7 +140,7 @@ public class FirstCard extends Bank {
 				 */
 				String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
 				strDate = "20"+strDate.charAt(0)+strDate.charAt(1)+"-"+strDate.charAt(2)+strDate.charAt(3)+"-"+strDate.charAt(4)+strDate.charAt(5);
-				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim()+(matcher.group(3).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(6)).negate()));
+				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(5)).negate()));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {

commit 62f8d610b6bc5ad69a1f0fbc1e0e1854d5255a5f
Author: liato <x@x00.us>
Date:   Sun Nov 14 06:35:03 2010 +0100

    Added swedish translation for settings and lock pattern.

diff --git res/values-sv/array.xml res/values-sv/array.xml
new file mode 100644
index 0000000..255a855
--- /dev/null
+++ res/values-sv/array.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<string-array
+		name="refreshrateNames">
+		<item>15 minuter</item>
+		<item>30 minuter</item>
+		<item>1 timme</item>
+		<item>2 timmar</item>
+		<item>4 timmar</item>
+		<item>8 timmar</item>
+		<item>16 timmar</item>
+		<item>Dagligen</item>
+	</string-array>
+</resources>
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index ae1ee3a..79647ce 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     
     <string name="about">Om</string>
     <string name="version">Version $version av liato</string>
@@ -100,5 +101,88 @@
 	\ncola (OKQ8)
 	\nRikko (FirstCard)
 	\nnihplod (Eurocard)
-    </string>	    
+    </string>
+    
+
+	<!-- Lock Pattern settings -->
+    <!-- Security & location settings screen, header -->
+    <string name="lock_settings_title">Lås för SIM-kort</string>
+    <!-- Security & location settings screen, setting option name -->
+    <string name="lockpattern_change_lock_pattern_label">Byt grafiskt lösenord</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern".  We first ask the user toe nter the current pattern, and this is the message seen -->
+    <string name="lockpattern_need_to_unlock">Bekräfta sparat grafiskt lösenord</string>
+    <!-- Do not translate. -->
+    <string name="lockpattern_need_to_unlock_footer"></string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction if user draws incorrect pattern -->
+    <string name="lockpattern_need_to_unlock_wrong">Försök igen:</string>
+    <!-- Do not translate. -->
+    <string name="lockpattern_need_to_unlock_wrong_footer"></string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen.  This si when they are supposed to draw a new unlock pattern (for example, if they are changing their unlock patterns)..-->
+    <string name="lockpattern_recording_intro_header">Rita ett grafiskt lösenord</string>
+    <!-- Security & location settings screen, change unlock pattern screen hint on bottom of screen.  We are telling them to press the menu button to see more options or help. -->
+    <string name="lockpattern_recording_intro_footer">Tryck på Meny om du vill ha hjälp.</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen while drawing pattern -->
+    <string name="lockpattern_recording_inprogress">Lyft fingret när du är klar.</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen if user doesn't connect enough dots -->
+    <string name="lockpattern_recording_incorrect_too_short">Anslut minst <xliff:g id="number">%d</xliff:g> punkter. Försök igen:</string>
+    <!-- Security & location settings screen, change unlock pattern screen message on top of screen after drawing pattern -->
+    <string name="lockpattern_pattern_entered_header">Det grafiska lösenordet har registrerats!</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen to confirm pattern -->
+    <string name="lockpattern_need_to_confirm">Rita ditt grafiska lösenord igen för att bekräfta:</string>
+    <string name="lockpattern_pattern_confirmed_header">Ditt nya grafiska lösenord:</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen.  After they draw a pattern and release their finger, we display the pattern so they remember.  When they are ready to draw it once again to confirm it, they press this button. -->
+    <string name="lockpattern_confirm_button_text">Bekräfta</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen.  After they draw a pattern and release their finger, we display the pattern so they remember.  If they are nto satisfied with this pattern, they click this button to redraw the pattern. -->
+    <string name="lockpattern_restart_button_text">Rita igen</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen. If they are supposed to enter their current pattern before being able to draw another one, and they screw up, they hit this button to try again -->
+    <string name="lockpattern_retry_button_text">Försök igen</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen. Once they draw a new pattern and confirm it by drawing it again, they press this button to exit -->
+    <string name="lockpattern_continue_button_text">Fortsätt</string>
+    <!-- Security & location settings screen, unlock screen activity title -->
+    <string name="lockpattern_settings_title">Grafiskt lösenord</string>
+    <!-- Security & location settings screen, setting check box title if the unlock pattern MUST be drawn everytime they turn on the screen -->
+    <string name="lockpattern_settings_enable_title">Begär grafiskt lösenord</string>
+    <!-- Security & location settings screen, setting summary for the checkbox "Require pattern" -->
+    <string name="lockpattern_settings_enable_summary">Måste rita grafiskt lösenord för att låsa upp skärmen</string>
+    <!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern.  If checked, this line is drawn.  If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
+    <string name="lockpattern_settings_enable_visible_pattern_title">Anv. synligt graf. lös.</string>
+    <!-- Security & location settings screen, setting check box title. This setting controls whether tactile feedback will be produced when the user draws the pattern.-->
+    <string name="lockpattern_settings_enable_tactile_feedback_title">Använd känslig feedback</string>
+    <!-- Security & location settings screen, setting option name when user has never set an unlock pattern -->
+    <string name="lockpattern_settings_choose_lock_pattern">Ange grafiskt lösenord</string>
+    <!-- Security & location settings screen, setting option name when user has previously set an unlock pattern and wants to change to a new pattern -->
+    <string name="lockpattern_settings_change_lock_pattern">Byt grafiskt lösenord</string>
+    <!-- Security & location settings screen, the help instructions (an animation) caption -->
+    <string name="lockpattern_settings_help_how_to_record">Så här ritar du ett grafiskt lösenord</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen after too many incorrect attempts -->
+    <string name="lockpattern_too_many_failed_confirmation_attempts_header">För många felaktiga försök!</string>
+    <!-- Security & location settings screen, change unlock pattern screen countdown hint on bottom of screen after too many incorrect attempts -->
+    <string name="lockpattern_too_many_failed_confirmation_attempts_footer">Försök igen om <xliff:g id="number">%d</xliff:g> sekunder.</string>
+
+    <!-- ChooseLockPatternTutorial --> <skip />
+    <!-- ChooseLockPatternTutorial, button labels: This is to cancel the tutorial -->
+    <string name="skip_button_label">Avbryt</string>
+    <!-- ChooseLockPatternTutorial, button labels: Continue to the next page of the tutorial -->
+    <string name="next_button_label">Nästa</string>
+    <!-- ChooseLockPatternTutorial, tutorial screen title -->
+    <string name="lock_title">Skydda din telefon</string>
+    <!-- ChooseLockPatternTutorial, tutorial screen text -->
+    <string name="lock_intro_message">><font size="17">Skydda din telefon från obehörig användning genom att skapa ett personligt grafiskt lösenord på skärmen.
+		\n<font height="17">\n</font><b>1</b>\u00A0 Se hur ett grafiskt lösenord ritas på nästa skärm.
+		\n<font height="17">\n</font><b>2</b>\u00A0 Rita ditt eget grafiska lösenord. Experimentera med olika grafiska lösenord men anslut minst fyra punkter.
+		\n<font height="17">\n</font><b>3</b>\u00A0 Rita ditt grafiska lösenord igen för att bekräfta.
+		\n<font height="17">\n</font><b>Är du redo att börja? Välj \u201CNästa\u201D</b>.
+		\n<font height="3">\n</font>"Välj \u201CAvbryt\u201D om du vill lämna telefonen oskyddad.</font>
+		
+	</string>
+    <!-- ChooseLockPatternExample --> <skip />
+    <!-- ChooseLockPatternExample, screen title that shows an example pattern -->
+    <string name="lock_example_title">Exempel på grafiskt lösenord</string>
+    <!-- ChooseLockPatternExample, screen hint text at bottom of screen. These are instructions and rules for drawing a good patttern -->
+    <string name="lock_example_message">Anslut minst fyra punkter.
+    \n\nVälj \u201CNästa\u201D när du vill rita ditt eget grafiska lösenord.
+    </string>
+	<string name="lock_cancel">Avbryt</string>
+	<string name="lock_ok">Ok</string>
+    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 4bbde44..c147fd3 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -105,7 +105,6 @@
      </string>
      
      
-
     <!-- Lock Pattern settings -->
     <!-- Security & location settings screen, header -->
     <string name="lock_settings_title">Screen unlock pattern</string>
diff --git res/xml-sv/settings.xml res/xml-sv/settings.xml
new file mode 100644
index 0000000..5f53c6a
--- /dev/null
+++ res/xml-sv/settings.xml
@@ -0,0 +1,119 @@
+<PreferenceScreen
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<PreferenceCategory
+		android:title="Säkerhet">
+		<CheckBoxPreference
+			android:key="patternlock_enabled"
+			android:defaultValue="false"
+			android:title="Aktivera grafiskt lösenord"
+			android:summary="Skydda appen och widgets med ett grafiskt lösenord" />
+		<Preference
+			android:title="Ändra grafiskt lösenord"
+			android:summary="Ändra ditt nuvarande grafiska lösenord"
+			android:key="patternlock_change"
+			android:dependency="patternlock_enabled" />
+	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Automatiska Uppdateringar">
+		<CheckBoxPreference
+			android:key="autoupdates_enabled"
+			android:defaultValue="true"
+			android:title="Aktivera"
+			android:summary="Aktivera automatiska uppdateringar" />
+		<ListPreference
+			android:title="Uppdateringsfrekvens"
+			android:key="refresh_rate"
+			android:defaultValue="60"
+			android:entries="@array/refreshrateNames"
+			android:entryValues="@array/refreshrateValues"
+			android:dependency="autoupdates_enabled" />
+		<CheckBoxPreference
+			android:key="autoupdates_transactions_enabled"
+			android:defaultValue="true"
+			android:title="Uppdatera kontoutdrag"
+			android:summary="Uppdatera kontoutdrag vid automatiska uppdateringar" />
+	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Notifieringar">
+		<CheckBoxPreference
+			android:key="notify_on_change"
+			android:defaultValue="true"
+			android:title="Aktivera notifieringar"
+			android:summary="Notifiera vid kontoförändringar" />
+		<CheckBoxPreference
+			android:key="notify_with_vibration"
+			android:defaultValue="true"
+			android:title="Vibrera"
+			android:summary="Vibrera vid kontoförändringar"
+			android:dependency="notify_on_change" />
+		<RingtonePreference
+			android:key="notification_sound"
+			android:name="Välj ljud"
+			android:summary="Välj ett notifieringsljud"
+			android:title="Notifieringsljud"
+			android:ringtoneType="notification"
+			android:showDefault="true"
+			android:showSilent="true"
+			
+			android:dependency="notify_on_change" />
+		<PreferenceScreen
+			android:key="account_types_screen"
+			android:title="Kontotyper"
+			android:summary="Visa endast notifieringar för valda kontotyper"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_for_deposit"
+				android:defaultValue="true"
+				android:title="@string/deposit_account" />
+			<CheckBoxPreference
+				android:key="notify_for_funds"
+				android:defaultValue="false"
+				android:title="@string/loans" />
+			<CheckBoxPreference
+				android:key="notify_for_loans"
+				android:defaultValue="false"
+				android:title="@string/funds" />
+			<CheckBoxPreference
+				android:key="notify_for_ccards"
+				android:defaultValue="true"
+				android:title="@string/ccards" />
+			<CheckBoxPreference
+				android:key="notify_for_other"
+				android:defaultValue="false"
+				android:title="@string/other" />
+		</PreferenceScreen>
+		<PreferenceScreen
+			android:key="remotenotifier_screen"
+			android:title="Remote Notifier-integrering"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_remotenotifier"
+				android:defaultValue="false"
+				android:title="Aktivera"
+				android:summary="Aktivera Remote Notifier-integrering" />
+			<Preference
+				android:title="Vad är Remote Notifier?"
+				android:summary="Läs mer om Remote Notifier på deras webbsida"
+				android:key="remotenotifier_help" />
+		</PreferenceScreen>
+		<PreferenceScreen
+			android:key="openwatch_screen"
+			android:title="OpenWatch-integrering"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_openwatch"
+				android:defaultValue="false"
+				android:title="Aktivera"
+				android:summary="Aktivera OpenWatch-integrering" />
+			<CheckBoxPreference
+				android:key="notify_openwatch_vibrate"
+				android:defaultValue="false"
+				android:title="Vibrera"
+				android:summary="Vibrera OpenWatch-enheten" />
+			<Preference
+				android:title="Vad är OpenWatch?"
+				android:summary="Läs mer om OpenWatch på deras webbsida"
+				android:key="openwatch_help" />
+		</PreferenceScreen>
+	</PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file

commit 9d15333589125674750fb07afc49135b2d76980f
Author: liato <x@x00.us>
Date:   Fri Nov 12 05:31:08 2010 +0100

    Don't add balance from hidden accounts to total bank balance. Closes #18.

diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 61fcfc1..bff868b 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -37,6 +37,7 @@ public abstract class Bank implements Comparable<Bank> {
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
     protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
     protected String INPUT_HINT_USERNAME = null;
+    protected boolean STATIC_BALANCE = false;
 
 	protected Context context;
 	protected Resources res;
@@ -131,7 +132,20 @@ public abstract class Bank implements Comparable<Bank> {
 	}
 
 	public BigDecimal getBalance() {
-		return balance;
+	    if (STATIC_BALANCE) {
+	        return balance;
+	    }
+	    else {
+	        BigDecimal bal = new BigDecimal(0); 
+	        for (Account account : accounts) {
+	            if (account.getType() == Account.REGULAR || account.getType() == Account.CCARD) {
+	                if (!account.isHidden()) {
+	                    bal = bal.add(account.getBalance());
+	                }
+	            }
+	        }
+	        return bal;
+	    }
 	}
 
 	public int getBanktypeId() {
diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banks/PayPal.java
index 8b2a547..1fe54a4 100644
--- src/com/liato/bankdroid/banks/PayPal.java
+++ src/com/liato/bankdroid/banks/PayPal.java
@@ -30,6 +30,7 @@ public class PayPal extends Bank {
 	private static final String URL = "https://www.paypal.com/";
 	private static final int BANKTYPE_ID = Bank.PAYPAL;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+	private static final boolean STATIC_BALANCE = true;
 	
 	private Pattern reFormAction = Pattern.compile("<form.*?login_form.*?action=\"([^\"]+)\".*?>", Pattern.CASE_INSENSITIVE);
 	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*<span\\s*class=\"balance\">\\s*<[^<]+>[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
@@ -43,6 +44,7 @@ public class PayPal extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.STATIC_BALANCE = STATIC_BALANCE;
 	}
 
 	public PayPal(String username, String password, Context context) throws BankException, LoginException {

commit 5f83f69a0c30cc160d3dc6cd8668751634329258
Author: liato <x@x00.us>
Date:   Fri Nov 12 03:18:59 2010 +0100

    Fixed Eurocard. Closes #21

diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 29b79d4..a320fd2 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -1,6 +1,7 @@
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
@@ -34,8 +35,9 @@ public class Eurocard extends Bank {
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
-	private Pattern reAccounts = Pattern.compile("getInvoiceList\\.do\\?id=([^\"]+)\">([^<]+)</a></td>(?:\\s*<td>[^<]+</td>){2}\\s*<td\\s*align=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("<nobr>(\\d\\d-\\d\\d)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>[^<]+</nobr>\\s*</td>\\s*<td><div\\s*class=\"BreakLine\">([^<]+)</div>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td[^>]+>\\s*<nobr>([^>]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">[^<]+</td>\\s*<td[^>]+>\\s*<nobr>([^<]+)</nobr>", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("Welcomepagecardimagecontainer\">\\s*[^<]+<br>[^>]+<br>([^>]+)</div>\\s*</div>\\s*</div>.*?indentationwrapper\">\\s*<a\\s*href=\"getPendingTransactions\\.do\\?id=([^\"]+)\">.*?billedamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reSaldo = Pattern.compile("Billingunitbalanceamount\">\\s*([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	public Eurocard(Context context) {
 		super(context);
@@ -90,10 +92,44 @@ public class Eurocard extends Bank {
 		}
 		urlopen = login();
 		Matcher matcher = reAccounts.matcher(response);
-		while (matcher.find()) {
-			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+		if (matcher.find()) {
+            /*
+             * Capture groups:
+             * GROUP                     EXAMPLE DATA
+             * 1: account number         **** **** **** 1234
+             * 2: id                     a1c2d3d4e5f6s7b8c9d0
+             * 3: ofakturerat amount     &nbsp;2 988,96
+             * 
+             */
+
+		    // Create a separate account for "Ofakturerat".
+		    // Set the balance for the main account to 0 and update it later
+			accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), new BigDecimal(0), matcher.group(2).trim()));
+			accounts.add(new Account("Ofakturerat", Helpers.parseBalance(matcher.group(3)), "o:ofak", Account.OTHER));
+		}
+		try {
+            /*
+             * Capture groups:
+             * GROUP                     EXAMPLE DATA
+             * 1: balance                &nbsp;40 988,96
+             * 
+             */		    
+            response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getBillingUnits.do");
+            matcher = reSaldo.matcher(response);
+            if (matcher.find()) {
+                // Update the main account balance
+                if (accounts.isEmpty()) {
+                    accounts.get(0).setBalance(Helpers.parseBalance(matcher.group(1)));
+                }
+            }
 		}
+        catch (ClientProtocolException e) {
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+
 
 		if (accounts.isEmpty()) {
 			throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -105,27 +141,30 @@ public class Eurocard extends Bank {
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
 		Matcher matcher;
+		// If the account is of type "other" it's probably the fake "Ofakturerat" account.
+		if (account.getType() == Account.OTHER) return;
 		try {
-			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do");
-			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do");
+			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+account.getId());
+			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do?id="+account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			String strDate = null;
 			Calendar cal = Calendar.getInstance();
 			while (matcher.find()) {
-				/*
-				 * Capture groups:
-				 * GROUP				EXAMPLE DATA
-				 * 1: date		 		09-26
-				 * 2: specification		ICA Kvantum
-				 * 3: location          Stockholm
-				 * 4: currency			SEK or empty
-				 * 5: tax				12.99 or empty
-				 * 6: amount			118.65
-				 * 
-				 */
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: trans. date       10-18
+                 * 2: reg. date         10-19
+                 * 3: specification     ICA Kvantum
+                 * 4: location          Stockholm
+                 * 5: currency          SEK
+                 * 6: amount/tax        147,64
+                 * 7: amount in sek     5791,18
+                 * 
+                 */     			    
 				strDate = ""+cal.get(Calendar.YEAR)+"-"+Html.fromHtml(matcher.group(1)).toString().trim();
-				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim()+(matcher.group(3).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(6)).negate()));
+				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(7)).negate()));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {

commit eb6c077bca92ad3907f0603d27b9037ac3496d12
Author: liato <x@x00.us>
Date:   Thu Nov 11 16:38:10 2010 +0100

    Fixed PayPal.

diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banks/PayPal.java
index c74671a..8b2a547 100644
--- src/com/liato/bankdroid/banks/PayPal.java
+++ src/com/liato/bankdroid/banks/PayPal.java
@@ -31,8 +31,9 @@ public class PayPal extends Bank {
 	private static final int BANKTYPE_ID = Bank.PAYPAL;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
 	
-	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*<span\\s*class=\"balance\">[^0-9,.-]*([0-9,. ]+)([A-Z]+)</span>", Pattern.CASE_INSENSITIVE);
-	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">[^0-9,.-]*([0-9,. ]+)([A-Z]+)</td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reFormAction = Pattern.compile("<form.*?login_form.*?action=\"([^\"]+)\".*?>", Pattern.CASE_INSENSITIVE);
+	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*<span\\s*class=\"balance\">\\s*<[^<]+>[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^<]+>\\s*</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">\\s*<[^>]+>\\s*[^0-9,.-]*([0-9,. ]+)([A-Z]+)\\s*<[^>]+>\\s*</td>", Pattern.CASE_INSENSITIVE);
 	private String response = null;
 	public PayPal(Context context) {
 		super(context);
@@ -53,11 +54,18 @@ public class PayPal extends Bank {
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib(true);
 		try {
-		    //Get cookies
+		    //Get cookies and url to post to
 		    response = urlopen.open("https://www.paypal.com/en");
-
+		    Matcher matcher = reFormAction.matcher(response);
+		    String strPostUrl;
+		    if (matcher.find()) {
+		        strPostUrl = Html.fromHtml(matcher.group(1)).toString();
+		        Log.d(TAG, "Found post url: "+strPostUrl);
+		    }
+		    else {
+		        throw new BankException(res.getText(R.string.unable_to_find).toString()+" post url.");
+		    }
 		    List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));				
 			postData.add(new BasicNameValuePair("login_email", username));
 			postData.add(new BasicNameValuePair("login_password", password));
 			postData.add(new BasicNameValuePair("target_page", "0"));
@@ -67,18 +75,22 @@ public class PayPal extends Bank {
 			postData.add(new BasicNameValuePair("browser_version", "undefined"));
 			postData.add(new BasicNameValuePair("operating_system", "Windows"));
 			postData.add(new BasicNameValuePair("bp_mid", "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
-			postData.add(new BasicNameValuePair("bp_ks1", "v=1;l=16;Di0:1103361Ui0:95Di1:5Ui1:138Di2:171Di3:154Ui2:59Ui3:81Di4:562Ui4:147Di5:369Ui5:118Di6:401Ui6:124Di7:296Ui7:74Di8:71Ui8:101Di9:61Ui9:81Di10:7Ui10:94Di11:666Ui11:131Di12:79Ui12:107Di13:114Ui13:109Di14:5Ui14:152Di15:400Ui15:121"));
+			postData.add(new BasicNameValuePair("bp_ks1", "v=1;l=16;Di0:2663Di1:48Ui0:15Ui1:81Di2:176Di3:48Ui2:32Ui3:96Di4:384Ui4:48Di5:352Ui5:48Di6:128Ui6:80Di7:112Ui7:48Di8:113Ui8:79Di9:125Ui9:51Di10:98Ui10:72Di11:227Ui11:51Di12:80Ui12:80Di13:128Ui13:64Di14:48Ui14:80Di15:416Ui15:80"));
 			postData.add(new BasicNameValuePair("bp_ks2", ""));
 			postData.add(new BasicNameValuePair("bp_ks3", ""));
 			postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
 			postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
 			
-			Log.d(TAG, "Posting to https://www.paypal.com/cgi-bin/webscr?cmd=_login-submit&dispatch=5885d80a13c0db1f8e263663d3faee8dc60d77e6184470d515cedf52660ea0cd");
-			response = urlopen.open("https://www.paypal.com/cgi-bin/webscr?cmd=_login-submit&dispatch=5885d80a13c0db1f8e263663d3faee8dc60d77e6184470d515cedf52660ea0cd", postData);
+			Log.d(TAG, "Posting to " + strPostUrl);
+			response = urlopen.open(strPostUrl, postData);
 			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
 			if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
+			if (response.contains("your last action could not be completed")) {
+			    throw new BankException("Error: PPL92");
+			}
+
 			
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());

commit 2bd1e1486ca317ac52d88d0bfea9012aa7f2ab2e
Author: liato <x@x00.us>
Date:   Thu Nov 11 09:09:57 2010 +0100

    Add missing bank.xml file.

diff --git res/layout/bank.xml res/layout/bank.xml
new file mode 100644
index 0000000..4d22c6b
--- /dev/null
+++ res/layout/bank.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat"
+	android:layout_width="fill_parent">
+
+	<ScrollView
+
+		android:layout_height="fill_parent"
+		android:layout_width="fill_parent"
+		android:fillViewport="true" android:layout_above="@+id/TableLayout01">
+		<LinearLayout
+			android:id="@+id/LinearLayout01"
+			android:layout_height="wrap_content"
+			android:layout_below="@+id/txtErrorDesc"
+			android:layout_width="wrap_content"
+			android:orientation="vertical"
+			android:layout_alignParentTop="true"
+			android:padding="10dp">
+			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/bank" /><Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/username" />
+			<EditText
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/edtBankeditUsername" android:inputType="textEmailAddress"></EditText>
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/password" />
+			<EditText
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp" android:text="@string/custom_name"/><EditText
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/edtBankeditCustomName" android:inputType="textCapWords"></EditText>
+			
+			
+			<TextView
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:drawableLeft="@drawable/indicator_input_error"
+				android:text="@string/error_desc"
+				android:textSize="12sp"
+				android:drawablePadding="5dp"
+				android:id="@+id/txtErrorDesc"
+				android:visibility="invisible"></TextView>
+		</LinearLayout>
+	</ScrollView>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:stretchColumns="0,2"
+		android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentRight="true"
+		android:layout_width="wrap_content"
+		android:layout_below="@+id/LinearLayout01"
+		android:gravity="bottom">
+		<TableRow
+			android:id="@+id/TableRow01"
+			android:layout_height="wrap_content"
+			android:gravity="center_vertical|center_horizontal"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent">
+			<Button
+				android:text="@string/cancel"
+				android:drawableLeft="@drawable/button_cancel"
+				android:id="@+id/btnSettingsCancel"
+				style="@style/Menu_Button"></Button>
+			<ImageView
+				android:layout_height="wrap_content"
+				android:focusable="false"
+				android:src="@drawable/menu_separator"
+				android:adjustViewBounds="true"
+				android:scaleType="fitXY"
+				android:minWidth="3dp"
+				android:maxWidth="3dp"
+				android:layout_width="wrap_content"></ImageView>
+			<Button
+				android:id="@+id/btnSettingsOk"
+				android:drawableLeft="@drawable/button_save"
+				android:text="@string/save"
+				style="@style/Menu_Button"></Button>
+		</TableRow>
+	</TableLayout>
+</RelativeLayout>
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 12e2e1f..e0664d3 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -32,7 +32,7 @@ public class StartupReceiver extends BroadcastReceiver{
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*1*1000, refreshRate*1*1000, alarmSender);
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*60*1000, refreshRate*60*1000, alarmSender);
         	Log.d(TAG,"Automatic updates set to "+refreshRate.toString()+" minutes.");
         }
 	

commit 700c7b2781d1e4389189a926f4de474603959d70
Author: liato <x@x00.us>
Date:   Thu Nov 11 08:38:15 2010 +0100

    Replaced Settings screen with PreferenceActivity. Replaced password lock with pattern lock, closes #9. Option to set custom notification sound, closes #8. Option not to update transactions on automatic updates, closes #1. Added Remote Notifier integration, closes #17. Added OpenWatch integration.

diff --git .classpath .classpath
index 609aa00..6d8bf51 100644
--- .classpath
+++ .classpath
@@ -3,5 +3,6 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="src" path="gen"/>
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="lib" path="C:/Program Files (x86)/android-sdk-windows/libs/google-collect-1.0/google-collect-1.0.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git AndroidManifest.xml AndroidManifest.xml
index 2758f03..0bff922 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,17 +2,27 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="42" android:versionName="1.4.2">
+	android:versionName="1.4.2"
+	android:versionCode="42">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
 		android:debuggable="false">
+		<!--
+			<activity android:label="@string/app_name"
+			android:multiprocess="false" android:name=".MainActivity"
+			android:alwaysRetainTaskState="false"
+			android:theme="@android:style/Theme.Dialog"> <intent-filter> <action
+			android:name="android.intent.action.MAIN" /> <category
+			android:name="android.intent.category.LAUNCHER" /> </intent-filter>
+			</activity>
+		-->
 		<activity
+			android:name=".MainActivity"
 			android:label="@string/app_name"
 			android:multiprocess="false"
-			android:name=".LoginActivity"
 			android:alwaysRetainTaskState="false"
-			android:theme="@android:style/Theme.Dialog">
+			android:configChanges="keyboardHidden|orientation">
 			<intent-filter>
 				<action
 					android:name="android.intent.action.MAIN" />
@@ -20,11 +30,6 @@
 					android:name="android.intent.category.LAUNCHER" />
 			</intent-filter>
 		</activity>
-		<activity
-			android:name=".MainActivity"
-			android:label="@string/app_name"
-			android:configChanges="keyboardHidden|orientation">
-		</activity>
 		<activity
 			android:name=".TransactionsActivity"
 			android:label="@string/app_name">
@@ -114,8 +119,8 @@
 		</receiver>
 	</application>
 	<uses-sdk
-		android:minSdkVersion="4"
-		android:targetSdkVersion="4" />
+		android:targetSdkVersion="4"
+		android:minSdkVersion="4" />
 	<uses-permission
 		android:name="android.permission.INTERNET"></uses-permission>
 	<uses-permission
diff --git res/drawable-hdpi-v4/btn_code_lock_default.png res/drawable-hdpi-v4/btn_code_lock_default.png
new file mode 100644
index 0000000..df3137f
Binary files /dev/null and res/drawable-hdpi-v4/btn_code_lock_default.png differ
diff --git res/drawable-hdpi-v4/btn_code_lock_touched.png res/drawable-hdpi-v4/btn_code_lock_touched.png
new file mode 100644
index 0000000..bf9e46a
Binary files /dev/null and res/drawable-hdpi-v4/btn_code_lock_touched.png differ
diff --git res/drawable-hdpi-v4/ic_btn_next.png res/drawable-hdpi-v4/ic_btn_next.png
new file mode 100644
index 0000000..ad00a95
Binary files /dev/null and res/drawable-hdpi-v4/ic_btn_next.png differ
diff --git res/drawable/ic_btn_next.png res/drawable/ic_btn_next.png
new file mode 100644
index 0000000..c6cf436
Binary files /dev/null and res/drawable/ic_btn_next.png differ
diff --git res/drawable/indicator_code_lock_drag_direction_green_up.png res/drawable/indicator_code_lock_drag_direction_green_up.png
new file mode 100644
index 0000000..ef91dc4
Binary files /dev/null and res/drawable/indicator_code_lock_drag_direction_green_up.png differ
diff --git res/drawable/indicator_code_lock_drag_direction_red_up.png res/drawable/indicator_code_lock_drag_direction_red_up.png
new file mode 100644
index 0000000..f3d4204
Binary files /dev/null and res/drawable/indicator_code_lock_drag_direction_red_up.png differ
diff --git res/drawable/indicator_code_lock_point_area_default.png res/drawable/indicator_code_lock_point_area_default.png
new file mode 100644
index 0000000..4e88b37
Binary files /dev/null and res/drawable/indicator_code_lock_point_area_default.png differ
diff --git res/drawable/indicator_code_lock_point_area_green.png res/drawable/indicator_code_lock_point_area_green.png
new file mode 100644
index 0000000..8020846
Binary files /dev/null and res/drawable/indicator_code_lock_point_area_green.png differ
diff --git res/drawable/indicator_code_lock_point_area_red.png res/drawable/indicator_code_lock_point_area_red.png
new file mode 100644
index 0000000..b7aee1b
Binary files /dev/null and res/drawable/indicator_code_lock_point_area_red.png differ
diff --git res/drawable/lock_anim.xml res/drawable/lock_anim.xml
new file mode 100644
index 0000000..ca1f9d8
--- /dev/null
+++ res/drawable/lock_anim.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<animation-list
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:oneshot="false">
+    <item android:drawable="@drawable/lock_anim_00" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_02" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_04" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_06" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_08" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_10" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_12" android:duration="400" />
+    <item android:drawable="@drawable/lock_anim_14" android:duration="400" />
+</animation-list>
diff --git res/drawable/lock_anim_00.png res/drawable/lock_anim_00.png
new file mode 100644
index 0000000..afdda8b
Binary files /dev/null and res/drawable/lock_anim_00.png differ
diff --git res/drawable/lock_anim_02.png res/drawable/lock_anim_02.png
new file mode 100644
index 0000000..0542b1d
Binary files /dev/null and res/drawable/lock_anim_02.png differ
diff --git res/drawable/lock_anim_04.png res/drawable/lock_anim_04.png
new file mode 100644
index 0000000..a3ca629
Binary files /dev/null and res/drawable/lock_anim_04.png differ
diff --git res/drawable/lock_anim_06.png res/drawable/lock_anim_06.png
new file mode 100644
index 0000000..90205a6
Binary files /dev/null and res/drawable/lock_anim_06.png differ
diff --git res/drawable/lock_anim_08.png res/drawable/lock_anim_08.png
new file mode 100644
index 0000000..af7cd28
Binary files /dev/null and res/drawable/lock_anim_08.png differ
diff --git res/drawable/lock_anim_10.png res/drawable/lock_anim_10.png
new file mode 100644
index 0000000..5de840e
Binary files /dev/null and res/drawable/lock_anim_10.png differ
diff --git res/drawable/lock_anim_12.png res/drawable/lock_anim_12.png
new file mode 100644
index 0000000..8778d98
Binary files /dev/null and res/drawable/lock_anim_12.png differ
diff --git res/drawable/lock_anim_14.png res/drawable/lock_anim_14.png
new file mode 100644
index 0000000..ea1aa31
Binary files /dev/null and res/drawable/lock_anim_14.png differ
diff --git res/layout-land/choose_lock_pattern.xml res/layout-land/choose_lock_pattern.xml
new file mode 100644
index 0000000..176efd8
--- /dev/null
+++ res/layout-land/choose_lock_pattern.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+	<!--
+		Copyright (C) 2008 The Android Open Source Project Licensed under the
+		Apache License, Version 2.0 (the "License"); you may not use this file
+		except in compliance with the License. You may obtain a copy of the
+		License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
+		by applicable law or agreed to in writing, software distributed under
+		the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+		CONDITIONS OF ANY KIND, either express or implied. See the License for
+		the specific language governing permissions and limitations under the
+		License.
+	-->
+
+<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/topLayout"
+	android:orientation="horizontal"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	android:background="@color/black">
+
+	<!-- left side: instructions and messages -->
+	<LinearLayout
+		android:orientation="vertical"
+		android:layout_width="0dip"
+		android:layout_height="fill_parent"
+		android:layout_weight="1.0">
+
+		<!-- header message -->
+		<TextView
+			android:id="@+id/headerText"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:gravity="center"
+			android:textSize="18sp" />
+
+		<!-- footer can show a message, or confirm / restart buttons -->
+		<RelativeLayout
+			android:layout_width="fill_parent"
+			android:layout_height="0dip"
+			android:layout_weight="1.0">
+
+			<!-- right / bottom button: confirm or ok -->
+			<Button
+				android:id="@+id/footerRightButton"
+				android:layout_height="wrap_content"
+				android:layout_width="140dip"
+				android:layout_alignParentBottom="true"
+				android:layout_centerHorizontal="true"
+				android:ellipsize="marquee"
+				android:singleLine="true"
+				android:drawableRight="@drawable/ic_btn_next"
+				android:drawablePadding="3dip"
+				android:text="@string/lockpattern_confirm_button_text" />
+
+
+			<!-- left / top button: skip, or re-try -->
+			<Button
+				android:id="@+id/footerLeftButton"
+				android:layout_height="wrap_content"
+				android:layout_width="140dip"
+				android:layout_above="@id/footerRightButton"
+				android:layout_centerHorizontal="true"
+				android:ellipsize="marquee"
+				android:singleLine="true"
+				android:text="@string/lockpattern_restart_button_text" />
+
+
+			<!-- message above buttons -->
+			<TextView
+				android:id="@+id/footerText"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:layout_above="@+id/footerLeftButton"
+				android:layout_centerHorizontal="true"
+				android:layout_marginBottom="4dip"
+				android:textSize="14sp" />
+		</RelativeLayout>
+	</LinearLayout>
+
+	<View
+		android:background="@*android:drawable/code_lock_left"
+		android:layout_width="2dip"
+		android:layout_height="fill_parent" />
+	<!-- right side: lock pattern -->
+	<com.liato.bankdroid.LockPatternView
+		android:id="@+id/lockPattern"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content" />
+
+
+</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
+
diff --git res/layout-land/confirm_lock_pattern.xml res/layout-land/confirm_lock_pattern.xml
new file mode 100644
index 0000000..4abb098
--- /dev/null
+++ res/layout-land/confirm_lock_pattern.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+        xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/topLayout"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="@color/black">
+
+    <!-- left side: instructions and messages -->
+    <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="0dip"
+            android:layout_height="fill_parent"
+            android:layout_weight="1.0"
+            >
+
+        <!-- header message -->
+        <TextView android:id="@+id/headerText"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:textSize="18sp"/>
+
+        <!-- fill space between header and button below -->
+        <View
+            android:layout_weight="1.0"
+            android:layout_width="fill_parent"
+            android:layout_height="0dip"
+            />
+
+        <!-- footer message -->
+        <TextView android:id="@+id/footerText"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:gravity="center"
+                  android:textSize="14sp"/>
+    </LinearLayout>
+
+    <View
+         android:background="@*android:drawable/code_lock_left"
+         android:layout_width="2dip"
+         android:layout_height="fill_parent" />
+    <!-- right side: lock pattern -->
+    <com.liato.bankdroid.LockPatternView android:id="@+id/lockPattern"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content" />
+
+
+</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
+
diff --git res/layout/bank.xml res/layout/bank.xml
deleted file mode 100644
index 4d22c6b..0000000
--- res/layout/bank.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat"
-	android:layout_width="fill_parent">
-
-	<ScrollView
-
-		android:layout_height="fill_parent"
-		android:layout_width="fill_parent"
-		android:fillViewport="true" android:layout_above="@+id/TableLayout01">
-		<LinearLayout
-			android:id="@+id/LinearLayout01"
-			android:layout_height="wrap_content"
-			android:layout_below="@+id/txtErrorDesc"
-			android:layout_width="wrap_content"
-			android:orientation="vertical"
-			android:layout_alignParentTop="true"
-			android:padding="10dp">
-			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/bank" /><Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/username" />
-			<EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditUsername" android:inputType="textEmailAddress"></EditText>
-			<TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/password" />
-			<EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView
-				android:layout_width="fill_parent"
-				android:layout_height="wrap_content"
-				android:typeface="sans"
-				android:textSize="20sp" android:text="@string/custom_name"/><EditText
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditCustomName" android:inputType="textCapWords"></EditText>
-			
-			
-			<TextView
-				android:layout_width="wrap_content"
-				android:layout_height="wrap_content"
-				android:drawableLeft="@drawable/indicator_input_error"
-				android:text="@string/error_desc"
-				android:textSize="12sp"
-				android:drawablePadding="5dp"
-				android:id="@+id/txtErrorDesc"
-				android:visibility="invisible"></TextView>
-		</LinearLayout>
-	</ScrollView>
-	<TableLayout
-		android:id="@+id/TableLayout01"
-		android:stretchColumns="0,2"
-		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content"
-		android:layout_below="@+id/LinearLayout01"
-		android:gravity="bottom">
-		<TableRow
-			android:id="@+id/TableRow01"
-			android:layout_height="wrap_content"
-			android:gravity="center_vertical|center_horizontal"
-			android:layout_gravity="center_vertical|center_horizontal"
-			android:layout_width="fill_parent">
-			<Button
-				android:text="@string/cancel"
-				android:drawableLeft="@drawable/button_cancel"
-				android:id="@+id/btnSettingsCancel"
-				style="@style/Menu_Button"></Button>
-			<ImageView
-				android:layout_height="wrap_content"
-				android:focusable="false"
-				android:src="@drawable/menu_separator"
-				android:adjustViewBounds="true"
-				android:scaleType="fitXY"
-				android:minWidth="3dp"
-				android:maxWidth="3dp"
-				android:layout_width="wrap_content"></ImageView>
-			<Button
-				android:id="@+id/btnSettingsOk"
-				android:drawableLeft="@drawable/button_save"
-				android:text="@string/save"
-				style="@style/Menu_Button"></Button>
-		</TableRow>
-	</TableLayout>
-</RelativeLayout>
diff --git res/layout/banks.xml res/layout/banks.xml
deleted file mode 100644
index ed4e9ba..0000000
--- res/layout/banks.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	android:id="@+id/RelativeLayout01"
-	android:layout_width="wrap_content"
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_height="fill_parent"
-	android:tag="rv">
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:id="@+id/txtBanksDesc"
-		android:visibility="visible"
-		android:layout_margin="10dp"
-		android:text="@string/banks_instructions" />
-	<ListView
-		android:layout_width="fill_parent"
-		android:id="@+id/lstvBanksList"
-		android:layout_height="fill_parent"
-		android:fitsSystemWindows="true"
-		android:layout_above="@+id/LinearLayout01"></ListView>
-	<LinearLayout
-		android:id="@+id/LinearLayout01"
-		android:gravity="bottom"
-		android:layout_width="fill_parent"
-		android:layout_weight="1"
-		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true">
-		<Button
-			android:id="@+id/btnBanksNewaccount"
-			android:drawableLeft="@android:drawable/ic_menu_add"
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:layout_gravity="bottom"
-			android:layout_marginLeft="10dp"
-			android:layout_marginRight="10dp"
-			android:text="@string/add_new_account"></Button>
-	</LinearLayout>
-</RelativeLayout>
diff --git res/layout/choose_lock_pattern.xml res/layout/choose_lock_pattern.xml
new file mode 100644
index 0000000..3b06f0c
--- /dev/null
+++ res/layout/choose_lock_pattern.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+        xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/topLayout"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="fill_parent"
+    android:background="@color/black">
+
+    <TextView android:id="@+id/headerText"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:textSize="18sp"/>
+
+    <View
+         android:background="@*android:drawable/code_lock_top"
+         android:layout_width="fill_parent"
+         android:layout_height="2dip" />
+    <com.liato.bankdroid.LockPatternView android:id="@+id/lockPattern"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content" />
+    <View
+         android:background="@*android:drawable/code_lock_bottom"
+         android:layout_width="fill_parent"
+         android:layout_height="8dip" />
+
+    <!-- message just above the button bar -->
+    <TextView android:id="@+id/footerText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:textSize="14sp"/>
+
+    <!-- confirm / restart buttons -->
+    <LinearLayout style="@android:style/ButtonBar"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <!-- left button: skip, or retry -->
+        <Button android:id="@+id/footerLeftButton"
+            android:layout_height="wrap_content"
+            android:layout_width="140dip"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:text="@string/lockpattern_restart_button_text"/>
+
+        <!-- Placeholder to get blank space between the two buttons -->
+        <View
+            android:visibility="invisible"
+            android:layout_height="0dip"
+            android:layout_width="1dip"
+            android:layout_weight="1" />
+
+        <!-- right button: confirm or ok -->
+        <Button android:id="@+id/footerRightButton"
+            android:layout_height="wrap_content"
+            android:layout_width="140dip"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:drawableRight="@drawable/ic_btn_next"
+            android:drawablePadding="3dip"
+            android:text="@string/lockpattern_confirm_button_text"/>
+
+    </LinearLayout>
+
+</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
diff --git res/layout/choose_lock_pattern_example.xml res/layout/choose_lock_pattern_example.xml
new file mode 100644
index 0000000..d1e816c
--- /dev/null
+++ res/layout/choose_lock_pattern_example.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_height="fill_parent"
+    android:layout_width="fill_parent">
+    
+    <ScrollView 
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_weight="1">
+        
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_height="fill_parent"
+            android:layout_width="fill_parent"
+            android:padding="5dip">
+            
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/lock_example_title"
+                android:gravity="center_horizontal"
+                style="?android:attr/textAppearanceLarge"
+            />
+        
+            <ImageView android:id="@+id/lock_anim"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="11dip"
+                android:layout_gravity="center_horizontal"
+                android:focusable="false"
+                android:clickable="false"
+            />
+            
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="5dip"
+                android:text="@string/lock_example_message"
+                android:layout_gravity="left"
+                style="?android:attr/textAppearanceMedium"
+            />
+            
+        </LinearLayout>
+
+    </ScrollView>
+    
+    <LinearLayout style="@android:style/ButtonBar"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+        
+        <Button android:id="@+id/skip_button"
+            android:layout_height="wrap_content"
+            android:layout_width="140dip"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:text="@string/skip_button_label"
+        />
+      
+        <!-- Placeholder to get blank space between the two buttons -->
+        <View
+            android:visibility="invisible"
+            android:layout_height="0dip"
+            android:layout_width="1dip"
+            android:layout_weight="1" />
+            
+        <Button android:id="@+id/next_button"
+            android:layout_height="wrap_content"
+            android:layout_width="140dip"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:drawableRight="@drawable/ic_btn_next"
+            android:drawablePadding="3dip"
+            android:text="@string/next_button_label"
+        />
+        
+    </LinearLayout>
+    
+</LinearLayout>
diff --git res/layout/choose_lock_pattern_tutorial.xml res/layout/choose_lock_pattern_tutorial.xml
new file mode 100644
index 0000000..8eadc01
--- /dev/null
+++ res/layout/choose_lock_pattern_tutorial.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_height="fill_parent"
+    android:layout_width="fill_parent">
+    
+    <ScrollView 
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1">
+        
+        <LinearLayout
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:padding="5dip">
+            
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:gravity="center_horizontal"
+                android:text="@string/lock_title"
+                android:paddingBottom="10dip"
+                android:layout_marginTop="3dip"
+                style="?android:attr/textAppearanceLarge"
+            />
+        
+            <TextView 
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_marginTop="10dip"
+                android:text="@string/lock_intro_message"
+            />
+            
+        </LinearLayout>
+       
+    </ScrollView>
+    
+    <LinearLayout style="@android:style/ButtonBar"
+        android:orientation="horizontal"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+
+        <Button android:id="@+id/skip_button"
+            android:layout_height="wrap_content"
+            android:layout_width="140dip"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:text="@string/skip_button_label"
+        />
+        
+        <!-- Placeholder to get blank space between the two buttons -->
+        <View
+            android:visibility="invisible"
+            android:layout_height="0dip"
+            android:layout_width="1dip"
+            android:layout_weight="1" />
+        
+        <Button android:id="@+id/next_button"
+            android:layout_height="wrap_content"
+            android:layout_width="140dip"
+            android:drawableRight="@drawable/ic_btn_next"
+            android:drawablePadding="3dip"
+            android:ellipsize="marquee"
+            android:singleLine="true"
+            android:text="@string/next_button_label"
+        />
+        
+    </LinearLayout>
+    
+</LinearLayout >
diff --git res/layout/confirm_lock_pattern.xml res/layout/confirm_lock_pattern.xml
new file mode 100644
index 0000000..22880bf
--- /dev/null
+++ res/layout/confirm_lock_pattern.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient
+        xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/topLayout"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="fill_parent"
+    android:background="@color/black">
+
+    <TextView android:id="@+id/headerText"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1.0"
+        android:gravity="center"
+        android:textSize="18sp"/>
+
+    <View
+         android:background="@*android:drawable/code_lock_top"
+         android:layout_width="fill_parent"
+         android:layout_height="2dip" />
+    <com.liato.bankdroid.LockPatternView android:id="@+id/lockPattern"
+         android:layout_width="wrap_content"
+         android:layout_height="wrap_content" />
+    <View
+         android:background="@*android:drawable/code_lock_bottom"
+         android:layout_width="fill_parent"
+         android:layout_height="8dip" />
+
+    <TextView android:id="@+id/footerText"
+        android:layout_width="fill_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1.0"
+        android:gravity="center"
+        android:textSize="14sp"/>
+
+
+</com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient>
diff --git res/layout/login.xml res/layout/login.xml
deleted file mode 100644
index e9a1c01..0000000
--- res/layout/login.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	android:id="@+id/RelativeLayout01"
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent">
-	<LinearLayout
-		android:orientation="vertical"
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:paddingLeft="10dp"
-		android:paddingRight="10dp"
-		android:paddingTop="10dp"
-		android:layout_gravity="center_vertical"
-		android:gravity="center_vertical"
-		android:fitsSystemWindows="true">
-
-
-		<TextView
-			android:id="@+id/TextView01"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:gravity="center_horizontal"
-			android:layout_gravity="center_horizontal"
-			android:text="BANKDROID"
-			android:layout_width="fill_parent"
-			android:visibility="visible"
-			android:textColor="#fff"
-			android:textSize="42dp"></TextView>
-		<LinearLayout
-			android:id="@+id/LinearLayout01"
-			android:layout_height="wrap_content"
-			android:orientation="horizontal"
-			android:layout_width="fill_parent">
-			<ImageView
-				android:id="@+id/ImageView01"
-				android:background="@drawable/icon_large"
-				android:layout_width="100dp"
-				android:layout_height="100dp"
-				android:layout_gravity="center_horizontal"
-				android:visibility="visible"></ImageView>
-			<LinearLayout
-				android:id="@+id/LinearLayout02"
-				android:layout_height="wrap_content"
-				android:orientation="vertical"
-				android:layout_width="fill_parent">
-				<EditText
-					android:layout_height="wrap_content"
-					android:layout_width="fill_parent"
-					android:inputType="textPassword"
-					android:layout_gravity="center_vertical"
-					android:hint="@string/access_code"
-					android:id="@+id/edtAccessCode"></EditText>
-				<Button
-					android:id="@+id/btnLogin"
-					android:layout_gravity="right|center_vertical"
-					android:layout_width="fill_parent"
-					android:layout_height="52dp"
-					android:drawableRight="@drawable/ic_menu_forward"></Button>
-			</LinearLayout>
-		</LinearLayout>
-
-
-
-
-
-
-		<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:id="@+id/txtResult"
-			android:textColor="#CC4B28"
-			android:text="@string/invalid_access_code"
-			android:gravity="center_vertical"
-			android:drawableLeft="@drawable/ic_bullet_key_permission"
-			android:layout_gravity="center_horizontal"
-			android:visibility="invisible"></TextView>
-
-	</LinearLayout>
-</RelativeLayout>
diff --git res/layout/main_htc.xml res/layout/main_htc.xml
new file mode 100644
index 0000000..80d877e
--- /dev/null
+++ res/layout/main_htc.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_width="wrap_content"
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat">
+	<CheckBox
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:id="@+id/chkTransperantBackground"
+		android:visibility="gone"
+		android:layout_margin="10dp"
+		android:text="@string/transparent_background" />
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:id="@+id/txtAccountsDesc"
+		android:visibility="visible"
+		android:layout_margin="10dp"
+		android:text="@string/main_instructions" />
+	<com.htc.widget.HtcListView
+		android:layout_width="fill_parent"
+		android:id="@+id/lstAccountsList"
+		android:layout_height="wrap_content"
+		android:cacheColorHint="#00000000"
+		android:layout_above="@+id/layMainMenu"
+		android:layout_below="@+id/chkTransperantBackground"
+		android:layout_alignWithParentIfMissing="true"
+		android:dividerHeight="0dp" />
+	<TableLayout
+		android:stretchColumns="0,2"
+		android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentRight="true"
+		android:layout_width="wrap_content"
+		android:id="@+id/layMainMenu">
+		<TableRow
+			android:id="@+id/TableRow01"
+			android:layout_height="wrap_content"
+			android:gravity="center_vertical|center_horizontal"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent">
+			<Button
+				android:text="@string/add_new_account"
+				android:drawableLeft="@drawable/button_add"
+				android:id="@+id/btnAddBank"
+				style="@style/Menu_Button" />
+			<ImageView
+				android:layout_height="wrap_content"
+				android:focusable="false"
+				android:src="@drawable/menu_separator"
+				android:adjustViewBounds="true"
+				android:scaleType="fitXY"
+				android:minWidth="3dp"
+				android:maxWidth="3dp"
+				android:layout_width="wrap_content" />
+			<Button
+				android:id="@+id/btnAccountsRefresh"
+				android:drawableLeft="@drawable/button_refresh"
+				android:text="@string/refresh_balance"
+				style="@style/Menu_Button" />
+		</TableRow>
+	</TableLayout>
+</RelativeLayout>
diff --git res/layout/settings.xml res/layout/settings.xml
deleted file mode 100644
index 83879a5..0000000
--- res/layout/settings.xml
+++ /dev/null
@@ -1,142 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:id="@+id/RelativeLayout01"
-	android:layout_height="fill_parent"
-	android:background="@drawable/background_repeat"
-	android:layout_width="fill_parent">
-
-	<ScrollView
-
-		android:layout_height="fill_parent"
-		android:layout_width="fill_parent"
-		android:fillViewport="true" android:layout_above="@+id/TableLayout01">
-	<LinearLayout
-		android:orientation="vertical"
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:padding="10dp"
-		android:background="@drawable/background_repeat">
-		<TextView
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:textSize="20sp"
-			android:text="@string/access_code" />
-		<EditText
-			android:layout_height="wrap_content"
-			android:layout_width="fill_parent"
-			android:inputType="textPassword"
-			android:id="@+id/edtAccessCode"></EditText>
-		<TextView
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:textSize="20sp"
-			android:text="@string/access_code_repeat" />
-		<EditText
-			android:layout_height="wrap_content"
-			android:layout_width="fill_parent"
-			android:inputType="textPassword"
-			android:id="@+id/edtAccessCodeRepeat"></EditText>
-
-		<TextView
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:id="@+id/txtSettingsPinDesc"
-			android:text="@string/pin_desc"
-			android:textSize="12sp"
-			android:textColor="#A4A4A4"
-			android:drawableLeft="@android:drawable/ic_dialog_info"
-			android:drawablePadding="5dp"
-			android:layout_marginBottom="3dp"></TextView>
-		<TextView
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:textSize="20sp"
-			android:text="@string/update_frequency"
-			android:visibility="visible" />
-		<Spinner
-			android:layout_height="wrap_content"
-			android:layout_width="fill_parent"
-			android:id="@+id/spnUpdateFrequency"
-			android:visibility="visible"></Spinner>
-
-
-
-
-
-		<LinearLayout
-			android:id="@+id/LinearLayout01"
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:orientation="vertical"
-			android:paddingLeft="10dp">
-			<CheckBox
-				android:layout_width="wrap_content"
-				android:layout_height="wrap_content"
-				android:text="@string/notify_on_change"
-				android:id="@+id/chkNotifyOnChange"
-				android:visibility="visible"></CheckBox>
-			<CheckBox
-				android:layout_width="wrap_content"
-				android:layout_height="wrap_content"
-				android:text="@string/with_sound"
-				android:id="@+id/chkWithSound"
-				android:textSize="14sp"
-				android:layout_marginLeft="10dp"></CheckBox>
-			<CheckBox
-				android:layout_width="wrap_content"
-				android:layout_height="wrap_content"
-				android:textSize="14sp"
-				android:id="@+id/chkWithVibration"
-				android:text="@string/vibrate"
-				android:layout_marginLeft="10dp"></CheckBox><LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginLeft="10dp"><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/notify_account_types"></TextView><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkDeposit" android:text="@string/deposit_account"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkLoans" android:text="@string/loans"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkFunds" android:text="@string/funds"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkCCards" android:text="@string/ccards"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkOther" android:text="@string/other"></CheckBox>
-</LinearLayout>
-		
-
-</LinearLayout>
-		
-	
-
-</LinearLayout>
-	</ScrollView>
-	<TableLayout
-		android:id="@+id/TableLayout01"
-		android:stretchColumns="0,2"
-		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content"
-		android:layout_below="@+id/LinearLayout01"
-		android:gravity="bottom">
-		<TableRow
-			android:id="@+id/TableRow01"
-			android:layout_height="wrap_content"
-			android:gravity="center_vertical|center_horizontal"
-			android:layout_gravity="center_vertical|center_horizontal"
-			android:layout_width="fill_parent">
-			<Button
-				android:text="@string/cancel"
-				android:drawableLeft="@drawable/button_cancel"
-				android:id="@+id/btnSettingsCancel"
-				style="@style/Menu_Button"></Button>
-			<ImageView
-				android:layout_height="wrap_content"
-				android:focusable="false"
-				android:src="@drawable/menu_separator"
-				android:adjustViewBounds="true"
-				android:scaleType="fitXY"
-				android:minWidth="3dp"
-				android:maxWidth="3dp"
-				android:layout_width="wrap_content"></ImageView>
-			<Button
-				android:id="@+id/btnSettingsOk"
-				android:drawableLeft="@drawable/button_save"
-				android:text="@string/save"
-				style="@style/Menu_Button"></Button>
-		</TableRow>
-	</TableLayout>
-</RelativeLayout>
\ No newline at end of file
diff --git res/layout/transactions.xml res/layout/transactions.xml
index 442b1e4..ed598e2 100644
--- res/layout/transactions.xml
+++ res/layout/transactions.xml
@@ -16,6 +16,7 @@
 		android:layout_width="fill_parent"
 		android:layout_height="fill_parent"
 		android:fitsSystemWindows="true"
+		android:background="@drawable/background_repeat"
 		android:cacheColorHint="#00000000" android:layout_below="@+id/layBankHeader" android:layout_alignParentBottom="true" android:id="@+id/lstTransactionsList" android:footerDividersEnabled="true" android:clickable="false" android:scrollbarStyle="outsideInset"/>
 	
 </RelativeLayout>
diff --git res/layout/transactions_htc.xml res/layout/transactions_htc.xml
new file mode 100644
index 0000000..b8e4682
--- /dev/null
+++ res/layout/transactions_htc.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_width="wrap_content"
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat">
+	<include
+		android:id="@+id/layBankHeader"
+		layout="@layout/listitem_accounts_group" />
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:visibility="visible"
+		android:layout_margin="10dp"
+		android:layout_below="@+id/layBankHeader"
+		android:id="@+id/txtTranDesc"
+		android:text="@string/tran_desc" />
+	<com.htc.widget.HtcListView
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:fitsSystemWindows="true"
+		android:background="@drawable/background_repeat"
+		android:cacheColorHint="#00000000"
+		android:layout_below="@+id/layBankHeader"
+		android:layout_alignParentBottom="true"
+		android:id="@+id/lstTransactionsList"
+		android:footerDividersEnabled="true"
+		android:clickable="false"
+		android:scrollbarStyle="outsideInset" />
+
+</RelativeLayout>
diff --git res/values/array.xml res/values/array.xml
new file mode 100644
index 0000000..3be9c89
--- /dev/null
+++ res/values/array.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<string-array
+		name="refreshrateNames">
+		<item>15 minutes</item>
+		<item>30 minutes</item>
+		<item>1 hour</item>
+		<item>2 hour</item>
+		<item>4 hour</item>
+		<item>8 hours</item>
+		<item>16 hours</item>
+		<item>Daily</item>
+	</string-array>
+	<string-array
+		name="refreshrateValues">
+		<item>15</item>
+		<item>30</item>
+		<item>60</item>
+		<item>120</item>
+		<item>240</item>
+		<item>480</item>
+		<item>960</item>
+		<item>1440</item>
+	</string-array>
+</resources>
diff --git res/values/colors.xml res/values/colors.xml
new file mode 100644
index 0000000..193388c
--- /dev/null
+++ res/values/colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <color name="black">#000</color>
+    <color name="red">#F00</color>
+</resources>
+         
diff --git res/values/strings.xml res/values/strings.xml
index ebd21d6..4bbde44 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources  xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="version">Version $version by liato</string>
     <string name="app_name">Bankdroid</string>
     <string name="widget_name_small">Bankdroid (Small)</string>
@@ -101,6 +101,91 @@
 	\nDEGE (Handelsbanken)
 	\ncola (OKQ8)
 	\nRikko (FirstCard)
-	\nnihplod (Eurocard)
+	\nNihplod (Eurocard)
      </string>
+     
+     
+
+    <!-- Lock Pattern settings -->
+    <!-- Security & location settings screen, header -->
+    <string name="lock_settings_title">Screen unlock pattern</string>
+    <!-- Security & location settings screen, setting option name -->
+    <string name="lockpattern_change_lock_pattern_label">Change unlock pattern</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction when the user chooses "Change unlock pattern".  We first ask the user toe nter the current pattern, and this is the message seen -->
+    <string name="lockpattern_need_to_unlock">Confirm saved pattern</string>
+    <!-- Do not translate. -->
+    <string name="lockpattern_need_to_unlock_footer"></string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction if user draws incorrect pattern -->
+    <string name="lockpattern_need_to_unlock_wrong">Sorry, try again:</string>
+    <!-- Do not translate. -->
+    <string name="lockpattern_need_to_unlock_wrong_footer"></string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen.  This si when they are supposed to draw a new unlock pattern (for example, if they are changing their unlock patterns)..-->
+    <string name="lockpattern_recording_intro_header">Draw an unlock pattern</string>
+    <!-- Security & location settings screen, change unlock pattern screen hint on bottom of screen.  We are telling them to press the menu button to see more options or help. -->
+    <string name="lockpattern_recording_intro_footer">Press Menu for help.</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen while drawing pattern -->
+    <string name="lockpattern_recording_inprogress">Release finger when done.</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen if user doesn't connect enough dots -->
+    <string name="lockpattern_recording_incorrect_too_short">Connect at least <xliff:g id="number">%d</xliff:g> dots. Try again:</string>
+    <!-- Security & location settings screen, change unlock pattern screen message on top of screen after drawing pattern -->
+    <string name="lockpattern_pattern_entered_header">Pattern recorded!</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen to confirm pattern -->
+    <string name="lockpattern_need_to_confirm">Draw pattern again to confirm:</string>
+    <string name="lockpattern_pattern_confirmed_header">Your new unlock pattern:</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen.  After they draw a pattern and release their finger, we display the pattern so they remember.  When they are ready to draw it once again to confirm it, they press this button. -->
+    <string name="lockpattern_confirm_button_text">Confirm</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen.  After they draw a pattern and release their finger, we display the pattern so they remember.  If they are nto satisfied with this pattern, they click this button to redraw the pattern. -->
+    <string name="lockpattern_restart_button_text">Redraw</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen. If they are supposed to enter their current pattern before being able to draw another one, and they screw up, they hit this button to try again -->
+    <string name="lockpattern_retry_button_text">Retry</string>
+    <!-- Security & location settings screen, change unlock pattern screen button, on bottom of screen. Once they draw a new pattern and confirm it by drawing it again, they press this button to exit -->
+    <string name="lockpattern_continue_button_text">Continue</string>
+    <!-- Security & location settings screen, unlock screen activity title -->
+    <string name="lockpattern_settings_title">Unlock pattern</string>
+    <!-- Security & location settings screen, setting check box title if the unlock pattern MUST be drawn everytime they turn on the screen -->
+    <string name="lockpattern_settings_enable_title">Require pattern</string>
+    <!-- Security & location settings screen, setting summary for the checkbox "Require pattern" -->
+    <string name="lockpattern_settings_enable_summary">Must draw pattern to unlock screen</string>
+    <!-- Security & location settings screen, setting check box title. This setting controls whether a visible green line is drawn as the user moves his finger around while drawing the unlock pattern.  If checked, this line is drawn.  If unchecked, there is nothing drawn so the user does not reveal his pattern while he unlocks the phone.-->
+    <string name="lockpattern_settings_enable_visible_pattern_title">Use visible pattern</string>
+    <!-- Security & location settings screen, setting check box title. This setting controls whether tactile feedback will be produced when the user draws the pattern.-->
+    <string name="lockpattern_settings_enable_tactile_feedback_title">Use tactile feedback</string>
+    <!-- Security & location settings screen, setting option name when user has never set an unlock pattern -->
+    <string name="lockpattern_settings_choose_lock_pattern">Set unlock pattern</string>
+    <!-- Security & location settings screen, setting option name when user has previously set an unlock pattern and wants to change to a new pattern -->
+    <string name="lockpattern_settings_change_lock_pattern">Change unlock pattern</string>
+    <!-- Security & location settings screen, the help instructions (an animation) caption -->
+    <string name="lockpattern_settings_help_how_to_record">How to draw an unlock pattern</string>
+    <!-- Security & location settings screen, change unlock pattern screen instruction on top of screen after too many incorrect attempts -->
+    <string name="lockpattern_too_many_failed_confirmation_attempts_header">Too many incorrect attempts!</string>
+    <!-- Security & location settings screen, change unlock pattern screen countdown hint on bottom of screen after too many incorrect attempts -->
+    <string name="lockpattern_too_many_failed_confirmation_attempts_footer">Try again in <xliff:g id="number">%d</xliff:g> seconds.</string>
+
+    <!-- ChooseLockPatternTutorial --> <skip />
+    <!-- ChooseLockPatternTutorial, button labels: This is to cancel the tutorial -->
+    <string name="skip_button_label">Cancel</string>
+    <!-- ChooseLockPatternTutorial, button labels: Continue to the next page of the tutorial -->
+    <string name="next_button_label">Next</string>
+    <!-- ChooseLockPatternTutorial, tutorial screen title -->
+    <string name="lock_title">Securing your phone</string>
+    <!-- ChooseLockPatternTutorial, tutorial screen text -->
+    <string name="lock_intro_message"><font size="17">Protect your phone from unauthorized use by creating a personal screen unlock pattern.
+        \n<font height="17">\n</font><b>1</b>\u00A0 On the next screen, watch while an example pattern is drawn.
+        \n<font height="17">\n</font><b>2</b>\u00A0 When ready, draw your own personal unlock pattern. Experiment with different patterns but connect at least four dots.
+        \n<font height="17">\n</font><b>3</b>\u00A0 Redraw your pattern to confirm.
+        \n<font height="17">\n</font><b>Ready to start? Select \u201CNext\u201D</b>.
+        \n<font height="3">\n</font>To leave your phone unprotected, select \u201CCancel\u201D.</font>
+    </string>    
+        
+    <!-- ChooseLockPatternExample --> <skip />
+    <!-- ChooseLockPatternExample, screen title that shows an example pattern -->
+    <string name="lock_example_title">Example pattern</string>
+    <!-- ChooseLockPatternExample, screen hint text at bottom of screen. These are instructions and rules for drawing a good patttern -->
+    <string name="lock_example_message">Connect at least four dots.\n
+        \nSelect \u201CNext\u201D when you\u2019re ready to draw your own pattern.
+    </string>
+	<string name="lock_cancel">Cancel</string>
+	<string name="lock_ok">Ok</string>
+	
+         
 </resources>
diff --git res/xml/settings.xml res/xml/settings.xml
new file mode 100644
index 0000000..ad40abc
--- /dev/null
+++ res/xml/settings.xml
@@ -0,0 +1,119 @@
+<PreferenceScreen
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<PreferenceCategory
+		android:title="Security">
+		<CheckBoxPreference
+			android:key="patternlock_enabled"
+			android:defaultValue="false"
+			android:title="Enable Pattern Lock"
+			android:summary="Lock the app and widgets with a pattern lock" />
+		<Preference
+			android:title="Change pattern"
+			android:summary="Change your current lock pattern"
+			android:key="patternlock_change"
+			android:dependency="patternlock_enabled" />
+	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Automatic Updates">
+		<CheckBoxPreference
+			android:key="autoupdates_enabled"
+			android:defaultValue="true"
+			android:title="Enable"
+			android:summary="Enable automatic updates" />
+		<ListPreference
+			android:title="Update frequency"
+			android:key="refresh_rate"
+			android:defaultValue="60"
+			android:entries="@array/refreshrateNames"
+			android:entryValues="@array/refreshrateValues"
+			android:dependency="autoupdates_enabled" />
+		<CheckBoxPreference
+			android:key="autoupdates_transactions_enabled"
+			android:defaultValue="true"
+			android:title="Update transaction history"
+			android:summary="Update transaction history when updating automatically" />
+	</PreferenceCategory>
+	<PreferenceCategory
+		android:title="Notifications">
+		<CheckBoxPreference
+			android:key="notify_on_change"
+			android:defaultValue="true"
+			android:title="Enable notifications"
+			android:summary="Notify on account changes" />
+		<CheckBoxPreference
+			android:key="notify_with_vibration"
+			android:defaultValue="true"
+			android:title="Vibrate"
+			android:summary="Vibrate on account changes"
+			android:dependency="notify_on_change" />
+		<RingtonePreference
+			android:key="notification_sound"
+			android:name="Select sound"
+			android:summary="Select notification sound"
+			android:title="Notification sound"
+			android:ringtoneType="notification"
+			android:showDefault="true"
+			android:showSilent="true"
+			
+			android:dependency="notify_on_change" />
+		<PreferenceScreen
+			android:key="account_types_screen"
+			android:title="Account types"
+			android:summary="Only show notifications for selected account types"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_for_deposit"
+				android:defaultValue="true"
+				android:title="@string/deposit_account" />
+			<CheckBoxPreference
+				android:key="notify_for_funds"
+				android:defaultValue="false"
+				android:title="@string/loans" />
+			<CheckBoxPreference
+				android:key="notify_for_loans"
+				android:defaultValue="false"
+				android:title="@string/funds" />
+			<CheckBoxPreference
+				android:key="notify_for_ccards"
+				android:defaultValue="true"
+				android:title="@string/ccards" />
+			<CheckBoxPreference
+				android:key="notify_for_other"
+				android:defaultValue="false"
+				android:title="@string/other" />
+		</PreferenceScreen>
+		<PreferenceScreen
+			android:key="remotenotifier_screen"
+			android:title="Remote Notifier Integration"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_remotenotifier"
+				android:defaultValue="false"
+				android:title="Enable"
+				android:summary="Enable Remote Notifier integration" />
+			<Preference
+				android:title="What is Remote Notifier?"
+				android:summary="Read more about Remote Notifier on their website"
+				android:key="remotenotifier_help" />
+		</PreferenceScreen>
+		<PreferenceScreen
+			android:key="openwatch_screen"
+			android:title="OpenWatch Integration"
+			android:dependency="notify_on_change">
+			<CheckBoxPreference
+				android:key="notify_openwatch"
+				android:defaultValue="false"
+				android:title="Enable"
+				android:summary="Enable OpenWatch integration" />
+			<CheckBoxPreference
+				android:key="notify_openwatch_vibrate"
+				android:defaultValue="false"
+				android:title="Vibrate"
+				android:summary="Vibrate the OpenWatch device" />
+			<Preference
+				android:title="What is OpenWatch?"
+				android:summary="Read more about OpenWatch on their website"
+				android:key="openwatch_help" />
+		</PreferenceScreen>
+	</PreferenceCategory>
+</PreferenceScreen>
\ No newline at end of file
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index 2b3c41e..a8fc404 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -13,6 +13,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
+import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
@@ -22,6 +23,9 @@ public class AutoRefreshService extends Service {
 	private final static String TAG = "AutoRefreshService";
 	final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
 	final static String BROADCAST_MAIN_REFRESH = "com.liato.bankdroid.MAIN_REFRESH";
+    final static String BROADCAST_REMOTE_NOTIFIER = "org.damazio.notifier.service.UserReceiver.USER_MESSAGE";
+    final static String BROADCAST_OPENWATCH_TEXT = "com.smartmadsoft.openwatch.action.TEXT";
+    final static String BROADCAST_OPENWATCH_VIBRATE = "com.smartmadsoft.openwatch.action.VIBRATE";
     NotificationManager notificationManager;
 
     @Override
@@ -40,21 +44,21 @@ public class AutoRefreshService extends Service {
         return null;
     }
 
-    private void showNotification(String text, int icon, String title) {
+    private void showNotification(String text, int icon, String title, String bank) {
     	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		if (!prefs.getBoolean("notify_on_change", true)) return;
 		
         Notification notification = new Notification(icon, text,
                 System.currentTimeMillis());
+        // Remove notification from statusbar when clicked
         notification.flags |= Notification.FLAG_AUTO_CANCEL;
-		if (prefs.getBoolean("notify_with_sound", true)) {
-			//http://www.freesound.org/samplesViewSingle.php?id=91924
-			//http://www.freesound.org/samplesViewSingle.php?id=75235
-	        notification.defaults |= Notification.DEFAULT_SOUND;
-		}
+        
+        
+        //http://www.freesound.org/samplesViewSingle.php?id=75235
+        //http://www.freesound.org/samplesViewSingle.php?id=91924
+        Log.d(TAG, "Notification sound: "+prefs.getString("notification_sound", "none"));
+        notification.sound = Uri.parse(prefs.getString("notification_sound", null));
 		if (prefs.getBoolean("notify_with_vibration", true)) {
-			//long[] vib = {23,28,27,143,20,30,26,364,22,26,28,26,28,26,28,26,29,25,27,27,27,27,28,28,28,28,28,27,27,26,27};
-			//long[] vib = {46, 56, 54, 286, 40, 60, 52, 728, 44, 52, 56, 52, 56, 52, 56, 52, 58, 50, 54, 54, 54, 54, 56, 56, 56, 56, 56, 54, 54, 52, 54};
 			long[] vib = {0, 90, 130, 80, 350, 190, 20, 380};
 			notification.vibrate = vib;
 			//notification.defaults |= Notification.DEFAULT_VIBRATE;
@@ -65,9 +69,36 @@ public class AutoRefreshService extends Service {
         notification.setLatestEventInfo(this, title, text, contentIntent);
 
         notificationManager.notify(R.id.about, notification);
+        
+        // Broadcast to Remote Notifier if enabled
+        // http://code.google.com/p/android-notifier/
+        if (prefs.getBoolean("notify_remotenotifier", false)) {
+            Intent i = new Intent(BROADCAST_REMOTE_NOTIFIER);
+            i.putExtra("title", String.format("%s (%s)", bank, title));
+            i.putExtra("description", text);
+            sendBroadcast(i);
+        }
+
+        // Broadcast to OpenWatch if enabled
+        // http://forum.xda-developers.com/showthread.php?t=554551
+        if (prefs.getBoolean("notify_openwatch", false)) {
+            Intent i;
+            if (prefs.getBoolean("notify_openwatch_vibrate", false)) {
+                i = new Intent(BROADCAST_OPENWATCH_TEXT);
+            }
+            else {
+                i = new Intent(BROADCAST_OPENWATCH_VIBRATE);
+            }
+            i.putExtra("line1", String.format("%s (%s)", bank, title));
+            i.putExtra("line2", text);
+            sendBroadcast(i);
+        }
+        
+        
     }
     
     private class DataRetrieverTask extends AsyncTask<String, String, Void> {
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(AutoRefreshService.this);
     	private ArrayList<String> errors;
     	private Resources res;
 
@@ -110,7 +141,6 @@ public class AutoRefreshService extends Service {
     						if (oldAccount != null) {
     							if (account.getBalance().compareTo(oldAccount.getBalance()) != 0) {
     							    boolean notify = false;
-    							    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(AutoRefreshService.this);
     							    switch (account.getType()) {
     							    case Account.REGULAR:
     							        notify = prefs.getBoolean("notify_for_deposit", true);
@@ -135,13 +165,15 @@ public class AutoRefreshService extends Service {
     		                        if (notify) {
     		                            diff = account.getBalance().subtract(oldAccount.getBalance());
         								showNotification(account.getName()+ ": "+ ((diff.compareTo(new BigDecimal(0)) == 1) ? "+" : "") + Helpers.formatBalance(diff, account.getCurrency()) + " ("+Helpers.formatBalance(account.getBalance(), account.getCurrency())+")",
-        												 bank.getImageResource(), bank.getDisplayName());
+        												 bank.getImageResource(), bank.getDisplayName(), bank.getName());
                                     }
     								refreshWidgets = true;
     							}
     						}
     					}
-    					bank.updateAllTransactions();
+    					if (prefs.getBoolean("autoupdates_transactions_enabled", true)) {
+    					    bank.updateAllTransactions();    					    
+    					}
     				}
     				bank.closeConnection();
     				db.updateBank(bank);
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index fab4933..f91ed81 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -90,7 +90,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		else {
 			views.setViewVisibility(R.id.frmWarning, View.INVISIBLE);
 		}
-		Intent intent = new Intent(context, LoginActivity.class);
+		Intent intent = new Intent(context, MainActivity.class);
 		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
 		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
 		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
@@ -132,7 +132,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
 		views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
 
-		Intent intent = new Intent(context, LoginActivity.class);
+		Intent intent = new Intent(context, MainActivity.class);
 		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
 		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
 		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
diff --git src/com/liato/bankdroid/ChooseLockPattern.java src/com/liato/bankdroid/ChooseLockPattern.java
new file mode 100644
index 0000000..1d92f5b
--- /dev/null
+++ src/com/liato/bankdroid/ChooseLockPattern.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import com.google.common.collect.Lists;
+
+import com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient;
+import com.liato.bankdroid.LockPatternUtils;
+import com.liato.bankdroid.LockPatternView;
+import static com.liato.bankdroid.LockPatternView.DisplayMode;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.Window;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * If the user has a lock pattern set already, makes them confirm the existing one.
+ *
+ * Then, prompts the user to choose a lock pattern:
+ * - prompts for initial pattern
+ * - asks for confirmation / restart
+ * - saves chosen password when confirmed
+ */
+public class ChooseLockPattern extends Activity implements View.OnClickListener{
+
+    /**
+     * Used by the choose lock pattern wizard to indicate the wizard is
+     * finished, and each activity in the wizard should finish.
+     * <p>
+     * Previously, each activity in the wizard would finish itself after
+     * starting the next activity. However, this leads to broken 'Back'
+     * behavior. So, now an activity does not finish itself until it gets this
+     * result.
+     */
+    static final int RESULT_FINISHED = RESULT_FIRST_USER;
+    
+    // how long after a confirmation message is shown before moving on
+    static final int INFORMATION_MSG_TIMEOUT_MS = 3000;
+
+    // how long we wait to clear a wrong pattern
+    private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
+
+    private static final int ID_EMPTY_MESSAGE = -1;
+
+
+    protected TextView mHeaderText;
+    protected LockPatternView mLockPatternView;
+    protected TextView mFooterText;
+    private TextView mFooterLeftButton;
+    private TextView mFooterRightButton;
+
+    protected List<LockPatternView.Cell> mChosenPattern = null;
+
+    protected LockPatternUtils mLockPatternUtils;
+
+    /**
+     * The patten used during the help screen to show how to draw a pattern.
+     */
+    private final List<LockPatternView.Cell> mAnimatePattern =
+            Collections.unmodifiableList(
+                Lists.newArrayList(
+                        LockPatternView.Cell.of(0, 0),
+                        LockPatternView.Cell.of(0, 1),
+                        LockPatternView.Cell.of(1, 1),
+                        LockPatternView.Cell.of(2, 1)
+                    ));
+
+
+    /**
+     * The pattern listener that responds according to a user choosing a new
+     * lock pattern.
+     */
+    protected LockPatternView.OnPatternListener mChooseNewLockPatternListener = new LockPatternView.OnPatternListener() {
+
+            public void onPatternStart() {
+                mLockPatternView.removeCallbacks(mClearPatternRunnable);
+                patternInProgress();
+            }
+
+            public void onPatternCleared() {
+                mLockPatternView.removeCallbacks(mClearPatternRunnable);
+            }
+
+            public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+                if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {
+                    if (mChosenPattern == null) throw new IllegalStateException("null chosen pattern in stage 'need to confirm");
+                    if (mChosenPattern.equals(pattern)) {
+                        updateStage(Stage.ChoiceConfirmed);
+                    } else {
+                        updateStage(Stage.ConfirmWrong);
+                    }
+                } else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){
+                    if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
+                        updateStage(Stage.ChoiceTooShort);
+                    } else {
+                        mChosenPattern = new ArrayList<LockPatternView.Cell>(pattern);
+                        updateStage(Stage.FirstChoiceValid);
+                    }
+                } else {
+                    throw new IllegalStateException("Unexpected stage " + mUiStage + " when "
+                            + "entering the pattern.");
+                }
+            }
+
+            private void patternInProgress() {
+                mHeaderText.setText(R.string.lockpattern_recording_inprogress);
+                mFooterText.setText("");
+                mFooterLeftButton.setEnabled(false);
+                mFooterRightButton.setEnabled(false);
+            }
+     };
+
+
+    /**
+     * The states of the left footer button.
+     */
+    enum LeftButtonMode {
+        Cancel(R.string.lock_cancel, true),
+        CancelDisabled(R.string.lock_cancel, false),
+        Retry(R.string.lockpattern_retry_button_text, true),
+        RetryDisabled(R.string.lockpattern_retry_button_text, false),
+        Gone(ID_EMPTY_MESSAGE, false);
+
+
+        /**
+         * @param text The displayed text for this mode.
+         * @param enabled Whether the button should be enabled.
+         */
+        LeftButtonMode(int text, boolean enabled) {
+            this.text = text;
+            this.enabled = enabled;
+        }
+
+        final int text;
+        final boolean enabled;
+    }
+
+    /**
+     * The states of the right button.
+     */
+    enum RightButtonMode {
+        Continue(R.string.lockpattern_continue_button_text, true),
+        ContinueDisabled(R.string.lockpattern_continue_button_text, false),
+        Confirm(R.string.lockpattern_confirm_button_text, true),
+        ConfirmDisabled(R.string.lockpattern_confirm_button_text, false),
+        Ok(R.string.lock_ok, true);
+
+        /**
+         * @param text The displayed text for this mode.
+         * @param enabled Whether the button should be enabled.
+         */
+        RightButtonMode(int text, boolean enabled) {
+            this.text = text;
+            this.enabled = enabled;
+        }
+
+        final int text;
+        final boolean enabled;
+    }
+
+    /**
+     * Keep track internally of where the user is in choosing a pattern.
+     */
+    protected enum Stage {
+
+        Introduction(
+                R.string.lockpattern_recording_intro_header,
+                LeftButtonMode.Cancel, RightButtonMode.ContinueDisabled,
+                R.string.lockpattern_recording_intro_footer, true),
+        HelpScreen(
+                R.string.lockpattern_settings_help_how_to_record,
+                LeftButtonMode.Gone, RightButtonMode.Ok, ID_EMPTY_MESSAGE, false),
+        ChoiceTooShort(
+                R.string.lockpattern_recording_incorrect_too_short,
+                LeftButtonMode.Retry, RightButtonMode.ContinueDisabled,
+                ID_EMPTY_MESSAGE, true),
+        FirstChoiceValid(
+                R.string.lockpattern_pattern_entered_header,
+                LeftButtonMode.Retry, RightButtonMode.Continue, ID_EMPTY_MESSAGE, false),
+        NeedToConfirm(
+                R.string.lockpattern_need_to_confirm,
+                LeftButtonMode.CancelDisabled, RightButtonMode.ConfirmDisabled,
+                ID_EMPTY_MESSAGE, true),
+        ConfirmWrong(
+                R.string.lockpattern_need_to_unlock_wrong,
+                LeftButtonMode.Cancel, RightButtonMode.ConfirmDisabled,
+                ID_EMPTY_MESSAGE, true),
+        ChoiceConfirmed(
+                R.string.lockpattern_pattern_confirmed_header,
+                LeftButtonMode.Cancel, RightButtonMode.Confirm, ID_EMPTY_MESSAGE, false);
+
+
+        /**
+         * @param headerMessage The message displayed at the top.
+         * @param leftMode The mode of the left button.
+         * @param rightMode The mode of the right button.
+         * @param footerMessage The footer message.
+         * @param patternEnabled Whether the pattern widget is enabled.
+         */
+        Stage(int headerMessage,
+                LeftButtonMode leftMode,
+                RightButtonMode rightMode,
+                int footerMessage, boolean patternEnabled) {
+            this.headerMessage = headerMessage;
+            this.leftMode = leftMode;
+            this.rightMode = rightMode;
+            this.footerMessage = footerMessage;
+            this.patternEnabled = patternEnabled;
+        }
+
+        final int headerMessage;
+        final LeftButtonMode leftMode;
+        final RightButtonMode rightMode;
+        final int footerMessage;
+        final boolean patternEnabled;
+    }
+
+    private Stage mUiStage = Stage.Introduction;
+
+    private Runnable mClearPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
+        }
+    };
+
+    private static final String KEY_UI_STAGE = "uiStage";
+    private static final String KEY_PATTERN_CHOICE = "chosenPattern";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mLockPatternUtils = new LockPatternUtils(this);
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        setupViews();
+        
+        // make it so unhandled touch events within the unlock screen go to the
+        // lock pattern view.
+        final LinearLayoutWithDefaultTouchRecepient topLayout
+                = (LinearLayoutWithDefaultTouchRecepient) findViewById(
+                R.id.topLayout);
+        topLayout.setDefaultTouchRecepient(mLockPatternView);
+
+        if (savedInstanceState == null) {
+            // first launch
+            updateStage(Stage.Introduction);
+            if (mLockPatternUtils.savedPatternExists()) {
+                confirmPattern();
+            } 
+        } else {
+            // restore from previous state
+            final String patternString = savedInstanceState.getString(KEY_PATTERN_CHOICE);
+            if (patternString != null) {
+                mChosenPattern = LockPatternUtils.stringToPattern(patternString);
+            }
+            updateStage(Stage.values()[savedInstanceState.getInt(KEY_UI_STAGE)]);
+        }
+    }
+    
+    /**
+     * Keep all "find view" related stuff confined to this function since in
+     * case someone needs to subclass and customize.
+     */
+    protected void setupViews() {
+        setContentView(R.layout.choose_lock_pattern);
+        
+        mHeaderText = (TextView) findViewById(R.id.headerText);
+
+        mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
+        mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
+        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());        
+
+        mFooterText = (TextView) findViewById(R.id.footerText);
+
+        mFooterLeftButton = (TextView) findViewById(R.id.footerLeftButton);
+        mFooterRightButton = (TextView) findViewById(R.id.footerRightButton);
+
+        mFooterLeftButton.setOnClickListener(this);
+        mFooterRightButton.setOnClickListener(this);
+    }
+
+    public void onClick(View v) {
+        if (v == mFooterLeftButton) {
+            if (mUiStage.leftMode == LeftButtonMode.Retry) {
+                mChosenPattern = null;
+                mLockPatternView.clearPattern();
+                updateStage(Stage.Introduction);
+            } else if (mUiStage.leftMode == LeftButtonMode.Cancel) {
+                // They are canceling the entire wizard
+                setResult(RESULT_FINISHED);
+                finish();
+            } else {
+                throw new IllegalStateException("left footer button pressed, but stage of " +
+                    mUiStage + " doesn't make sense");
+            }
+        } else if (v == mFooterRightButton) {
+
+            if (mUiStage.rightMode == RightButtonMode.Continue) {
+                if (mUiStage != Stage.FirstChoiceValid) {
+                    throw new IllegalStateException("expected ui stage " + Stage.FirstChoiceValid
+                            + " when button is " + RightButtonMode.Continue);
+                }
+                updateStage(Stage.NeedToConfirm);
+            } else if (mUiStage.rightMode == RightButtonMode.Confirm) {
+                if (mUiStage != Stage.ChoiceConfirmed) {
+                    throw new IllegalStateException("expected ui stage " + Stage.ChoiceConfirmed
+                            + " when button is " + RightButtonMode.Confirm);
+                }
+                saveChosenPatternAndFinish();
+            } else if (mUiStage.rightMode == RightButtonMode.Ok) {
+                if (mUiStage != Stage.HelpScreen) {
+                    throw new IllegalStateException("Help screen is only mode with ok button, but " +
+                            "stage is " + mUiStage);
+                }
+                mLockPatternView.clearPattern();
+                mLockPatternView.setDisplayMode(DisplayMode.Correct);
+                updateStage(Stage.Introduction);
+            }
+        }
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
+            if (mUiStage == Stage.HelpScreen) {
+                updateStage(Stage.Introduction);
+                return true;
+            }
+        }
+        if (keyCode == KeyEvent.KEYCODE_MENU && mUiStage == Stage.Introduction) {
+            updateStage(Stage.HelpScreen);
+            return true;
+        }
+
+        return super.onKeyDown(keyCode, event);
+    }
+
+    /**
+     * Launch screen to confirm the existing lock pattern.
+     * @see #onActivityResult(int, int, android.content.Intent)
+     */
+    protected void confirmPattern() {
+        final Intent intent = new Intent();
+        intent.setClassName("com.liato.bankdroid", "com.liato.bankdroid.ConfirmLockPattern");
+        startActivityForResult(intent, 55);
+    }
+
+    /**
+     * @see #confirmPattern
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode != 55) {
+            return;
+        }
+
+        if (resultCode != Activity.RESULT_OK) {
+            setResult(RESULT_FINISHED);
+            finish();
+        }
+        updateStage(Stage.Introduction);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putInt(KEY_UI_STAGE, mUiStage.ordinal());
+        if (mChosenPattern != null) {
+            outState.putString(KEY_PATTERN_CHOICE, LockPatternUtils.patternToString(mChosenPattern));
+        }
+    }
+
+
+    /**
+     * Updates the messages and buttons appropriate to what stage the user
+     * is at in choosing a view.  This doesn't handle clearing out the pattern;
+     * the pattern is expected to be in the right state.
+     * @param stage
+     */
+    protected void updateStage(Stage stage) {
+
+        mUiStage = stage;
+
+        // header text, footer text, visibility and 
+        // enabled state all known from the stage
+        if (stage == Stage.ChoiceTooShort) {
+            mHeaderText.setText(
+                    getResources().getString(
+                            stage.headerMessage,
+                            LockPatternUtils.MIN_LOCK_PATTERN_SIZE));
+        } else {
+            mHeaderText.setText(stage.headerMessage);
+        }
+        if (stage.footerMessage == ID_EMPTY_MESSAGE) {
+            mFooterText.setText("");
+        } else {
+            mFooterText.setText(stage.footerMessage);
+        }
+
+        if (stage.leftMode == LeftButtonMode.Gone) {
+            mFooterLeftButton.setVisibility(View.GONE);
+        } else {
+            mFooterLeftButton.setVisibility(View.VISIBLE);
+            mFooterLeftButton.setText(stage.leftMode.text);
+            mFooterLeftButton.setEnabled(stage.leftMode.enabled);
+        }
+
+        mFooterRightButton.setText(stage.rightMode.text);
+        mFooterRightButton.setEnabled(stage.rightMode.enabled);
+
+        // same for whether the patten is enabled
+        if (stage.patternEnabled) {
+            mLockPatternView.enableInput();
+        } else {
+            mLockPatternView.disableInput();
+        }
+
+        // the rest of the stuff varies enough that it is easier just to handle
+        // on a case by case basis.
+        mLockPatternView.setDisplayMode(DisplayMode.Correct);
+
+        switch (mUiStage) {
+            case Introduction:
+                mLockPatternView.clearPattern();
+                break;
+            case HelpScreen:
+                mLockPatternView.setPattern(DisplayMode.Animate, mAnimatePattern);
+                break;
+            case ChoiceTooShort:
+                mLockPatternView.setDisplayMode(DisplayMode.Wrong);
+                postClearPatternRunnable();
+                break;
+            case FirstChoiceValid:
+                break;
+            case NeedToConfirm:
+                mLockPatternView.clearPattern();
+                break;
+            case ConfirmWrong:
+                mLockPatternView.setDisplayMode(DisplayMode.Wrong);
+                postClearPatternRunnable();
+                break;
+            case ChoiceConfirmed:
+                break;
+        }
+    }
+
+
+    // clear the wrong pattern unless they have started a new one
+    // already
+    private void postClearPatternRunnable() {
+        mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
+    }
+
+    private void saveChosenPatternAndFinish() {
+        final boolean lockVirgin = !mLockPatternUtils.isPatternEverChosen();
+
+        mLockPatternUtils.saveLockPattern(mChosenPattern);
+        mLockPatternUtils.setLockPatternEnabled(true);
+
+        if (lockVirgin) {
+            mLockPatternUtils.setVisiblePatternEnabled(true);
+            mLockPatternUtils.setTactileFeedbackEnabled(false);
+        }
+        
+        setResult(RESULT_FINISHED);
+        finish();
+    }
+}
diff --git src/com/liato/bankdroid/ChooseLockPatternExample.java src/com/liato/bankdroid/ChooseLockPatternExample.java
new file mode 100644
index 0000000..bc149cf
--- /dev/null
+++ src/com/liato/bankdroid/ChooseLockPatternExample.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.ImageView;
+
+public class ChooseLockPatternExample extends Activity implements View.OnClickListener {
+    private static final int REQUESTCODE_CHOOSE = 1;
+    private static final long START_DELAY = 1000;
+    protected static final String TAG = "Settings";
+    private View mNextButton;
+    private View mSkipButton;
+    private View mImageView;
+    private AnimationDrawable mAnimation;
+    private Handler mHandler = new Handler();
+    private Runnable mRunnable = new Runnable() {
+        public void run() {
+            startAnimation(mAnimation);
+        }
+    };
+   
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.choose_lock_pattern_example);
+        initViews();
+    }
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mHandler.postDelayed(mRunnable, START_DELAY);
+    }
+    
+    @Override
+    protected void onPause() {
+        super.onPause();
+        stopAnimation(mAnimation);
+    }
+    
+    public void onClick(View v) {
+        if (v == mSkipButton) {
+            // Canceling, so finish all
+            setResult(ChooseLockPattern.RESULT_FINISHED);
+            finish();
+        } else if (v == mNextButton) {
+            stopAnimation(mAnimation);
+            Intent intent = new Intent(this, ChooseLockPattern.class);
+            startActivityForResult(intent, REQUESTCODE_CHOOSE);
+        }
+    }
+    
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUESTCODE_CHOOSE && resultCode == ChooseLockPattern.RESULT_FINISHED) {
+            setResult(resultCode);
+            finish();
+        }
+    }
+    
+    private void initViews() {
+        mNextButton = findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+        
+        mSkipButton = findViewById(R.id.skip_button);
+        mSkipButton.setOnClickListener(this);
+        
+        mImageView = (ImageView) findViewById(R.id.lock_anim);
+        mImageView.setBackgroundResource(R.drawable.lock_anim);
+        mImageView.setOnClickListener(this);
+        mAnimation = (AnimationDrawable) mImageView.getBackground();
+    }
+    
+    protected void startAnimation(final AnimationDrawable animation) {
+        if (animation != null && !animation.isRunning()) {
+            animation.run();
+        }
+    }
+   
+    protected void stopAnimation(final AnimationDrawable animation) {
+        if (animation != null && animation.isRunning()) animation.stop();
+    }
+}
+
diff --git src/com/liato/bankdroid/ChooseLockPatternTutorial.java src/com/liato/bankdroid/ChooseLockPatternTutorial.java
new file mode 100644
index 0000000..dfaeb9b
--- /dev/null
+++ src/com/liato/bankdroid/ChooseLockPatternTutorial.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import com.liato.bankdroid.LockPatternUtils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+public class ChooseLockPatternTutorial extends Activity implements View.OnClickListener {
+    private static final int REQUESTCODE_EXAMPLE = 1;
+    
+    private View mNextButton;
+    private View mSkipButton;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Don't show the tutorial if the user has seen it before.
+        LockPatternUtils lockPatternUtils = new LockPatternUtils(this);
+        if (savedInstanceState == null && lockPatternUtils.isPatternEverChosen()) {
+            Intent intent = new Intent();
+            intent.setClassName("com.android.settings", "com.android.settings.ChooseLockPattern");
+            startActivity(intent);
+            finish();
+        } else {
+            initViews();
+        }
+    }
+    
+    private void initViews() {
+        setContentView(R.layout.choose_lock_pattern_tutorial);
+        mNextButton = findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+        mSkipButton = findViewById(R.id.skip_button);
+        mSkipButton.setOnClickListener(this);
+    }
+
+    public void onClick(View v) {
+        if (v == mSkipButton) {
+            // Canceling, so finish all
+            setResult(ChooseLockPattern.RESULT_FINISHED);
+            finish();
+        } else if (v == mNextButton) {
+            startActivityForResult(new Intent(this, ChooseLockPatternExample.class),
+                    REQUESTCODE_EXAMPLE);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUESTCODE_EXAMPLE && resultCode == ChooseLockPattern.RESULT_FINISHED) {
+            setResult(resultCode);
+            finish();
+        }
+    }
+    
+}
+
diff --git src/com/liato/bankdroid/ConfirmLockPattern.java src/com/liato/bankdroid/ConfirmLockPattern.java
new file mode 100644
index 0000000..6faee30
--- /dev/null
+++ src/com/liato/bankdroid/ConfirmLockPattern.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import com.liato.bankdroid.LockPatternUtils;
+import com.liato.bankdroid.LockPatternView;
+import com.liato.bankdroid.LinearLayoutWithDefaultTouchRecepient;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.CountDownTimer;
+import android.os.SystemClock;
+import android.os.Bundle;
+import android.widget.TextView;
+import android.view.KeyEvent;
+import android.view.Window;
+
+import java.util.List;
+
+/**
+ * Launch this when you want the user to confirm their lock pattern.
+ *
+ * Sets an activity result of {@link Activity#RESULT_OK} when the user
+ * successfully confirmed their pattern.
+ */
+public class ConfirmLockPattern extends Activity {
+
+    /**
+     * Names of {@link CharSequence} fields within the originating {@link Intent}
+     * that are used to configure the keyguard confirmation view's labeling.
+     * The view will use the system-defined resource strings for any labels that
+     * the caller does not supply.
+     */
+    public static final String HEADER_TEXT = "com.liato.bankdroid.header";
+    public static final String FOOTER_TEXT = "com.liato.bankdroid.footer";
+    public static final String HEADER_WRONG_TEXT = "com.liato.bankdroid.header_wrong";
+    public static final String FOOTER_WRONG_TEXT = "com.liato.bankdroid.footer_wrong";
+    public static final String DISABLE_BACK_KEY = "com.liato.bankdroid.ConfirmLockPattern.disable_back_key";
+    
+    // how long we wait to clear a wrong pattern
+    private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 2000;
+
+    private static final String KEY_NUM_WRONG_ATTEMPTS = "num_wrong_attempts";
+
+    private LockPatternView mLockPatternView;
+    private LockPatternUtils mLockPatternUtils;
+    private int mNumWrongConfirmAttempts;
+    private CountDownTimer mCountdownTimer;
+
+    private TextView mHeaderTextView;
+    private TextView mFooterTextView;
+
+    // caller-supplied text for various prompts
+    private CharSequence mHeaderText;
+    private CharSequence mFooterText;
+    private CharSequence mHeaderWrongText;
+    private CharSequence mFooterWrongText;
+    private boolean mDisableBackButton = false;
+
+
+    private enum Stage {
+        NeedToUnlock,
+        NeedToUnlockWrong,
+        LockedOut
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mLockPatternUtils = new LockPatternUtils(this);
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(R.layout.confirm_lock_pattern);
+
+        mHeaderTextView = (TextView) findViewById(R.id.headerText);
+        mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
+        mFooterTextView = (TextView) findViewById(R.id.footerText);
+
+        // make it so unhandled touch events within the unlock screen go to the
+        // lock pattern view.
+        final LinearLayoutWithDefaultTouchRecepient topLayout
+                = (LinearLayoutWithDefaultTouchRecepient) findViewById(
+                R.id.topLayout);
+        topLayout.setDefaultTouchRecepient(mLockPatternView);        
+
+        Intent intent = getIntent();
+        if (intent != null) {
+            mHeaderText = intent.getCharSequenceExtra(HEADER_TEXT);
+            mFooterText = intent.getCharSequenceExtra(FOOTER_TEXT);
+            mHeaderWrongText = intent.getCharSequenceExtra(HEADER_WRONG_TEXT);
+            mFooterWrongText = intent.getCharSequenceExtra(FOOTER_WRONG_TEXT);
+            mDisableBackButton = intent.getBooleanExtra(DISABLE_BACK_KEY, false);
+        }
+
+        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+        mLockPatternView.setOnPatternListener(mConfirmExistingLockPatternListener);
+        updateStage(Stage.NeedToUnlock);
+
+        if (savedInstanceState != null) {
+            mNumWrongConfirmAttempts = savedInstanceState.getInt(KEY_NUM_WRONG_ATTEMPTS);
+        } else {
+            // on first launch, if no lock pattern is set, then finish with
+            // success (don't want user to get stuck confirming something that
+            // doesn't exist).
+            if (!mLockPatternUtils.savedPatternExists()) {
+                setResult(RESULT_OK);
+                finish();
+            }
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        // deliberately not calling super since we are managing this in full
+        outState.putInt(KEY_NUM_WRONG_ATTEMPTS, mNumWrongConfirmAttempts);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        if (mCountdownTimer != null) {
+            mCountdownTimer.cancel();
+        }
+    }
+
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+      if (keyCode == KeyEvent.KEYCODE_BACK && this.mDisableBackButton) {
+          return true;
+      }
+      return super.onKeyDown(keyCode, event);
+    }    
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // if the user is currently locked out, enforce it.
+        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+        if (deadline != 0) {
+            handleAttemptLockout(deadline);
+        }
+    }
+
+    private void updateStage(Stage stage) {
+
+        switch (stage) {
+            case NeedToUnlock:
+                if (mHeaderText != null) {
+                    mHeaderTextView.setText(mHeaderText);
+                } else {
+                    mHeaderTextView.setText(R.string.lockpattern_need_to_unlock);
+                }
+                if (mFooterText != null) {
+                    mFooterTextView.setText(mFooterText);
+                } else {
+                    mFooterTextView.setText(R.string.lockpattern_need_to_unlock_footer);
+                }
+                
+                mLockPatternView.setEnabled(true);
+                mLockPatternView.enableInput();
+                break;
+            case NeedToUnlockWrong:
+                if (mHeaderWrongText != null) {
+                    mHeaderTextView.setText(mHeaderWrongText);
+                } else {
+                    mHeaderTextView.setText(R.string.lockpattern_need_to_unlock_wrong);
+                }
+                if (mFooterWrongText != null) {
+                    mFooterTextView.setText(mFooterWrongText);
+                } else {
+                    mFooterTextView.setText(R.string.lockpattern_need_to_unlock_wrong_footer);
+                }
+                
+                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
+                mLockPatternView.setEnabled(true);
+                mLockPatternView.enableInput();
+                break;
+            case LockedOut:
+                mLockPatternView.clearPattern();
+                // enabled = false means: disable input, and have the
+                // appearance of being disabled.
+                mLockPatternView.setEnabled(false); // appearance of being disabled
+                break;
+        }
+    }
+
+    private Runnable mClearPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
+        }
+    };
+
+    // clear the wrong pattern unless they have started a new one
+    // already
+    private void postClearPatternRunnable() {
+        mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
+    }
+
+    /**
+     * The pattern listener that responds according to a user confirming
+     * an existing lock pattern.
+     */
+    private LockPatternView.OnPatternListener mConfirmExistingLockPatternListener = new LockPatternView.OnPatternListener()  {
+
+        public void onPatternStart() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        }
+
+        public void onPatternCleared() {
+            mLockPatternView.removeCallbacks(mClearPatternRunnable);
+        }
+
+        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+            if (mLockPatternUtils.checkPattern(pattern)) {
+                setResult(RESULT_OK);
+                finish();
+            } else {
+                if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
+                        ++mNumWrongConfirmAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
+                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                    handleAttemptLockout(deadline);
+                } else {
+                    updateStage(Stage.NeedToUnlockWrong);
+                    postClearPatternRunnable();
+                }
+            }
+        }
+    };
+
+
+    private void handleAttemptLockout(long elapsedRealtimeDeadline) {
+        updateStage(Stage.LockedOut);
+        long elapsedRealtime = SystemClock.elapsedRealtime();
+        mCountdownTimer = new CountDownTimer(
+                elapsedRealtimeDeadline - elapsedRealtime,
+                LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS) {
+
+            @Override
+            public void onTick(long millisUntilFinished) {
+                mHeaderTextView.setText(R.string.lockpattern_too_many_failed_confirmation_attempts_header);
+                final int secondsCountdown = (int) (millisUntilFinished / 1000);
+                mFooterTextView.setText(getString(
+                        R.string.lockpattern_too_many_failed_confirmation_attempts_footer,
+                        secondsCountdown));
+            }
+
+            @Override
+            public void onFinish() {
+                mNumWrongConfirmAttempts = 0;
+                updateStage(Stage.NeedToUnlock);
+            }
+        }.start();
+    }
+}
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index bbf3c85..376333b 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -1,9 +1,13 @@
 package com.liato.bankdroid;
 
+import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 
+import android.app.Activity;
+import android.util.Log;
+
 public class Helpers {
 	public static BigDecimal parseBalance(String balance) {
 		//balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
@@ -37,4 +41,27 @@ public class Helpers {
 	public static String formatBalance(Double balance, String curr) {
 		return formatBalance(new BigDecimal(balance), curr);
 	}
+	
+	public static void slowDebug(String TAG, String text) {
+	    for (String s : text.split("\n")) {
+	        Log.d(TAG, s);
+	        try {
+                Thread.sleep(100);
+            }
+            catch (InterruptedException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+	    }
+	}
+	
+	static public void setActivityAnimation(Activity activity, int in, int out) {
+	    try {
+	        Method method = Activity.class.getMethod("overridePendingTransition", new Class[]{int.class, int.class});
+	        method.invoke(activity, in, out);
+	    } catch (Exception e) {
+	        // Can't change animation, so do nothing
+	    }
+	}
+	
 }
diff --git src/com/liato/bankdroid/LinearLayoutWithDefaultTouchRecepient.java src/com/liato/bankdroid/LinearLayoutWithDefaultTouchRecepient.java
new file mode 100644
index 0000000..ac3d3ab
--- /dev/null
+++ src/com/liato/bankdroid/LinearLayoutWithDefaultTouchRecepient.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+
+
+/**
+ * Like a normal linear layout, but supports dispatching all otherwise unhandled
+ * touch events to a particular descendant.  This is for the unlock screen, so
+ * that a wider range of touch events than just the lock pattern widget can kick
+ * off a lock pattern if the finger is eventually dragged into the bounds of the
+ * lock pattern view.
+ */
+public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout {
+
+    private final Rect mTempRect = new Rect();
+    private View mDefaultTouchRecepient;
+
+    public LinearLayoutWithDefaultTouchRecepient(Context context) {
+        super(context);
+    }
+
+    public LinearLayoutWithDefaultTouchRecepient(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setDefaultTouchRecepient(View defaultTouchRecepient) {
+        mDefaultTouchRecepient = defaultTouchRecepient;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (mDefaultTouchRecepient == null) {
+            return super.dispatchTouchEvent(ev);
+        }
+
+        if (super.dispatchTouchEvent(ev)) {
+            return true;
+        }
+        mTempRect.set(0, 0, 0, 0);
+        offsetRectIntoDescendantCoords(mDefaultTouchRecepient, mTempRect);
+        ev.setLocation(ev.getX() + mTempRect.left, ev.getY() + mTempRect.top);
+        return mDefaultTouchRecepient.dispatchTouchEvent(ev);
+    }
+
+}
diff --git src/com/liato/bankdroid/LockPatternUtils.java src/com/liato/bankdroid/LockPatternUtils.java
new file mode 100644
index 0000000..687ded6
--- /dev/null
+++ src/com/liato/bankdroid/LockPatternUtils.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.List;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Utilities for the lock patten and its settings.
+ */
+public class LockPatternUtils {
+
+    private static final String TAG = "LockPatternUtils";
+    
+    private static final String LOCK_PATTERN_FILE = "gesture.key";
+
+    /**
+     * The maximum number of incorrect attempts before the user is prevented
+     * from trying again for {@link #FAILED_ATTEMPT_TIMEOUT_MS}.
+     */
+    public static final int FAILED_ATTEMPTS_BEFORE_TIMEOUT = 5;
+
+    /**
+     * The number of incorrect attempts before which we fall back on an alternative
+     * method of verifying the user, and resetting their lock pattern.
+     */
+    public static final int FAILED_ATTEMPTS_BEFORE_RESET = 20;
+
+    /**
+     * How long the user is prevented from trying again after entering the
+     * wrong pattern too many times.
+     */
+    public static final long FAILED_ATTEMPT_TIMEOUT_MS = 30000L;
+
+    /**
+     * The interval of the countdown for showing progress of the lockout.
+     */
+    public static final long FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS = 1000L;
+
+    /**
+     * The minimum number of dots in a valid pattern.
+     */
+    public static final int MIN_LOCK_PATTERN_SIZE = 4;
+
+    /**
+     * The minimum number of dots the user must include in a wrong pattern
+     * attempt for it to be counted against the counts that affect
+     * {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET}
+     */
+    public static final int MIN_PATTERN_REGISTER_FAIL = 3;    
+
+    private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
+    private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
+    private final static String PATTERN_EVER_CHOSEN = "lockscreen.patterneverchosen";
+
+    private final ContentResolver mContentResolver;
+
+    private static String sLockPatternFilename;
+    private static Context mContext;
+    private static SharedPreferences mPrefs;
+    
+    /**
+     * @param contentResolver Used to look up and save settings.
+     */
+    public LockPatternUtils(Context context) {
+        mContext = context;
+        mContentResolver = context.getContentResolver();
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+        // Initialize the location of gesture lock file
+        if (sLockPatternFilename == null) {
+            sLockPatternFilename = context.getFilesDir() + LOCK_PATTERN_FILE;
+            //sLockPatternFilename = android.os.Environment.getDataDirectory() 
+            //        .getAbsolutePath() + LOCK_PATTERN_FILE;
+        }
+    }
+
+    /**
+     * Check to see if a pattern matches the saved pattern.  If no pattern exists,
+     * always returns true.
+     * @param pattern The pattern to check.
+     * @return Whether the pattern matchees the stored one.
+     */
+    public boolean checkPattern(List<LockPatternView.Cell> pattern) {
+        try {
+            // Read all the bytes from the file
+            RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "r");
+            final byte[] stored = new byte[(int) raf.length()];
+            int got = raf.read(stored, 0, stored.length);
+            raf.close();
+            if (got <= 0) {
+                return true;
+            }
+            // Compare the hash from the file with the entered pattern's hash
+            return Arrays.equals(stored, LockPatternUtils.patternToHash(pattern));
+        } catch (FileNotFoundException fnfe) {
+            return true;
+        } catch (IOException ioe) {
+            return true;
+        }
+    }
+
+    /**
+     * Check to see if the user has stored a lock pattern.
+     * @return Whether a saved pattern exists.
+     */
+    public boolean savedPatternExists() {
+        try {
+            // Check if we can read a byte from the file
+            RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "r");
+            byte first = raf.readByte();
+            raf.close();
+            return true;
+        } catch (FileNotFoundException fnfe) {
+            return false;
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Return true if the user has ever chosen a pattern.  This is true even if the pattern is
+     * currently cleared.
+     *
+     * @return True if the user has ever chosen a pattern.
+     */
+    public boolean isPatternEverChosen() {
+        return getBoolean(PATTERN_EVER_CHOSEN);
+    }
+
+    /**
+     * Save a lock pattern.
+     * @param pattern The new pattern to save.
+     */
+    public void saveLockPattern(List<LockPatternView.Cell> pattern) {
+        if (pattern == null) {
+            Log.d(TAG, "Removing lock pattern");
+        }
+        else {
+            Log.d(TAG, "Saving lock pattern: "+LockPatternUtils.patternToString(pattern));
+        }
+        // Compute the hash
+        final byte[] hash  = LockPatternUtils.patternToHash(pattern);
+        try {
+            // Write the hash to file
+            RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "rw");
+            // Truncate the file if pattern is null, to clear the lock
+            if (pattern == null) {
+                raf.setLength(0);
+            } else {
+                raf.write(hash, 0, hash.length);
+            }
+            raf.close();
+            setBoolean(PATTERN_EVER_CHOSEN, true);
+        } catch (FileNotFoundException fnfe) {
+            // Cant do much, unless we want to fail over to using the settings provider
+            Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
+        } catch (IOException ioe) {
+            // Cant do much
+            Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
+        }
+    }
+
+    /**
+     * Deserialize a pattern.
+     * @param string The pattern serialized with {@link #patternToString}
+     * @return The pattern.
+     */
+    public static List<LockPatternView.Cell> stringToPattern(String string) {
+        List<LockPatternView.Cell> result = Lists.newArrayList();
+
+        final byte[] bytes = string.getBytes();
+        for (int i = 0; i < bytes.length; i++) {
+            byte b = bytes[i];
+            result.add(LockPatternView.Cell.of(b / 3, b % 3));
+        }
+        return result;
+    }
+
+    /**
+     * Serialize a pattern.
+     * @param pattern The pattern.
+     * @return The pattern in string form.
+     */
+    public static String patternToString(List<LockPatternView.Cell> pattern) {
+        if (pattern == null) {
+            return "";
+        }
+        final int patternSize = pattern.size();
+
+        byte[] res = new byte[patternSize];
+        for (int i = 0; i < patternSize; i++) {
+            LockPatternView.Cell cell = pattern.get(i);
+            res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+        }
+        return new String(res);
+    }
+    
+    /*
+     * Generate an SHA-1 hash for the pattern. Not the most secure, but it is
+     * at least a second level of protection. First level is that the file
+     * is in a location only readable by the system process.
+     * @param pattern the gesture pattern.
+     * @return the hash of the pattern in a byte array.
+     */
+    static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
+        if (pattern == null) {
+            return null;
+        }
+        
+        final int patternSize = pattern.size();
+        byte[] res = new byte[patternSize];
+        for (int i = 0; i < patternSize; i++) {
+            LockPatternView.Cell cell = pattern.get(i);
+            res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+        }
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            byte[] hash = md.digest(res);
+            return hash;
+        } catch (NoSuchAlgorithmException nsa) {
+            return res;
+        }
+    }
+
+    /**
+     * @return Whether the lock pattern is enabled.
+     */
+    public boolean isLockPatternEnabled() {
+        return getBoolean(Settings.System.LOCK_PATTERN_ENABLED);
+    }
+
+    /**
+     * Set whether the lock pattern is enabled.
+     */
+    public void setLockPatternEnabled(boolean enabled) {
+        setBoolean(Settings.System.LOCK_PATTERN_ENABLED, enabled);
+    }
+
+    /**
+     * @return Whether the visible pattern is enabled.
+     */
+    public boolean isVisiblePatternEnabled() {
+        return getBoolean(Settings.System.LOCK_PATTERN_VISIBLE);
+    }
+
+    /**
+     * Set whether the visible pattern is enabled.
+     */
+    public void setVisiblePatternEnabled(boolean enabled) {
+        setBoolean(Settings.System.LOCK_PATTERN_VISIBLE, enabled);
+    }
+
+    /**
+     * @return Whether tactile feedback for the pattern is enabled.
+     */
+    public boolean isTactileFeedbackEnabled() {
+        return getBoolean(Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED);
+    }
+
+    /**
+     * Set whether tactile feedback for the pattern is enabled.
+     */
+    public void setTactileFeedbackEnabled(boolean enabled) {
+        setBoolean(Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, enabled);
+    }
+
+    /**
+     * Set and store the lockout deadline, meaning the user can't attempt his/her unlock
+     * pattern until the deadline has passed.
+     * @return the chosen deadline.
+     */
+    public long setLockoutAttemptDeadline() {
+        final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
+        setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline);
+        return deadline;
+    }
+
+    /**
+     * @return The elapsed time in millis in the future when the user is allowed to
+     *   attempt to enter his/her lock pattern, or 0 if the user is welcome to
+     *   enter a pattern.
+     */
+    public long getLockoutAttemptDeadline() {
+        final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L);
+        final long now = SystemClock.elapsedRealtime();
+        if (deadline < now || deadline > (now + FAILED_ATTEMPT_TIMEOUT_MS)) {
+            return 0L;
+        }
+        return deadline;
+    }
+
+    /**
+     * @return Whether the user is permanently locked out until they verify their
+     *   credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
+     *   attempts.
+     */
+    public boolean isPermanentlyLocked() {
+        return getBoolean(LOCKOUT_PERMANENT_KEY);
+    }
+
+    /**
+     * Set the state of whether the device is permanently locked, meaning the user
+     * must authenticate via other means.  If false, that means the user has gone
+     * out of permanent lock, so the existing (forgotten) lock pattern needs to
+     * be cleared.
+     * @param locked Whether the user is permanently locked out until they verify their
+     *   credentials.  Occurs after {@link #FAILED_ATTEMPTS_BEFORE_RESET} failed
+     *   attempts.
+     */
+    public void setPermanentlyLocked(boolean locked) {
+        setBoolean(LOCKOUT_PERMANENT_KEY, locked);
+
+        if (!locked) {
+            setLockPatternEnabled(false);
+            saveLockPattern(null);
+        }
+    }
+
+    /**
+     * @return A formatted string of the next alarm (for showing on the lock screen),
+     *   or null if there is no next alarm.
+     */
+    public String getNextAlarm() {
+        String nextAlarm = Settings.System.getString(mContentResolver,
+                Settings.System.NEXT_ALARM_FORMATTED);
+        if (nextAlarm == null || TextUtils.isEmpty(nextAlarm)) {
+            return null;
+        }
+        return nextAlarm;
+    }
+
+    private boolean getBoolean(String systemSettingKey) {
+        return mPrefs.getBoolean(systemSettingKey, false);
+    }
+
+    private void setBoolean(String systemSettingKey, boolean enabled) {
+        Editor editor = mPrefs.edit();
+        editor.putBoolean(systemSettingKey, enabled);
+        editor.commit();        
+    }
+
+    private long getLong(String systemSettingKey, long def) {
+        return mPrefs.getLong(systemSettingKey, def);
+    }
+
+    private void setLong(String systemSettingKey, long value) {
+        Editor editor = mPrefs.edit();
+        editor.putLong(systemSettingKey, value);
+        editor.commit(); 
+    }
+
+
+}
diff --git src/com/liato/bankdroid/LockPatternView.java src/com/liato/bankdroid/LockPatternView.java
new file mode 100644
index 0000000..da6db20
--- /dev/null
+++ src/com/liato/bankdroid/LockPatternView.java
@@ -0,0 +1,1029 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.liato.bankdroid;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.Vibrator;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Displays and detects the user's unlock attempt, which is a drag of a finger
+ * across 9 regions of the screen.
+ *
+ * Is also capable of displaying a static pattern in "in progress", "wrong" or
+ * "correct" states.
+ */
+public class LockPatternView extends View {
+    // Vibrator pattern for creating a tactile bump
+    private static final long[] VIBE_PATTERN = {0, 1, 40, 41};
+
+    private static final boolean PROFILE_DRAWING = false;
+    private boolean mDrawingProfilingStarted = false;
+
+    private Paint mPaint = new Paint();
+    private Paint mPathPaint = new Paint();
+    protected int mPaddingLeft;
+    protected int mPaddingRight;
+    protected int mPaddingTop;
+    protected int mPaddingBottom;
+
+    // TODO: make this common with PhoneWindow
+    static final int STATUS_BAR_HEIGHT = 25;
+
+    /**
+     * How many milliseconds we spend animating each circle of a lock pattern
+     * if the animating mode is set.  The entire animation should take this
+     * constant * the length of the pattern to complete.
+     */
+    private static final int MILLIS_PER_CIRCLE_ANIMATING = 700;
+
+    private OnPatternListener mOnPatternListener;
+    private ArrayList<Cell> mPattern = new ArrayList<Cell>(9);
+
+    /**
+     * Lookup table for the circles of the pattern we are currently drawing.
+     * This will be the cells of the complete pattern unless we are animating,
+     * in which case we use this to hold the cells we are drawing for the in
+     * progress animation.
+     */
+    private boolean[][] mPatternDrawLookup = new boolean[3][3];
+
+    /**
+     * the in progress point:
+     * - during interaction: where the user's finger is
+     * - during animation: the current tip of the animating line
+     */
+    private float mInProgressX = -1;
+    private float mInProgressY = -1;
+
+    private long mAnimatingPeriodStart;
+
+    private DisplayMode mPatternDisplayMode = DisplayMode.Correct;
+    private boolean mInputEnabled = true;
+    private boolean mInStealthMode = false;
+    private boolean mTactileFeedbackEnabled = true;
+    private boolean mPatternInProgress = false;
+
+    private float mDiameterFactor = 0.5f;
+    private float mHitFactor = 0.6f;
+
+    private float mSquareWidth;
+    private float mSquareHeight;
+
+    private Bitmap mBitmapBtnDefault;
+    private Bitmap mBitmapBtnTouched;
+    private Bitmap mBitmapCircleDefault;
+    private Bitmap mBitmapCircleGreen;
+    private Bitmap mBitmapCircleRed;
+
+    private Bitmap mBitmapArrowGreenUp;
+    private Bitmap mBitmapArrowRedUp;
+
+    private final Path mCurrentPath = new Path();
+    private final Rect mInvalidate = new Rect();
+
+    private int mBitmapWidth;
+    private int mBitmapHeight;
+   
+
+    private Vibrator vibe; // Vibrator for creating tactile feedback
+
+    /**
+     * Represents a cell in the 3 X 3 matrix of the unlock pattern view.
+     */
+    public static class Cell {
+        int row;
+        int column;
+
+        // keep # objects limited to 9
+        static Cell[][] sCells = new Cell[3][3];
+        static {
+            for (int i = 0; i < 3; i++) {
+                for (int j = 0; j < 3; j++) {
+                    sCells[i][j] = new Cell(i, j);
+                }
+            }
+        }
+
+        /**
+         * @param row The row of the cell.
+         * @param column The column of the cell.
+         */
+        private Cell(int row, int column) {
+            checkRange(row, column);
+            this.row = row;
+            this.column = column;
+        }
+
+        public int getRow() {
+            return row;
+        }
+
+        public int getColumn() {
+            return column;
+        }
+
+        /**
+         * @param row The row of the cell.
+         * @param column The column of the cell.
+         */
+        public static synchronized Cell of(int row, int column) {
+            checkRange(row, column);
+            return sCells[row][column];
+        }
+
+        private static void checkRange(int row, int column) {
+            if (row < 0 || row > 2) {
+                throw new IllegalArgumentException("row must be in range 0-2");
+            }
+            if (column < 0 || column > 2) {
+                throw new IllegalArgumentException("column must be in range 0-2");
+            }
+        }
+
+        public String toString() {
+            return "(row=" + row + ",clmn=" + column + ")";
+        }
+    }
+
+    /**
+     * How to display the current pattern.
+     */
+    public enum DisplayMode {
+
+        /**
+         * The pattern drawn is correct (i.e draw it in a friendly color)
+         */
+        Correct,
+
+        /**
+         * Animate the pattern (for demo, and help).
+         */
+        Animate,
+
+        /**
+         * The pattern is wrong (i.e draw a foreboding color)
+         */
+        Wrong
+    }
+
+    /**
+     * The call back interface for detecting patterns entered by the user.
+     */
+    public static interface OnPatternListener {
+
+        /**
+         * A new pattern has begun.
+         */
+        void onPatternStart();
+
+        /**
+         * The pattern was cleared.
+         */
+        void onPatternCleared();
+
+        /**
+         * A pattern was detected from the user.
+         * @param pattern The pattern.
+         */
+        void onPatternDetected(List<Cell> pattern);
+    }
+
+    public LockPatternView(Context context) {
+        this(context, null);
+    }
+
+    public LockPatternView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        //vibe = new Vibrator();
+        vibe = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);  
+
+        setClickable(true);
+
+        mPathPaint.setAntiAlias(true);
+        mPathPaint.setDither(true);
+        mPathPaint.setColor(Color.WHITE);   // TODO this should be from the style
+        mPathPaint.setAlpha(128);
+        mPathPaint.setStyle(Paint.Style.STROKE);
+        mPathPaint.setStrokeJoin(Paint.Join.ROUND);
+        mPathPaint.setStrokeCap(Paint.Cap.ROUND);
+
+        // lot's of bitmaps!
+        /*
+        mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default);
+        mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched);
+        mBitmapCircleDefault = getBitmapFor(R.drawable.indicator_code_lock_point_area_default);
+        mBitmapCircleGreen = getBitmapFor(R.drawable.indicator_code_lock_point_area_green);
+        mBitmapCircleRed = getBitmapFor(R.drawable.indicator_code_lock_point_area_red);
+
+        mBitmapArrowGreenUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_green_up);
+        mBitmapArrowRedUp = getBitmapFor(R.drawable.indicator_code_lock_drag_direction_red_up);
+        */
+        
+        mBitmapBtnDefault = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_default", null, null));
+        mBitmapBtnTouched = getBitmapFor(getResources().getIdentifier("android:drawable/btn_code_lock_touched", null, null));
+        mBitmapCircleDefault = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_default", null, null));
+        mBitmapCircleGreen = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_green", null, null));
+        mBitmapCircleRed = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_point_area_red", null, null));
+
+        mBitmapArrowGreenUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_green_up", null, null));
+        mBitmapArrowRedUp = getBitmapFor(getResources().getIdentifier("android:drawable/indicator_code_lock_drag_direction_red_up", null, null));     
+
+        // we assume all bitmaps have the same size
+        mBitmapWidth = mBitmapBtnDefault.getWidth();
+        mBitmapHeight = mBitmapBtnDefault.getHeight();
+    }
+
+    private Bitmap getBitmapFor(int resId) {
+        return BitmapFactory.decodeResource(getContext().getResources(), resId);
+    }
+
+    /**
+     * @return Whether the view is in stealth mode.
+     */
+    public boolean isInStealthMode() {
+        return mInStealthMode;
+    }
+
+    /**
+     * @return Whether the view has tactile feedback enabled.
+     */
+    public boolean isTactileFeedbackEnabled() {
+        return mTactileFeedbackEnabled;
+    }
+
+    /**
+     * Set whether the view is in stealth mode.  If true, there will be no
+     * visible feedback as the user enters the pattern.
+     *
+     * @param inStealthMode Whether in stealth mode.
+     */
+    public void setInStealthMode(boolean inStealthMode) {
+        mInStealthMode = inStealthMode;
+    }
+
+    /**
+     * Set whether the view will use tactile feedback.  If true, there will be
+     * tactile feedback as the user enters the pattern.
+     *
+     * @param tactileFeedbackEnabled Whether tactile feedback is enabled
+     */
+    public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) {
+        mTactileFeedbackEnabled = tactileFeedbackEnabled;
+    }
+
+    /**
+     * Set the call back for pattern detection.
+     * @param onPatternListener The call back.
+     */
+    public void setOnPatternListener(
+            OnPatternListener onPatternListener) {
+        mOnPatternListener = onPatternListener;
+    }
+
+    /**
+     * Set the pattern explicitely (rather than waiting for the user to input
+     * a pattern).
+     * @param displayMode How to display the pattern.
+     * @param pattern The pattern.
+     */
+    public void setPattern(DisplayMode displayMode, List<Cell> pattern) {
+        mPattern.clear();
+        mPattern.addAll(pattern);
+        clearPatternDrawLookup();
+        for (Cell cell : pattern) {
+            mPatternDrawLookup[cell.getRow()][cell.getColumn()] = true;
+        }
+
+        setDisplayMode(displayMode);
+    }
+
+    /**
+     * Set the display mode of the current pattern.  This can be useful, for
+     * instance, after detecting a pattern to tell this view whether change the
+     * in progress result to correct or wrong.
+     * @param displayMode The display mode.
+     */
+    public void setDisplayMode(DisplayMode displayMode) {
+        mPatternDisplayMode = displayMode;
+        if (displayMode == DisplayMode.Animate) {
+            if (mPattern.size() == 0) {
+                throw new IllegalStateException("you must have a pattern to "
+                        + "animate if you want to set the display mode to animate");
+            }
+            mAnimatingPeriodStart = SystemClock.elapsedRealtime();
+            final Cell first = mPattern.get(0);
+            mInProgressX = getCenterXForColumn(first.getColumn());
+            mInProgressY = getCenterYForRow(first.getRow());
+            clearPatternDrawLookup();
+        }
+        invalidate();
+    }
+
+    /**
+     * Clear the pattern.
+     */
+    public void clearPattern() {
+        resetPattern();
+    }
+
+    /**
+     * Reset all pattern state.
+     */
+    private void resetPattern() {
+        mPattern.clear();
+        clearPatternDrawLookup();
+        mPatternDisplayMode = DisplayMode.Correct;
+        invalidate();
+    }
+
+    /**
+     * Clear the pattern lookup table.
+     */
+    private void clearPatternDrawLookup() {
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                mPatternDrawLookup[i][j] = false;
+            }
+        }
+    }
+
+    /**
+     * Disable input (for instance when displaying a message that will
+     * timeout so user doesn't get view into messy state).
+     */
+    public void disableInput() {
+        mInputEnabled = false;
+    }
+
+    /**
+     * Enable input.
+     */
+    public void enableInput() {
+        mInputEnabled = true;
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        final int width = w - mPaddingLeft - mPaddingRight;
+        mSquareWidth = width / 3.0f;
+
+        final int height = h - mPaddingTop - mPaddingBottom;
+        mSquareHeight = height / 3.0f;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int height = MeasureSpec.getSize(heightMeasureSpec);
+        final int squareSide = Math.min(width, height);
+        setMeasuredDimension(squareSide, squareSide);
+    }
+
+    /**
+     * Determines whether the point x, y will add a new point to the current
+     * pattern (in addition to finding the cell, also makes heuristic choices
+     * such as filling in gaps based on current pattern).
+     * @param x The x coordinate.
+     * @param y The y coordinate.
+     */
+    private Cell detectAndAddHit(float x, float y) {
+        final Cell cell = checkForNewHit(x, y);
+        if (cell != null) {
+
+            // check for gaps in existing pattern
+            Cell fillInGapCell = null;
+            final ArrayList<Cell> pattern = mPattern;
+            if (!pattern.isEmpty()) {
+                final Cell lastCell = pattern.get(pattern.size() - 1);
+                int dRow = cell.row - lastCell.row;
+                int dColumn = cell.column - lastCell.column;
+
+                int fillInRow = lastCell.row;
+                int fillInColumn = lastCell.column;
+
+                if (Math.abs(dRow) == 2 && Math.abs(dColumn) != 1) {
+                    fillInRow = lastCell.row + ((dRow > 0) ? 1 : -1);
+                }
+
+                if (Math.abs(dColumn) == 2 && Math.abs(dRow) != 1) {
+                    fillInColumn = lastCell.column + ((dColumn > 0) ? 1 : -1);
+                }
+
+                fillInGapCell = Cell.of(fillInRow, fillInColumn);
+            }
+
+            if (fillInGapCell != null &&
+                    !mPatternDrawLookup[fillInGapCell.row][fillInGapCell.column]) {
+                addCellToPattern(fillInGapCell);
+            }
+            addCellToPattern(cell);
+            if (mTactileFeedbackEnabled){
+                vibe.vibrate(VIBE_PATTERN, -1); // Generate tactile feedback
+            }
+            return cell;
+        }
+        return null;
+    }
+
+    private void addCellToPattern(Cell newCell) {
+        mPatternDrawLookup[newCell.getRow()][newCell.getColumn()] = true;
+        mPattern.add(newCell);
+    }
+
+    // helper method to find which cell a point maps to
+    private Cell checkForNewHit(float x, float y) {
+
+        final int rowHit = getRowHit(y);
+        if (rowHit < 0) {
+            return null;
+        }
+        final int columnHit = getColumnHit(x);
+        if (columnHit < 0) {
+            return null;
+        }
+
+        if (mPatternDrawLookup[rowHit][columnHit]) {
+            return null;
+        }
+        return Cell.of(rowHit, columnHit);
+    }
+
+    /**
+     * Helper method to find the row that y falls into.
+     * @param y The y coordinate
+     * @return The row that y falls in, or -1 if it falls in no row.
+     */
+    private int getRowHit(float y) {
+
+        final float squareHeight = mSquareHeight;
+        float hitSize = squareHeight * mHitFactor;
+
+        float offset = mPaddingTop + (squareHeight - hitSize) / 2f;
+        for (int i = 0; i < 3; i++) {
+
+            final float hitTop = offset + squareHeight * i;
+            if (y >= hitTop && y <= hitTop + hitSize) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Helper method to find the column x fallis into.
+     * @param x The x coordinate.
+     * @return The column that x falls in, or -1 if it falls in no column.
+     */
+    private int getColumnHit(float x) {
+        final float squareWidth = mSquareWidth;
+        float hitSize = squareWidth * mHitFactor;
+
+        float offset = mPaddingLeft + (squareWidth - hitSize) / 2f;
+        for (int i = 0; i < 3; i++) {
+
+            final float hitLeft = offset + squareWidth * i;
+            if (x >= hitLeft && x <= hitLeft + hitSize) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent motionEvent) {
+        if (!mInputEnabled || !isEnabled()) {
+            return false;
+        }
+
+        final float x = motionEvent.getX();
+        final float y = motionEvent.getY();
+        Cell hitCell;
+        switch(motionEvent.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                resetPattern();
+                hitCell = detectAndAddHit(x, y);
+                if (hitCell != null && mOnPatternListener != null) {
+                    mPatternInProgress = true;
+                    mPatternDisplayMode = DisplayMode.Correct;
+                    mOnPatternListener.onPatternStart();
+                } else if (mOnPatternListener != null) {
+                    mPatternInProgress = false;
+                    mOnPatternListener.onPatternCleared();
+                }
+                if (hitCell != null) {
+                    final float startX = getCenterXForColumn(hitCell.column);
+                    final float startY = getCenterYForRow(hitCell.row);
+
+                    final float widthOffset = mSquareWidth / 2f;
+                    final float heightOffset = mSquareHeight / 2f;
+
+                    invalidate((int) (startX - widthOffset), (int) (startY - heightOffset),
+                            (int) (startX + widthOffset), (int) (startY + heightOffset));
+                }
+                mInProgressX = x;
+                mInProgressY = y;
+                if (PROFILE_DRAWING) {
+                    if (!mDrawingProfilingStarted) {
+                        Debug.startMethodTracing("LockPatternDrawing");
+                        mDrawingProfilingStarted = true;
+                    }
+                }
+                return true;
+            case MotionEvent.ACTION_UP:
+                // report pattern detected
+                if (!mPattern.isEmpty() && mOnPatternListener != null) {
+                    mPatternInProgress = false;
+                    mOnPatternListener.onPatternDetected(mPattern);
+                    invalidate();
+                }
+                if (PROFILE_DRAWING) {
+                    if (mDrawingProfilingStarted) {
+                        Debug.stopMethodTracing();
+                        mDrawingProfilingStarted = false;
+                    }
+                }
+                return true;
+            case MotionEvent.ACTION_MOVE:
+                final int patternSizePreHitDetect = mPattern.size();
+                hitCell = detectAndAddHit(x, y);
+                final int patternSize = mPattern.size();
+                if (hitCell != null && (mOnPatternListener != null) && (patternSize == 1)) {
+                    mPatternInProgress = true;
+                    mOnPatternListener.onPatternStart();
+                }
+                // note current x and y for rubber banding of in progress
+                // patterns
+                final float dx = Math.abs(x - mInProgressX);
+                final float dy = Math.abs(y - mInProgressY);
+                if (dx + dy > mSquareWidth * 0.01f) {
+                    float oldX = mInProgressX;
+                    float oldY = mInProgressY;
+
+                    mInProgressX = x;
+                    mInProgressY = y;
+
+                    if (mPatternInProgress && patternSize > 0) {
+                        final ArrayList<Cell> pattern = mPattern;
+                        final float radius = mSquareWidth * mDiameterFactor * 0.5f;
+
+                        final Cell lastCell = pattern.get(patternSize - 1);
+
+                        float startX = getCenterXForColumn(lastCell.column);
+                        float startY = getCenterYForRow(lastCell.row);
+
+                        float left;
+                        float top;
+                        float right;
+                        float bottom;
+
+                        final Rect invalidateRect = mInvalidate;
+
+                        if (startX < x) {
+                            left = startX;
+                            right = x;
+                        } else {
+                            left = x;
+                            right = startX;
+                        }
+
+                        if (startY < y) {
+                            top = startY;
+                            bottom = y;
+                        } else {
+                            top = y;
+                            bottom = startY;
+                        }
+
+                        // Invalidate between the pattern's last cell and the current location
+                        invalidateRect.set((int) (left - radius), (int) (top - radius),
+                                (int) (right + radius), (int) (bottom + radius));
+
+                        if (startX < oldX) {
+                            left = startX;
+                            right = oldX;
+                        } else {
+                            left = oldX;
+                            right = startX;
+                        }
+
+                        if (startY < oldY) {
+                            top = startY;
+                            bottom = oldY;
+                        } else {
+                            top = oldY;
+                            bottom = startY;
+                        }
+
+                        // Invalidate between the pattern's last cell and the previous location
+                        invalidateRect.union((int) (left - radius), (int) (top - radius),
+                                (int) (right + radius), (int) (bottom + radius));
+
+                        // Invalidate between the pattern's new cell and the pattern's previous cell
+                        if (hitCell != null) {
+                            startX = getCenterXForColumn(hitCell.column);
+                            startY = getCenterYForRow(hitCell.row);
+
+                            if (patternSize >= 2) {
+                                // (re-using hitcell for old cell)
+                                hitCell = pattern.get(patternSize - 1 - (patternSize - patternSizePreHitDetect));
+                                oldX = getCenterXForColumn(hitCell.column);
+                                oldY = getCenterYForRow(hitCell.row);
+
+                                if (startX < oldX) {
+                                    left = startX;
+                                    right = oldX;
+                                } else {
+                                    left = oldX;
+                                    right = startX;
+                                }
+
+                                if (startY < oldY) {
+                                    top = startY;
+                                    bottom = oldY;
+                                } else {
+                                    top = oldY;
+                                    bottom = startY;
+                                }
+                            } else {
+                                left = right = startX;
+                                top = bottom = startY;
+                            }
+
+                            final float widthOffset = mSquareWidth / 2f;
+                            final float heightOffset = mSquareHeight / 2f;
+
+                            invalidateRect.set((int) (left - widthOffset),
+                                    (int) (top - heightOffset), (int) (right + widthOffset),
+                                    (int) (bottom + heightOffset));
+                        }
+
+                        invalidate(invalidateRect);
+                    } else {
+                        invalidate();
+                    }
+                }
+                return true;
+            case MotionEvent.ACTION_CANCEL:
+                resetPattern();
+                if (mOnPatternListener != null) {
+                    mPatternInProgress = false;
+                    mOnPatternListener.onPatternCleared();
+                }
+                if (PROFILE_DRAWING) {
+                    if (mDrawingProfilingStarted) {
+                        Debug.stopMethodTracing();
+                        mDrawingProfilingStarted = false;
+                    }
+                }
+                return true;
+        }
+        return false;
+    }
+
+    private float getCenterXForColumn(int column) {
+        return mPaddingLeft + column * mSquareWidth + mSquareWidth / 2f;
+    }
+
+    private float getCenterYForRow(int row) {
+        return mPaddingTop + row * mSquareHeight + mSquareHeight / 2f;
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        final ArrayList<Cell> pattern = mPattern;
+        final int count = pattern.size();
+        final boolean[][] drawLookup = mPatternDrawLookup;
+
+        if (mPatternDisplayMode == DisplayMode.Animate) {
+
+            // figure out which circles to draw
+
+            // + 1 so we pause on complete pattern
+            final int oneCycle = (count + 1) * MILLIS_PER_CIRCLE_ANIMATING;
+            final int spotInCycle = (int) (SystemClock.elapsedRealtime() -
+                    mAnimatingPeriodStart) % oneCycle;
+            final int numCircles = spotInCycle / MILLIS_PER_CIRCLE_ANIMATING;
+
+            clearPatternDrawLookup();
+            for (int i = 0; i < numCircles; i++) {
+                final Cell cell = pattern.get(i);
+                drawLookup[cell.getRow()][cell.getColumn()] = true;
+            }
+
+            // figure out in progress portion of ghosting line
+
+            final boolean needToUpdateInProgressPoint = numCircles > 0
+                    && numCircles < count;
+
+            if (needToUpdateInProgressPoint) {
+                final float percentageOfNextCircle =
+                        ((float) (spotInCycle % MILLIS_PER_CIRCLE_ANIMATING)) /
+                                MILLIS_PER_CIRCLE_ANIMATING;
+
+                final Cell currentCell = pattern.get(numCircles - 1);
+                final float centerX = getCenterXForColumn(currentCell.column);
+                final float centerY = getCenterYForRow(currentCell.row);
+
+                final Cell nextCell = pattern.get(numCircles);
+                final float dx = percentageOfNextCircle *
+                        (getCenterXForColumn(nextCell.column) - centerX);
+                final float dy = percentageOfNextCircle *
+                        (getCenterYForRow(nextCell.row) - centerY);
+                mInProgressX = centerX + dx;
+                mInProgressY = centerY + dy;
+            }
+            // TODO: Infinite loop here...
+            invalidate();
+        }
+
+        final float squareWidth = mSquareWidth;
+        final float squareHeight = mSquareHeight;
+
+        float radius = (squareWidth * mDiameterFactor * 0.5f);
+        mPathPaint.setStrokeWidth(radius);
+
+        final Path currentPath = mCurrentPath;
+        currentPath.rewind();
+
+        // TODO: the path should be created and cached every time we hit-detect a cell
+        // only the last segment of the path should be computed here
+        // draw the path of the pattern (unless the user is in progress, and
+        // we are in stealth mode)
+        final boolean drawPath = (!mInStealthMode || mPatternDisplayMode == DisplayMode.Wrong);
+        if (drawPath) {
+            boolean anyCircles = false;
+            for (int i = 0; i < count; i++) {
+                Cell cell = pattern.get(i);
+
+                // only draw the part of the pattern stored in
+                // the lookup table (this is only different in the case
+                // of animation).
+                if (!drawLookup[cell.row][cell.column]) {
+                    break;
+                }
+                anyCircles = true;
+
+                float centerX = getCenterXForColumn(cell.column);
+                float centerY = getCenterYForRow(cell.row);
+                if (i == 0) {
+                    currentPath.moveTo(centerX, centerY);
+                } else {
+                    currentPath.lineTo(centerX, centerY);
+                }
+            }
+
+            // add last in progress section
+            if ((mPatternInProgress || mPatternDisplayMode == DisplayMode.Animate)
+                    && anyCircles) {
+                currentPath.lineTo(mInProgressX, mInProgressY);
+            }
+            canvas.drawPath(currentPath, mPathPaint);
+        }
+
+        // draw the circles
+        final int paddingTop = mPaddingTop;
+        final int paddingLeft = mPaddingLeft;
+
+        for (int i = 0; i < 3; i++) {
+            float topY = paddingTop + i * squareHeight;
+            //float centerY = mPaddingTop + i * mSquareHeight + (mSquareHeight / 2);
+            for (int j = 0; j < 3; j++) {
+                float leftX = paddingLeft + j * squareWidth;
+                drawCircle(canvas, (int) leftX, (int) topY, drawLookup[i][j]);
+            }
+        }
+
+        // draw the arrows associated with the path (unless the user is in progress, and
+        // we are in stealth mode)
+        boolean oldFlag = (mPaint.getFlags() & Paint.FILTER_BITMAP_FLAG) != 0;
+        mPaint.setFilterBitmap(true); // draw with higher quality since we render with transforms
+        if (drawPath) {
+            for (int i = 0; i < count - 1; i++) {
+                Cell cell = pattern.get(i);
+                Cell next = pattern.get(i + 1);
+
+                // only draw the part of the pattern stored in
+                // the lookup table (this is only different in the case
+                // of animation).
+                if (!drawLookup[next.row][next.column]) {
+                    break;
+                }
+
+                float leftX = paddingLeft + cell.column * squareWidth;
+                float topY = paddingTop + cell.row * squareHeight;
+
+                drawArrow(canvas, leftX, topY, cell, next);
+            }
+        }
+        mPaint.setFilterBitmap(oldFlag); // restore default flag
+    }
+
+    private void drawArrow(Canvas canvas, float leftX, float topY, Cell start, Cell end) {
+        boolean green = mPatternDisplayMode != DisplayMode.Wrong;
+
+        final int endRow = end.row;
+        final int startRow = start.row;
+        final int endColumn = end.column;
+        final int startColumn = start.column;
+
+        // offsets for centering the bitmap in the cell
+        final int offsetX = ((int) mSquareWidth - mBitmapWidth) / 2;
+        final int offsetY = ((int) mSquareHeight - mBitmapHeight) / 2;
+
+        // compute transform to place arrow bitmaps at correct angle inside circle.
+        // This assumes that the arrow image is drawn at 12:00 with it's top edge
+        // coincident with the circle bitmap's top edge.
+        Bitmap arrow = green ? mBitmapArrowGreenUp : mBitmapArrowRedUp;
+        Matrix matrix = new Matrix();
+        final int cellWidth = mBitmapCircleDefault.getWidth();
+        final int cellHeight = mBitmapCircleDefault.getHeight();
+        
+        // the up arrow bitmap is at 12:00, so find the rotation from x axis and add 90 degrees.
+        final float theta = (float) Math.atan2(
+                (double) (endRow - startRow), (double) (endColumn - startColumn));
+        final float angle = (float) Math.toDegrees(theta) + 90.0f; 
+        
+        // compose matrix
+        matrix.setTranslate(leftX + offsetX, topY + offsetY); // transform to cell position
+        matrix.preRotate(angle, cellWidth / 2.0f, cellHeight / 2.0f);  // rotate about cell center
+        matrix.preTranslate((cellWidth - arrow.getWidth()) / 2.0f, 0.0f); // translate to 12:00 pos
+        canvas.drawBitmap(arrow, matrix, mPaint); 
+    }
+
+    /**
+     * @param canvas
+     * @param leftX
+     * @param topY
+     * @param partOfPattern Whether this circle is part of the pattern.
+     */
+    private void drawCircle(Canvas canvas, int leftX, int topY, boolean partOfPattern) {
+        Bitmap outerCircle;
+        Bitmap innerCircle;
+
+        if (!partOfPattern || (mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong)) {
+            // unselected circle
+            outerCircle = mBitmapCircleDefault;
+            innerCircle = mBitmapBtnDefault;
+        } else if (mPatternInProgress) {
+            // user is in middle of drawing a pattern
+            outerCircle = mBitmapCircleGreen;
+            innerCircle = mBitmapBtnTouched;
+        } else if (mPatternDisplayMode == DisplayMode.Wrong) {
+            // the pattern is wrong
+            outerCircle = mBitmapCircleRed;
+            innerCircle = mBitmapBtnDefault;
+        } else if (mPatternDisplayMode == DisplayMode.Correct ||
+                mPatternDisplayMode == DisplayMode.Animate) {
+            // the pattern is correct
+            outerCircle = mBitmapCircleGreen;
+            innerCircle = mBitmapBtnDefault;
+        } else {
+            throw new IllegalStateException("unknown display mode " + mPatternDisplayMode);
+        }
+
+        final int width = mBitmapWidth;
+        final int height = mBitmapHeight;
+
+        final float squareWidth = mSquareWidth;
+        final float squareHeight = mSquareHeight;
+
+        int offsetX = (int) ((squareWidth - width) / 2f);
+        int offsetY = (int) ((squareHeight - height) / 2f);
+
+        canvas.drawBitmap(outerCircle, leftX + offsetX, topY + offsetY, mPaint);
+        canvas.drawBitmap(innerCircle, leftX + offsetX, topY + offsetY, mPaint);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        return new SavedState(superState,
+                LockPatternUtils.patternToString(mPattern),
+                mPatternDisplayMode.ordinal(),
+                mInputEnabled, mInStealthMode, mTactileFeedbackEnabled);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        final SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        setPattern(
+                DisplayMode.Correct,
+                LockPatternUtils.stringToPattern(ss.getSerializedPattern()));
+        mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()];
+        mInputEnabled = ss.isInputEnabled();
+        mInStealthMode = ss.isInStealthMode();
+        mTactileFeedbackEnabled = ss.isTactileFeedbackEnabled();
+    }
+
+    /**
+     * The parecelable for saving and restoring a lock pattern view.
+     */
+    private static class SavedState extends BaseSavedState {
+
+        private final String mSerializedPattern;
+        private final int mDisplayMode;
+        private final boolean mInputEnabled;
+        private final boolean mInStealthMode;
+        private final boolean mTactileFeedbackEnabled;
+
+        /**
+         * Constructor called from {@link LockPatternView#onSaveInstanceState()}
+         */
+        private SavedState(Parcelable superState, String serializedPattern, int displayMode,
+                boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) {
+            super(superState);
+            mSerializedPattern = serializedPattern;
+            mDisplayMode = displayMode;
+            mInputEnabled = inputEnabled;
+            mInStealthMode = inStealthMode;
+            mTactileFeedbackEnabled = tactileFeedbackEnabled;
+        }
+
+        /**
+         * Constructor called from {@link #CREATOR}
+         */
+        private SavedState(Parcel in) {
+            super(in);
+            mSerializedPattern = in.readString();
+            mDisplayMode = in.readInt();
+            mInputEnabled = (Boolean) in.readValue(null);
+            mInStealthMode = (Boolean) in.readValue(null);
+            mTactileFeedbackEnabled = (Boolean) in.readValue(null);
+        }
+        
+        public String getSerializedPattern() {
+            return mSerializedPattern;
+        }
+
+        public int getDisplayMode() {
+            return mDisplayMode;
+        }
+
+        public boolean isInputEnabled() {
+            return mInputEnabled;
+        }
+
+        public boolean isInStealthMode() {
+            return mInStealthMode;
+        }
+
+        public boolean isTactileFeedbackEnabled(){
+            return mTactileFeedbackEnabled;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeString(mSerializedPattern);
+            dest.writeInt(mDisplayMode);
+            dest.writeValue(mInputEnabled);
+            dest.writeValue(mInStealthMode);
+            dest.writeValue(mTactileFeedbackEnabled);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Creator<SavedState>() {
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+}
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
index 79c35f9..97cf5ab 100644
--- src/com/liato/bankdroid/LockableActivity.java
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -1,50 +1,79 @@
 package com.liato.bankdroid;
 
+import com.liato.bankdroid.LockPatternUtils;
+
 import android.app.Activity;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.util.Log;
 
 public class LockableActivity extends Activity {
+    private static String TAG = "LockableActivity";
+    private static int PATTERNLOCK_UNLOCK = 42;
 	private SharedPreferences prefs;
 	private Editor editor;
+	private LockPatternUtils mLockPatternUtils;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		mLockPatternUtils = new LockPatternUtils(this);		
 	}
 
 	@Override
 	protected void onPause() {
 		super.onPause();
-		if (!isProtected()) return;
-		editor = prefs.edit();
-		editor.putLong("locked_at", System.currentTimeMillis());
-		editor.commit();
+        Log.d(TAG, "Pausing...");
+		// Don't do anything if not lock pattern is set
+		if (!mLockPatternUtils.isLockPatternEnabled()) return;
+        // Save the current time If a lock pattern has been set
+		writeLockTime();
 	}
 
 	@Override
 	protected void onResume() {
 		super.onResume();
-		if (!isProtected()) return;
+        // Don't do anything if not lock pattern is set
+		if (!mLockPatternUtils.isLockPatternEnabled()) {
+		    return;
+		}
+		// If a lock pattern is set we need to check the time for when the last
+		// activity was open. If it's been more than two seconds the user
+		// will have to enter the lock pattern to continue.
 		long currentTime = System.currentTimeMillis();
 		long lockedAt = prefs.getLong("locked_at", currentTime-10000);
 		long timedif = currentTime - lockedAt;
-		if (timedif > 3000) {
-			Intent intent = new Intent(this, LoginActivity.class);
-			startActivity(intent);
-			finish();
+		if (timedif > 2000) {
+		    launchPatternLock();
 		}
 	}
+
+	private void launchPatternLock() {
+        Intent intent = new Intent(this, ConfirmLockPattern.class);
+        intent.putExtra(ConfirmLockPattern.DISABLE_BACK_KEY, true);
+        intent.putExtra(ConfirmLockPattern.HEADER_TEXT, "Draw pattern to unlock Bankdroid");
+        startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
+	}
 	
-	private boolean isProtected() {
-		String access_code = prefs.getString("access_code", "");
-		if (access_code.length() > 0) return true;
-		return false;
-		
+	private void writeLockTime() {
+        editor = prefs.edit();
+        editor.putLong("locked_at", System.currentTimeMillis());
+        editor.commit();	    
 	}
-
+	
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        if (requestCode == PATTERNLOCK_UNLOCK) {
+            if (resultCode == RESULT_OK) {
+                writeLockTime();
+            }
+            else {
+                launchPatternLock();
+            }
+        }
+    }   	
 }
diff --git src/com/liato/bankdroid/LockablePreferenceActivity.java src/com/liato/bankdroid/LockablePreferenceActivity.java
new file mode 100644
index 0000000..6ce018f
--- /dev/null
+++ src/com/liato/bankdroid/LockablePreferenceActivity.java
@@ -0,0 +1,91 @@
+package com.liato.bankdroid;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+
+public class LockablePreferenceActivity extends PreferenceActivity {
+    private static String TAG = "LockablePreferenceActivity";
+    private static int PATTERNLOCK_UNLOCK = 42;
+	private SharedPreferences prefs;
+	private Editor editor;
+	private LockPatternUtils mLockPatternUtils;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		mLockPatternUtils = new LockPatternUtils(this);		
+	}
+
+	@Override
+	protected void onPause() {
+		super.onPause();
+		// Don't do anything if not lock pattern is set
+		if (!mLockPatternUtils.isLockPatternEnabled()) return;
+        // Save the current time If a lock pattern has been set
+		writeLockTime();
+	}
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+        // Don't do anything if not lock pattern is set
+		if (!mLockPatternUtils.isLockPatternEnabled() || !isLockEnabled()) {
+		    return;
+		}
+		// If a lock pattern is set we need to check the time for when the last
+		// activity was open. If it's been more than two seconds the user
+		// will have to enter the lock pattern to continue.
+		long currentTime = System.currentTimeMillis();
+		long lockedAt = prefs.getLong("locked_at", currentTime-10000);
+		long timedif = currentTime - lockedAt;
+		if (timedif > 2000) {
+		    launchPatternLock();
+		}
+	}
+
+	private void launchPatternLock() {
+        Intent intent = new Intent(this, ConfirmLockPattern.class);
+        intent.putExtra(ConfirmLockPattern.DISABLE_BACK_KEY, true);
+        intent.putExtra(ConfirmLockPattern.HEADER_TEXT, "Draw pattern to unlock Bankdroid");
+        startActivityForResult(intent, PATTERNLOCK_UNLOCK);         
+	}
+	
+	private void writeLockTime() {
+        editor = prefs.edit();
+        editor.putLong("locked_at", System.currentTimeMillis());
+        editor.commit();	    
+	}
+
+	protected void setLockEnabled(boolean enabled) {
+        editor = prefs.edit();
+        editor.putBoolean("lock_enabled", enabled);
+        editor.commit();        
+	}
+
+    protected boolean isLockEnabled() {
+        return prefs.getBoolean("lock_enabled", true);       
+    }	
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (requestCode == PATTERNLOCK_UNLOCK) {
+            if (resultCode == RESULT_OK) {
+                writeLockTime();
+            }
+            else {
+                launchPatternLock();
+            }
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        setLockEnabled(true);
+    }   	
+}
diff --git src/com/liato/bankdroid/LoginActivity.java src/com/liato/bankdroid/LoginActivity.java
deleted file mode 100644
index ffe9e79..0000000
--- src/com/liato/bankdroid/LoginActivity.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.liato.bankdroid;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.view.View;
-import android.view.animation.AlphaAnimation;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-public class LoginActivity extends Activity {
-	private SharedPreferences prefs;
-	private String access_code;
-
-	public void onCreate(Bundle savedInstanceState) {
-		String widgetAction = getIntent().getAction();
-		if ("widgetLogin".equals(widgetAction)) {
-		    setTheme(android.R.style.Theme);
-		}
-		super.onCreate(savedInstanceState);
-	
-		prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		access_code = prefs.getString("access_code", "");
-		setResult(Activity.RESULT_CANCELED); // default
-		if (access_code.length() > 0) {
-			setContentView(R.layout.login);
-			((Button)findViewById(R.id.btnLogin)).setOnClickListener(new View.OnClickListener() {
-				public void onClick(View v) {
-					if (((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(access_code)) {
-						Log.d("LoginActivity", "Success");
-						String widgetAction = getIntent().getAction();
-						if ("widgetLogin".equals(widgetAction)) {
-							Log.d("LoginActivity", "unLockOnly");
-							setResult(Activity.RESULT_OK);
-							finish();
-						} else {
-							loginSuccess();
-						}
-					}
-					else {
-						TextView txtResult = (TextView)findViewById(R.id.txtResult);
-				    	txtResult.setVisibility(TextView.VISIBLE);
-				    	AlphaAnimation anim = new AlphaAnimation(1, 0);
-				    	anim.setFillAfter(true);
-				    	anim.setStartOffset(5000);
-					    anim.setDuration(1000);
-				    	txtResult.startAnimation(anim);
-				 
-					}
-				}
-			});	
-		}
-		else {
-			Log.d("LoginActivity", "Action:"+ widgetAction);
-			if ("widgetLogin".equals(widgetAction)) {
-				Log.d("LoginActivity", "unLockOnly");
-				setResult(Activity.RESULT_OK);
-				finish();
-			} else {
-				loginSuccess();
-			}
-		}
-	}
-	
-	private void loginSuccess() {
-		unLock();
-		Intent intent = new Intent(this, MainActivity.class);
-		startActivity(intent);
-		this.finish();
-	}
-	
-	private void unLock() {
-		Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
-		editor.putLong("locked_at", System.currentTimeMillis());
-		editor.commit();
-	}
-}
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index b132a7c..7137406 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -1,5 +1,6 @@
 package com.liato.bankdroid;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 import android.app.AlertDialog;
@@ -15,6 +16,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.InflateException;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -22,6 +24,7 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.OnClickListener;
+import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.ListView;
@@ -39,9 +42,10 @@ public class MainActivity extends LockableActivity {
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
+        //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
 
-		setContentView(R.layout.main);
-		Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
+        setContentView(R.layout.main);
+        Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
 		btnRefresh.setOnClickListener(new View.OnClickListener() {
 			public void onClick(View v) {
 				new DataRetrieverTask(MainActivity.this).execute();
@@ -55,11 +59,12 @@ public class MainActivity extends LockableActivity {
 			}
 		});
 
-		ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+		//ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 		adapter = new AccountsAdapter(this, showHidden);
 		ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
 		adapter.setGroups(banks);
-		lv.setAdapter(adapter);
+        ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+        lv.setAdapter(adapter);
 		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
             public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                 Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
@@ -90,9 +95,11 @@ public class MainActivity extends LockableActivity {
 			}
 		});
 	}
-
+	
 	public void onResume() {
 		super.onResume();
+		// Receive refresh Intent from AutoRefreshService and refresh the main view if changes
+		// have been detected.
 		registerReceiver(receiver, new IntentFilter(AutoRefreshService.BROADCAST_MAIN_REFRESH));		
 		refreshView();
 	}
@@ -163,6 +170,7 @@ public class MainActivity extends LockableActivity {
 		case R.id.settings:
 			intent = new Intent(this, SettingsActivity.class);
 			this.startActivity(intent);
+	        //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
 			return true;
 		case R.id.about:
 			showDialog(0);
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 81a0a38..27b2f9b 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -1,170 +1,122 @@
 package com.liato.bankdroid;
 
-import java.util.ArrayList;
-
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
+import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.AdapterView.OnItemSelectedListener;
-
-public class SettingsActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
-	private SharedPreferences prefs;
-	private Integer refreshrate;
-
-	@Override
-	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.settings);
-		prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		ArrayList<Pair<String, Integer>> items = new ArrayList<Pair<String, Integer>>();
-		items.add(new Pair<String, Integer>(getString(R.string.disabled), -1));
-		items.add(new Pair<String, Integer>("15 "+getString(R.string.minutes), 15));
-		items.add(new Pair<String, Integer>("30 "+getString(R.string.minutes), 30));
-		items.add(new Pair<String, Integer>("1 "+getString(R.string.hour), 60));
-		items.add(new Pair<String, Integer>("2 "+getString(R.string.hours), 60*2));
-		items.add(new Pair<String, Integer>("4 "+getString(R.string.hours), 60*4));
-		items.add(new Pair<String, Integer>("8 "+getString(R.string.hours), 60*8));
-		items.add(new Pair<String, Integer>("16 "+getString(R.string.hours), 60*16));
-		items.add(new Pair<String, Integer>(getString(R.string.daily), 60*24));
-
-		Spinner spnFrequency = (Spinner)findViewById(R.id.spnUpdateFrequency);
-		ArrayAdapter<Pair<String, Integer>> adapter = new ArrayAdapter<Pair<String, Integer>>(this,
-				android.R.layout.simple_spinner_item, items);
-		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-		spnFrequency.setAdapter(adapter);
-		int refreshrate = prefs.getInt("refreshrate", -1);
-		for (int i = 0; i < items.size(); i++) {
-			if (items.get(i).getValue() == refreshrate) {
-				spnFrequency.setSelection(i);
-				break;
-			}
-			
-		}
-		spnFrequency.setOnItemSelectedListener(this);
-
-		findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
-		findViewById(R.id.btnSettingsOk).setOnClickListener(this);
-		findViewById(R.id.chkNotifyOnChange).setOnClickListener(this);
-	}
-	
-	private class Pair<T, S> {
-		private T key;
-		private S value;
-		public Pair(T key, S value) { 
-			this.key = key;
-			this.value = value;   
-		}
-
-		public T getKey() {
-			return key;
-		}
-
-		public S getValue() {
-			return value;
-		}
-
-		public String toString() { 
-			return (String) getKey(); 
-		}
-	}
-
-	@Override
-	public void onClick(View v) {
-		if (v.getId() == R.id.btnSettingsCancel) {
-			this.finish();
-		}
-		else if (v.getId() == R.id.btnSettingsOk){
-			if (!(((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(((EditText)findViewById(R.id.edtAccessCodeRepeat)).getText().toString()))) {
-				AlertDialog.Builder builder = new AlertDialog.Builder(this);
-				builder.setMessage(getText(R.string.passwords_mismatch)).setTitle(getText(R.string.passwords_mismatch_title))
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
-						dialog.cancel();
-					}
-				});
-				AlertDialog alert = builder.create();
-				alert.show();
-			}
-			else {
-				Editor editor = prefs.edit();
-				editor.putString("access_code", ((EditText)findViewById(R.id.edtAccessCode)).getText().toString());
-				editor.putBoolean("notify_on_change", ((CheckBox)findViewById(R.id.chkNotifyOnChange)).isChecked());
-				editor.putBoolean("notify_with_sound", ((CheckBox)findViewById(R.id.chkWithSound)).isChecked());
-                editor.putBoolean("notify_with_vibration", ((CheckBox)findViewById(R.id.chkWithVibration)).isChecked());
-                editor.putBoolean("notify_for_deposit", ((CheckBox)findViewById(R.id.chkDeposit)).isChecked());
-                editor.putBoolean("notify_for_funds", ((CheckBox)findViewById(R.id.chkFunds)).isChecked());
-                editor.putBoolean("notify_for_loans", ((CheckBox)findViewById(R.id.chkLoans)).isChecked());
-                editor.putBoolean("notify_for_ccards", ((CheckBox)findViewById(R.id.chkCCards)).isChecked());
-                editor.putBoolean("notify_for_other", ((CheckBox)findViewById(R.id.chkOther)).isChecked());
-                editor.putInt("refreshrate", refreshrate);
-				editor.commit();
-				StartupReceiver.setAlarm(this);
-				this.finish();
-			}
-		}
-		else if (v.getId() == R.id.chkNotifyOnChange) {
-			findViewById(R.id.chkWithSound).setEnabled(((CheckBox)v).isChecked());
-            findViewById(R.id.chkWithVibration).setEnabled(((CheckBox)v).isChecked());
-            findViewById(R.id.chkDeposit).setEnabled(((CheckBox)v).isChecked());
-            findViewById(R.id.chkFunds).setEnabled(((CheckBox)v).isChecked());
-            findViewById(R.id.chkLoans).setEnabled(((CheckBox)v).isChecked());
-            findViewById(R.id.chkCCards).setEnabled(((CheckBox)v).isChecked());
-            findViewById(R.id.chkOther).setEnabled(((CheckBox)v).isChecked());
-		}
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.util.Log;
 
-	}
+public class SettingsActivity extends LockablePreferenceActivity implements OnPreferenceClickListener {
+    private final static String TAG = "SettingsActivity";
+    private final static int DISABLE_LOCKPATTERN = 1;
+    private final static int ENABLE_LOCKPATTERN = 2;
+    private final static int CHANGE_LOCKPATTERN = 3;
+    private LockPatternUtils mLockPatternUtils;
+    
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mLockPatternUtils = new LockPatternUtils(this);
+        addPreferencesFromResource(R.xml.settings);
+        getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
+        ((Preference)findPreference("patternlock_change")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("patternlock_change")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("remotenotifier_help")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("openwatch_help")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("account_types_screen")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("remotenotifier_screen")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("openwatch_screen")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("autoupdates_enabled")).setOnPreferenceClickListener(this);
+        ((Preference)findPreference("notification_sound")).setOnPreferenceClickListener(this);
+        CheckBoxPreference patternLock = ((CheckBoxPreference)findPreference("patternlock_enabled"));
+        patternLock.setOnPreferenceClickListener(this);
+        // Check the pattern lock check box if the lock pattern is enabled
+        patternLock.setChecked(mLockPatternUtils.isLockPatternEnabled());
+    }
 
-	@Override
-	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-		Pair<String, Integer> pair = (Pair<String, Integer>)parentView.getItemAtPosition(pos);
-		refreshrate = pair.getValue();
-	}
-	
-	
-	@Override
-	public void onNothingSelected(AdapterView<?> arg) {
-	}
-	
-	@Override
-	protected void onResume() {
-		super.onResume();
-		((EditText)findViewById(R.id.edtAccessCode)).setText(prefs.getString("access_code", ""));
-		((EditText)findViewById(R.id.edtAccessCodeRepeat)).setText(prefs.getString("access_code", ""));
-		((CheckBox)findViewById(R.id.chkNotifyOnChange)).setChecked(prefs.getBoolean("notify_on_change", true));
-		((CheckBox)findViewById(R.id.chkWithSound)).setChecked(prefs.getBoolean("notify_with_sound", true));
-		((CheckBox)findViewById(R.id.chkWithSound)).setEnabled(prefs.getBoolean("notify_on_change", true));
-		((CheckBox)findViewById(R.id.chkWithVibration)).setChecked(prefs.getBoolean("notify_with_vibration", true));
-		((CheckBox)findViewById(R.id.chkWithVibration)).setEnabled(prefs.getBoolean("notify_on_change", true));
-        ((CheckBox)findViewById(R.id.chkDeposit)).setChecked(prefs.getBoolean("notify_for_deposit", true));
-        ((CheckBox)findViewById(R.id.chkDeposit)).setEnabled(prefs.getBoolean("notify_on_change", true));
-        ((CheckBox)findViewById(R.id.chkFunds)).setChecked(prefs.getBoolean("notify_for_funds", false));
-        ((CheckBox)findViewById(R.id.chkFunds)).setEnabled(prefs.getBoolean("notify_on_change", true));
-        ((CheckBox)findViewById(R.id.chkLoans)).setChecked(prefs.getBoolean("notify_for_loans", false));
-        ((CheckBox)findViewById(R.id.chkLoans)).setEnabled(prefs.getBoolean("notify_on_change", true));
-        ((CheckBox)findViewById(R.id.chkCCards)).setChecked(prefs.getBoolean("notify_for_ccards", true));
-        ((CheckBox)findViewById(R.id.chkCCards)).setEnabled(prefs.getBoolean("notify_on_change", true));
-        ((CheckBox)findViewById(R.id.chkOther)).setChecked(prefs.getBoolean("notify_for_other", false));
-        ((CheckBox)findViewById(R.id.chkOther)).setEnabled(prefs.getBoolean("notify_on_change", true));
-	}
+    @Override
+    public boolean onPreferenceClick(Preference pref) {
+        String prefKey = pref.getKey();
+        if ("account_types_screen".equals(prefKey) || "openwatch_screen".equals(prefKey) || "remotenotifier_screen".equals(prefKey)) {
+            ((PreferenceScreen)pref).getDialog().getWindow().setBackgroundDrawableResource(R.drawable.background_repeat);
+            return false;            
+        }
+        
+        if ("notification_sound".equals(prefKey)) {
+            this.setLockEnabled(false);
+            return false;
+        }
+        
+        if ("patternlock_enabled".equals(prefKey)) {
+            this.setLockEnabled(false);
+            if (mLockPatternUtils.isLockPatternEnabled()) {
+                // The user is trying to disable the lock pattern,
+                // only disable if the user knows the pattern.
+                startActivityForResult(new Intent(this, ConfirmLockPattern.class), DISABLE_LOCKPATTERN);
+                return true;
+            }
+            else {
+                // No lock pattern has been set yet, let the user choose a new one.
+                startActivityForResult(new Intent(this, ChooseLockPattern.class), ENABLE_LOCKPATTERN);
+                return true;
+            }
+        }
+        else if ("patternlock_change".equals(prefKey)) {
+            this.setLockEnabled(false);
+            startActivityForResult(new Intent(this, ChooseLockPattern.class), CHANGE_LOCKPATTERN);
+            return true;
+        }
+        else if ("remotenotifier_help".equals(prefKey)) {
+            startActivity(new Intent(Intent.ACTION_VIEW,
+                    Uri.parse("http://code.google.com/p/android-notifier/")));            
+            return true;
+        }
+        else if ("openwatch_help".equals(prefKey)) {
+            startActivity(new Intent(Intent.ACTION_VIEW,
+                                     Uri.parse("http://forum.xda-developers.com/showthread.php?t=554551")));            
+            return true;
+        }
+        return false;
+    }
+    
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        Log.d(TAG, "onActivityResult: req:"+requestCode+"; res:"+resultCode);
+        if (requestCode == DISABLE_LOCKPATTERN) {
+            if (resultCode == RESULT_OK) {
+                mLockPatternUtils.setLockPatternEnabled(false);
+                mLockPatternUtils.saveLockPattern(null);
+                ((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(false);
+                Log.d(TAG, "Pattern lock has been disabled.");
+            }
+            else {
+                Log.d(TAG, "User was unable to disable pattern lock.");
+            }
+        }
+        else if (requestCode == ENABLE_LOCKPATTERN) {
+            // User attempted to enable the pattern lock, toggle the checkbox.
+            ((CheckBoxPreference)findPreference("patternlock_enabled")).setChecked(mLockPatternUtils.isLockPatternEnabled());
+        }
+        else if (requestCode == CHANGE_LOCKPATTERN) {
+            // Don't do anything special
+        }
+    }
 
-	@Override
-	protected void onPause() {
-		super.onPause();
-	}
+    @Override
+    protected void onResume() {
+        super.onResume();
+        this.setLockEnabled(true);
+    }
 
-	@Override
-	protected void onSaveInstanceState(Bundle outState) {
-		super.onSaveInstanceState(outState);
-	}   
-}
+    @Override
+    protected void onPause() {
+        super.onPause();
+        StartupReceiver.setAlarm(this);
+    }
+    
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 5f00200..12e2e1f 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -11,6 +11,7 @@ import android.preference.PreferenceManager;
 import android.util.Log;
 
 public class StartupReceiver extends BroadcastReceiver{
+    private final static String TAG = "StartupReceiver";
 	@Override
 	public void onReceive(Context context, Intent intent) {
 		//Set alarms for auto updates on boot, package update, package replace and package new
@@ -21,18 +22,18 @@ public class StartupReceiver extends BroadcastReceiver{
 	public static void setAlarm(Context context) {
 		PendingIntent alarmSender;
 		alarmSender = PendingIntent.getService(context, 0, new Intent(context, AutoRefreshService.class), 0);
-		
 		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-		Integer refreshrate = prefs.getInt("refreshrate", -1);
+        boolean autoUpdatesEnabled = prefs.getBoolean("autoupdates_enabled", true);
+        Integer refreshRate = Integer.parseInt(prefs.getString("refresh_rate", "0")); 
         AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
-        if (refreshrate < 0) {
+        if (!autoUpdatesEnabled) {
         	am.cancel(alarmSender);
-        	Log.d("","Alarm disabled.");
+        	Log.d(TAG,"Automatic updates have been disabled.");
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*60*1000, refreshrate*60*1000, alarmSender);
-        	Log.d("StartupReceiever.SetAlarm","Alarm set to "+refreshrate.toString()+" minutes.");
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshRate*1*1000, refreshRate*1*1000, alarmSender);
+        	Log.d(TAG,"Automatic updates set to "+refreshRate.toString()+" minutes.");
         }
 	
 	}
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index 171d4a3..4f06884 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -1,13 +1,16 @@
 package com.liato.bankdroid;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 import android.content.Context;
 import android.os.Bundle;
 import android.util.Log;
+import android.view.InflateException;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Adapter;
 import android.widget.BaseAdapter;
 import android.widget.ImageView;
 import android.widget.ListView;
@@ -16,17 +19,24 @@ import android.widget.TextView;
 public class TransactionsActivity extends LockableActivity {
 	final static String TAG = "TransactionActivity";
 	
-	@Override
+    @Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		setContentView(R.layout.transactions);
+        //Helpers.setActivityAnimation(this, R.anim.zoom_enter, R.anim.zoom_exit);
+		//Use HtcListView if available
+		try {
+		    setContentView(R.layout.transactions_htc);
+		}
+		catch (InflateException e) {
+		    setContentView(R.layout.transactions);
+		}
 		Bundle extras = getIntent().getExtras();
 		Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
 		Account account = BankFactory.accountFromDb(this, extras.getLong("bank")+"_"+extras.getString("account"), true);
 		TextView viewBankName = (TextView)findViewById(R.id.txtListitemAccountsGroupAccountname);
 		TextView viewAccountName = (TextView)findViewById(R.id.txtListitemAccountsGroupBankname);
 		TextView viewAccountBalance = (TextView)findViewById(R.id.txtListitemAccountsGroupTotal);
-		ListView viewTransactionsList = (ListView)findViewById(R.id.lstTransactionsList);
+
 		ImageView icon = (ImageView)findViewById(R.id.imgListitemAccountsGroup);
 		viewBankName.setText(bank.getDisplayName());
 		viewAccountName.setText(account.getName());
@@ -37,7 +47,16 @@ public class TransactionsActivity extends LockableActivity {
 		if (transactions.size() > 0) {
 			findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
 			TransactionsAdapter adapter = new TransactionsAdapter(transactions);
-			viewTransactionsList.setAdapter(adapter);
+	        try {
+	            Class<?> c = Class.forName("com.htc.widget.HtcListView");
+	            Object viewTransactionsList = c.cast(findViewById(R.id.lstTransactionsList));
+	            Method  method = c.getDeclaredMethod("setAdapter", Adapter.class);
+	            method.invoke(viewTransactionsList, adapter);
+	        }
+	        catch (Exception e) {
+	            ListView viewTransactionsList = (ListView)findViewById(R.id.lstTransactionsList);
+	            viewTransactionsList.setAdapter(adapter);
+	        }
 		}
 	}
 
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index 2ad198e..c31121f 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -15,7 +15,7 @@ import android.widget.CheckBox;
 import android.widget.ListView;
 import android.widget.AdapterView.OnItemClickListener;
 
-public class WidgetConfigureActivity extends Activity {
+public class WidgetConfigureActivity extends LockableActivity {
     private static final String WIDGET_PREFIX = "widget_";
 	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
 	private static final int LOGIN_ID = 1;
@@ -29,32 +29,15 @@ public class WidgetConfigureActivity extends Activity {
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-
-		Log.d("Widget Configre", "##########################");
-		Intent login = new Intent(this, LoginActivity.class);
-		login.setAction("widgetLogin");
-		startActivityForResult(login, LOGIN_ID);
 	}	
 	
-	public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        switch (requestCode) {
-        case LOGIN_ID:
-            if (resultCode == Activity.RESULT_OK) {
-            	Log.d("RESULT OK", "WHOOOOO #############");
-            	firstDraw();
-            } else {
-            	finish();
-            }
-            break;
-        }
-    }
-	
-	private void firstDraw() {
+	public void onResume() {
+		super.onResume();
 
-		setContentView(R.layout.main);
-		this.setTitle(this.getString(R.string.choose_an_account));
+        setContentView(R.layout.main);
+        this.setTitle(this.getString(R.string.choose_an_account));
         setResult(RESULT_CANCELED);
-		((View)findViewById(R.id.layMainMenu)).setVisibility(View.GONE);
+        ((View)findViewById(R.id.layMainMenu)).setVisibility(View.GONE);
 
         Intent intent = getIntent();
         Bundle extras = intent.getExtras();
@@ -63,38 +46,33 @@ public class WidgetConfigureActivity extends Activity {
         }
         if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
             finish();
-        }		
+        }       
 
         ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-		lv.setOnItemClickListener(new OnItemClickListener() {
-			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-				if (adapter.getItemViewType(position) != AccountsAdapter.VIEWTYPE_ACCOUNT) return;
-				final Context context = WidgetConfigureActivity.this;
-	            Account account = (Account)parent.getItemAtPosition(position);
-	            Bank bank = account.getBank();
-	            WidgetConfigureActivity.setAccountBankId(context, mAppWidgetId, account.getId(), bank.getDbId());
-	            SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-	            prefs.putBoolean("transperant_background" + mAppWidgetId, ((CheckBox)findViewById(R.id.chkTransperantBackground)).isChecked());
-	            prefs.commit();	            
-	            // Push widget update to surface with newly set prefix
-	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
-	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
-	                    mAppWidgetId, account);
+        lv.setOnItemClickListener(new OnItemClickListener() {
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                if (adapter.getItemViewType(position) != AccountsAdapter.VIEWTYPE_ACCOUNT) return;
+                final Context context = WidgetConfigureActivity.this;
+                Account account = (Account)parent.getItemAtPosition(position);
+                Bank bank = account.getBank();
+                WidgetConfigureActivity.setAccountBankId(context, mAppWidgetId, account.getId(), bank.getDbId());
+                SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+                prefs.putBoolean("transperant_background" + mAppWidgetId, ((CheckBox)findViewById(R.id.chkTransperantBackground)).isChecked());
+                prefs.commit();             
+                // Push widget update to surface with newly set prefix
+                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+                BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
+                        mAppWidgetId, account);
 
-	            Intent resultValue = new Intent();
-	            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
-	            setResult(RESULT_OK, resultValue);
-	            finish();
-			}
-		});
-		
-		refreshView();
-	}
-	
-//	public void onResume() {
-//		super.onResume();
-//		refreshView();
-//	}
+                Intent resultValue = new Intent();
+                resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+                setResult(RESULT_OK, resultValue);
+                finish();
+            }
+        });
+        
+        refreshView();
+    }
 	
 	public static void setAccountBankId(Context context, int appWidgetId, String accountId, long bankId) {
         SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
@@ -134,13 +112,5 @@ public class WidgetConfigureActivity extends Activity {
 		}
 	}
 
-	public void onDestroy() {
-		super.onDestroy();
-	}
-
-	
-	public void onActivityResult() {
-		
-	}
 
 }

commit b6aeb2ecb16ec9a4c411f46ca787d19a47a5f0e1
Author: liato <x@x00.us>
Date:   Sun Nov 7 21:03:46 2010 +0100

    Fix loan account detection on swedbank.

diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index bd9a893..2694ee2 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -98,8 +98,8 @@ public class Swedbank extends Bank {
 			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
-				if (matcher.group(2).trim() == "loan") {
+				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim() == "loan" ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
+				if (matcher.group(1).trim() == "loan") {
 				    account.setType(Account.LOANS);
 				}
 				else {

commit 9376d99e86d26a599d88374a6c20386fea8a751c
Author: liato <x@x00.us>
Date:   Wed Nov 3 23:30:51 2010 +0100

    Added hints for the username field when adding a bank.

diff --git AndroidManifest.xml AndroidManifest.xml
index a5e089c..2758f03 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,7 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionCode="41" android:versionName="1.4.1">
+	android:versionCode="42" android:versionName="1.4.2">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 5f619d9..61fcfc1 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -36,6 +36,7 @@ public abstract class Bank implements Comparable<Bank> {
 	protected String URL;
     protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
     protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
+    protected String INPUT_HINT_USERNAME = null;
 
 	protected Context context;
 	protected Resources res;
@@ -225,6 +226,10 @@ public abstract class Bank implements Comparable<Bank> {
         return INPUT_TYPE_PASSWORD;
     }
 
+    public String getInputHintUsername() {
+        return INPUT_HINT_USERNAME;
+    }
+
     public int getImageResource() {
 		return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
 	}
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index b0013a1..4426805 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -92,9 +92,12 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
 		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
-        ((EditText)findViewById(R.id.edtBankeditUsername)).setInputType(SELECTED_BANK.getInputTypeUsername());
+		EditText edtUsername = (EditText)findViewById(R.id.edtBankeditUsername);
+		edtUsername.setInputType(SELECTED_BANK.getInputTypeUsername());
+		edtUsername.setHint(SELECTED_BANK.getInputHintUsername());
         //Not possible to set a textfield to both PHONE and PASSWORD :\
         //((EditText)findViewById(R.id.edtBankeditPassword)).setInputType(SELECTED_BANK.getInputTypePassword());
+        
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 7d53bb3..2301d20 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -14,7 +14,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -32,7 +31,6 @@ public class Avanza extends Bank {
 	private static final String NAME_SHORT = "avanza";
 	private static final String URL = "https://www.avanza.se/";
 	private static final int BANKTYPE_ID = Bank.AVANZA;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -43,7 +41,6 @@ public class Avanza extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Avanza(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banks/AvanzaMini.java
index 9b2ffbf..c20579f 100644
--- src/com/liato/bankdroid/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banks/AvanzaMini.java
@@ -12,7 +12,6 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
-import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -29,7 +28,6 @@ public class AvanzaMini extends Bank {
 	private static final String NAME_SHORT = "avanzamini";
 	private static final String URL = "https://www.avanza.se/mini/hem/";
 	private static final int BANKTYPE_ID = Bank.AVANZAMINI;
-	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
     private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tbody>\\s*(.*)</tbody>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern accountsAvanzaMini = Pattern.compile("<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -40,7 +38,6 @@ public class AvanzaMini extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public AvanzaMini(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index b29952d..29b79d4 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -32,6 +32,7 @@ public class Eurocard extends Bank {
 	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
 	private static final int BANKTYPE_ID = Bank.EUROCARD;
 	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
 	private Pattern reAccounts = Pattern.compile("getInvoiceList\\.do\\?id=([^\"]+)\">([^<]+)</a></td>(?:\\s*<td>[^<]+</td>){2}\\s*<td\\s*align=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<nobr>(\\d\\d-\\d\\d)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>[^<]+</nobr>\\s*</td>\\s*<td><div\\s*class=\"BreakLine\">([^<]+)</div>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td[^>]+>\\s*<nobr>([^>]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">[^<]+</td>\\s*<td[^>]+>\\s*<nobr>([^<]+)</nobr>", Pattern.CASE_INSENSITIVE);
@@ -44,6 +45,7 @@ public class Eurocard extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public Eurocard(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
index eb8c265..9a37116 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -31,6 +31,7 @@ public class FirstCard extends Bank {
 	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
 	private static final int BANKTYPE_ID = Bank.FIRSTCARD;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
 	private Pattern reAccounts = Pattern.compile("translist\\.jsp\\?p=a&(?:amp;)?cardID=([^\"]+)\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("pagecolumns\">(\\d{6})</td>\\s*<td>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
@@ -43,6 +44,7 @@ public class FirstCard extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public FirstCard(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index de59342..92336ac 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -35,6 +35,7 @@ public class Handelsbanken extends Bank {
 	private static final String URL = "https://m.handelsbanken.se/";
 	private static final int BANKTYPE_ID = Bank.HANDELSBANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
 	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
@@ -50,6 +51,7 @@ public class Handelsbanken extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public Handelsbanken(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banks/ICA.java
index 6f1a34f..5363a20 100644
--- src/com/liato/bankdroid/banks/ICA.java
+++ src/com/liato/bankdroid/banks/ICA.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 
 import com.liato.bankdroid.Account;
 import com.liato.bankdroid.Bank;
@@ -28,6 +29,8 @@ public class ICA extends Bank {
 	private static final String NAME_SHORT = "ica";
 	private static final String URL = "http://mobil.ica.se/";
 	private static final int BANKTYPE_ID = Bank.ICA;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
 	private Pattern reAccounts = Pattern.compile("lblAvaibleAmount\">([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>\\s*([^<]+).*?amount\">([^<]+)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
@@ -40,6 +43,8 @@ public class ICA extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public ICA(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index ce2bf87..82ebfe3 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -31,6 +31,8 @@ public class ICABanken extends Bank {
 	private static final String URL = "https://mobil.icabanken.se/";
 	private static final int BANKTYPE_ID = Bank.ICABANKEN;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -46,7 +48,9 @@ public class ICABanken extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public ICABanken(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index 79102a9..a0d560a 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -31,6 +31,7 @@ public class Lansforsakringar extends Bank {
 	private static final int BANKTYPE_ID = Bank.LANSFORSAKRINGAR;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -47,6 +48,7 @@ public class Lansforsakringar extends Bank {
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 602e11f..4c45600 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -2,7 +2,6 @@ package com.liato.bankdroid.banks;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -33,6 +32,7 @@ public class Nordea extends Bank {
 	private static final int BANKTYPE_ID = Bank.NORDEA;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
     private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 	
 	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
 	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -49,6 +49,7 @@ public class Nordea extends Bank {
 		super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
         super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public Nordea(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index d72eb6c..575e72d 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -36,6 +36,7 @@ public class OKQ8 extends Bank {
 	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
 	private static final int BANKTYPE_ID = Bank.OKQ8;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 	
 	private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
 	private Pattern reBalance = Pattern.compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
@@ -50,6 +51,7 @@ public class OKQ8 extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public OKQ8(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banks/PayPal.java
index e0c6d5b..c74671a 100644
--- src/com/liato/bankdroid/banks/PayPal.java
+++ src/com/liato/bankdroid/banks/PayPal.java
@@ -97,6 +97,7 @@ public class PayPal extends Bank {
 		urlopen = login();
 		try {
             response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
+            //Helpers.slowDebug(TAG, response);
             Matcher matcher = reBalance.matcher(response);
             if (matcher.find()) {
                 /*
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index 3c0a5fc..e787f8f 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -32,6 +32,7 @@ public class Statoil extends Bank {
 	private static final String URL = "https://applications.sebkort.com/nis/external/stse/login.do";
 	private static final int BANKTYPE_ID = Bank.STATOIL;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDDXXXX";
 
 	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunitlastdisposableamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]+>\\s*<span>([^<]*)</span>\\s*</div>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
@@ -44,6 +45,7 @@ public class Statoil extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
 		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public Statoil(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 3d727ca..bd9a893 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -31,6 +31,7 @@ public class Swedbank extends Bank {
 	private static final String URL = "https://mobilbank.swedbank.se/";
 	private static final int BANKTYPE_ID = Bank.SWEDBANK;
     private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final String INPUT_HINT_USERNAME = "ÅÅMMDD-XXXX";
 
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
@@ -44,6 +45,7 @@ public class Swedbank extends Bank {
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
         super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_HINT_USERNAME = INPUT_HINT_USERNAME;
 	}
 
 	public Swedbank(String username, String password, Context context) throws BankException, LoginException {

commit a7a36b83a8b025a27a62df05dc668405112ce1d7
Author: liato <x@x00.us>
Date:   Wed Nov 3 10:46:30 2010 +0100

    Fix for Nordea.

diff --git AndroidManifest.xml AndroidManifest.xml
index c8cc243..a5e089c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -2,8 +2,7 @@
 <manifest
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.liato.bankdroid"
-	android:versionName="1.4.0"
-	android:versionCode="40">
+	android:versionCode="41" android:versionName="1.4.1">
 	<application
 		android:icon="@drawable/icon"
 		android:label="@string/app_name"
@@ -39,7 +38,22 @@
 			android:name=".SettingsActivity"
 			android:label="@string/app_name">
 		</activity>
-
+		<activity
+			android:name=".ChooseLockPattern"
+			android:label="@string/app_name">
+		</activity>
+		<activity
+			android:name=".ChooseLockPatternExample"
+			android:label="@string/app_name">
+		</activity>
+		<activity
+			android:name=".ChooseLockPatternTutorial"
+			android:label="@string/app_name">
+		</activity>
+		<activity
+			android:name=".ConfirmLockPattern"
+			android:label="@string/app_name">
+		</activity>
 		<activity
 			android:name=".WidgetConfigureActivity"
 			android:theme="@android:style/Theme.Dialog">
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 8c6cbb0..602e11f 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -37,7 +37,7 @@ public class Nordea extends Bank {
 	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
 	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reCards = Pattern.compile("/card/details\\.html\\?id=(\\d{1,})[^\"]*\".*?>\\s*<span[^>]*>\\s*<span>([^<]+)</span>\\s*<span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(\\d{2}.\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 
 	public Nordea(Context context) {
@@ -164,14 +164,8 @@ public class Nordea extends Bank {
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
-			String strDate = null;
-			String[] strMonthDay = null;
-			Calendar cal = Calendar.getInstance();
 			while (matcher.find()) {
-				strMonthDay = Html.fromHtml(matcher.group(1)).toString().trim().split("\\.");
-				strDate = ""+cal.get(Calendar.YEAR)+"-"+strMonthDay[1]+"-"+strMonthDay[0];
-				//Log.d(TAG, "Date: "+strDate+"; Trans: "+Html.fromHtml(matcher.group(2)).toString().trim()+"; Amount: "+Helpers.parseBalance(matcher.group(3)).toString());
-				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+				transactions.add(new Transaction(Html.fromHtml(matcher.group(1)).toString().trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {

commit c85eac5144d58ec51835452f45bfb5b52b79af5c
Author: liato <x@x00.us>
Date:   Wed Nov 3 04:14:56 2010 +0100

    Don't recreate activity on rotation. Fixes FC bug when rotating during an update.

diff --git AndroidManifest.xml AndroidManifest.xml
index 73f31b9..c8cc243 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,64 +1,113 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0" android:versionCode="40">
-	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
-		<activity android:label="@string/app_name"
-			android:multiprocess="false" android:name=".LoginActivity"
-			android:alwaysRetainTaskState="false" android:theme="@android:style/Theme.Dialog">
+<manifest
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	package="com.liato.bankdroid"
+	android:versionName="1.4.0"
+	android:versionCode="40">
+	<application
+		android:icon="@drawable/icon"
+		android:label="@string/app_name"
+		android:debuggable="false">
+		<activity
+			android:label="@string/app_name"
+			android:multiprocess="false"
+			android:name=".LoginActivity"
+			android:alwaysRetainTaskState="false"
+			android:theme="@android:style/Theme.Dialog">
 			<intent-filter>
-				<action android:name="android.intent.action.MAIN" />
-				<category android:name="android.intent.category.LAUNCHER" />
+				<action
+					android:name="android.intent.action.MAIN" />
+				<category
+					android:name="android.intent.category.LAUNCHER" />
 			</intent-filter>
 		</activity>
-		<activity android:name=".MainActivity" android:label="@string/app_name">
+		<activity
+			android:name=".MainActivity"
+			android:label="@string/app_name"
+			android:configChanges="keyboardHidden|orientation">
 		</activity>
-		<activity android:name=".TransactionsActivity" android:label="@string/app_name">
+		<activity
+			android:name=".TransactionsActivity"
+			android:label="@string/app_name">
 		</activity>
-		<activity android:name=".BankEditActivity" android:label="@string/app_name">
+		<activity
+			android:name=".BankEditActivity"
+			android:label="@string/app_name"
+			android:configChanges="keyboardHidden|orientation">
 		</activity>
-		<activity android:name=".SettingsActivity" android:label="@string/app_name">
+		<activity
+			android:name=".SettingsActivity"
+			android:label="@string/app_name">
 		</activity>
 
-		<activity android:name=".WidgetConfigureActivity"
+		<activity
+			android:name=".WidgetConfigureActivity"
 			android:theme="@android:style/Theme.Dialog">
 			<intent-filter>
-				<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+				<action
+					android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
 			</intent-filter>
 		</activity>
-		<receiver android:name="BankdroidWidgetProvider_2x1" android:label="@string/widget_name_small">
+		<receiver
+			android:name="BankdroidWidgetProvider_2x1"
+			android:label="@string/widget_name_small">
 			<intent-filter>
-				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
-				<action android:name="com.liato.bankdroid.WIDGET_REFRESH" />
+				<action
+					android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+				<action
+					android:name="com.liato.bankdroid.WIDGET_REFRESH" />
 			</intent-filter>
-			<meta-data android:name="android.appwidget.provider"
+			<meta-data
+				android:name="android.appwidget.provider"
 				android:resource="@xml/appwidget_info" />
 		</receiver>
 
-		<receiver android:name="BankdroidWidgetProvider_4x1" android:label="@string/widget_name_large">
+		<receiver
+			android:name="BankdroidWidgetProvider_4x1"
+			android:label="@string/widget_name_large">
 			<intent-filter>
-				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
-				<action android:name="com.liato.bankdroid.WIDGET_REFRESH" />
+				<action
+					android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+				<action
+					android:name="com.liato.bankdroid.WIDGET_REFRESH" />
 			</intent-filter>
-			<meta-data android:name="android.appwidget.provider"
+			<meta-data
+				android:name="android.appwidget.provider"
 				android:resource="@xml/appwidget_info_large" />
 		</receiver>
 
-		<service android:enabled="true" android:name=".AutoRefreshService" />
-		<service android:enabled="true" android:name=".BankdroidWidgetProvider$WidgetService" />
-		<receiver android:name="StartupReceiver">
+		<service
+			android:enabled="true"
+			android:name=".AutoRefreshService" />
+		<service
+			android:enabled="true"
+			android:name=".BankdroidWidgetProvider$WidgetService" />
+		<receiver
+			android:name="StartupReceiver">
 			<intent-filter>
-				<action android:name="android.intent.action.BOOT_COMPLETED" />
-                <action android:name="android.intent.action.PACKAGE_ADDED"></action> 
-                <action android:name="android.intent.action.PACKAGE_CHANGED"></action> 
-				<action android:name="android.intent.action.PACKAGE_REPLACED" />
-				<data android:scheme="package" android:path="com.liato.bankdroid" />
+				<action
+					android:name="android.intent.action.BOOT_COMPLETED" />
+				<action
+					android:name="android.intent.action.PACKAGE_ADDED"></action>
+				<action
+					android:name="android.intent.action.PACKAGE_CHANGED"></action>
+				<action
+					android:name="android.intent.action.PACKAGE_REPLACED" />
+				<data
+					android:scheme="package"
+					android:path="com.liato.bankdroid" />
 			</intent-filter>
 		</receiver>
 	</application>
-	<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="4" />
-	<uses-permission android:name="android.permission.INTERNET"></uses-permission>
-	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
-	<uses-permission android:name="android.permission.VIBRATE" />
+	<uses-sdk
+		android:minSdkVersion="4"
+		android:targetSdkVersion="4" />
+	<uses-permission
+		android:name="android.permission.INTERNET"></uses-permission>
+	<uses-permission
+		android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+	<uses-permission
+		android:name="android.permission.VIBRATE" />
 	<supports-screens
 		android:largeScreens="true"
 		android:normalScreens="true"

commit 112838dc6b24806f4e2aaa7e67c5c4bd50da89a7
Author: liato <x@x00.us>
Date:   Tue Nov 2 21:18:32 2010 +0100

    Fix version code in manifest.

diff --git AndroidManifest.xml AndroidManifest.xml
index 38996bf..73f31b9 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0" android:versionCode="31">
+	package="com.liato.bankdroid" android:versionName="1.4.0" android:versionCode="40">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index afc1e01..3d727ca 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -66,7 +66,6 @@ public class Swedbank extends Bank {
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			postData.add(new BasicNameValuePair("xyz", username));
 			postData.add(new BasicNameValuePair("zyx", password));
-			Log.d(TAG, "user: "+username+"; pass: "+password);
 			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
 

commit 864a35c37626b6d3966f15d47c9f2e042d5cfd22
Author: liato <x@x00.us>
Date:   Tue Nov 2 21:07:34 2010 +0100

    Bump version to 1.4.0

diff --git AndroidManifest.xml AndroidManifest.xml
index ff85f43..38996bf 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0-RC6" android:versionCode="30">
+	package="com.liato.bankdroid" android:versionName="1.4.0" android:versionCode="31">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"

commit 0285814dcdb849bc8f96e1e57b5b352c78038eeb
Author: liato <x@x00.us>
Date:   Tue Nov 2 21:05:52 2010 +0100

    Don't add loan balance to total balance.

diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 2835d3c..afc1e01 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -110,7 +110,6 @@ public class Swedbank extends Bank {
 			int accid = 0;
 			while (matcher.find()) {
 				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll:"+accid);
-				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
 				account.setType(Account.OTHER);
                 accounts.add(account);
                 accid++;

commit e77ce0ffdcddaedcde297eb28695007e8477cd7d
Author: liato <x@x00.us>
Date:   Mon Nov 1 21:37:03 2010 +0100

    Fix transactions bug in Nordea.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8bbccb8..ff85f43 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0-RC5" android:versionCode="29">
+	package="com.liato.bankdroid" android:versionName="1.4.0-RC6" android:versionCode="30">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index f2ece16..8c6cbb0 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -151,7 +151,6 @@ public class Nordea extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (new String("").equals(new String(""))) return;
 
 		//No transaction history for loans, funds and credit cards.
 		int accType = account.getType();

commit b599d69c317b03bf3ea6cc1ab7453ff6dac819c8
Author: liato <x@x00.us>
Date:   Mon Nov 1 21:05:53 2010 +0100

    Fix Coop regex.

diff --git AndroidManifest.xml AndroidManifest.xml
index 97e695c..8bbccb8 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0-RC4" android:versionCode="28">
+	package="com.liato.bankdroid" android:versionName="1.4.0-RC5" android:versionCode="29">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 6c09a08..9117da7 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -31,7 +31,7 @@ public class Coop extends Bank {
 	private static final int BANKTYPE_ID = Bank.COOP;
 
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalanceVisa = Pattern.compile("Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceVisa = Pattern.compile("MedMera\\s*Visa</h3>\\s*<h6>Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);

commit bc2d1bbb7510b2bfd2fe80a74129d41f13cebdd2
Author: liato <x@x00.us>
Date:   Mon Nov 1 20:01:46 2010 +0100

    Fix FC when adding a Coop account.

diff --git AndroidManifest.xml AndroidManifest.xml
index 3906ec8..97e695c 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0-RC3" android:versionCode="27">
+	package="com.liato.bankdroid" android:versionName="1.4.0-RC4" android:versionCode="28">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index ba0c568..6c09a08 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -92,7 +92,6 @@ public class Coop extends Bank {
 		}
 
 		urlopen = login();
-		String response = null;
 		Matcher matcher;
 		try {
 			Account account;

commit 57f78524f31b32d93474a440a2129c884528e92f
Author: liato <x@x00.us>
Date:   Mon Nov 1 19:42:31 2010 +0100

    Kepp account settings when updating from widget.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8300173..3906ec8 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.4.0-RC2" android:versionCode="26">
+	package="com.liato.bankdroid" android:versionName="1.4.0-RC3" android:versionCode="27">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 0c9cfd9..fab4933 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -226,7 +226,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 					return null;
 				}
 				long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
-				Bank bank = BankFactory.bankFromDb(new Long(bankId), context, false);
+				Bank bank = BankFactory.bankFromDb(new Long(bankId), context, true);
 				if (bank == null) {
 					return null;
 				}

commit b2bf315f465af23acb109194e3d630540cf26ff7
Author: liato <x@x00.us>
Date:   Mon Nov 1 14:15:07 2010 +0100

    Bump version to 1.4.0-rc2.

diff --git AndroidManifest.xml AndroidManifest.xml
index 1425aba..8300173 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionCode="25" android:versionName="1.4.0-RC1">
+	package="com.liato.bankdroid" android:versionName="1.4.0-RC2" android:versionCode="26">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 6306cc6..ae1ee3a 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -98,7 +98,7 @@
 	\nasperon (Transparent widget)
 	\nDEGE (Handelsbanken)
 	\ncola (OKQ8)
-	\nFirstCard (Rikko)
-	\nEurocard (nihplod)
+	\nRikko (FirstCard)
+	\nnihplod (Eurocard)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 6bd99dd..ebd21d6 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -100,7 +100,7 @@
 	\nasperon (Transparent widget)
 	\nDEGE (Handelsbanken)
 	\ncola (OKQ8)
-	\nFirstCard (Rikko)
-	\nEurocard (nihplod)
+	\nRikko (FirstCard)
+	\nnihplod (Eurocard)
      </string>
 </resources>

commit fd41d0a2cadc0286718552f996823cd27b584188
Author: liato <x@x00.us>
Date:   Mon Nov 1 13:42:57 2010 +0100

    Prevent account settings from disappearing on updates.

diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index c9044cd..f2ece16 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -112,7 +112,7 @@ public class Nordea extends Bank {
 
 			matcher = reFundsLoans.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f_"+matcher.group(1).trim(), -1L, Account.FUNDS));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f:"+matcher.group(1).trim(), -1L, Account.FUNDS));
 			}
 
 			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
@@ -120,13 +120,13 @@ public class Nordea extends Bank {
 			
 			matcher = reFundsLoans.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l_"+matcher.group(1).trim(), -1L, Account.LOANS));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l:"+matcher.group(1).trim(), -1L, Account.LOANS));
 			}
 			matcher = reCards.matcher(response);
 			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c_"+matcher.group(1).trim(), -1L, Account.CCARD));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c:"+matcher.group(1).trim(), -1L, Account.CCARD));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 			if (accounts.isEmpty()) {
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 92bd509..2835d3c 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -97,7 +97,7 @@ public class Swedbank extends Bank {
 			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "loan_" + matcher.group(2).trim() : matcher.group(2).trim());
+				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l:" + matcher.group(2).trim() : matcher.group(2).trim());
 				if (matcher.group(2).trim() == "loan") {
 				    account.setType(Account.LOANS);
 				}
@@ -109,7 +109,7 @@ public class Swedbank extends Bank {
 			matcher = reLinklessAccounts.matcher(response);
 			int accid = 0;
 			while (matcher.find()) {
-				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll_"+accid);
+				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll:"+accid);
 				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
 				account.setType(Account.OTHER);
                 accounts.add(account);

commit e2017af8a55f7b7477e3e6d07ab9b9cae67be0ee
Author: liato <x@x00.us>
Date:   Mon Nov 1 02:40:19 2010 +0100

    Bump version to 1.4.0-rc1.

diff --git AndroidManifest.xml AndroidManifest.xml
index 6e6b4bc..1425aba 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.3.1" android:versionCode="34">
+	package="com.liato.bankdroid" android:versionCode="25" android:versionName="1.4.0-RC1">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 1509878..6306cc6 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -96,5 +96,9 @@
     \nNiclas Ljungstrand (Nordea)
 	\nOzzy (Avanza)
 	\nasperon (Transparent widget)
+	\nDEGE (Handelsbanken)
+	\ncola (OKQ8)
+	\nFirstCard (Rikko)
+	\nEurocard (nihplod)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index f30d899..6bd99dd 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -98,5 +98,9 @@
     \nNiclas Ljungstrand (Nordea)
 	\nOzzy (Avanza)
 	\nasperon (Transparent widget)
+	\nDEGE (Handelsbanken)
+	\ncola (OKQ8)
+	\nFirstCard (Rikko)
+	\nEurocard (nihplod)
      </string>
 </resources>
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index c701f90..ba0c568 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -31,10 +31,11 @@ public class Coop extends Bank {
 	private static final int BANKTYPE_ID = Bank.COOP;
 
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalanceVisa = Pattern.compile("aktuellt\\s*saldo:</span>\\s*<span>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceVisa = Pattern.compile("Disponibelt\\s*belopp[^<]*</h6>\\s*<ul>(.*?)</ul>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+	private String response;
 	
 	public Coop(Context context) {
 		super(context);
@@ -53,7 +54,6 @@ public class Coop extends Bank {
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib();
-		String response = null;
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
@@ -96,11 +96,11 @@ public class Coop extends Bank {
 		Matcher matcher;
 		try {
 			Account account;
-			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 			matcher = reBalanceVisa.matcher(response);
 			if (matcher.find()) {
 				account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+	            response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 				matcher = reTransactionsVisa.matcher(response);
 				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 				while (matcher.find()) {

commit b13a6b7d6138f19fa7e5f90402bd48fdb97fc639
Author: liato <x@x00.us>
Date:   Mon Nov 1 01:05:42 2010 +0100

    Added PayPal. Keyboard layout for the username field is changed to phone or email when appropriate.

diff --git logos.psd logos.psd
index 5557d71..4dc9df1 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/logo_nordea.png res/drawable/logo_nordea.png
index 42662e2..7b5d539 100644
Binary files res/drawable/logo_nordea.png and res/drawable/logo_nordea.png differ
diff --git res/drawable/logo_paypal.png res/drawable/logo_paypal.png
new file mode 100644
index 0000000..e5d5252
Binary files /dev/null and res/drawable/logo_paypal.png differ
diff --git res/layout/bank.xml res/layout/bank.xml
index 224bf39..4d22c6b 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -29,7 +29,7 @@
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditUsername" android:inputType="number"></EditText>
+				android:id="@+id/edtBankeditUsername" android:inputType="textEmailAddress"></EditText>
 			<TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index 43c831f..3e7a7ee 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -3,7 +3,6 @@ package com.liato.bankdroid;
 import java.util.ArrayList;
 
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.graphics.Color;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -26,7 +25,7 @@ public class AccountsAdapter extends BaseAdapter {
     public AccountsAdapter(Context context, boolean showHidden) {
 		this.context = context;
 		this.banks = new ArrayList<Bank>();
-		inflater = LayoutInflater.from(context);
+		inflater = LayoutInflater.from(this.context);
 		this.showHidden = showHidden;
 	}
 
@@ -83,7 +82,7 @@ public class AccountsAdapter extends BaseAdapter {
 		if (convertView == null) {
 			convertView = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
 		}
-		convertView.findViewById(R.id.divider).setBackgroundColor(Color.argb(60, 255, 255, 255));
+		convertView.findViewById(R.id.divider).setBackgroundColor(Color.argb(30, 255, 255, 255));
 		TextView txtAccountName = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemAccountname));
         TextView txtBalance = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance));
 		txtAccountName.setText(account.getName());
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 8548d3b..5f619d9 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -6,6 +6,7 @@ import java.util.HashMap;
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.text.InputType;
 
 import com.liato.urllib.Urllib;
 
@@ -24,6 +25,8 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int OKQ8 = 12;
 	public final static int EUROCARD = 13;
 	public final static int FIRSTCARD = 14;
+	public final static int PAYPAL = 15;
+	public final static int Payson = 16;
 	
 
 	protected String TAG = "Bank";
@@ -31,12 +34,12 @@ public abstract class Bank implements Comparable<Bank> {
 	protected String NAME_SHORT = "bank";
 	protected int BANKTYPE_ID = 0;
 	protected String URL;
+    protected int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT;
+    protected int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_TEXT;
 
 	protected Context context;
 	protected Resources res;
 
-    protected boolean usernameNumeric = false;
-    protected boolean passwordNumeric = false;
 	
 	protected String username;
 	protected String password;
@@ -214,15 +217,15 @@ public abstract class Bank implements Comparable<Bank> {
 		return URL;
 	}
 	
-    public boolean isUsernameNumeric() {
-        return usernameNumeric;
+	public int getInputTypeUsername() {
+        return INPUT_TYPE_USERNAME;
     }
 
-    public boolean isPasswordNumeric() {
-        return passwordNumeric;
-    }	
-	
-	public int getImageResource() {
+    public int getInputTypePassword() {
+        return INPUT_TYPE_PASSWORD;
+    }
+
+    public int getImageResource() {
 		return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
 	}
 
diff --git src/com/liato/bankdroid/BankEditActivity.java src/com/liato/bankdroid/BankEditActivity.java
index d664475..b0013a1 100644
--- src/com/liato/bankdroid/BankEditActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -92,23 +92,9 @@ public class BankEditActivity extends LockableActivity implements OnClickListene
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
 		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
-		if (SELECTED_BANK.isUsernameNumeric()) {
-		    ((EditText) findViewById(R.id.edtBankeditUsername)).setInputType(InputType.TYPE_CLASS_PHONE);
-		}
-		else {
-		    ((EditText) findViewById(R.id.edtBankeditUsername)).setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
-		}
-        
-		/*
-		 * Not possible to set a textfield to both PHONE and PASSWORD :\ 
-
-    		if (SELECTED_BANK.isPasswordNumeric()) {
-                ((EditText) findViewById(R.id.edtBankeditPassword)).setInputType(InputType.TYPE_CLASS_PHONE);
-            }
-            else {
-                ((EditText) findViewById(R.id.edtBankeditPassword)).setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
-            }
-        */
+        ((EditText)findViewById(R.id.edtBankeditUsername)).setInputType(SELECTED_BANK.getInputTypeUsername());
+        //Not possible to set a textfield to both PHONE and PASSWORD :\
+        //((EditText)findViewById(R.id.edtBankeditPassword)).setInputType(SELECTED_BANK.getInputTypePassword());
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index ae88cc1..f1dab83 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -4,7 +4,6 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
-
 import android.content.Context;
 import android.database.Cursor;
 
@@ -18,6 +17,8 @@ import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
 import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
+import com.liato.bankdroid.banks.OKQ8;
+import com.liato.bankdroid.banks.PayPal;
 import com.liato.bankdroid.banks.Statoil;
 import com.liato.bankdroid.banks.Swedbank;
 import com.liato.bankdroid.banks.Villabanken;
@@ -46,8 +47,16 @@ public class BankFactory {
 			return new Avanza(context);
 		case Bank.VILLABANKEN:
 			return new Villabanken(context);
-		case Bank.AVANZAMINI:
-			return new AvanzaMini(context);
+        case Bank.AVANZAMINI:
+            return new AvanzaMini(context);
+        case Bank.OKQ8:
+            return new OKQ8(context);
+        case Bank.EUROCARD:
+            return new Eurocard(context);
+        case Bank.FIRSTCARD:
+            return new FirstCard(context);
+        case Bank.PAYPAL:
+            return new PayPal(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -67,8 +76,10 @@ public class BankFactory {
 		banks.add(new Avanza(context));
 		banks.add(new Villabanken(context));
 		banks.add(new AvanzaMini(context));
+        banks.add(new OKQ8(context));
 		banks.add(new Eurocard(context));
-		banks.add(new FirstCard(context));
+        banks.add(new FirstCard(context));
+        banks.add(new PayPal(context));
 		return banks;
 	}
 
@@ -168,6 +179,7 @@ public class BankFactory {
                                       c.getInt(c.getColumnIndex("acctype")));
         account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
         account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
+        account.setCurrency(c.getString(c.getColumnIndex("currency")));
 		c.close();
 		if (loadTransactions) {
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -207,6 +219,7 @@ public class BankFactory {
                                           c.getInt(c.getColumnIndex("acctype")));
 	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
 	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
+	        account.setCurrency(c.getString(c.getColumnIndex("currency")));
 			accounts.add(account);
 		}
 		c.close();
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 2301d20..7d53bb3 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -14,6 +14,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -31,6 +32,7 @@ public class Avanza extends Bank {
 	private static final String NAME_SHORT = "avanza";
 	private static final String URL = "https://www.avanza.se/";
 	private static final int BANKTYPE_ID = Bank.AVANZA;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -41,6 +43,7 @@ public class Avanza extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Avanza(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banks/AvanzaMini.java
index c20579f..9b2ffbf 100644
--- src/com/liato/bankdroid/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banks/AvanzaMini.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -28,6 +29,7 @@ public class AvanzaMini extends Bank {
 	private static final String NAME_SHORT = "avanzamini";
 	private static final String URL = "https://www.avanza.se/mini/hem/";
 	private static final int BANKTYPE_ID = Bank.AVANZAMINI;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
     private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tbody>\\s*(.*)</tbody>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
     private Pattern accountsAvanzaMini = Pattern.compile("<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -38,6 +40,7 @@ public class AvanzaMini extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public AvanzaMini(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 2e9e0f1..b29952d 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -13,6 +13,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -30,6 +31,7 @@ public class Eurocard extends Bank {
 	private static final String NAME_SHORT = "eurocard";
 	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
 	private static final int BANKTYPE_ID = Bank.EUROCARD;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
 	private Pattern reAccounts = Pattern.compile("getInvoiceList\\.do\\?id=([^\"]+)\">([^<]+)</a></td>(?:\\s*<td>[^<]+</td>){2}\\s*<td\\s*align=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("<nobr>(\\d\\d-\\d\\d)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>[^<]+</nobr>\\s*</td>\\s*<td><div\\s*class=\"BreakLine\">([^<]+)</div>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td[^>]+>\\s*<nobr>([^>]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">[^<]+</td>\\s*<td[^>]+>\\s*<nobr>([^<]+)</nobr>", Pattern.CASE_INSENSITIVE);
@@ -41,6 +43,7 @@ public class Eurocard extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Eurocard(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
index 9475220..eb8c265 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -29,6 +30,7 @@ public class FirstCard extends Bank {
 	private static final String NAME_SHORT = "firstcard";
 	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
 	private static final int BANKTYPE_ID = Bank.FIRSTCARD;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
 	private Pattern reAccounts = Pattern.compile("translist\\.jsp\\?p=a&(?:amp;)?cardID=([^\"]+)\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("pagecolumns\">(\\d{6})</td>\\s*<td>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
@@ -40,6 +42,7 @@ public class FirstCard extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public FirstCard(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 23426ec..de59342 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -33,6 +34,7 @@ public class Handelsbanken extends Bank {
 	private static final String NAME_SHORT = "handelsbanken";
 	private static final String URL = "https://m.handelsbanken.se/";
 	private static final int BANKTYPE_ID = Bank.HANDELSBANKEN;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 
 	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
@@ -47,6 +49,7 @@ public class Handelsbanken extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Handelsbanken(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index e16c012..ce2bf87 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -29,6 +30,7 @@ public class ICABanken extends Bank {
 	private static final String NAME_SHORT = "icabanken";
 	private static final String URL = "https://mobil.icabanken.se/";
 	private static final int BANKTYPE_ID = Bank.ICABANKEN;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -44,6 +46,7 @@ public class ICABanken extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public ICABanken(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index 6ac50fe..79102a9 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -28,6 +29,8 @@ public class Lansforsakringar extends Bank {
 	private static final String NAME_SHORT = "lansforsakringar";
 	private static final String URL = "https://secure246.lansforsakringar.se/lfportal/login/privat";
 	private static final int BANKTYPE_ID = Bank.LANSFORSAKRINGAR;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
 
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
@@ -42,6 +45,8 @@ public class Lansforsakringar extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+		super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
 	}
 
 	public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 35adb5d..c9044cd 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -13,6 +13,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -30,6 +31,8 @@ public class Nordea extends Bank {
 	private static final String NAME_SHORT = "nordea";
 	private static final String URL = "https://mobil.nordea.se/";
 	private static final int BANKTYPE_ID = Bank.NORDEA;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
+    private static final int INPUT_TYPE_PASSWORD = InputType.TYPE_CLASS_PHONE;
 	
 	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
 	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
@@ -44,6 +47,8 @@ public class Nordea extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+        super.INPUT_TYPE_PASSWORD = INPUT_TYPE_PASSWORD;
 	}
 
 	public Nordea(String username, String password, Context context) throws BankException, LoginException {
@@ -70,11 +75,6 @@ public class Nordea extends Bank {
 			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html", postData);
 			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
-			/*
-			for (String s : response.split("\n")) {
-				Log.d("BankNordea-ResponseData", s);
-			}
-			*/
 			
 			if (response.contains("felaktiga uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
@@ -100,23 +100,19 @@ public class Nordea extends Bank {
 		try {
 			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			/*for (String s : response.split("\n")) {
-				Log.d("BankNordea-ResponseData", s);
-			}*/
 			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
-
+			
 			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
 
 			matcher = reFundsLoans.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f"+matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f_"+matcher.group(1).trim(), -1L, Account.FUNDS));
 			}
 
 			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
@@ -124,17 +120,15 @@ public class Nordea extends Bank {
 			
 			matcher = reFundsLoans.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l"+matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l_"+matcher.group(1).trim(), -1L, Account.LOANS));
 			}
 			matcher = reCards.matcher(response);
 			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c"+matcher.group(1).trim()));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c_"+matcher.group(1).trim(), -1L, Account.CCARD));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
-
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
@@ -149,14 +143,19 @@ public class Nordea extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+		finally {
+		    super.updateComplete();
+		}
 	}
 
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
+		if (new String("").equals(new String(""))) return;
 
 		//No transaction history for loans, funds and credit cards.
-		if (account.getId().startsWith("l") || account.getId().startsWith("f") || account.getId().startsWith("c")) return;
+		int accType = account.getType();
+		if (accType == Account.LOANS || accType == Account.FUNDS || accType == Account.CCARD) return;
 
 		String response = null;
 		Matcher matcher;
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index cfb76c9..d72eb6c 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -13,6 +13,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -34,7 +35,7 @@ public class OKQ8 extends Bank {
 	private static final String NAME_SHORT = "okq8";
 	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
 	private static final int BANKTYPE_ID = Bank.OKQ8;
-
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 	
 	private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
 	private Pattern reBalance = Pattern.compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
@@ -48,6 +49,7 @@ public class OKQ8 extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public OKQ8(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/PayPal.java src/com/liato/bankdroid/banks/PayPal.java
new file mode 100644
index 0000000..e0c6d5b
--- /dev/null
+++ src/com/liato/bankdroid/banks/PayPal.java
@@ -0,0 +1,146 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.InputType;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class PayPal extends Bank {
+	private static final String TAG = "PayPal";
+	private static final String NAME = "PayPal";
+	private static final String NAME_SHORT = "paypal";
+	private static final String URL = "https://www.paypal.com/";
+	private static final int BANKTYPE_ID = Bank.PAYPAL;
+	private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_TEXT | + InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+	
+	private Pattern reBalance = Pattern.compile("PayPal\\s*balance:\\s*<span\\s*class=\"balance\">[^0-9,.-]*([0-9,. ]+)([A-Z]+)</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("row\">([^>]+)</td>\\s*<td\\s*class=\"textright\">[^0-9,.-]*([0-9,. ]+)([A-Z]+)</td>", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	public PayPal(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
+	}
+
+	public PayPal(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		try {
+		    //Get cookies
+		    response = urlopen.open("https://www.paypal.com/en");
+
+		    List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));				
+			postData.add(new BasicNameValuePair("login_email", username));
+			postData.add(new BasicNameValuePair("login_password", password));
+			postData.add(new BasicNameValuePair("target_page", "0"));
+			postData.add(new BasicNameValuePair("submit.x", "Log In"));
+			postData.add(new BasicNameValuePair("form_charset", "UTF-8"));
+			postData.add(new BasicNameValuePair("browser_name", "undefined"));
+			postData.add(new BasicNameValuePair("browser_version", "undefined"));
+			postData.add(new BasicNameValuePair("operating_system", "Windows"));
+			postData.add(new BasicNameValuePair("bp_mid", "v=1;a1=na~a2=na~a3=na~a4=Mozilla~a5=Netscape~a6=5.0 (Windows; en-US)~a7=20100713~a8=na~a9=true~a10=Windows NT 6.1~a11=true~a12=Win32~a13=na~a14=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 ( .NET CLR 3.5.30729; .NET4.0C)~a15=true~a16=en-US~a17=na~a18=www.paypal.com~a19=na~a20=na~a21=na~a22=na~a23=1280~a24=720~a25=24~a26=658~a27=na~a28=Sun Oct 31 2010 18:41:07 GMT 0100~a29=1~a30=def|qt1|qt2|qt3|qt4|qt5|qt6|swf|~a31=yes~a32=na~a33=na~a34=no~a35=no~a36=yes~a37=no~a38=online~a39=no~a40=Windows NT 6.1~a41=no~a42=no~"));
+			postData.add(new BasicNameValuePair("bp_ks1", "v=1;l=16;Di0:1103361Ui0:95Di1:5Ui1:138Di2:171Di3:154Ui2:59Ui3:81Di4:562Ui4:147Di5:369Ui5:118Di6:401Ui6:124Di7:296Ui7:74Di8:71Ui8:101Di9:61Ui9:81Di10:7Ui10:94Di11:666Ui11:131Di12:79Ui12:107Di13:114Ui13:109Di14:5Ui14:152Di15:400Ui15:121"));
+			postData.add(new BasicNameValuePair("bp_ks2", ""));
+			postData.add(new BasicNameValuePair("bp_ks3", ""));
+			postData.add(new BasicNameValuePair("flow_name", "xpt/Marketing_CommandDriven/homepage/IndividualsHome"));
+			postData.add(new BasicNameValuePair("fso", "k2TDENTlxEJnhbuYDYFmKMyVq0kUZPsdK6j3V1gPUwuZvyAmzzpRs4Cmjet0z19AwlxXfW"));
+			
+			Log.d(TAG, "Posting to https://www.paypal.com/cgi-bin/webscr?cmd=_login-submit&dispatch=5885d80a13c0db1f8e263663d3faee8dc60d77e6184470d515cedf52660ea0cd");
+			response = urlopen.open("https://www.paypal.com/cgi-bin/webscr?cmd=_login-submit&dispatch=5885d80a13c0db1f8e263663d3faee8dc60d77e6184470d515cedf52660ea0cd", postData);
+			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
+			if (response.contains("If you still can't log in") || response.contains("both your email address and password")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+            response = urlopen.open("https://www.paypal.com/en/cgi-bin/webscr?cmd=_login-done&login_access="+((int)(System.currentTimeMillis() / 1000L)));
+            Matcher matcher = reBalance.matcher(response);
+            if (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: balance           554.70
+                 * 2: currency          SEK
+                 * 
+                 */
+                balance = Helpers.parseBalance(matcher.group(1));
+                currency = matcher.group(2).trim();
+            }
+    		matcher = reAccounts.matcher(response);
+    		int accId = 1;
+    		while (matcher.find()) {
+                /*
+                 * Capture groups:
+                 * GROUP                EXAMPLE DATA
+                 * 1: name              SEK (Primary)
+                 * 2: amount            554.70
+                 * 3: currency          SEK
+                 * 
+                 */
+    		    Account account = new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), ""+accId);
+    		    account.setCurrency(matcher.group(3).trim());
+    		    accounts.add(account);
+    		    accId++;
+    		}
+
+    		if (accounts.isEmpty()) {
+    			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+    		}
+        }
+        catch (ClientProtocolException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        finally {
+            super.updateComplete();
+        }
+	}
+	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index 24633cc..3c0a5fc 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -13,6 +13,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -30,6 +31,7 @@ public class Statoil extends Bank {
 	private static final String NAME_SHORT = "statoil";
 	private static final String URL = "https://applications.sebkort.com/nis/external/stse/login.do";
 	private static final int BANKTYPE_ID = Bank.STATOIL;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 
 	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunitlastdisposableamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]+>\\s*<span>([^<]*)</span>\\s*</div>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
@@ -41,6 +43,7 @@ public class Statoil extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+		super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Statoil(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index f339975..92bd509 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -12,6 +12,7 @@ import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
 import android.text.Html;
+import android.text.InputType;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -29,6 +30,7 @@ public class Swedbank extends Bank {
 	private static final String NAME_SHORT = "swedbank";
 	private static final String URL = "https://mobilbank.swedbank.se/";
 	private static final int BANKTYPE_ID = Bank.SWEDBANK;
+    private static final int INPUT_TYPE_USERNAME = InputType.TYPE_CLASS_PHONE;
 
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
@@ -41,7 +43,7 @@ public class Swedbank extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
-        super.usernameNumeric = true;
+        super.INPUT_TYPE_USERNAME = INPUT_TYPE_USERNAME;
 	}
 
 	public Swedbank(String username, String password, Context context) throws BankException, LoginException {
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index 0f82761..6294c27 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -73,7 +73,7 @@ public class Urllib {
     		//URL urli = new URL(url); 
     		HttpGet urlConnection = new HttpGet(url);
     		urlConnection.addHeader("User-Agent", USER_AGENT);
-    		response = httpclient.execute(urlConnection, responseHandler, context); 
+    		response = httpclient.execute(urlConnection, responseHandler, context);
     	}
     	else {
     		HttpPost urlConnection = new HttpPost(url);
@@ -101,6 +101,9 @@ public class Urllib {
     	return currentURI;
     }
     
+    public DefaultHttpClient getHttpclient() {
+        return httpclient;
+    }
     public boolean acceptsInvalidCertificates() {
     	return acceptInvalidCertificates;
     }

commit d8eeb93c90e9f4ac0690c76fe9b575b1ccf466fc
Author: liato <x@x00.us>
Date:   Sun Oct 31 15:28:53 2010 +0100

    Resized menu icons. Activate notifications based on account type. Toggle hidden accounts visibility.

diff --git res/drawable-hdpi-v4/button_cancel.png res/drawable-hdpi-v4/button_cancel.png
index 9e4a17f..09a9931 100644
Binary files res/drawable-hdpi-v4/button_cancel.png and res/drawable-hdpi-v4/button_cancel.png differ
diff --git res/drawable-hdpi-v4/button_edit.png res/drawable-hdpi-v4/button_edit.png
index f9a0bf2..1b7c2c3 100644
Binary files res/drawable-hdpi-v4/button_edit.png and res/drawable-hdpi-v4/button_edit.png differ
diff --git res/drawable-hdpi-v4/button_hide.png res/drawable-hdpi-v4/button_hide.png
index e76b11b..4353284 100644
Binary files res/drawable-hdpi-v4/button_hide.png and res/drawable-hdpi-v4/button_hide.png differ
diff --git res/drawable-hdpi-v4/button_notification.png res/drawable-hdpi-v4/button_notification.png
index cf7c749..f2148d7 100644
Binary files res/drawable-hdpi-v4/button_notification.png and res/drawable-hdpi-v4/button_notification.png differ
diff --git res/drawable-hdpi-v4/button_refresh.png res/drawable-hdpi-v4/button_refresh.png
index 39c04e3..6f7bd1a 100644
Binary files res/drawable-hdpi-v4/button_refresh.png and res/drawable-hdpi-v4/button_refresh.png differ
diff --git res/drawable-hdpi-v4/button_save.png res/drawable-hdpi-v4/button_save.png
index bb8dfc3..9262d60 100644
Binary files res/drawable-hdpi-v4/button_save.png and res/drawable-hdpi-v4/button_save.png differ
diff --git res/drawable-hdpi-v4/button_www.png res/drawable-hdpi-v4/button_www.png
index 1bf2311..1bb8436 100644
Binary files res/drawable-hdpi-v4/button_www.png and res/drawable-hdpi-v4/button_www.png differ
diff --git res/drawable/ic_menu_refresh.png res/drawable/ic_menu_refresh.png
deleted file mode 100644
index 77d70dd..0000000
Binary files res/drawable/ic_menu_refresh.png and /dev/null differ
diff --git res/layout/popup.xml res/layout/popup.xml
deleted file mode 100644
index edabf1d..0000000
--- res/layout/popup.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_height="wrap_content"
-	android:background="@drawable/popup_bg_down"
-	android:layout_width="fill_parent"
-	android:layout_gravity="fill_horizontal"
-	android:id="@+id/layPopupCont">
-	<Button style="@style/Popup_Button"
-		android:id="@+id/btnRefresh"
-		android:drawableTop="@drawable/button_refresh"
-		android:text="Refresh"
-		></Button>
-	<ImageView style="@style/Popup_Separator"></ImageView>		
-	<Button
-		android:id="@+id/btnEdit"
-		android:drawableTop="@drawable/button_edit"
-		android:text="Edit"
-		style="@style/Popup_Button"></Button>
-	<ImageView style="@style/Popup_Separator"></ImageView>		
-	<Button
-		android:id="@+id/btnWWW"
-		android:drawableTop="@drawable/button_www"
-		android:text="WWW"
-		style="@style/Popup_Button"></Button>
-	<ImageView style="@style/Popup_Separator"></ImageView>		
-	<Button
-		android:id="@+id/btnRemove"
-		android:drawableTop="@drawable/button_cancel"
-		android:text="Remove"
-		style="@style/Popup_Button"></Button>
-	<ImageView style="@style/Popup_Separator"></ImageView>		
-</LinearLayout>
\ No newline at end of file
diff --git res/layout/settings.xml res/layout/settings.xml
index d41c055..83879a5 100644
--- res/layout/settings.xml
+++ res/layout/settings.xml
@@ -92,10 +92,15 @@
 				android:textSize="14sp"
 				android:id="@+id/chkWithVibration"
 				android:text="@string/vibrate"
-				android:layout_marginLeft="10dp"></CheckBox>
-		</LinearLayout>
+				android:layout_marginLeft="10dp"></CheckBox><LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginLeft="10dp"><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/notify_account_types"></TextView><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkDeposit" android:text="@string/deposit_account"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkLoans" android:text="@string/loans"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkFunds" android:text="@string/funds"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkCCards" android:text="@string/ccards"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkOther" android:text="@string/other"></CheckBox>
+</LinearLayout>
+		
+
+</LinearLayout>
 		
-	</LinearLayout>
+	
+
+</LinearLayout>
 	</ScrollView>
 	<TableLayout
 		android:id="@+id/TableLayout01"
diff --git res/menu-sv/menu.xml res/menu-sv/menu.xml
index eaae083..da14f73 100644
--- res/menu-sv/menu.xml
+++ res/menu-sv/menu.xml
@@ -5,12 +5,12 @@
 		android:id="@+id/settings"
 		android:title="Inställningar"
 		android:icon="@android:drawable/ic_menu_preferences" />
+	<item
+		android:id="@+id/toggle_hidden"
+		android:title="@string/menu_show_hidden"
+		android:icon="@drawable/ic_menu_view"/>
 	<item
 		android:id="@+id/about"
 		android:title="Om"
 		android:icon="@android:drawable/ic_menu_info_details" />
-	<item
-		android:id="@+id/toggle_hidden"
-		android:title="Visa/göm\ngömda konton"
-		android:icon="@drawable/ic_menu_view"/>
 </menu>
\ No newline at end of file
diff --git res/menu/menu.xml res/menu/menu.xml
index 06de842..083c539 100644
--- res/menu/menu.xml
+++ res/menu/menu.xml
@@ -5,12 +5,12 @@
 		android:id="@+id/settings"
 		android:title="Settings"
 		android:icon="@android:drawable/ic_menu_preferences" />
+	<item
+		android:id="@+id/toggle_hidden"
+		android:title="@string/menu_show_hidden"
+		android:icon="@drawable/ic_menu_view"/>
 	<item
 		android:id="@+id/about"
 		android:title="About"
 		android:icon="@android:drawable/ic_menu_info_details" />
-	<item
-		android:id="@+id/toggle_hidden"
-		android:title="Show/hide\nhidden accounts"
-		android:icon="@drawable/ic_menu_view"/>
 </menu>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 1cbd894..1509878 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -43,6 +43,12 @@
 	<string name="notify_on_change">Notifiera vid kontohändelser</string>
 	<string name="with_sound">Med ljud</string>
 	<string name="vibrate">Vibrera</string>
+	<string name="notify_account_types">Endast för följande konototyper:</string>
+	<string name="funds">Fonder</string>
+	<string name="ccards">Kreditkort</string>
+	<string name="loans">Lån</string>
+	<string name="deposit_account">Transaktionskonto</string>
+	<string name="other">Andra</string>
 	
     <string name="login">Logga in</string>
     <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
@@ -67,6 +73,9 @@
     <string name="remove_bank_title">Radera bank?</string>
     <string name="yes">Ja</string>
     <string name="no">Nej</string>
+ 
+    <string name="menu_show_hidden">Visa gömda konton</string>
+    <string name="menu_hide_hidden">Göm gömda konton</string>
     
     <string name="tran_desc">Inget kontoutdrag tillgängligt för detta konto.</string>
 
diff --git res/values/strings.xml res/values/strings.xml
index d70ed44..f30d899 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -44,6 +44,12 @@
 	<string name="notify_on_change">Notify on changes</string>
 	<string name="with_sound">With sound</string>
 	<string name="vibrate">Vibrate</string>
+	<string name="notify_account_types">Only for the following account types:</string>
+	<string name="funds">Funds</string>
+	<string name="ccards">Credit cards</string>
+	<string name="loans">Loans</string>
+	<string name="deposit_account">Deposit accounts</string>
+	<string name="other">Other</string>
 	
     <string name="login">Login</string>
     <string name="invalid_access_code">Invalid access code. Try again.</string>
@@ -69,6 +75,9 @@
     <string name="remove_bank_title">Remove bank?</string>
     <string name="yes">Yes</string>
     <string name="no">No</string>
+    
+    <string name="menu_show_hidden">Show hidden accounts</string>
+    <string name="menu_hide_hidden">Hide hidden accounts</string>
 
     <string name="tran_desc">No transaction history available for this account.</string>
     
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index e04425d..2b3c41e 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -110,27 +110,26 @@ public class AutoRefreshService extends Service {
     						if (oldAccount != null) {
     							if (account.getBalance().compareTo(oldAccount.getBalance()) != 0) {
     							    boolean notify = false;
+    							    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(AutoRefreshService.this);
     							    switch (account.getType()) {
     							    case Account.REGULAR:
-    							        notify = true;
+    							        notify = prefs.getBoolean("notify_for_deposit", true);
     							        break;
     							    case Account.FUNDS:
-    							        notify = false;
+    							        notify = prefs.getBoolean("notify_for_funds", false);
     							        break;
     							    case Account.LOANS:
-    							        notify = false;
+    							        notify = prefs.getBoolean("notify_for_loans", false);
     							        break;
     							    case Account.CCARD:
-    							        notify = true;
+    							        notify = prefs.getBoolean("notify_for_ccards", true);
     							        break;
     							    case Account.OTHER:
-    							        notify = false;
+    							        notify = prefs.getBoolean("notify_for_other", false);
     							        break;
     							    }
-    							    if (account.getType() == Account.REGULAR) {
-    							        notify = true;
-    							    }
-    							    if (account.isHidden() || account.isNotify()) {
+    							    Log.d(TAG, "Account type: "+account.getType()+"; notify: "+notify);
+    							    if (account.isHidden() || !account.isNotify()) {
     							        notify = false;
     							    }
     		                        if (notify) {
diff --git src/com/liato/bankdroid/BetterPopupWindow.java src/com/liato/bankdroid/BetterPopupWindow.java
index 6c3d71d..1ea3e8d 100644
--- src/com/liato/bankdroid/BetterPopupWindow.java
+++ src/com/liato/bankdroid/BetterPopupWindow.java
@@ -4,6 +4,7 @@ import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -41,6 +42,7 @@ public class BetterPopupWindow {
 		this.window.setTouchInterceptor(new OnTouchListener() {
 			@Override
 			public boolean onTouch(View v, MotionEvent event) {
+			    Log.d("TOCUH", "TOUCH!");
 				if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
 					BetterPopupWindow.this.window.dismiss();
 					return true;
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 96c7c66..b132a7c 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -66,11 +66,10 @@ public class MainActivity extends LockableActivity {
                 if (adapter.getItem(position) instanceof Account) {
                     selected_account = (Account)adapter.getItem(position);
                     PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
-                    pmenu.setContentView(R.layout.popup_account);
                     pmenu.showLikeQuickAction(0, 12);
                     return true;
                 }
-                return true;
+                return false;
             }
         });
 		lv.setOnItemClickListener(new OnItemClickListener() {
@@ -82,14 +81,11 @@ public class MainActivity extends LockableActivity {
 					pmenu.showLikeQuickAction(0, 12);					
 				}
 				else {
-					/*Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
+					Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
 					Account account = (Account) adapter.getItem(position);
 					intent.putExtra("account", account.getId());
 					intent.putExtra("bank", account.getBankDbId());
-					MainActivity.this.startActivity(intent);*/
-                    selected_account = (Account) adapter.getItem(position);
-                    PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
-                    pmenu.showLikeQuickAction(0, 12);   				    
+					MainActivity.this.startActivity(intent);
 				}
 			}
 		});
@@ -156,6 +152,12 @@ public class MainActivity extends LockableActivity {
 		switch (item.getItemId()) {
 		case R.id.toggle_hidden:
 		    showHidden = !showHidden;
+		    if (showHidden) {
+		        item.setTitle(R.string.menu_hide_hidden);
+		    }
+		    else {
+		        item.setTitle(R.string.menu_show_hidden);
+		    }
 		    refreshView();
 			return true;
 		case R.id.settings:
@@ -310,8 +312,6 @@ public class MainActivity extends LockableActivity {
 
         @Override
         public void onClick(View v) {
-            final Context context = this.anchor.getContext();
-            Log.d(TAG, "CLICK!");
             int id = v.getId();
             switch (id) {
             case R.id.btnHide:
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index d177054..81a0a38 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -101,8 +101,13 @@ public class SettingsActivity extends LockableActivity implements OnClickListene
 				editor.putString("access_code", ((EditText)findViewById(R.id.edtAccessCode)).getText().toString());
 				editor.putBoolean("notify_on_change", ((CheckBox)findViewById(R.id.chkNotifyOnChange)).isChecked());
 				editor.putBoolean("notify_with_sound", ((CheckBox)findViewById(R.id.chkWithSound)).isChecked());
-				editor.putBoolean("notify_with_vibration", ((CheckBox)findViewById(R.id.chkWithVibration)).isChecked());
-				editor.putInt("refreshrate", refreshrate);
+                editor.putBoolean("notify_with_vibration", ((CheckBox)findViewById(R.id.chkWithVibration)).isChecked());
+                editor.putBoolean("notify_for_deposit", ((CheckBox)findViewById(R.id.chkDeposit)).isChecked());
+                editor.putBoolean("notify_for_funds", ((CheckBox)findViewById(R.id.chkFunds)).isChecked());
+                editor.putBoolean("notify_for_loans", ((CheckBox)findViewById(R.id.chkLoans)).isChecked());
+                editor.putBoolean("notify_for_ccards", ((CheckBox)findViewById(R.id.chkCCards)).isChecked());
+                editor.putBoolean("notify_for_other", ((CheckBox)findViewById(R.id.chkOther)).isChecked());
+                editor.putInt("refreshrate", refreshrate);
 				editor.commit();
 				StartupReceiver.setAlarm(this);
 				this.finish();
@@ -110,7 +115,12 @@ public class SettingsActivity extends LockableActivity implements OnClickListene
 		}
 		else if (v.getId() == R.id.chkNotifyOnChange) {
 			findViewById(R.id.chkWithSound).setEnabled(((CheckBox)v).isChecked());
-			findViewById(R.id.chkWithVibration).setEnabled(((CheckBox)v).isChecked());
+            findViewById(R.id.chkWithVibration).setEnabled(((CheckBox)v).isChecked());
+            findViewById(R.id.chkDeposit).setEnabled(((CheckBox)v).isChecked());
+            findViewById(R.id.chkFunds).setEnabled(((CheckBox)v).isChecked());
+            findViewById(R.id.chkLoans).setEnabled(((CheckBox)v).isChecked());
+            findViewById(R.id.chkCCards).setEnabled(((CheckBox)v).isChecked());
+            findViewById(R.id.chkOther).setEnabled(((CheckBox)v).isChecked());
 		}
 
 	}
@@ -136,6 +146,16 @@ public class SettingsActivity extends LockableActivity implements OnClickListene
 		((CheckBox)findViewById(R.id.chkWithSound)).setEnabled(prefs.getBoolean("notify_on_change", true));
 		((CheckBox)findViewById(R.id.chkWithVibration)).setChecked(prefs.getBoolean("notify_with_vibration", true));
 		((CheckBox)findViewById(R.id.chkWithVibration)).setEnabled(prefs.getBoolean("notify_on_change", true));
+        ((CheckBox)findViewById(R.id.chkDeposit)).setChecked(prefs.getBoolean("notify_for_deposit", true));
+        ((CheckBox)findViewById(R.id.chkDeposit)).setEnabled(prefs.getBoolean("notify_on_change", true));
+        ((CheckBox)findViewById(R.id.chkFunds)).setChecked(prefs.getBoolean("notify_for_funds", false));
+        ((CheckBox)findViewById(R.id.chkFunds)).setEnabled(prefs.getBoolean("notify_on_change", true));
+        ((CheckBox)findViewById(R.id.chkLoans)).setChecked(prefs.getBoolean("notify_for_loans", false));
+        ((CheckBox)findViewById(R.id.chkLoans)).setEnabled(prefs.getBoolean("notify_on_change", true));
+        ((CheckBox)findViewById(R.id.chkCCards)).setChecked(prefs.getBoolean("notify_for_ccards", true));
+        ((CheckBox)findViewById(R.id.chkCCards)).setEnabled(prefs.getBoolean("notify_on_change", true));
+        ((CheckBox)findViewById(R.id.chkOther)).setChecked(prefs.getBoolean("notify_for_other", false));
+        ((CheckBox)findViewById(R.id.chkOther)).setEnabled(prefs.getBoolean("notify_on_change", true));
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index d1a0e97..5f00200 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -31,7 +31,7 @@ public class StartupReceiver extends BroadcastReceiver{
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*1000, refreshrate*1000, alarmSender);
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*60*1000, refreshrate*60*1000, alarmSender);
         	Log.d("StartupReceiever.SetAlarm","Alarm set to "+refreshrate.toString()+" minutes.");
         }
 	

commit fb54f4779237aa5d7eddcf9c0325414b994d1668
Author: liato <x@x00.us>
Date:   Sun Oct 31 09:42:32 2010 +0100

    Encrypt passwords. Option to hide accounts. Option to turn of notifications on accounts.

diff --git AndroidManifest.xml AndroidManifest.xml
index 2ddced1..6e6b4bc 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -14,7 +14,7 @@
 		</activity>
 		<activity android:name=".TransactionsActivity" android:label="@string/app_name">
 		</activity>
-		<activity android:name=".AccountActivity" android:label="@string/app_name">
+		<activity android:name=".BankEditActivity" android:label="@string/app_name">
 		</activity>
 		<activity android:name=".SettingsActivity" android:label="@string/app_name">
 		</activity>
diff --git res/drawable-hdpi-v4/button_add.png res/drawable-hdpi-v4/button_add.png
index ba86dfb..48c537e 100644
Binary files res/drawable-hdpi-v4/button_add.png and res/drawable-hdpi-v4/button_add.png differ
diff --git res/drawable-hdpi-v4/button_cancel.png res/drawable-hdpi-v4/button_cancel.png
index 9fcfe15..9e4a17f 100644
Binary files res/drawable-hdpi-v4/button_cancel.png and res/drawable-hdpi-v4/button_cancel.png differ
diff --git res/drawable-hdpi-v4/button_edit.png res/drawable-hdpi-v4/button_edit.png
index 835cd12..f9a0bf2 100644
Binary files res/drawable-hdpi-v4/button_edit.png and res/drawable-hdpi-v4/button_edit.png differ
diff --git res/drawable-hdpi-v4/button_hide.png res/drawable-hdpi-v4/button_hide.png
new file mode 100644
index 0000000..e76b11b
Binary files /dev/null and res/drawable-hdpi-v4/button_hide.png differ
diff --git res/drawable-hdpi-v4/button_notification.png res/drawable-hdpi-v4/button_notification.png
new file mode 100644
index 0000000..cf7c749
Binary files /dev/null and res/drawable-hdpi-v4/button_notification.png differ
diff --git res/drawable-hdpi-v4/button_refresh.png res/drawable-hdpi-v4/button_refresh.png
index 0462b18..39c04e3 100644
Binary files res/drawable-hdpi-v4/button_refresh.png and res/drawable-hdpi-v4/button_refresh.png differ
diff --git res/drawable-hdpi-v4/button_save.png res/drawable-hdpi-v4/button_save.png
index dadcf27..bb8dfc3 100644
Binary files res/drawable-hdpi-v4/button_save.png and res/drawable-hdpi-v4/button_save.png differ
diff --git res/drawable-hdpi-v4/button_www.png res/drawable-hdpi-v4/button_www.png
index 0de88a9..1bf2311 100644
Binary files res/drawable-hdpi-v4/button_www.png and res/drawable-hdpi-v4/button_www.png differ
diff --git res/drawable-hdpi-v4/ic_menu_info_details.png res/drawable-hdpi-v4/ic_menu_info_details.png
new file mode 100644
index 0000000..7696ceb
Binary files /dev/null and res/drawable-hdpi-v4/ic_menu_info_details.png differ
diff --git res/drawable-hdpi-v4/ic_menu_view.png res/drawable-hdpi-v4/ic_menu_view.png
new file mode 100644
index 0000000..75155d4
Binary files /dev/null and res/drawable-hdpi-v4/ic_menu_view.png differ
diff --git res/drawable/ic_menu_info_details.png res/drawable/ic_menu_info_details.png
new file mode 100644
index 0000000..1786d1e
Binary files /dev/null and res/drawable/ic_menu_info_details.png differ
diff --git res/drawable/ic_menu_view.png res/drawable/ic_menu_view.png
new file mode 100644
index 0000000..69828a9
Binary files /dev/null and res/drawable/ic_menu_view.png differ
diff --git res/layout/bank.xml res/layout/bank.xml
index 07251e8..224bf39 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -20,7 +20,7 @@
 			android:orientation="vertical"
 			android:layout_alignParentTop="true"
 			android:padding="10dp">
-			<TextView
+			<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/bank" /><Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
 				android:typeface="sans"
@@ -29,7 +29,7 @@
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditUsername"></EditText>
+				android:id="@+id/edtBankeditUsername" android:inputType="number"></EditText>
 			<TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
@@ -39,18 +39,16 @@
 			<EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/edtBankeditPassword"
-				android:inputType="textPassword"></EditText>
-			<TextView
+				android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView
 				android:layout_width="fill_parent"
 				android:layout_height="wrap_content"
 				android:typeface="sans"
-				android:textSize="20sp"
-				android:text="@string/bank" />
-			<Spinner
+				android:textSize="20sp" android:text="@string/custom_name"/><EditText
 				android:layout_height="wrap_content"
 				android:layout_width="fill_parent"
-				android:id="@+id/spnBankeditBanklist"></Spinner>
+				android:id="@+id/edtBankeditCustomName" android:inputType="textCapWords"></EditText>
+			
+			
 			<TextView
 				android:layout_width="wrap_content"
 				android:layout_height="wrap_content"
diff --git res/layout/empty.xml res/layout/empty.xml
new file mode 100644
index 0000000..5869ae3
--- /dev/null
+++ res/layout/empty.xml
@@ -0,0 +1 @@
+<LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content"></LinearLayout>
diff --git res/layout/listitem_accounts_item.xml res/layout/listitem_accounts_item.xml
index b880c6c..cbbec0d 100644
--- res/layout/listitem_accounts_item.xml
+++ res/layout/listitem_accounts_item.xml
@@ -3,9 +3,7 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent"
 	android:layout_height="35dp"
-	android:layout_gravity="center_horizontal"
-	android:paddingLeft="15dp"
-	android:paddingRight="10dp">
+	android:layout_gravity="center_horizontal">
 
 	<TextView
 		android:layout_alignParentBottom="true"
@@ -20,7 +18,7 @@
 		android:inputType="none"
 		android:text="Kontonamn"
 		android:textStyle="bold"
-		android:layout_height="fill_parent" />
+		android:layout_height="fill_parent" android:paddingLeft="15dp"/>
 
 
 	<TextView
@@ -29,12 +27,13 @@
 		android:text="00000 SEK"
 		android:layout_width="wrap_content"
 		android:layout_alignParentRight="true"
-		android:textColor="#fff"
 		android:layout_alignParentTop="true"
 		android:id="@+id/txtListitemAccountsItemBalance"
 		android:inputType="none"
 		android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname"
 		android:gravity="right|center_vertical"
-		android:layout_height="fill_parent" />
+		android:layout_height="fill_parent" android:textColor="#fff" android:paddingRight="10dp"/>
+
 
+<RelativeLayout android:layout_width="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:minHeight="1dp" android:layout_height="wrap_content" android:layout_alignWithParentIfMissing="true" android:layout_alignParentTop="false" android:layout_alignParentBottom="true" android:id="@+id/divider"></RelativeLayout>
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/main.xml res/layout/main.xml
index 64e1097..88cd44b 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -25,7 +25,7 @@
 		android:layout_height="wrap_content"
 		android:cacheColorHint="#00000000"
 		android:layout_above="@+id/layMainMenu"
-		android:layout_below="@+id/chkTransperantBackground" android:layout_alignWithParentIfMissing="true"/>
+		android:layout_below="@+id/chkTransperantBackground" android:layout_alignWithParentIfMissing="true" android:dividerHeight="0dp"/>
 	<TableLayout
 		android:stretchColumns="0,2"
 		android:layout_height="wrap_content"
diff --git res/layout/popup_account.xml res/layout/popup_account.xml
new file mode 100644
index 0000000..c09a45b
--- /dev/null
+++ res/layout/popup_account.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_height="wrap_content"
+	android:background="@drawable/popup_bg_down"
+	android:layout_width="fill_parent"
+	android:layout_gravity="fill_horizontal"
+	android:id="@+id/layPopupCont">
+	<Button style="@style/Popup_Button"
+		android:drawableTop="@drawable/button_hide" android:id="@+id/btnHide" android:text="@string/popup_hide"></Button><Button style="@style/Popup_Button"
+		android:drawableTop="@drawable/button_hide" android:id="@+id/btnUnhide" android:text="@string/popup_unhide"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		style="@style/Popup_Button" android:id="@+id/btnDisableNotifications" android:drawableTop="@drawable/button_notification" android:text="@string/popup_disable_notifications"></Button><Button
+		style="@style/Popup_Button" android:drawableTop="@drawable/button_notification" android:id="@+id/btnEnableNotifications" android:text="@string/popup_enable_notifications"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	
+			
+	
+			
+</LinearLayout>
\ No newline at end of file
diff --git res/layout/popup_bank.xml res/layout/popup_bank.xml
new file mode 100644
index 0000000..44e7ebf
--- /dev/null
+++ res/layout/popup_bank.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_height="wrap_content"
+	android:background="@drawable/popup_bg_down"
+	android:layout_width="fill_parent"
+	android:layout_gravity="fill_horizontal"
+	android:id="@+id/layPopupCont">
+	<Button style="@style/Popup_Button"
+		android:id="@+id/btnRefresh"
+		android:drawableTop="@drawable/button_refresh" android:text="@string/popup_refresh"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		android:id="@+id/btnEdit"
+		android:drawableTop="@drawable/button_edit"
+		style="@style/Popup_Button" android:text="@string/popup_edit"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		android:id="@+id/btnWWW"
+		android:drawableTop="@drawable/button_www"
+		style="@style/Popup_Button" android:text="@string/popup_www"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		android:id="@+id/btnRemove"
+		android:drawableTop="@drawable/button_cancel"
+		style="@style/Popup_Button" android:text="@string/popup_remove"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+</LinearLayout>
\ No newline at end of file
diff --git res/menu-sv/menu.xml res/menu-sv/menu.xml
index ccee6c8..eaae083 100644
--- res/menu-sv/menu.xml
+++ res/menu-sv/menu.xml
@@ -10,7 +10,7 @@
 		android:title="Om"
 		android:icon="@android:drawable/ic_menu_info_details" />
 	<item
-		android:id="@+id/exit"
-		android:title="Avsluta"
-		android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+		android:id="@+id/toggle_hidden"
+		android:title="Visa/göm\ngömda konton"
+		android:icon="@drawable/ic_menu_view"/>
 </menu>
\ No newline at end of file
diff --git res/menu/menu.xml res/menu/menu.xml
index 5f3e08b..06de842 100644
--- res/menu/menu.xml
+++ res/menu/menu.xml
@@ -10,7 +10,7 @@
 		android:title="About"
 		android:icon="@android:drawable/ic_menu_info_details" />
 	<item
-		android:id="@+id/exit"
-		android:title="Exit"
-		android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+		android:id="@+id/toggle_hidden"
+		android:title="Show/hide\nhidden accounts"
+		android:icon="@drawable/ic_menu_view"/>
 </menu>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index d4cc561..1cbd894 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -12,14 +12,15 @@
     <string name="could_not_create_account">Kunde ej skapa konto</string>
     <string name="menu_edit">Redigera</string>
     <string name="menu_remove">Radera</string>
-    <string name="invalid_username_password">Personnummer och lösenord stämmer ej.</string>
+    <string name="invalid_username_password">Användarnamn och lösenord stämmer ej.</string>
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="no_accounts_found">Inga konton funna</string>
     <string name="transparent_background">Transparent bakgrund</string>
     
-    <string name="username">Personnummer</string>
+    <string name="username">Användarnamn</string>
     <string name="password">Lösenord</string>
     <string name="bank">Bank</string>
+    <string name="custom_name">Eget Namn (frivilligt)</string>
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
     <string name="cancel">AVBRYT</string>
@@ -57,6 +58,11 @@
     <string name="popup_www">WWW</string>
     <string name="popup_remove">Radera</string>
 
+    <string name="popup_hide">Göm</string>
+    <string name="popup_unhide">Göm ej</string>
+    <string name="popup_enable_notifications">Aktivera notifieringar</string>
+    <string name="popup_disable_notifications">Inaktivera notifieringar</string>
+
     <string name="remove_bank_msg">Är du säker på att du vill ta bort denna bank?</string>
     <string name="remove_bank_title">Radera bank?</string>
     <string name="yes">Ja</string>
diff --git res/values/strings.xml res/values/strings.xml
index 6a2e7e1..d70ed44 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -19,9 +19,11 @@
     
     <string name="username">Username</string>
     <string name="password">Password</string>
+    <string name="custom_name">Custom Name (optional)</string>
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
 
+
     <string name="cancel">CANCEL</string>
     <string name="save">SAVE</string>
     
@@ -57,7 +59,12 @@
     <string name="popup_edit">Edit</string>
     <string name="popup_www">WWW</string>
     <string name="popup_remove">Remove</string>
-    
+
+    <string name="popup_hide">Hide</string>
+    <string name="popup_unhide">Unhide</string>
+    <string name="popup_enable_notifications">Enable notifications</string>
+    <string name="popup_disable_notifications">Disable notifications</string>
+        
     <string name="remove_bank_msg">Are you sure you want to remove this bank?</string>
     <string name="remove_bank_title">Remove bank?</string>
     <string name="yes">Yes</string>
diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
index 20241dd..8f55f7d 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/Account.java
@@ -7,13 +7,18 @@ public class Account {
 	public final static int REGULAR = 1;
 	public final static int FUNDS = 2;
 	public final static int LOANS = 3;
-	public final static int OTHER = 4;
+	public final static int CCARD = 4;
+	public final static int OTHER = 5;
 	
 	private String name;
 	private BigDecimal balance;
 	private String id;
 	private Bank bank = null;
 	private long bankId = -1;
+	private int type = Account.REGULAR;
+	private boolean hidden = false;
+	private boolean notify = true;
+	private String currency;
 	private ArrayList<Transaction> transactions;
 
 	public ArrayList<Transaction> getTransactions() {
@@ -24,18 +29,45 @@ public class Account {
 		this.transactions = transactions;
 	}
 
-	public Account(String name, BigDecimal balance, String id, long bankId) {
+	public Account(String name, BigDecimal balance, String id, long bankId,
+	               int type, String currency) {
 		this.name = name;
 		this.balance = balance;
 		this.id = id;
 		this.bankId = bankId;
+		this.type = type;
+		this.currency = currency;
 	}
 
-	public Account(String name, BigDecimal balance, String id) {
-		this(name, balance, id, -1);
-	}	
+    public Account(String name, BigDecimal balance, String id, long bankId) {
+        this(name, balance, id, bankId, REGULAR, "SEK");
+    }
+    
+	public Account(String name, BigDecimal balance, String id, long bankId, int type) {
+        this(name, balance, id, bankId, type, "SEK");
+    }
+    
+    public Account(String name, BigDecimal balance, String id) {
+        this(name, balance, id, -1L);
+    }
+    
+    public Account(String name, BigDecimal balance, String id, int type) {
+        this(name, balance, id, -1L, type);
+    }	
 
-	public void setBalance(BigDecimal balance) {
+    public Account(String name, BigDecimal balance, String id, int type, String currency) {
+        this(name, balance, id, -1L, type, currency);
+    }
+
+    public boolean isNotify() {
+        return notify;
+    }
+
+    public void setNotify(boolean notify) {
+        this.notify = notify;
+    }
+    
+    public void setBalance(BigDecimal balance) {
 		this.balance = balance;
 	}
 
@@ -62,4 +94,29 @@ public class Account {
 	public long getBankDbId() {
 		return bankId;
 	}
+
+	public void setType(int type) {
+		this.type = type;
+	}
+
+	public int getType() {
+		return type;
+	}
+
+    public boolean isHidden() {
+        return this.hidden;
+    }
+    
+    public void setHidden(boolean hidden) {
+        this.hidden = hidden;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+    
 }
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index 772d1f3..43c831f 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -3,6 +3,8 @@ package com.liato.bankdroid;
 import java.util.ArrayList;
 
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -13,40 +15,59 @@ import android.widget.TextView;
 
 public class AccountsAdapter extends BaseAdapter {
 	public final static int VIEWTYPE_BANK = 0;
-	public final static int VIEWTYPE_ACCOUNT = 1;
-	private ArrayList<Bank> groups;
+    public final static int VIEWTYPE_ACCOUNT = 1;
+    public final static int VIEWTYPE_EMPTY = 2;
+	private ArrayList<Bank> banks;
 	private Context context;
 	private LayoutInflater inflater;
+	private boolean showHidden; 
 
-	public AccountsAdapter(Context context) {
+
+    public AccountsAdapter(Context context, boolean showHidden) {
 		this.context = context;
-		this.groups = new ArrayList<Bank>();
+		this.banks = new ArrayList<Bank>();
 		inflater = LayoutInflater.from(context);
-		
+		this.showHidden = showHidden;
 	}
 
-	public void addGroup(Bank group) {
-		groups.add(group);
+	public void addGroup(Bank bank) {
+		banks.add(bank);
 	}
 	
 	public void setGroups(ArrayList<Bank> banks) {
-		groups = banks;
+		this.banks = banks;
+		/*for (Bank b : this.banks) {
+		    ArrayList<Account> as = b.getAccounts(); 
+		    for (Account a : as) {
+		        if (a.isHidden() && !showHidden) {
+		            as.remove(a);
+		        }
+		            
+		    }
+		}*/
 	}
 
-	public View newGroupView(Bank group, ViewGroup parent, View convertView) {
+    public boolean isShowHidden() {
+        return showHidden;
+    }
+
+    public void setShowHidden(boolean showHidden) {
+        this.showHidden = showHidden;
+    }
+    
+	public View newBankView(Bank bank, ViewGroup parent, View convertView) {
 		if (convertView == null) {
 			convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
 		}
-		//Log.d("Convertview", ""+convertView);
-		//Log.d("Missing view?", ""+convertView.findViewById(R.id.txtListitemAccountsGroupAccountname));
+
 		ImageView icon = (ImageView)convertView.findViewById(R.id.imgListitemAccountsGroup);
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getUsername());
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getName());
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getBalance()));
-		icon.setImageResource(group.getImageResource());
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(bank.getDisplayName());
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(bank.getName());
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(bank.getBalance(), bank.getCurrency()));
+		icon.setImageResource(bank.getImageResource());
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
-		Log.d("AccountsAdapter", ""+group.isDisabled());
-		if (group.isDisabled()) {
+		Log.d("AccountsAdapter", ""+bank.isDisabled());
+		if (bank.isDisabled()) {
 			warning.setVisibility(View.VISIBLE);
 		}
 		else {
@@ -55,22 +76,34 @@ public class AccountsAdapter extends BaseAdapter {
 		return convertView;
 	}
 
-	public View newItemView(Account item, ViewGroup parent, View convertView) {
+	public View newAccountView(Account account, ViewGroup parent, View convertView) {
+        if (account.isHidden() && !showHidden) {
+            return convertView == null ? inflater.inflate(R.layout.empty, parent, false) : convertView;
+        }
 		if (convertView == null) {
 			convertView = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
 		}
-		//Log.d("Convertview", ""+convertView);
-		//Log.d("Missing view?", ""+convertView.findViewById(R.id.txtListitemAccountsItemAccountname));
-		
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsItemAccountname)).setText(item.getName());
-		((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance)).setText(Helpers.formatBalance(item.getBalance()));
+		convertView.findViewById(R.id.divider).setBackgroundColor(Color.argb(60, 255, 255, 255));
+		TextView txtAccountName = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemAccountname));
+        TextView txtBalance = ((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance));
+		txtAccountName.setText(account.getName());
+		txtBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
+		Log.d("ACCADDAPTER", "Account: "+account.getName()+"; hidden: "+account.isHidden());
+		if (account.isHidden()) {
+            txtAccountName.setTextColor(Color.argb(255, 191, 191, 191));
+            txtBalance.setTextColor(Color.argb(255, 191, 191, 191));		    
+		}
+		else {
+            txtAccountName.setTextColor(Color.WHITE);
+            txtBalance.setTextColor(Color.WHITE);            
+		}
 		return convertView;
 	}
 
 	@Override
 	public int getCount() {
 		int c = 0;
-		for(Bank g : groups) {
+		for(Bank g : banks) {
 			c += g.getAccounts().size()+1;
 		}
 		return c;
@@ -78,15 +111,15 @@ public class AccountsAdapter extends BaseAdapter {
 
 	@Override
 	public Object getItem(int position) {
-		if (groups.size() == 0) {
+		if (banks.size() == 0) {
 			return null;
 		}
 		if (position == 0) {
-			return groups.get(0);
+			return banks.get(0);
 		}
 
 		int i = 0;
-		for (Bank g : groups) {
+		for (Bank g : banks) {
 			if (position == i) {
 				return g;
 			}
@@ -111,21 +144,23 @@ public class AccountsAdapter extends BaseAdapter {
 			return null;
 		}
 		if (item instanceof Bank) {
-			return newGroupView((Bank)item, parent, convertView);
+			return newBankView((Bank)item, parent, convertView);
 		}
 		else if (item instanceof Account) {
-			return newItemView((Account)item, parent, convertView);
+			return newAccountView((Account)item, parent, convertView);
 		}
 		return null;
 	}
 
 	public boolean isEnabled(int position) {
-		return true;
+	    if (getItemViewType(position) == VIEWTYPE_EMPTY) return false;
+	    return true;
 	}
+        
 
 	@Override
 	public int getViewTypeCount () {
-		return 2;
+		return 3;
 	}
 
 	@Override
@@ -134,6 +169,11 @@ public class AccountsAdapter extends BaseAdapter {
 		if (item instanceof Bank) {
 			return VIEWTYPE_BANK;
 		}
+		else {
+		    if (((Account)item).isHidden() && !showHidden) {
+		        return VIEWTYPE_EMPTY;
+		    }
+		}
 		return VIEWTYPE_ACCOUNT;
 	}	
 }
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index 57bff0c..e04425d 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -2,7 +2,6 @@ package com.liato.bankdroid;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 
 import android.app.Notification;
@@ -110,9 +109,35 @@ public class AutoRefreshService extends Service {
     						oldAccount = accounts.get(account.getId());
     						if (oldAccount != null) {
     							if (account.getBalance().compareTo(oldAccount.getBalance()) != 0) {
-    								diff = account.getBalance().subtract(oldAccount.getBalance());
-    								showNotification(account.getName()+ ": "+ ((diff.compareTo(new BigDecimal(0)) == 1) ? "+" : "") + Helpers.formatBalance(diff) + " ("+Helpers.formatBalance(account.getBalance())+")",
-    												 bank.getImageResource(), bank.getDisplayName());
+    							    boolean notify = false;
+    							    switch (account.getType()) {
+    							    case Account.REGULAR:
+    							        notify = true;
+    							        break;
+    							    case Account.FUNDS:
+    							        notify = false;
+    							        break;
+    							    case Account.LOANS:
+    							        notify = false;
+    							        break;
+    							    case Account.CCARD:
+    							        notify = true;
+    							        break;
+    							    case Account.OTHER:
+    							        notify = false;
+    							        break;
+    							    }
+    							    if (account.getType() == Account.REGULAR) {
+    							        notify = true;
+    							    }
+    							    if (account.isHidden() || account.isNotify()) {
+    							        notify = false;
+    							    }
+    		                        if (notify) {
+    		                            diff = account.getBalance().subtract(oldAccount.getBalance());
+        								showNotification(account.getName()+ ": "+ ((diff.compareTo(new BigDecimal(0)) == 1) ? "+" : "") + Helpers.formatBalance(diff, account.getCurrency()) + " ("+Helpers.formatBalance(account.getBalance(), account.getCurrency())+")",
+        												 bank.getImageResource(), bank.getDisplayName());
+                                    }
     								refreshWidgets = true;
     							}
     						}
@@ -124,8 +149,9 @@ public class AutoRefreshService extends Service {
     			} 
     			catch (BankException e) {
     				// Refresh widgets if an update fails
-    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; BankException: "+e.getMessage());
     			} catch (LoginException e) {
+                    Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; LoginException: "+e.getMessage());
     				refreshWidgets = true;
     				db.disableBank(bank.getDbId());
 				}
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 109a6f2..8548d3b 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -2,10 +2,10 @@ package com.liato.bankdroid;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.HashMap;
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.util.Log;
 
 import com.liato.urllib.Urllib;
 
@@ -34,14 +34,20 @@ public abstract class Bank implements Comparable<Bank> {
 
 	protected Context context;
 	protected Resources res;
+
+    protected boolean usernameNumeric = false;
+    protected boolean passwordNumeric = false;
+	
 	protected String username;
 	protected String password;
 	protected ArrayList<Account> accounts = new ArrayList<Account>();
+	protected HashMap<String, Account> oldAccounts;
 	protected BigDecimal balance = new BigDecimal(0);
 	protected boolean disabled = false;
 	protected long dbid = -1;
 	protected Urllib urlopen = null;
 	protected String customName;
+	protected String currency = "SEK";
 
 
 	public Urllib getUrlopen() {
@@ -57,7 +63,6 @@ public abstract class Bank implements Comparable<Bank> {
 	}
 
 	public Bank(Context context) {
-		Log.d(TAG, "Constructing bank...");
 		this.context = context;
 		this.res = this.context.getResources();
 	}
@@ -70,6 +75,10 @@ public abstract class Bank implements Comparable<Bank> {
 
 	public void update() throws BankException, LoginException {
 		balance = new BigDecimal(0);
+		oldAccounts = new HashMap<String, Account>();
+		for(Account account: accounts) {
+		    oldAccounts.put(account.getId(), account);
+		}
 		accounts = new ArrayList<Account>();
 	}
 
@@ -104,8 +113,8 @@ public abstract class Bank implements Comparable<Bank> {
 	
 	public void setAccounts(ArrayList<Account> accounts) {
 		this.accounts = accounts;
-		for (Account a : this.accounts) {
-			a.setBank(this);
+		for (Account a : accounts) {
+		    a.setBank(this);
 		}
 	}
 
@@ -135,20 +144,38 @@ public abstract class Bank implements Comparable<Bank> {
 	}
 
 	
-	public String getShortName() {
+	public String getCustomName() {
+        return customName;
+    }
+
+    public void setCustomName(String customName) {
+        this.customName = customName;
+    }
+
+    public String getShortName() {
 		return NAME_SHORT;
 	}
 
 	public void setData(String username, String password, BigDecimal balance,
-			boolean disabled, long dbid) {
+			boolean disabled, long dbid, String currency, String customName) {
 		this.username = username;
 		this.password = password;
 		this.balance = balance;
 		this.disabled = disabled;
 		this.dbid = dbid;
+		this.currency = currency;
+		this.customName = customName;
 	}
 	
-	public long getDbId() {
+	public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public long getDbId() {
 		return dbid;
 	}
 
@@ -187,12 +214,34 @@ public abstract class Bank implements Comparable<Bank> {
 		return URL;
 	}
 	
+    public boolean isUsernameNumeric() {
+        return usernameNumeric;
+    }
+
+    public boolean isPasswordNumeric() {
+        return passwordNumeric;
+    }	
+	
 	public int getImageResource() {
 		return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
 	}
 
 	public int compareTo(Bank another) {
 		return this.toString().compareToIgnoreCase(another.toString());
-	}	
+	}
+
+    public void updateComplete() {
+        for (Account a : this.accounts) {
+            //Preserve hidden and notify settings from old accounts
+            if (oldAccounts != null) {
+                Account oa = oldAccounts.get(a.getId());
+                if (oa != null) {
+                    a.setHidden(oa.isHidden());
+                    a.setNotify(oa.isNotify());
+                }
+            }
+            a.setBank(this);
+        }
+    }	
 	
 }
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/BankEditActivity.java
similarity index 76%
rename from src/com/liato/bankdroid/AccountActivity.java
rename to src/com/liato/bankdroid/BankEditActivity.java
index 03c7b4b..d664475 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/BankEditActivity.java
@@ -4,7 +4,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
@@ -12,6 +11,8 @@ import android.content.DialogInterface;
 import android.content.res.Resources;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.text.InputType;
+import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -24,7 +25,7 @@ import android.widget.Spinner;
 import android.widget.TextView;
 import android.widget.AdapterView.OnItemSelectedListener;
 
-public class AccountActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
+public class BankEditActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private final static String TAG = "AccountActivity";
 	private Bank SELECTED_BANK;
 	private long BANKID = -1;
@@ -51,8 +52,9 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 				Bank bank = BankFactory.bankFromDb(BANKID, this, false);
 				if (bank != null) {
 					((EditText)findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
-					((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
-					
+                    ((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
+                    ((EditText)findViewById(R.id.edtBankeditCustomName)).setText(bank.getCustomName());
+                    
 					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
 					if (bank.isDisabled()) {
 						errorDesc.setVisibility(View.VISIBLE);
@@ -79,7 +81,8 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 		}
 		else if (v.getId() == R.id.btnSettingsOk){
 			SELECTED_BANK.setUsername(((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim());
-			SELECTED_BANK.setPassword(((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+            SELECTED_BANK.setPassword(((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+            SELECTED_BANK.setCustomName(((EditText) findViewById(R.id.edtBankeditCustomName)).getText().toString().trim());
 			SELECTED_BANK.setDbid(BANKID);
 			new DataRetrieverTask(this, SELECTED_BANK).execute();
 		}
@@ -88,7 +91,24 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-		SELECTED_BANK = (Bank) parentView.getItemAtPosition(pos);
+		SELECTED_BANK = (Bank)parentView.getItemAtPosition(pos);
+		if (SELECTED_BANK.isUsernameNumeric()) {
+		    ((EditText) findViewById(R.id.edtBankeditUsername)).setInputType(InputType.TYPE_CLASS_PHONE);
+		}
+		else {
+		    ((EditText) findViewById(R.id.edtBankeditUsername)).setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
+		}
+        
+		/*
+		 * Not possible to set a textfield to both PHONE and PASSWORD :\ 
+
+    		if (SELECTED_BANK.isPasswordNumeric()) {
+                ((EditText) findViewById(R.id.edtBankeditPassword)).setInputType(InputType.TYPE_CLASS_PHONE);
+            }
+            else {
+                ((EditText) findViewById(R.id.edtBankeditPassword)).setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
+            }
+        */
 	}
 
 	@Override
@@ -124,13 +144,13 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 
 	}
 	private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
-		private final ProgressDialog dialog = new ProgressDialog(AccountActivity.this);
+		private final ProgressDialog dialog = new ProgressDialog(BankEditActivity.this);
 		private Exception exc = null;
 		private Bank bank;
-		private AccountActivity context;
+		private BankEditActivity context;
 		private Resources res;
 
-		public DataRetrieverTask(AccountActivity context, Bank bank) {
+		public DataRetrieverTask(BankEditActivity context, Bank bank) {
 			this.context = context;
 			this.res = context.getResources();
 			this.bank = bank;
@@ -164,7 +184,7 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 				this.dialog.dismiss();
 			}
 			if (this.exc != null) {
-				AlertDialog.Builder builder = new AlertDialog.Builder(AccountActivity.this);
+				AlertDialog.Builder builder = new AlertDialog.Builder(BankEditActivity.this);
 				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
 				.setIcon(android.R.drawable.ic_dialog_alert)
 				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 395d84d..ae88cc1 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -93,7 +93,9 @@ public class BankFactory {
 							 password,
 							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
 							 (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
-							 c.getLong(c.getColumnIndex("_id")));
+							 c.getLong(c.getColumnIndex("_id")),
+							 c.getString(c.getColumnIndex("currency")),
+							 c.getString(c.getColumnIndex("custname")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -123,8 +125,20 @@ public class BankFactory {
 			//Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
 			try {
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				bank.setData(c.getString(c.getColumnIndex("username")), c.getString(c.getColumnIndex("password")),
-						new BigDecimal(c.getString(c.getColumnIndex("balance"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
+	            String password = "";
+                try {
+                    password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
+                } catch (Exception e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                bank.setData(c.getString(c.getColumnIndex("username")),
+				             password,
+				             new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+				             (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+				             c.getLong(c.getColumnIndex("_id")),
+				             c.getString(c.getColumnIndex("currency")),
+				             c.getString(c.getColumnIndex("custname")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -147,7 +161,13 @@ public class BankFactory {
 			return null;
 		}
 
-		Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getString(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")).split("_")[1], c.getLong(c.getColumnIndex("bankid")));
+		Account account = new Account(c.getString(c.getColumnIndex("name")),
+                                      new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                                      c.getString(c.getColumnIndex("id")).split("_")[1],
+                                      c.getLong(c.getColumnIndex("bankid")),
+                                      c.getInt(c.getColumnIndex("acctype")));
+        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
+        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);
 		c.close();
 		if (loadTransactions) {
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -156,7 +176,10 @@ public class BankFactory {
 			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
 				while (!c.isLast() && !c.isAfterLast()) {
 					c.moveToNext();
-					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")), c.getString(c.getColumnIndex("btransaction")), new BigDecimal(c.getString(c.getColumnIndex("amount")))));
+					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")),
+                                     c.getString(c.getColumnIndex("btransaction")),
+                                     new BigDecimal(c.getString(c.getColumnIndex("amount"))),
+                                     c.getString(c.getColumnIndex("currency"))));
 				}
 			}
 			account.setTransactions(transactions);
@@ -177,7 +200,13 @@ public class BankFactory {
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
 			c.moveToNext();
-			Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getString(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")).split("_")[1], c.getLong(c.getColumnIndex("bankid")));
+			Account account = new Account(c.getString(c.getColumnIndex("name")),
+                                          new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+                                          c.getString(c.getColumnIndex("id")).split("_")[1],
+                                          c.getLong(c.getColumnIndex("bankid")),
+                                          c.getInt(c.getColumnIndex("acctype")));
+	        account.setHidden(c.getInt(c.getColumnIndex("hidden")) == 1 ? true : false);
+	        account.setNotify(c.getInt(c.getColumnIndex("notify")) == 1 ? true : false);			
 			accounts.add(account);
 		}
 		c.close();
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index b016e5c..0c9cfd9 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -34,13 +34,14 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			int appWidgetId) {
 		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
 		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
+		long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
 		if (accountId == null) {
 			Log.d("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
 		}
 		Log.d("BankdroidWidgetProvider", "Account ID: "+accountId);
-		Account account = BankFactory.accountFromDb(context, accountId, false);
+		Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false);
 		if (account == null) {
 			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
 			return disableAppWidget(context, appWidgetManager,
@@ -80,7 +81,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
 		views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
-		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance()));
+		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency()));
 		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
 		Log.d("Disabled", ""+bank.isDisabled());
 		if (bank.isDisabled()) {
@@ -224,7 +225,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 					Log.d("WidgetService", "Widget not found in db: "+appWidgetId);
 					return null;
 				}
-				String bankId = accountId.split("_")[0];
+				long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId);
 				Bank bank = BankFactory.bankFromDb(new Long(bankId), context, false);
 				if (bank == null) {
 					return null;
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index 9cc060a..53570a1 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -1,6 +1,8 @@
 package com.liato.bankdroid;
 
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 
 import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.ContentValues;
@@ -19,7 +21,7 @@ public class DBAdapter {
     private SQLiteDatabase mDb;
     
     private static final String DATABASE_NAME = "data";
-    private static final int DATABASE_VERSION = 8;
+    private static final int DATABASE_VERSION = 9;
 
     private final Context mCtx;
 
@@ -31,12 +33,30 @@ public class DBAdapter {
 
         @Override
         public void onCreate(SQLiteDatabase db) {
-            db.execSQL("create table banks (_id integer primary key autoincrement, "
-            		+ "balance text not null, "
-                    + "banktype integer not null, username text not null, "
-                    + "password text not null, disabled integer);");
-            db.execSQL("create table accounts (bankid integer not null, id text not null, balance text not null, name text not null);");
-            db.execSQL("create table transactions (_id integer primary key autoincrement, transdate text not null, btransaction text not null, amount text not null, account text not null);");
+            db.execSQL("create table banks (_id integer primary key autoincrement, " +
+            		   "balance text not null, " +
+                       "banktype integer not null, " +
+                       "username text not null, " +
+                       "password text not null, " +
+                       "custname text, " +
+                       "updated text, " +
+                       "sortorder real, " +
+                       "currency text, " +
+                       "disabled integer);");
+            db.execSQL("create table accounts (bankid integer not null, " +
+            		   "id text not null, " +
+                       "balance text not null, " +
+                       "acctype integer not null, " +
+                       "hidden integer not null, " +
+                       "notify integer not null, " +
+                       "currency text, " +
+            		   "name text not null);");
+            db.execSQL("create table transactions (_id integer primary key autoincrement, " +
+            		   "transdate text not null, " +
+            		   "btransaction text not null, " +
+            		   "amount text not null, " +
+            		   "currency text, " +
+            		   "account text not null);");
         }
 
         @Override
@@ -119,7 +139,7 @@ public class DBAdapter {
      * @return Cursor over all banks
      */
     public Cursor fetchBanks() {
-        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled"}, null, null, null, null, "_id asc");
+        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency"}, null, null, null, null, "_id asc");
     }
 
     
@@ -129,34 +149,40 @@ public class DBAdapter {
      * @return Cursor over all accounts belonging to a bank
      */
     public Cursor fetchAccounts(long bankId) {
-        return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id"}, "bankid="+bankId, null, null, null, null);
+        return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id", "acctype", "hidden", "notify", "currency"}, "bankid="+bankId, null, null, null, null);
     }
     
     public Cursor fetchTransactions(String account) {
-        return mDb.query("transactions", new String[] {"transdate", "btransaction", "amount"}, "account='"+account+"'", null, null, null, null);
+        return mDb.query("transactions", new String[] {"transdate", "btransaction", "amount", "currency"}, "account='"+account+"'", null, null, null, null);
     }    
 
     public long updateBank(Bank bank) {
-    	Log.d(TAG, "Updating bank");
+        Calendar cal = Calendar.getInstance();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        
     	ContentValues initialValues = new ContentValues();
         initialValues.put("banktype", bank.getBanktypeId());
         initialValues.put("username", bank.getUsername());
+        String password = "";
         try {
-			initialValues.put("password", SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword()));
+            password = SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword());
 		} catch (Exception e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
+        initialValues.put("password", password);
         initialValues.put("disabled", 0);
         initialValues.put("balance", bank.getBalance().toPlainString());
+        initialValues.put("currency", bank.getCurrency());
+        initialValues.put("custname", bank.getCustomName());
+        initialValues.put("updated", sdf.format(cal.getTime()));
+        
         long bankId = bank.getDbId();
-        Log.d(TAG, "Bankid: "+bankId);
+        Log.d(TAG, "Updating bank, DbId: "+bankId);
         if (bankId == -1) {
-            Log.d(TAG, "Inserting new bank");
         	bankId = mDb.insert("banks", null, initialValues);
         }
         else {
-            Log.d(TAG, "Updating existing bank");
         	mDb.update("banks", initialValues, "_id="+bankId, null);
             deleteAccounts(bankId);
         }
@@ -167,8 +193,13 @@ public class DBAdapter {
 	            ContentValues vals = new ContentValues();
 	            vals.put("bankid", bankId);
 	            vals.put("balance", acc.getBalance().toPlainString());
-	            vals.put("name", acc.getName());
+                vals.put("name", acc.getName());
 	            vals.put("id", new Long(bankId).toString()+"_"+acc.getId());
+                vals.put("hidden", acc.isHidden() ? 1 : 0);
+                vals.put("notify", acc.isNotify() ? 1 : 0);
+                vals.put("currency", acc.getCurrency());
+                vals.put("acctype", acc.getType());
+                Log.d(TAG, "Acctype: "+acc.getType());
 	            mDb.insert("accounts", null, vals);
 	            ArrayList<Transaction> transactions = acc.getTransactions();
 	            if (transactions != null && !transactions.isEmpty()) {
@@ -179,6 +210,8 @@ public class DBAdapter {
 			            transvals.put("btransaction", transaction.getTransaction());
 			            transvals.put("amount", transaction.getAmount().toPlainString());
 			            transvals.put("account", new Long(bankId).toString()+"_"+acc.getId());
+			            transvals.put("currency", transaction.getCurrency());
+			            
 			            mDb.insert("transactions", null, transvals);
 		            }
 	            }
@@ -196,7 +229,7 @@ public class DBAdapter {
     }
     
     public Cursor getBank(String bankId) {
-    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled"}, "_id="+bankId, null, null, null, null);
+    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled", "custname", "updated", "sortorder", "currency"}, "_id="+bankId, null, null, null, null);
     	if (c != null) {
     		c.moveToFirst();
     	}
@@ -208,7 +241,7 @@ public class DBAdapter {
     }
 
     public Cursor getAccount(String id) {
-    	Cursor c = mDb.query("accounts", new String[] {"id", "balance", "name", "bankid"}, "id='"+id+"'", null, null, null, null);
+    	Cursor c = mDb.query("accounts", new String[] {"id", "balance", "name", "bankid", "acctype", "hidden", "notify", "currency"}, "id='"+id+"'", null, null, null, null);
     	if (c != null) {
     		c.moveToFirst();
     	}
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index e952f36..bbf3c85 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -26,15 +26,15 @@ public class Helpers {
 		}
 		return ret;
 	}
-	public static String formatBalance(BigDecimal balance) {
+	public static String formatBalance(BigDecimal balance, String curr) {
 		DecimalFormatSymbols dfs = new DecimalFormatSymbols();
 		dfs.setDecimalSeparator(',');
 		dfs.setGroupingSeparator(' ');
-		DecimalFormat currency = new DecimalFormat("#,##0.00 SEK");
+		DecimalFormat currency = new DecimalFormat("#,##0.00 ");
 		currency.setDecimalFormatSymbols(dfs);
-		return currency.format(balance.doubleValue());
+		return currency.format(balance.doubleValue())+curr;
 	}
-	public static String formatBalance(Double balance) {
-		return formatBalance(new BigDecimal(balance));
+	public static String formatBalance(Double balance, String curr) {
+		return formatBalance(new BigDecimal(balance), curr);
 	}
 }
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 5ad3af2..96c7c66 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -27,11 +27,14 @@ import android.widget.Button;
 import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
 
 public class MainActivity extends LockableActivity {
 	private final static String TAG = "MainActivity";
 	protected AccountsAdapter adapter = null;
-	private static Bank selected_bank = null;
+    private static Bank selected_bank = null;
+    private static Account selected_account = null;
+    protected static boolean showHidden = false;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
@@ -47,31 +50,46 @@ public class MainActivity extends LockableActivity {
 		Button btnAddBank = (Button)findViewById(R.id.btnAddBank);
 		btnAddBank.setOnClickListener(new View.OnClickListener() {
 			public void onClick(View v) {
-				Intent intentAccount = new Intent(MainActivity.this, AccountActivity.class);
+				Intent intentAccount = new Intent(MainActivity.this, BankEditActivity.class);
 				startActivity(intentAccount);
 			}
 		});
 
 		ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-		adapter = new AccountsAdapter(this);
+		adapter = new AccountsAdapter(this, showHidden);
 		ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
 		adapter.setGroups(banks);
 		lv.setAdapter(adapter);
+		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
+            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+                Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
+                if (adapter.getItem(position) instanceof Account) {
+                    selected_account = (Account)adapter.getItem(position);
+                    PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
+                    pmenu.setContentView(R.layout.popup_account);
+                    pmenu.showLikeQuickAction(0, 12);
+                    return true;
+                }
+                return true;
+            }
+        });
 		lv.setOnItemClickListener(new OnItemClickListener() {
 			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-				//view.showContextMenu();
 				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
 				if (adapter.getItem(position) instanceof Bank) {
 					selected_bank = (Bank) adapter.getItem(position);
-					PopupMenu pmenu = new PopupMenu(view, MainActivity.this);
+					PopupMenuBank pmenu = new PopupMenuBank(view, MainActivity.this);
 					pmenu.showLikeQuickAction(0, 12);					
 				}
 				else {
-					Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
+					/*Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
 					Account account = (Account) adapter.getItem(position);
 					intent.putExtra("account", account.getId());
 					intent.putExtra("bank", account.getBankDbId());
-					MainActivity.this.startActivity(intent);
+					MainActivity.this.startActivity(intent);*/
+                    selected_account = (Account) adapter.getItem(position);
+                    PopupMenuAccount pmenu = new PopupMenuAccount(view, MainActivity.this);
+                    pmenu.showLikeQuickAction(0, 12);   				    
 				}
 			}
 		});
@@ -102,6 +120,7 @@ public class MainActivity extends LockableActivity {
 			//findViewById(R.id.btnAccountsRefresh).setClickable(false);
 		}
 
+		adapter.setShowHidden(showHidden);
 		adapter.setGroups(banks);
 		adapter.notifyDataSetChanged();
 	}
@@ -135,8 +154,9 @@ public class MainActivity extends LockableActivity {
 	public boolean onOptionsItemSelected (MenuItem item){
 		Intent intent;
 		switch (item.getItemId()) {
-		case R.id.exit:
-			this.finish();
+		case R.id.toggle_hidden:
+		    showHidden = !showHidden;
+		    refreshView();
 			return true;
 		case R.id.settings:
 			intent = new Intent(this, SettingsActivity.class);
@@ -151,6 +171,7 @@ public class MainActivity extends LockableActivity {
 
 	public void onDestroy() {
 		super.onDestroy();
+		unregisterReceiver(receiver);  
 	}
 
 	/**
@@ -161,9 +182,9 @@ public class MainActivity extends LockableActivity {
 	 * @author qbert
 	 * 
 	 */
-	private static class PopupMenu extends BetterPopupWindow implements OnClickListener {
+	private static class PopupMenuBank extends BetterPopupWindow implements OnClickListener {
 		MainActivity parent = null;
-		public PopupMenu(View anchor, MainActivity parent) {
+		public PopupMenuBank(View anchor, MainActivity parent) {
 			super(anchor);
 			this.parent = parent;
 		}
@@ -174,7 +195,7 @@ public class MainActivity extends LockableActivity {
 			LayoutInflater inflater =
 				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-			ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup, null);
+			ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_bank, null);
 			root.findViewById(R.id.btnRefresh).setOnClickListener(this);
 			root.findViewById(R.id.btnWWW).setOnClickListener(this);
 			root.findViewById(R.id.btnEdit).setOnClickListener(this);
@@ -198,7 +219,7 @@ public class MainActivity extends LockableActivity {
 				this.dismiss();
 				return; 
 			case R.id.btnEdit:
-				Intent intent = new Intent(context, AccountActivity.class);
+				Intent intent = new Intent(context, BankEditActivity.class);
 				intent.putExtra("id", selected_bank.getDbId());
 				context.startActivity(intent);
 				this.dismiss();
@@ -235,5 +256,92 @@ public class MainActivity extends LockableActivity {
 
 		}
 	}
+	
+	
+    /**
+     * Extends {@link BetterPopupWindow}
+     * <p>
+     * Overrides onCreate to create the view and register the button listeners
+     * 
+     * @author qbert
+     * 
+     */
+    private static class PopupMenuAccount extends BetterPopupWindow implements OnClickListener {
+        MainActivity parent = null;
+        public PopupMenuAccount(View anchor, MainActivity parent) {
+            super(anchor);
+            this.parent = parent;
+        }
+
+        @Override
+        protected void onCreate() {
+            Log.d(TAG, "PopUpMenuAcc, oncreate");
+            // inflate layout
+            LayoutInflater inflater =
+                (LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup_account, null);
+            Button btnHide = (Button) root.findViewById(R.id.btnHide);
+            Button btnUnhide = (Button)root.findViewById(R.id.btnUnhide);
+            Button btnDisableNotifications = (Button)root.findViewById(R.id.btnDisableNotifications);
+            Button btnEnableNotifications = (Button)root.findViewById(R.id.btnEnableNotifications);
+            if (selected_account.isHidden()) {
+                btnHide.setVisibility(View.GONE);
+                btnUnhide.setVisibility(View.VISIBLE);
+                btnUnhide.setOnClickListener(this);
+            }
+            else {
+                btnHide.setVisibility(View.VISIBLE);
+                btnUnhide.setVisibility(View.GONE);
+                btnHide.setOnClickListener(this);
+            }
+            if (selected_account.isNotify()) {
+                btnDisableNotifications.setVisibility(View.VISIBLE);
+                btnDisableNotifications.setOnClickListener(this);
+                btnEnableNotifications.setVisibility(View.GONE);
+            }
+            else {
+                btnDisableNotifications.setVisibility(View.GONE);
+                btnEnableNotifications.setOnClickListener(this);
+                btnEnableNotifications.setVisibility(View.VISIBLE);
+            }            
+            this.setContentView(root);
+        }
+
+        @Override
+        public void onClick(View v) {
+            final Context context = this.anchor.getContext();
+            Log.d(TAG, "CLICK!");
+            int id = v.getId();
+            switch (id) {
+            case R.id.btnHide:
+                this.dismiss();
+                selected_account.setHidden(true);
+                selected_account.getBank().save();
+                parent.refreshView();
+                return; 
+            case R.id.btnUnhide:
+                this.dismiss();
+                selected_account.setHidden(false);
+                selected_account.getBank().save();
+                parent.refreshView();
+                return; 
+            case R.id.btnEnableNotifications:
+                this.dismiss();
+                selected_account.setNotify(true);
+                selected_account.getBank().save();
+                parent.refreshView();
+                return; 
+            case R.id.btnDisableNotifications:
+                this.dismiss();
+                selected_account.setNotify(false);
+                selected_account.getBank().save();
+                parent.refreshView();
+                return; 
+
+            }
+
+        }
+    }	
 
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 5f00200..d1a0e97 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -31,7 +31,7 @@ public class StartupReceiver extends BroadcastReceiver{
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*60*1000, refreshrate*60*1000, alarmSender);
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*1000, refreshrate*1000, alarmSender);
         	Log.d("StartupReceiever.SetAlarm","Alarm set to "+refreshrate.toString()+" minutes.");
         }
 	
diff --git src/com/liato/bankdroid/Transaction.java src/com/liato/bankdroid/Transaction.java
index 59be14f..6a5535e 100644
--- src/com/liato/bankdroid/Transaction.java
+++ src/com/liato/bankdroid/Transaction.java
@@ -6,13 +6,19 @@ public class Transaction implements Comparable<Transaction> {
 	private String date;
 	private String transaction;
 	private BigDecimal amount;
+	private String currency;
 	
-	public Transaction(String date, String transaction, BigDecimal amount) {
+	public Transaction(String date, String transaction, BigDecimal amount, String currency) {
 		this.date = date;
 		this.transaction = transaction;
 		this.amount = amount;
+		this.currency = currency;
 	}
 
+    public Transaction(String date, String transaction, BigDecimal amount) {
+        this(date, transaction, amount, "SEK");
+    }	
+
 	public String getDate() {
 		return date;
 	}
@@ -37,7 +43,15 @@ public class Transaction implements Comparable<Transaction> {
 		this.amount = amount;
 	}
 
-	@Override
+	public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    @Override
 	public int compareTo(Transaction another) {
 		Integer thisdate = Integer.parseInt(date.replaceAll("-", ""));
 		Integer thatdate = Integer.parseInt((another).getDate().replaceAll("-", ""));
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index ccef5a7..171d4a3 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -28,9 +28,9 @@ public class TransactionsActivity extends LockableActivity {
 		TextView viewAccountBalance = (TextView)findViewById(R.id.txtListitemAccountsGroupTotal);
 		ListView viewTransactionsList = (ListView)findViewById(R.id.lstTransactionsList);
 		ImageView icon = (ImageView)findViewById(R.id.imgListitemAccountsGroup);
-		viewBankName.setText(bank.getUsername());
+		viewBankName.setText(bank.getDisplayName());
 		viewAccountName.setText(account.getName());
-		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance()));
+		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance(), account.getCurrency()));
 		icon.setImageResource(bank.getImageResource());
 		ArrayList<Transaction> transactions = account.getTransactions();
 		Log.d(TAG, "Transactions: "+transactions.size());
@@ -71,7 +71,7 @@ public class TransactionsActivity extends LockableActivity {
 				convertView = inflater.inflate(R.layout.transaction_item, parent, false);
 			}
 			((TextView)convertView.findViewById(R.id.txtTransaction)).setText(transaction.getTransaction());
-			((TextView)convertView.findViewById(R.id.txtAmount)).setText(Helpers.formatBalance(transaction.getAmount()));
+			((TextView)convertView.findViewById(R.id.txtAmount)).setText(Helpers.formatBalance(transaction.getAmount(), transaction.getCurrency()));
 			if (transaction.getAmount().signum() == 1) {
 				((ImageView)convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_positive);
 			}
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index 7a7a48d..2ad198e 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -71,7 +71,8 @@ public class WidgetConfigureActivity extends Activity {
 				if (adapter.getItemViewType(position) != AccountsAdapter.VIEWTYPE_ACCOUNT) return;
 				final Context context = WidgetConfigureActivity.this;
 	            Account account = (Account)parent.getItemAtPosition(position);
-	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, account.getId());
+	            Bank bank = account.getBank();
+	            WidgetConfigureActivity.setAccountBankId(context, mAppWidgetId, account.getId(), bank.getDbId());
 	            SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
 	            prefs.putBoolean("transperant_background" + mAppWidgetId, ((CheckBox)findViewById(R.id.chkTransperantBackground)).isChecked());
 	            prefs.commit();	            
@@ -95,20 +96,27 @@ public class WidgetConfigureActivity extends Activity {
 //		refreshView();
 //	}
 	
-	public static String getAccountId(Context context, int appWidgetId) {
-		SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
-		return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
-	}
-
-	public static void setAccountId(Context context, int appWidgetId, String value) {
+	public static void setAccountBankId(Context context, int appWidgetId, String accountId, long bankId) {
         SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-        prefs.putString(WIDGET_PREFIX + appWidgetId, value);
+        prefs.putString(WIDGET_PREFIX + appWidgetId, accountId);
+        prefs.putLong(WIDGET_PREFIX + appWidgetId + "_bankid", bankId);
         prefs.commit();
 	}
 
+    public static String getAccountId(Context context, int appWidgetId) {
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
+        return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
+    }
+
+    public static long getBankId(Context context, int appWidgetId) {
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
+        return prefs.getLong(WIDGET_PREFIX + appWidgetId + "_bankid", -1);
+    }
+	
 	public static void delAccountId(Context context, int appWidgetId) {
         SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
         prefs.remove(WIDGET_PREFIX + appWidgetId);
+        prefs.remove(WIDGET_PREFIX + appWidgetId + "_bankid");
         prefs.commit();
 	}
 	
@@ -120,7 +128,7 @@ public class WidgetConfigureActivity extends Activity {
 			findViewById(R.id.chkTransperantBackground).setVisibility(View.VISIBLE);
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
 			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-			adapter = new AccountsAdapter(this);
+			adapter = new AccountsAdapter(this, false);
 			adapter.setGroups(banks);
 			lv.setAdapter(adapter);
 		}
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 18c8bd7..2301d20 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -100,6 +100,9 @@ public class Avanza extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banks/AvanzaMini.java
index 4d6f748..c20579f 100644
--- src/com/liato/bankdroid/banks/AvanzaMini.java
+++ src/com/liato/bankdroid/banks/AvanzaMini.java
@@ -100,5 +100,8 @@ public class AvanzaMini extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index dd0447e..c701f90 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -134,5 +134,8 @@ public class Coop extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 663d3de..2e9e0f1 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -93,6 +93,7 @@ public class Eurocard extends Bank {
 		if (accounts.isEmpty()) {
 			throw new BankException(res.getText(R.string.no_accounts_found).toString());
 		}
+        super.updateComplete();
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
index 17f61f2..9475220 100644
--- src/com/liato/bankdroid/banks/FirstCard.java
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -108,7 +108,9 @@ public class FirstCard extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-
+        finally {
+            super.updateComplete();
+        }
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 78864f0..23426ec 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -132,6 +132,9 @@ public class Handelsbanken extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 	
 
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banks/ICA.java
index 8dc5dd9..6f1a34f 100644
--- src/com/liato/bankdroid/banks/ICA.java
+++ src/com/liato/bankdroid/banks/ICA.java
@@ -122,5 +122,8 @@ public class ICA extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 }
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index 65dc3de..e16c012 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -149,5 +149,8 @@ public class ICABanken extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
+        finally {
+            super.updateComplete();
+        }
 	}		
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index 93ae24e..6ac50fe 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -138,5 +138,8 @@ public class Lansforsakringar extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index a65d40c..cfb76c9 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -185,5 +185,8 @@ public class OKQ8 extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}		
+        finally {
+            super.updateComplete();
+        }
 	}
 }
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index 06c56ed..24633cc 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -102,7 +102,9 @@ public class Statoil extends Bank {
 				 * 1: amount			10 579,43
 				 * 
 				 */
-				accounts.add(new Account("Statoil MasterCard" , Helpers.parseBalance(matcher.group(1)), "1"));
+			    Account account = new Account("Statoil MasterCard" , Helpers.parseBalance(matcher.group(1)), "1");
+			    account.setType(Account.CCARD);
+				accounts.add(account);
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 			}
 			if (accounts.isEmpty()) {
@@ -115,6 +117,9 @@ public class Statoil extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 	
 	@Override
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 678f5f5..f339975 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -41,6 +41,7 @@ public class Swedbank extends Bank {
 		super.NAME_SHORT = NAME_SHORT;
 		super.BANKTYPE_ID = BANKTYPE_ID;
 		super.URL = URL;
+        super.usernameNumeric = true;
 	}
 
 	public Swedbank(String username, String password, Context context) throws BankException, LoginException {
@@ -63,6 +64,7 @@ public class Swedbank extends Bank {
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			postData.add(new BasicNameValuePair("xyz", username));
 			postData.add(new BasicNameValuePair("zyx", password));
+			Log.d(TAG, "user: "+username+"; pass: "+password);
 			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
 
@@ -93,15 +95,23 @@ public class Swedbank extends Bank {
 			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l"+matcher.group(2).trim() : matcher.group(2).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+				Account account = new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "loan_" + matcher.group(2).trim() : matcher.group(2).trim());
+				if (matcher.group(2).trim() == "loan") {
+				    account.setType(Account.LOANS);
+				}
+				else {
+				    balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+				}
+				accounts.add(account);
 			}
 			matcher = reLinklessAccounts.matcher(response);
 			int accid = 0;
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll"+accid));
+				Account account = new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll_"+accid);
 				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-				accid++;
+				account.setType(Account.OTHER);
+                accounts.add(account);
+                accid++;
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -116,12 +126,15 @@ public class Swedbank extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+		finally {
+	      super.updateComplete();
+		}
 	}
 	
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getId().startsWith("l")) return; //No transaction history for loans
+		if (account.getType() == Account.LOANS || account.getType() == Account.OTHER) return; //No transaction history for loans
 
 		String response = null;
 		Matcher matcher;
diff --git src/com/liato/bankdroid/banks/Villabanken.java src/com/liato/bankdroid/banks/Villabanken.java
index 127ae09..4442a61 100644
--- src/com/liato/bankdroid/banks/Villabanken.java
+++ src/com/liato/bankdroid/banks/Villabanken.java
@@ -155,5 +155,8 @@ public class Villabanken extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
+        finally {
+            super.updateComplete();
+        }
 	}
 }
\ No newline at end of file

commit b1bd2405c5ceb1caf490366b8f66784310fa504b
Author: liato <x@x00.us>
Date:   Sun Oct 31 01:26:06 2010 +0200

    Encrypt passwords before storing them in the database.

diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 870443d..395d84d 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -3,6 +3,8 @@ package com.liato.bankdroid;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
+
 import android.content.Context;
 import android.database.Cursor;
 
@@ -79,8 +81,19 @@ public class BankFactory {
 		if (c != null) {
 			try {
 				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
-				bank.setData(c.getString(c.getColumnIndex("username")), c.getString(c.getColumnIndex("password")),
-						new BigDecimal(c.getString(c.getColumnIndex("balance"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
+				String password = "";
+				try {
+					password = SimpleCrypto.decrypt(Crypto.getKey(), c.getString(c.getColumnIndex("password")));
+				} catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				
+				bank.setData(c.getString(c.getColumnIndex("username")),
+							 password,
+							 new BigDecimal(c.getString(c.getColumnIndex("balance"))),
+							 (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true),
+							 c.getLong(c.getColumnIndex("_id")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index fd2a013..9cc060a 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -1,7 +1,8 @@
 package com.liato.bankdroid;
 
-import java.math.BigDecimal;
 import java.util.ArrayList;
+
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
@@ -140,7 +141,12 @@ public class DBAdapter {
     	ContentValues initialValues = new ContentValues();
         initialValues.put("banktype", bank.getBanktypeId());
         initialValues.put("username", bank.getUsername());
-        initialValues.put("password", bank.getPassword());
+        try {
+			initialValues.put("password", SimpleCrypto.encrypt(Crypto.getKey(), bank.getPassword()));
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
         initialValues.put("disabled", 0);
         initialValues.put("balance", bank.getBalance().toPlainString());
         long bankId = bank.getDbId();
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index c2f767c..ccef5a7 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -22,7 +22,7 @@ public class TransactionsActivity extends LockableActivity {
 		setContentView(R.layout.transactions);
 		Bundle extras = getIntent().getExtras();
 		Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
-		Account account = BankFactory.accountFromDb(this, extras.getString("account"), true);
+		Account account = BankFactory.accountFromDb(this, extras.getLong("bank")+"_"+extras.getString("account"), true);
 		TextView viewBankName = (TextView)findViewById(R.id.txtListitemAccountsGroupAccountname);
 		TextView viewAccountName = (TextView)findViewById(R.id.txtListitemAccountsGroupBankname);
 		TextView viewAccountBalance = (TextView)findViewById(R.id.txtListitemAccountsGroupTotal);

commit 78757c566936b5b5745e86ac06746f8160484cac
Author: liato <x@x00.us>
Date:   Sat Oct 30 17:29:31 2010 +0200

    Notifications show changes per account insted of per bank, closes #7. Refresh the main screen if autorefreshservice detects a change. New vibration pattern. Store all BigDecimals as text in the databse to prevent floating point accuracy problems.

diff --git AndroidManifest.xml AndroidManifest.xml
index 4b763d0..2ddced1 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -48,6 +48,8 @@
 		<receiver android:name="StartupReceiver">
 			<intent-filter>
 				<action android:name="android.intent.action.BOOT_COMPLETED" />
+                <action android:name="android.intent.action.PACKAGE_ADDED"></action> 
+                <action android:name="android.intent.action.PACKAGE_CHANGED"></action> 
 				<action android:name="android.intent.action.PACKAGE_REPLACED" />
 				<data android:scheme="package" android:path="com.liato.bankdroid" />
 			</intent-filter>
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index 1e74862..57bff0c 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -1,6 +1,9 @@
 package com.liato.bankdroid;
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -18,7 +21,8 @@ import android.util.Log;
 
 public class AutoRefreshService extends Service {
 	private final static String TAG = "AutoRefreshService";
-	final static String WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
+	final static String BROADCAST_WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
+	final static String BROADCAST_MAIN_REFRESH = "com.liato.bankdroid.MAIN_REFRESH";
     NotificationManager notificationManager;
 
     @Override
@@ -37,26 +41,29 @@ public class AutoRefreshService extends Service {
         return null;
     }
 
-    private void showNotification(String text) {
+    private void showNotification(String text, int icon, String title) {
     	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		if (!prefs.getBoolean("notify_on_change", true)) return;
 		
-        Notification notification = new Notification(R.drawable.icon, text,
+        Notification notification = new Notification(icon, text,
                 System.currentTimeMillis());
         notification.flags |= Notification.FLAG_AUTO_CANCEL;
 		if (prefs.getBoolean("notify_with_sound", true)) {
+			//http://www.freesound.org/samplesViewSingle.php?id=91924
+			//http://www.freesound.org/samplesViewSingle.php?id=75235
 	        notification.defaults |= Notification.DEFAULT_SOUND;
 		}
 		if (prefs.getBoolean("notify_with_vibration", true)) {
 			//long[] vib = {23,28,27,143,20,30,26,364,22,26,28,26,28,26,28,26,29,25,27,27,27,27,28,28,28,28,28,27,27,26,27};
 			//long[] vib = {46, 56, 54, 286, 40, 60, 52, 728, 44, 52, 56, 52, 56, 52, 56, 52, 58, 50, 54, 54, 54, 54, 56, 56, 56, 56, 56, 54, 54, 52, 54};
-			//notification.vibrate = vib;
-			notification.defaults |= Notification.DEFAULT_VIBRATE;
+			long[] vib = {0, 90, 130, 80, 350, 190, 20, 380};
+			notification.vibrate = vib;
+			//notification.defaults |= Notification.DEFAULT_VIBRATE;
 		}
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                 new Intent(this, MainActivity.class), 0);
 
-        notification.setLatestEventInfo(this,  this.getString(R.string.app_name), text, contentIntent);
+        notification.setLatestEventInfo(this, title, text, contentIntent);
 
         notificationManager.notify(R.id.about, notification);
     }
@@ -71,31 +78,45 @@ public class AutoRefreshService extends Service {
     	}
 
     	protected Void doInBackground(final String... args) {
-    		Log.d("doinback", "round");
     		errors = new ArrayList<String>();
     		Boolean refreshWidgets = false;
-    		ArrayList<Bank> banks = BankFactory.banksFromDb(AutoRefreshService.this, false);
+    		ArrayList<Bank> banks = BankFactory.banksFromDb(AutoRefreshService.this, true);
     		if (banks.isEmpty()) {
     			return null;
     		}
     		DBAdapter db = new DBAdapter(AutoRefreshService.this);
     		db.open();    		
-    		Double currentBalance;
-    		Double diff;
+    		BigDecimal currentBalance;
+    		BigDecimal diff;
+    		HashMap<String, Account> accounts = new HashMap<String, Account>();
     		
     		for (Bank bank : banks) {
     			if (bank.isDisabled()) {
-    				Log.d("AA", bank.getName()+" ("+bank.getUsername()+") is disabled. Skipping refresh.");
+    				Log.d(TAG, bank.getName()+" ("+bank.getDisplayName()+") is disabled. Skipping refresh.");
     				continue;
     			}
-				Log.d("AA", "Refreshing "+bank.getName()+" ("+bank.getUsername()+").");
+				Log.d(TAG, "Refreshing "+bank.getName()+" ("+bank.getDisplayName()+").");
     			try {
-    				currentBalance = bank.getBalance().doubleValue();
+    				currentBalance = bank.getBalance();
+    				accounts.clear();
+    				for(Account account : bank.getAccounts()) {
+    					accounts.put(account.getId(), account);
+    				}
     				bank.update();
-					diff =  bank.getBalance().doubleValue() - currentBalance;
-    				if (diff != 0) {
-    					showNotification(bank.getName()+ ": "+ ((diff > 0) ? "+" : "") + Helpers.formatBalance(diff) + " ("+Helpers.formatBalance(bank.getBalance())+")");
-    					refreshWidgets = true;
+					diff = currentBalance.subtract(bank.getBalance());
+    				if (diff.compareTo(new BigDecimal(0)) != 0) {
+    					Account oldAccount;
+    					for(Account account : bank.getAccounts()) {
+    						oldAccount = accounts.get(account.getId());
+    						if (oldAccount != null) {
+    							if (account.getBalance().compareTo(oldAccount.getBalance()) != 0) {
+    								diff = account.getBalance().subtract(oldAccount.getBalance());
+    								showNotification(account.getName()+ ": "+ ((diff.compareTo(new BigDecimal(0)) == 1) ? "+" : "") + Helpers.formatBalance(diff) + " ("+Helpers.formatBalance(account.getBalance())+")",
+    												 bank.getImageResource(), bank.getDisplayName());
+    								refreshWidgets = true;
+    							}
+    						}
+    					}
     					bank.updateAllTransactions();
     				}
     				bank.closeConnection();
@@ -111,6 +132,8 @@ public class AutoRefreshService extends Service {
     		}
     		
 			if (refreshWidgets) {
+				Intent updateIntent = new Intent(BROADCAST_MAIN_REFRESH);
+				sendBroadcast(updateIntent);
 				sendWidgetRefresh(AutoRefreshService.this);
 			}
     		db.close();
@@ -137,7 +160,7 @@ public class AutoRefreshService extends Service {
     
     public static void sendWidgetRefresh(Context context) {
     	//Send intent to BankdroidWidgetProvider
-        Intent updateIntent = new Intent(WIDGET_REFRESH);
+        Intent updateIntent = new Intent(BROADCAST_WIDGET_REFRESH);
         PendingIntent pendingIntent = PendingIntent.getBroadcast(
         		context, 0, updateIntent,
                 PendingIntent.FLAG_UPDATE_CURRENT);
@@ -148,5 +171,4 @@ public class AutoRefreshService extends Service {
 				Log.e("", e.getMessage(), e);
 			}
     }    
-    
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 59e212b..109a6f2 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -41,6 +41,7 @@ public abstract class Bank implements Comparable<Bank> {
 	protected boolean disabled = false;
 	protected long dbid = -1;
 	protected Urllib urlopen = null;
+	protected String customName;
 
 
 	public Urllib getUrlopen() {
@@ -128,6 +129,12 @@ public abstract class Bank implements Comparable<Bank> {
 		return NAME;
 	}
 
+	public String getDisplayName() {
+		if (customName != null && customName.length() > 0) return customName;
+		return username;
+	}
+
+	
 	public String getShortName() {
 		return NAME_SHORT;
 	}
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 852391e..870443d 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -80,7 +80,7 @@ public class BankFactory {
 			try {
 				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
 				bank.setData(c.getString(c.getColumnIndex("username")), c.getString(c.getColumnIndex("password")),
-						new BigDecimal(c.getDouble(c.getColumnIndex("username"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
+						new BigDecimal(c.getString(c.getColumnIndex("balance"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -111,7 +111,7 @@ public class BankFactory {
 			try {
 				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
 				bank.setData(c.getString(c.getColumnIndex("username")), c.getString(c.getColumnIndex("password")),
-						new BigDecimal(c.getDouble(c.getColumnIndex("balance"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
+						new BigDecimal(c.getString(c.getColumnIndex("balance"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
 				if (loadAccounts) {
 					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
 				}
@@ -134,7 +134,7 @@ public class BankFactory {
 			return null;
 		}
 
-		Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getDouble(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")), c.getLong(c.getColumnIndex("bankid")));
+		Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getString(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")).split("_")[1], c.getLong(c.getColumnIndex("bankid")));
 		c.close();
 		if (loadTransactions) {
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
@@ -143,7 +143,7 @@ public class BankFactory {
 			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
 				while (!c.isLast() && !c.isAfterLast()) {
 					c.moveToNext();
-					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")), c.getString(c.getColumnIndex("btransaction")), new BigDecimal(c.getDouble(c.getColumnIndex("amount")))));
+					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")), c.getString(c.getColumnIndex("btransaction")), new BigDecimal(c.getString(c.getColumnIndex("amount")))));
 				}
 			}
 			account.setTransactions(transactions);
@@ -164,7 +164,7 @@ public class BankFactory {
 		}
 		while (!c.isLast() && !c.isAfterLast()) {
 			c.moveToNext();
-			Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getDouble(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")), c.getLong(c.getColumnIndex("bankid")));
+			Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getString(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")).split("_")[1], c.getLong(c.getColumnIndex("bankid")));
 			accounts.add(account);
 		}
 		c.close();
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 7256e5d..b016e5c 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -99,7 +99,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent);
 		
 		intent = new Intent(context, WidgetService.class);
-		intent.setAction(AutoRefreshService.WIDGET_REFRESH);
+		intent.setAction(AutoRefreshService.BROADCAST_WIDGET_REFRESH);
 		intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
 		intent.setData(Uri.parse("rofl://copter/"+appWidgetId+"/"+System.currentTimeMillis()));
 		pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
@@ -156,7 +156,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 
 		Log.d("BankdroidWidgetProvider", "intent=" + intent+"; action="+action);
-		if (action.equals(AutoRefreshService.WIDGET_REFRESH) || action.equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
+		if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH) || action.equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
 			AppWidgetManager appWM = AppWidgetManager.getInstance(context);
 			int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent());
 			final int N = appWidgetIds.length;
@@ -184,7 +184,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 			Log.d("WidgetService", "Updating widget: " + appWidgetId);
 
 			String action = intent.getAction();
-			if (action.equals(AutoRefreshService.WIDGET_REFRESH)) {
+			if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) {
 				Context context = getApplicationContext();
 				new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId).execute();
 			}
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index 180ba64..fd2a013 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -18,7 +18,7 @@ public class DBAdapter {
     private SQLiteDatabase mDb;
     
     private static final String DATABASE_NAME = "data";
-    private static final int DATABASE_VERSION = 7;
+    private static final int DATABASE_VERSION = 8;
 
     private final Context mCtx;
 
@@ -31,11 +31,11 @@ public class DBAdapter {
         @Override
         public void onCreate(SQLiteDatabase db) {
             db.execSQL("create table banks (_id integer primary key autoincrement, "
-            		+ "balance real not null, "
+            		+ "balance text not null, "
                     + "banktype integer not null, username text not null, "
                     + "password text not null, disabled integer);");
-            db.execSQL("create table accounts (bankid integer not null, id text not null, balance real not null, name text not null);");
-            db.execSQL("create table transactions (_id integer primary key autoincrement, transdate text not null, btransaction text not null, amount real not null, account text not null);");
+            db.execSQL("create table accounts (bankid integer not null, id text not null, balance text not null, name text not null);");
+            db.execSQL("create table transactions (_id integer primary key autoincrement, transdate text not null, btransaction text not null, amount text not null, account text not null);");
         }
 
         @Override
@@ -142,8 +142,7 @@ public class DBAdapter {
         initialValues.put("username", bank.getUsername());
         initialValues.put("password", bank.getPassword());
         initialValues.put("disabled", 0);
-        initialValues.put("balance", 0);
-        BigDecimal total = new BigDecimal(0);
+        initialValues.put("balance", bank.getBalance().toPlainString());
         long bankId = bank.getDbId();
         Log.d(TAG, "Bankid: "+bankId);
         if (bankId == -1) {
@@ -159,10 +158,9 @@ public class DBAdapter {
 	        ArrayList<Account> accounts = bank.getAccounts();
             Log.d(TAG, "Bank accounts: "+bank.getAccounts().size());
 	        for(Account acc : accounts) {
-	        	total = total.add(acc.getBalance());
 	            ContentValues vals = new ContentValues();
 	            vals.put("bankid", bankId);
-	            vals.put("balance", acc.getBalance().doubleValue());
+	            vals.put("balance", acc.getBalance().toPlainString());
 	            vals.put("name", acc.getName());
 	            vals.put("id", new Long(bankId).toString()+"_"+acc.getId());
 	            mDb.insert("accounts", null, vals);
@@ -173,15 +171,12 @@ public class DBAdapter {
 			            ContentValues transvals = new ContentValues();
 			            transvals.put("transdate", transaction.getDate());
 			            transvals.put("btransaction", transaction.getTransaction());
-			            transvals.put("amount", transaction.getAmount().doubleValue());
+			            transvals.put("amount", transaction.getAmount().toPlainString());
 			            transvals.put("account", new Long(bankId).toString()+"_"+acc.getId());
 			            mDb.insert("transactions", null, transvals);
 		            }
 	            }
 	        }
-	        ContentValues v = new ContentValues();
-	        v.put("balance", total.doubleValue());
-	        mDb.update("banks", v, "_id="+bankId, null);
         }
         Log.d(TAG, "Updated bank: "+bankId);
         return bankId;
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 34c4108..5ad3af2 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -4,9 +4,11 @@ import java.util.ArrayList;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -22,8 +24,8 @@ import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
 import android.widget.Button;
-import android.widget.TextView;
 import android.widget.ListView;
+import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
 
 public class MainActivity extends LockableActivity {
@@ -77,9 +79,16 @@ public class MainActivity extends LockableActivity {
 
 	public void onResume() {
 		super.onResume();
+		registerReceiver(receiver, new IntentFilter(AutoRefreshService.BROADCAST_MAIN_REFRESH));		
 		refreshView();
 	}
 
+	private BroadcastReceiver receiver=new BroadcastReceiver() {
+		public void onReceive(Context context, Intent intent) {
+			refreshView();
+		}
+	};	
+	
 	public void refreshView() {
 		Log.d(TAG, "refreshView()");
 		ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index f4ad6d6..5f00200 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -13,7 +13,7 @@ import android.util.Log;
 public class StartupReceiver extends BroadcastReceiver{
 	@Override
 	public void onReceive(Context context, Intent intent) {
-		//Set alarms for auto updates on boot
+		//Set alarms for auto updates on boot, package update, package replace and package new
 		Log.d("StartupReceiever", "Intent action: "+intent.getAction());
 		setAlarm(context);
 	}
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index cbcedd8..dd0447e 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -104,7 +104,7 @@ public class Coop extends Bank {
 				matcher = reTransactionsVisa.matcher(response);
 				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 				while (matcher.find()) {
-					String title = matcher.group(4).length() > 0 ? matcher.group(4).trim() + "(" + matcher.group(3).trim() + ")" : matcher.group(2);
+					String title = matcher.group(4).length() > 0 ? matcher.group(4).trim() + " (" + matcher.group(3).trim() + ")" : matcher.group(2);
 					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(5))));
 				}
 				account.setTransactions(transactions);

commit f3c4c4eb68e2302af7f08f79bdc2312028e4081b
Author: liato <x@x00.us>
Date:   Fri Oct 29 16:13:53 2010 +0200

    Added SimpleCrypto class to encrypt passwords.

diff --git .gitignore .gitignore
index 0d88f61..01d0b95 100644
--- .gitignore
+++ .gitignore
@@ -14,4 +14,6 @@ bin
 gen
 local.properties
 *.jar
-dev/
\ No newline at end of file
+dev/
+src/com/liato/bankdroid/Crypto.java
+src/com/liato/bankdroid/Crypto.java.dev
diff --git src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
new file mode 100644
index 0000000..ca45b90
--- /dev/null
+++ src/net/sf/andhsli/hotspotlogin/SimpleCrypto.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Ferenc Hechler - ferenc_hechler@users.sourceforge.net
+ * 
+ * This file is part of the Android Hotspot Login
+ *
+ * The Android Hotspot Login 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.
+ * 
+ * The Android Hotspot Login 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 the Android Hotspot Login;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  
+ *******************************************************************************/
+package net.sf.andhsli.hotspotlogin;
+
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Usage:
+ * <pre>
+ * String crypto = SimpleCrypto.encrypt(masterpassword, cleartext)
+ * ...
+ * String cleartext = SimpleCrypto.decrypt(masterpassword, crypto)
+ * </pre>
+ * @author ferenc.hechler
+ */
+public class SimpleCrypto {
+
+	public static String encrypt(String seed, String cleartext) throws Exception {
+		byte[] rawKey = getRawKey(seed.getBytes());
+		byte[] result = encrypt(rawKey, cleartext.getBytes());
+		return toHex(result);
+	}
+	
+	public static String decrypt(String seed, String encrypted) throws Exception {
+		byte[] rawKey = getRawKey(seed.getBytes());
+		byte[] enc = toByte(encrypted);
+		byte[] result = decrypt(rawKey, enc);
+		return new String(result);
+	}
+
+	private static byte[] getRawKey(byte[] seed) throws Exception {
+		KeyGenerator kgen = KeyGenerator.getInstance("AES");
+		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+		sr.setSeed(seed);
+	    kgen.init(128, sr); // 192 and 256 bits may not be available
+	    SecretKey skey = kgen.generateKey();
+	    byte[] raw = skey.getEncoded();
+	    return raw;
+	}
+
+	
+	private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
+	    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+		Cipher cipher = Cipher.getInstance("AES");
+	    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
+	    byte[] encrypted = cipher.doFinal(clear);
+		return encrypted;
+	}
+
+	private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
+	    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+		Cipher cipher = Cipher.getInstance("AES");
+	    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
+	    byte[] decrypted = cipher.doFinal(encrypted);
+		return decrypted;
+	}
+
+	public static String toHex(String txt) {
+		return toHex(txt.getBytes());
+	}
+	public static String fromHex(String hex) {
+		return new String(toByte(hex));
+	}
+	
+	public static byte[] toByte(String hexString) {
+		int len = hexString.length()/2;
+		byte[] result = new byte[len];
+		for (int i = 0; i < len; i++)
+			result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
+		return result;
+	}
+
+	public static String toHex(byte[] buf) {
+		if (buf == null)
+			return "";
+		StringBuffer result = new StringBuffer(2*buf.length);
+		for (int i = 0; i < buf.length; i++) {
+			appendHex(result, buf[i]);
+		}
+		return result.toString();
+	}
+	private final static String HEX = "0123456789ABCDEF";
+	private static void appendHex(StringBuffer sb, byte b) {
+		sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
+	}
+	
+}
\ No newline at end of file

commit 1db97f7876eae98f8fbfeed6f0742464d4334fa2
Author: liato <x@x00.us>
Date:   Fri Oct 29 16:10:19 2010 +0200

    Fixed Statoil.

diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index a9a2450..06c56ed 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -1,10 +1,8 @@
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collections;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -33,8 +31,9 @@ public class Statoil extends Bank {
 	private static final String URL = "https://applications.sebkort.com/nis/external/stse/login.do";
 	private static final int BANKTYPE_ID = Bank.STATOIL;
 
-	private Pattern reAccounts = Pattern.compile("class=\"Right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	private Pattern reTransactions = Pattern.compile("(?:7px\">|</a>)\\s*(\\d{2}-\\d{2})\\s*</td>\\s*<td>[^<]+</td>\\s*<[^>]+>([^<]+)</td>\\s*<[^>]+>([^<]+)<.*?nowrap>([^<]+)<", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reAccounts = Pattern.compile("Welcomepagebillingunitlastdisposableamount\">([^<]+)</div>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("transcol1\">\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>\\s*</td>\\s*<td[^>]+>\\s*<div[^>]+>\\s*<span>([^<]*)</span>\\s*</div>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^>]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]*)</span>\\s*</td>\\s*<td[^>]+>\\s*<span>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private String response = null;
 	public Statoil(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -52,7 +51,6 @@ public class Statoil extends Bank {
 	@Override
 	public Urllib login() throws LoginException, BankException {
 		urlopen = new Urllib(true);
-		String response = null;
 		try {
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
@@ -71,7 +69,7 @@ public class Statoil extends Bank {
 			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
 			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
 			response = urlopen.open("https://applications.sebkort.com/siteminderagent/forms/generic.fcc", postData);
-			if (response.contains("du loggar in till")) {
+			if (response.contains("elaktig kombination")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		}
@@ -91,12 +89,19 @@ public class Statoil extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 		urlopen = login();
-		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://applications.sebkort.com/nis/stse/main.do");
+			if (!"https://applications.sebkort.com/nis/stse/main.do".equals(urlopen.getCurrentURI())) {
+				response = urlopen.open("https://applications.sebkort.com/nis/stse/main.do");
+			}
 			matcher = reAccounts.matcher(response);
 			if (matcher.find()) {
+				/*
+				 * Capture groups:
+				 * GROUP				EXAMPLE DATA
+				 * 1: amount			10 579,43
+				 * 
+				 */
 				accounts.add(new Account("Statoil MasterCard" , Helpers.parseBalance(matcher.group(1)), "1"));
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 			}
@@ -127,10 +132,20 @@ public class Statoil extends Bank {
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			Calendar cal = Calendar.getInstance();
 			while (matcher.find()) {
-				transactions.add(new Transaction(""+cal.get(Calendar.YEAR)+"-"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim()+(Html.fromHtml(matcher.group(3)).toString().trim().length() > 1 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(4)).multiply(new BigDecimal(-1))));
+				/*
+				 * Capture groups:
+				 * GROUP				EXAMPLE DATA
+				 * 1: date				10-18
+				 * 2: date				10-19
+				 * 3: specification		ICA Kvantum
+				 * 4: location			Stockholm
+				 * 5: currency			always empty?
+				 * 6: amount			always empty?
+				 * 7: amount in sek		5791,18
+				 * 
+				 */				
+				transactions.add(new Transaction(""+cal.get(Calendar.YEAR)+"-"+matcher.group(1).trim(), Html.fromHtml(matcher.group(3)).toString().trim()+(matcher.group(4).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(4)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(7)).negate()));
 			}
-			Collections.sort(transactions);
-			Collections.reverse(transactions);
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block

commit 70f63c634436c89190f0f89eb239fe7eb6bdf561
Author: liato <x@x00.us>
Date:   Fri Oct 29 09:06:04 2010 +0200

    Added crypto key to encrypt passwords.

diff --git src/com/liato/bankdroid/Crypto.java src/com/liato/bankdroid/Crypto.java
new file mode 100644
index 0000000..42ae0f7
--- /dev/null
+++ src/com/liato/bankdroid/Crypto.java
@@ -0,0 +1,24 @@
+package com.liato.bankdroid;
+public class Crypto {
+	/*
+	 * The key used to encrypt all the account passwords before storing them in the database.
+	 * This key is not used in the market app.
+	 * 
+	 */
+	private final static String KEY = "KGLRqraqThYniEtasoCqfbjFDwctomjmiY4rvSJThyyU4qUTIPXNLhPxkivpFLgr";
+
+	public final static String getKey() {
+		/*
+		 * Manipulate the key before returning it.
+		 * 
+		 * ...
+		 * 
+		 * Code omitted.
+		 * 
+		 * ...
+		 * 
+		 */
+
+		return KEY;
+	}
+}

commit 988189f05c032de1f4464f27b787ecf09f75bc20
Author: liato <x@x00.us>
Date:   Fri Oct 29 07:42:14 2010 +0200

    Apparantly you can't put drawables in subfolders. Move them back and prepend 'logo_' to the file names.

diff --git res/drawable/logos/avanza.png res/drawable/logo_avanza.png
similarity index 100%
rename from res/drawable/logos/avanza.png
rename to res/drawable/logo_avanza.png
diff --git res/drawable/logos/avanzamini.png res/drawable/logo_avanzamini.png
similarity index 100%
rename from res/drawable/logos/avanzamini.png
rename to res/drawable/logo_avanzamini.png
diff --git res/drawable/logos/coop.png res/drawable/logo_coop.png
similarity index 100%
rename from res/drawable/logos/coop.png
rename to res/drawable/logo_coop.png
diff --git res/drawable/logos/eurocard.png res/drawable/logo_eurocard.png
similarity index 100%
rename from res/drawable/logos/eurocard.png
rename to res/drawable/logo_eurocard.png
diff --git res/drawable/logos/firstcard.png res/drawable/logo_firstcard.png
similarity index 100%
rename from res/drawable/logos/firstcard.png
rename to res/drawable/logo_firstcard.png
diff --git res/drawable/logos/handelsbanken.png res/drawable/logo_handelsbanken.png
similarity index 100%
rename from res/drawable/logos/handelsbanken.png
rename to res/drawable/logo_handelsbanken.png
diff --git res/drawable/logos/ica.png res/drawable/logo_ica.png
similarity index 100%
rename from res/drawable/logos/ica.png
rename to res/drawable/logo_ica.png
diff --git res/drawable/logos/icabanken.png res/drawable/logo_icabanken.png
similarity index 100%
rename from res/drawable/logos/icabanken.png
rename to res/drawable/logo_icabanken.png
diff --git res/drawable/logos/lansforsakringar.png res/drawable/logo_lansforsakringar.png
similarity index 100%
rename from res/drawable/logos/lansforsakringar.png
rename to res/drawable/logo_lansforsakringar.png
diff --git res/drawable/logos/nordea.png res/drawable/logo_nordea.png
similarity index 100%
rename from res/drawable/logos/nordea.png
rename to res/drawable/logo_nordea.png
diff --git res/drawable/logos/okq8.png res/drawable/logo_okq8.png
similarity index 100%
rename from res/drawable/logos/okq8.png
rename to res/drawable/logo_okq8.png
diff --git res/drawable/logos/statoil.png res/drawable/logo_statoil.png
similarity index 100%
rename from res/drawable/logos/statoil.png
rename to res/drawable/logo_statoil.png
diff --git res/drawable/logos/swedbank.png res/drawable/logo_swedbank.png
similarity index 100%
rename from res/drawable/logos/swedbank.png
rename to res/drawable/logo_swedbank.png
diff --git res/drawable/logos/villabanken.png res/drawable/logo_villabanken.png
similarity index 100%
rename from res/drawable/logos/villabanken.png
rename to res/drawable/logo_villabanken.png
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index cc71c1b..03c7b4b 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import net.sf.andhsli.hotspotlogin.SimpleCrypto;
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.Context;
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index 86904f9..772d1f3 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -43,7 +43,7 @@ public class AccountsAdapter extends BaseAdapter {
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getUsername());
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getName());
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getBalance()));
-		icon.setImageResource(context.getResources().getIdentifier("drawable/logos/"+group.getShortName(), null, context.getPackageName()));
+		icon.setImageResource(group.getImageResource());
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
 		Log.d("AccountsAdapter", ""+group.isDisabled());
 		if (group.isDisabled()) {
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 3325096..59e212b 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -181,7 +181,7 @@ public abstract class Bank implements Comparable<Bank> {
 	}
 	
 	public int getImageResource() {
-		return res.getIdentifier("drawable/logos/"+NAME_SHORT, null, context.getPackageName());	
+		return res.getIdentifier("logo_"+NAME_SHORT, "drawable", context.getPackageName());	
 	}
 
 	public int compareTo(Bank another) {

commit 84fadbf701d8a8307fd848b8db8dad063c0bb1fa
Author: liato <x@x00.us>
Date:   Fri Oct 29 06:49:23 2010 +0200

    Moved bank logos to separate dir.

diff --git res/drawable/avanza.png res/drawable/logos/avanza.png
similarity index 100%
rename from res/drawable/avanza.png
rename to res/drawable/logos/avanza.png
diff --git res/drawable/avanza_mini.png res/drawable/logos/avanzamini.png
similarity index 100%
rename from res/drawable/avanza_mini.png
rename to res/drawable/logos/avanzamini.png
diff --git res/drawable/coop.png res/drawable/logos/coop.png
similarity index 100%
rename from res/drawable/coop.png
rename to res/drawable/logos/coop.png
diff --git res/drawable/eurocard.png res/drawable/logos/eurocard.png
similarity index 100%
rename from res/drawable/eurocard.png
rename to res/drawable/logos/eurocard.png
diff --git res/drawable/firstcard.png res/drawable/logos/firstcard.png
similarity index 100%
rename from res/drawable/firstcard.png
rename to res/drawable/logos/firstcard.png
diff --git res/drawable/handelsbanken.png res/drawable/logos/handelsbanken.png
similarity index 100%
rename from res/drawable/handelsbanken.png
rename to res/drawable/logos/handelsbanken.png
diff --git res/drawable/ica.png res/drawable/logos/ica.png
similarity index 100%
rename from res/drawable/ica.png
rename to res/drawable/logos/ica.png
diff --git res/drawable/icabanken.png res/drawable/logos/icabanken.png
similarity index 100%
rename from res/drawable/icabanken.png
rename to res/drawable/logos/icabanken.png
diff --git res/drawable/lansforsakringar.png res/drawable/logos/lansforsakringar.png
similarity index 100%
rename from res/drawable/lansforsakringar.png
rename to res/drawable/logos/lansforsakringar.png
diff --git res/drawable/nordea.png res/drawable/logos/nordea.png
similarity index 100%
rename from res/drawable/nordea.png
rename to res/drawable/logos/nordea.png
diff --git res/drawable/okq8.png res/drawable/logos/okq8.png
similarity index 100%
rename from res/drawable/okq8.png
rename to res/drawable/logos/okq8.png
diff --git res/drawable/statoil.png res/drawable/logos/statoil.png
similarity index 100%
rename from res/drawable/statoil.png
rename to res/drawable/logos/statoil.png
diff --git res/drawable/swedbank.png res/drawable/logos/swedbank.png
similarity index 100%
rename from res/drawable/swedbank.png
rename to res/drawable/logos/swedbank.png
diff --git res/drawable/villabanken.png res/drawable/logos/villabanken.png
similarity index 100%
rename from res/drawable/villabanken.png
rename to res/drawable/logos/villabanken.png
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index b665582..86904f9 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -43,7 +43,7 @@ public class AccountsAdapter extends BaseAdapter {
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getUsername());
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getName());
 		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getBalance()));
-		icon.setImageResource(context.getResources().getIdentifier("drawable/"+group.getShortName(), null, context.getPackageName()));
+		icon.setImageResource(context.getResources().getIdentifier("drawable/logos/"+group.getShortName(), null, context.getPackageName()));
 		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
 		Log.d("AccountsAdapter", ""+group.isDisabled());
 		if (group.isDisabled()) {
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 2084a9c..3325096 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -179,6 +179,10 @@ public abstract class Bank implements Comparable<Bank> {
 	public String getURL() {
 		return URL;
 	}
+	
+	public int getImageResource() {
+		return res.getIdentifier("drawable/logos/"+NAME_SHORT, null, context.getPackageName());	
+	}
 
 	public int compareTo(Bank another) {
 		return this.toString().compareToIgnoreCase(another.toString());
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 7cbec9c..7256e5d 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -81,7 +81,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
 		views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
 		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance()));
-		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+bank.getShortName(), null, context.getPackageName()));
+		views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource());
 		Log.d("Disabled", ""+bank.isDisabled());
 		if (bank.isDisabled()) {
 			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
index 590f5cf..c2f767c 100644
--- src/com/liato/bankdroid/TransactionsActivity.java
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -31,7 +31,7 @@ public class TransactionsActivity extends LockableActivity {
 		viewBankName.setText(bank.getUsername());
 		viewAccountName.setText(account.getName());
 		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance()));
-		icon.setImageResource(getResources().getIdentifier("drawable/"+bank.getShortName(), null, getPackageName()));
+		icon.setImageResource(bank.getImageResource());
 		ArrayList<Transaction> transactions = account.getTransactions();
 		Log.d(TAG, "Transactions: "+transactions.size());
 		if (transactions.size() > 0) {

commit 95418a1fe53df9e928579b3f8c02b20f8a073c06
Author: liato <x@x00.us>
Date:   Fri Oct 29 06:16:06 2010 +0200

    Added FirstCard support.

diff --git logos.psd logos.psd
index d2ad949..5557d71 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/firstcard.png res/drawable/firstcard.png
new file mode 100644
index 0000000..b1b6987
Binary files /dev/null and res/drawable/firstcard.png differ
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 9b2dac2..852391e 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -10,6 +10,7 @@ import com.liato.bankdroid.banks.Avanza;
 import com.liato.bankdroid.banks.AvanzaMini;
 import com.liato.bankdroid.banks.Coop;
 import com.liato.bankdroid.banks.Eurocard;
+import com.liato.bankdroid.banks.FirstCard;
 import com.liato.bankdroid.banks.Handelsbanken;
 import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
@@ -65,6 +66,7 @@ public class BankFactory {
 		banks.add(new Villabanken(context));
 		banks.add(new AvanzaMini(context));
 		banks.add(new Eurocard(context));
+		banks.add(new FirstCard(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
index 011bd1a..663d3de 100644
--- src/com/liato/bankdroid/banks/Eurocard.java
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -116,6 +116,7 @@ public class Eurocard extends Bank {
 				 * 4: currency			SEK or empty
 				 * 5: tax				12.99 or empty
 				 * 6: amount			118.65
+				 * 
 				 */
 				strDate = ""+cal.get(Calendar.YEAR)+"-"+Html.fromHtml(matcher.group(1)).toString().trim();
 				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim()+(matcher.group(3).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(6)).negate()));
diff --git src/com/liato/bankdroid/banks/FirstCard.java src/com/liato/bankdroid/banks/FirstCard.java
new file mode 100644
index 0000000..17f61f2
--- /dev/null
+++ src/com/liato/bankdroid/banks/FirstCard.java
@@ -0,0 +1,148 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class FirstCard extends Bank {
+	private static final String TAG = "FirstCard";
+	private static final String NAME = "First Card";
+	private static final String NAME_SHORT = "firstcard";
+	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
+	private static final int BANKTYPE_ID = Bank.FIRSTCARD;
+	
+	private Pattern reAccounts = Pattern.compile("translist\\.jsp\\?p=a&(?:amp;)?cardID=([^\"]+)\">([^<]+)</a>\\s*</td>\\s*<td[^>]+>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("pagecolumns\">(\\d{6})</td>\\s*<td>\\s*</td>\\s*<td>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)</td>\\s*<td[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	public FirstCard(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public FirstCard(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		try {
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("op", "login"));				
+			postData.add(new BasicNameValuePair("searchIndex", ""));				
+			postData.add(new BasicNameValuePair("country", "0"));				
+			postData.add(new BasicNameValuePair("soktext", "Skriv sökord här"));				
+			postData.add(new BasicNameValuePair("pnr", username));
+			postData.add(new BasicNameValuePair("intpwd", password));
+			
+			Log.d(TAG, "Posting to https://www.firstcard.se/valkom.jsp");
+			response = urlopen.open("https://www.firstcard.se/valkom.jsp", postData);
+			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
+			
+			if (response.contains("felaktig identitet") || response.contains("obligatoriskt") || response.contains("ange en internetkod")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		try {
+			response = urlopen.open("https://www.firstcard.se/mkol/index.jsp");
+			Matcher matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+				/*
+				 * Capture groups:
+				 * GROUP				EXAMPLE DATA
+				 * 1: id				kdKPq4ghlcy9wpXymSzzS46wWQcS_0OT
+				 * 2: account number	1111 3333 7777 9999
+				 * 3: amount 			9 824,08
+				 * 
+				 */				
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}			
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
+			response = urlopen.open("https://www.firstcard.se/mkol/translist.jsp?p=a&cardID="+account.getId());
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				/*
+				 * Capture groups:
+				 * GROUP						EXAMPLE DATA
+				 * 1: date						101006
+				 * 2: specification				GOOGLE *RealArcade
+				 * 3: currency					USD
+				 * 4: amount					3,49
+				 * 5: amount in local currency	24,08
+				 * 
+				 */
+				String strDate = Html.fromHtml(matcher.group(1)).toString().trim();
+				strDate = "20"+strDate.charAt(0)+strDate.charAt(1)+"-"+strDate.charAt(2)+strDate.charAt(3)+"-"+strDate.charAt(4)+strDate.charAt(5);
+				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim()+(matcher.group(3).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(6)).negate()));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+}
\ No newline at end of file

commit 2655094aa465c8b3fa0b871d77a160b4a0c73d4a
Author: liato <x@x00.us>
Date:   Fri Oct 29 05:15:03 2010 +0200

    Close connection to the bank after an update.

diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index c6ffb54..cc71c1b 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -144,6 +144,7 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 				Log.d(TAG, "Updating "+bank);
 				bank.update();
 				bank.updateAllTransactions();
+				bank.closeConnection();
 				Log.d(TAG, "Saving "+bank);
 				bank.save();
 				Log.d(TAG, "Disabled: "+bank.isDisabled());
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index af2aa36..1e74862 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -98,6 +98,7 @@ public class AutoRefreshService extends Service {
     					refreshWidgets = true;
     					bank.updateAllTransactions();
     				}
+    				bank.closeConnection();
     				db.updateBank(bank);
     			} 
     			catch (BankException e) {
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 91c0c76..7cbec9c 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -233,6 +233,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 				try {
 					if (!bank.isDisabled()) {
 						bank.update();
+						bank.closeConnection();
 						bank.save();
 					}
 					else {
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index e91d935..e46c143 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -56,6 +56,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 			try {
 				bank.update();
 				bank.updateAllTransactions();
+				bank.closeConnection();
 				bank.save();
 				i++;
 			} 

commit d8cdd6b370347abc8bc47a825e6b14e0f0c910c8
Author: liato <x@x00.us>
Date:   Fri Oct 29 05:14:19 2010 +0200

    Added Eurocard.

diff --git logos.psd logos.psd
index 91d4619..d2ad949 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/eurocard.png res/drawable/eurocard.png
new file mode 100644
index 0000000..eb38336
Binary files /dev/null and res/drawable/eurocard.png differ
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 857eda9..2084a9c 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -22,6 +22,8 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int VILLABANKEN = 10;
 	public final static int AVANZAMINI = 11;
 	public final static int OKQ8 = 12;
+	public final static int EUROCARD = 13;
+	public final static int FIRSTCARD = 14;
 	
 
 	protected String TAG = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 9d162b4..9b2dac2 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -9,6 +9,7 @@ import android.database.Cursor;
 import com.liato.bankdroid.banks.Avanza;
 import com.liato.bankdroid.banks.AvanzaMini;
 import com.liato.bankdroid.banks.Coop;
+import com.liato.bankdroid.banks.Eurocard;
 import com.liato.bankdroid.banks.Handelsbanken;
 import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
@@ -63,6 +64,7 @@ public class BankFactory {
 		banks.add(new Avanza(context));
 		banks.add(new Villabanken(context));
 		banks.add(new AvanzaMini(context));
+		banks.add(new Eurocard(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/banks/Eurocard.java src/com/liato/bankdroid/banks/Eurocard.java
new file mode 100644
index 0000000..011bd1a
--- /dev/null
+++ src/com/liato/bankdroid/banks/Eurocard.java
@@ -0,0 +1,133 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class Eurocard extends Bank {
+	private static final String TAG = "Eurocard";
+	private static final String NAME = "Eurocard";
+	private static final String NAME_SHORT = "eurocard";
+	private static final String URL = "https://e-saldo.eurocard.se/nis/external/ecse/login.do";
+	private static final int BANKTYPE_ID = Bank.EUROCARD;
+	
+	private Pattern reAccounts = Pattern.compile("getInvoiceList\\.do\\?id=([^\"]+)\">([^<]+)</a></td>(?:\\s*<td>[^<]+</td>){2}\\s*<td\\s*align=\"right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<nobr>(\\d\\d-\\d\\d)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>[^<]+</nobr>\\s*</td>\\s*<td><div\\s*class=\"BreakLine\">([^<]+)</div>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">\\s*<nobr>([^<]*)</nobr>\\s*</td>\\s*<td[^>]+>\\s*<nobr>([^>]*)</nobr>\\s*</td>\\s*<td\\s*valign=\"top\">[^<]+</td>\\s*<td[^>]+>\\s*<nobr>([^<]+)</nobr>", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	public Eurocard(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Eurocard(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		try {
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("target", "/nis/ecse/main.do"));				
+			postData.add(new BasicNameValuePair("prodgroup", "0005"));				
+			postData.add(new BasicNameValuePair("USERNAME", "0005"+username));				
+			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));				
+			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));				
+			postData.add(new BasicNameValuePair("uname", username));
+			postData.add(new BasicNameValuePair("PASSWORD", password));
+			
+			Log.d(TAG, "Posting to https://e-saldo.eurocard.se/siteminderagent/forms/generic.fcc");
+			response = urlopen.open("https://e-saldo.eurocard.se/siteminderagent/forms/generic.fcc", postData);
+			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
+			
+			if (response.contains("Felaktig kombination")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		Matcher matcher = reAccounts.matcher(response);
+		while (matcher.find()) {
+			accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+			balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+		}
+
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do");
+			response = urlopen.open("https://e-saldo.eurocard.se/nis/ecse/getPendingTransactions.do");
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			String strDate = null;
+			Calendar cal = Calendar.getInstance();
+			while (matcher.find()) {
+				/*
+				 * Capture groups:
+				 * GROUP				EXAMPLE DATA
+				 * 1: date		 		09-26
+				 * 2: specification		ICA Kvantum
+				 * 3: location          Stockholm
+				 * 4: currency			SEK or empty
+				 * 5: tax				12.99 or empty
+				 * 6: amount			118.65
+				 */
+				strDate = ""+cal.get(Calendar.YEAR)+"-"+Html.fromHtml(matcher.group(1)).toString().trim();
+				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim()+(matcher.group(3).trim().length() > 0 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(6)).negate()));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+}
\ No newline at end of file

commit 43efbadc8a91022ab2d761733f1924f5bd5ef243
Author: liato <x@x00.us>
Date:   Fri Oct 29 02:36:29 2010 +0200

    Added transaction history to Coop.

diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index f0e34d5..cbcedd8 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -31,10 +31,11 @@ public class Coop extends Bank {
 	private static final int BANKTYPE_ID = Bank.COOP;
 
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalanceVisa = Pattern.compile("Disponibelt\\s*belopp:</td>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceVisa = Pattern.compile("aktuellt\\s*saldo:</span>\\s*<span>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
-
+	private Pattern reTransactionsVisa = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>([^<]*)</td>\\s*<td>([^<]*)</td>\\s*<td.*?</td>\\s*<td><s.*?value=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
+	
 	public Coop(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -94,16 +95,25 @@ public class Coop extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/?t=MedMeraVisa");
+			Account account;
+			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Visa/");
 			matcher = reBalanceVisa.matcher(response);
 			if (matcher.find()) {
-				accounts.add(new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1"));
+				account = new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1");
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+				matcher = reTransactionsVisa.matcher(response);
+				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+				while (matcher.find()) {
+					String title = matcher.group(4).length() > 0 ? matcher.group(4).trim() + "(" + matcher.group(3).trim() + ")" : matcher.group(2);
+					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(5))));
+				}
+				account.setTransactions(transactions);
+				accounts.add(account);
 			}
 			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
 			matcher = reBalanceKonto.matcher(response);
 			if (matcher.find()) {
-				Account account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
+				account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 				matcher = reTransactionsKonto.matcher(response);
 				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
index 280f764..a65d40c 100644
--- src/com/liato/bankdroid/banks/OKQ8.java
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -147,26 +147,26 @@ public class OKQ8 extends Bank {
 			Log.d(TAG, "Response is null, login again.");
 			urlopen = login();
 		}
-		/*
-		 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
-		 * The balance is the first value (of three) that are matched by reBalance expression.
-		 */
-		Matcher matcher;
-		matcher = reBalance.matcher(response);
-		if (matcher.find()) {
-			accounts.add(new Account("OKQ8 VISA" , Helpers.parseBalance(matcher.group(1)), "1"));
-			balance = balance.add(Helpers.parseBalance(matcher.group(1)));
-		}
-		
-		if (accounts.isEmpty()) {
-			throw new BankException(res.getText(R.string.no_accounts_found).toString());
-		}
-	}
-	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
-		super.updateTransactions(account, urlopen);
 		try {
+			/*
+			 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
+			 * The balance is the first value (of three) that are matched by reBalance expression.
+			 */
+			Matcher matcher;
+			matcher = reBalance.matcher(response);
+			if (matcher.find()) {
+				accounts.add(new Account("OKQ8 VISA" , Helpers.parseBalance(matcher.group(1)), "1"));
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			}
+			
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+	
+	
 			response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
-			Matcher matcher = reTransactions.matcher(response);
+	
+			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {
 				/*
@@ -177,13 +177,13 @@ public class OKQ8 extends Bank {
 				 */
 				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)).negate()));
 			}
-			account.setTransactions(transactions);
+			accounts.get(0).setTransactions(transactions);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		} catch (IOException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
-		}
+		}		
 	}
 }

commit c1b1beee1ec0b4f0812e09b0157da0ab8281af3f
Author: liato <x@x00.us>
Date:   Fri Oct 29 02:04:12 2010 +0200

    Added OKQ8.

diff --git logos.psd logos.psd
index 2746dd1..91d4619 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/okq8.png res/drawable/okq8.png
new file mode 100644
index 0000000..30eb0fb
Binary files /dev/null and res/drawable/okq8.png differ
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 6763013..857eda9 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -21,6 +21,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int AVANZA = 9;
 	public final static int VILLABANKEN = 10;
 	public final static int AVANZAMINI = 11;
+	public final static int OKQ8 = 12;
 	
 
 	protected String TAG = "Bank";
diff --git src/com/liato/bankdroid/banks/OKQ8.java src/com/liato/bankdroid/banks/OKQ8.java
new file mode 100644
index 0000000..280f764
--- /dev/null
+++ src/com/liato/bankdroid/banks/OKQ8.java
@@ -0,0 +1,189 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+/**
+ * @author COLA
+ */
+
+public class OKQ8 extends Bank {
+	private static final String TAG = "OKQ8";
+	private static final String NAME = "OKQ8";
+	private static final String NAME_SHORT = "okq8";
+	private static final String URL = "https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8";
+	private static final int BANKTYPE_ID = Bank.OKQ8;
+
+	
+	private Pattern reLoginRedir = Pattern.compile("value=\"([^\"]*)\"", Pattern.CASE_INSENSITIVE);
+	private Pattern reBalance = Pattern.compile("<div class=\"numberpositive\">([^<]*)</div>", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("style=\"white-space: nowrap\">([^<]*)</td>\\s*<td[^>]*>[^<]*</td>\\s*<td[^>]*>[^<]*</td>\\s*<td[^>]*>([^<]*)</td>\\s*<td[^>]*><div[^>]*>([^<]*)</div></td>", Pattern.CASE_INSENSITIVE);
+	private String response = null;
+	
+	public OKQ8(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public OKQ8(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true);
+		Matcher matcher;
+		Date d = new Date();
+		String value = null;
+		
+		try {
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			
+			response = urlopen.open("https://nettbank.edb.com/Logon/index.jsp?domain=0066&from_page=http://www.okq8.se&to_page=https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8");
+			
+			/*
+			 * Post the login information to the login page.
+			 */
+			postData.clear();
+			//p_tranid is the epoch time in milliseconds
+			postData.add(new BasicNameValuePair("p_tranid", Long.toString(d.getTime())));
+			postData.add(new BasicNameValuePair("p_errorScreen", "LOGON_REPOST_ERROR"));
+			postData.add(new BasicNameValuePair("n_bank", ""));
+			postData.add(new BasicNameValuePair("empty_pwd", ""));
+			postData.add(new BasicNameValuePair("user_id", username.toUpperCase()));
+			postData.add(new BasicNameValuePair("password", password));
+			response = urlopen.open("https://nettbank.edb.com/Logon/logon/step1", postData);
+			
+			if (!response.contains("LOGON_OK")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+			/*
+			 * After login ok we end up at an intermediate login page with a submit
+			 * form that contains information that must be passed to the next page:
+			 * <input type="hidden" name="so" value="xxx"/>
+			 * <input type="hidden" name="last_logon_time" value="xxx"/>
+			 * <input type="hidden" name="failed_logon_attempts" value="xxx"/>
+			 * <input type="hidden" name="login_service_url" value="xxx"/>
+			 */
+			matcher = reLoginRedir.matcher(response);
+			postData.clear();
+			if(!matcher.find())
+			{
+				throw new LoginException("Could not find value for 'so'.");
+			}
+			value = matcher.group(1);
+			postData.add(new BasicNameValuePair("so", value));
+			
+			if(!matcher.find())
+			{
+				throw new LoginException("Could not find value for 'last_logon_time'.");
+			}
+			value = matcher.group(1);
+			postData.add(new BasicNameValuePair("last_logon_time", value));
+			
+			if(!matcher.find())
+			{
+				throw new LoginException("Could not find value for 'failed_logon_attempts'.");
+			}
+			value = matcher.group(1);
+			postData.add(new BasicNameValuePair("failed_logon_attempts", value));
+			
+			if(!matcher.find())
+			{
+				throw new LoginException("Could not find value for 'login_service_url'.");
+			}
+			value = matcher.group(1);
+			postData.add(new BasicNameValuePair("login_service_url", value));
+			
+			response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/logon/done/okq8", postData);
+			
+			if(response.contains("HTML REDIRECT"))
+			{
+				throw new LoginException("Login failed.");
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		if (response == null) {
+			Log.d(TAG, "Response is null, login again.");
+			urlopen = login();
+		}
+		/*
+		 * The start page contains the balance of the account ("Kvar att utnytta") so read it.
+		 * The balance is the first value (of three) that are matched by reBalance expression.
+		 */
+		Matcher matcher;
+		matcher = reBalance.matcher(response);
+		if (matcher.find()) {
+			accounts.add(new Account("OKQ8 VISA" , Helpers.parseBalance(matcher.group(1)), "1"));
+			balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+		}
+		
+		if (accounts.isEmpty()) {
+			throw new BankException(res.getText(R.string.no_accounts_found).toString());
+		}
+	}
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		try {
+			response = urlopen.open("https://nettbank.edb.com/cardpayment/transigo/card/overview/lastTransactionsAccount");
+			Matcher matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				/*
+				 * Capture group 1 = date
+				 * Capture group 2 = text
+				 * Capture group 3 = amount
+				 * Negate the amount since buys are reported as positive.
+				 */
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)).negate()));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+}

commit fb18ffc4f66ee0bb6ddc4423873ee1b4134a206a
Author: liato <x@x00.us>
Date:   Fri Oct 29 01:32:20 2010 +0200

    Credit card support for Nordea.

diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index cb35028..35adb5d 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -33,6 +33,7 @@ public class Nordea extends Bank {
 	
 	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
 	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reCards = Pattern.compile("/card/details\\.html\\?id=(\\d{1,})[^\"]*\".*?>\\s*<span[^>]*>\\s*<span>([^<]+)</span>\\s*<span[^>]+>([^<]+)<", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("(\\d{2}.\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 
@@ -126,9 +127,18 @@ public class Nordea extends Bank {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l"+matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
+			matcher = reCards.matcher(response);
+			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/card/list.html");
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "c"+matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
+			
 			// Konungens konto
 			//accounts.add(new Account("Personkonto", Helpers.parseBalance("568268.37"), "1"));
 			//accounts.add(new Account("Kapitalkonto", Helpers.parseBalance("5789002.00"), "0"));
@@ -144,7 +154,9 @@ public class Nordea extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		super.updateTransactions(account, urlopen);
-		if (account.getId().startsWith("l") || account.getId().startsWith("f")) return; //No transaction history for loans and funds
+
+		//No transaction history for loans, funds and credit cards.
+		if (account.getId().startsWith("l") || account.getId().startsWith("f") || account.getId().startsWith("c")) return;
 
 		String response = null;
 		Matcher matcher;

commit a73764bc303cab6a3613426a4b65b1cfd1b0eb4d
Author: liato <x@x00.us>
Date:   Fri Oct 29 01:03:38 2010 +0200

    All banks reuse their urllib object, skipping one unnecessary login. Split Avanza to Avanza and AvanzaMini.

diff --git logos.psd logos.psd
index 83f0abe..2746dd1 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/avanza_mini.png res/drawable/avanza_mini.png
new file mode 100644
index 0000000..f19d914
Binary files /dev/null and res/drawable/avanza_mini.png differ
diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
index 9459cb5..20241dd 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/Account.java
@@ -4,6 +4,11 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 
 public class Account {
+	public final static int REGULAR = 1;
+	public final static int FUNDS = 2;
+	public final static int LOANS = 3;
+	public final static int OTHER = 4;
+	
 	private String name;
 	private BigDecimal balance;
 	private String id;
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 51f10a9..6763013 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -20,6 +20,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int STATOIL = 8;
 	public final static int AVANZA = 9;
 	public final static int VILLABANKEN = 10;
+	public final static int AVANZAMINI = 11;
 	
 
 	protected String TAG = "Bank";
@@ -88,6 +89,11 @@ public abstract class Bank implements Comparable<Bank> {
 		return null;
 	}
 
+	public void closeConnection() {
+		if (urlopen != null) {
+			urlopen.close();
+		}
+	}
 	public ArrayList<Account> getAccounts() {
 		return this.accounts;
 	}
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index d9af4d5..9d162b4 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -7,6 +7,7 @@ import android.content.Context;
 import android.database.Cursor;
 
 import com.liato.bankdroid.banks.Avanza;
+import com.liato.bankdroid.banks.AvanzaMini;
 import com.liato.bankdroid.banks.Coop;
 import com.liato.bankdroid.banks.Handelsbanken;
 import com.liato.bankdroid.banks.ICA;
@@ -41,6 +42,8 @@ public class BankFactory {
 			return new Avanza(context);
 		case Bank.VILLABANKEN:
 			return new Villabanken(context);
+		case Bank.AVANZAMINI:
+			return new AvanzaMini(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -59,6 +62,7 @@ public class BankFactory {
 		banks.add(new Statoil(context));
 		banks.add(new Avanza(context));
 		banks.add(new Villabanken(context));
+		banks.add(new AvanzaMini(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index 2443c15..18c8bd7 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -34,8 +34,6 @@ public class Avanza extends Bank {
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)</td.*?<td><strong>([^<]+)</strong></td>\\s+<td[^>]+>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private boolean avanzaMini = false;
 	public Avanza(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -52,7 +50,7 @@ public class Avanza extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib(true);
+		urlopen = new Urllib(true, true);
 		String response = null;
 		try {
 			//response = urlopen.open("https://www.avanza.se/aza/login/logout.jsp");
@@ -67,17 +65,11 @@ public class Avanza extends Bank {
 			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
-			if (urlopen.getCurrentURI().equalsIgnoreCase("https://www.avanza.se/mini/hem/index.html")) {
-				avanzaMini = true;
-			}
-			
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
 		} catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}
 		return urlopen;
 	}
 	@Override
@@ -90,26 +82,13 @@ public class Avanza extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			if (!avanzaMini) {
-				Log.d("BankAvanza", "Opening: https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
-				response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
-							
-				matcher = reAccounts.matcher(response);
-				while (matcher.find()) {
-					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
-					balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-				}
-			}
-			else {
-				Log.d("BankAvanza", "Opening: https://www.avanza.se/mini/mitt_konto/index.html");
-				response = urlopen.open("https://www.avanza.se/mini/mitt_konto/index.html");
-				matcher = reAvanzaMini.matcher(response);
-				if (matcher.find()) {
-					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), "1"));
-					accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(), Helpers.parseBalance(matcher.group(4)), "2"));
-					balance = balance.add(Helpers.parseBalance(matcher.group(2)));
-					balance = balance.add(Helpers.parseBalance(matcher.group(4)));
-				}
+			Log.d("BankAvanza", "Opening: https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
+			response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
+						
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -121,22 +100,12 @@ public class Avanza extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
-		super.updateTransactions(account, urlopened);
-		if (avanzaMini) return;
-		Urllib urlopen = null;
-		if (urlopened == null) {
-			urlopen = login();
-		}
-		else {
-			urlopen = urlopened;
-		}
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+
 		String response = null;
 		Matcher matcher;
 		try {						
@@ -160,9 +129,6 @@ public class Avanza extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		if (urlopened == null) {
-			urlopen.close();
-		}
 	}
 	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/AvanzaMini.java src/com/liato/bankdroid/banks/AvanzaMini.java
new file mode 100644
index 0000000..4d6f748
--- /dev/null
+++ src/com/liato/bankdroid/banks/AvanzaMini.java
@@ -0,0 +1,104 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class AvanzaMini extends Bank {
+	private static final String TAG = "AvanzaMini";
+	private static final String NAME = "Avanza Mini";
+	private static final String NAME_SHORT = "avanzamini";
+	private static final String URL = "https://www.avanza.se/mini/hem/";
+	private static final int BANKTYPE_ID = Bank.AVANZAMINI;
+	
+    private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tbody>\\s*(.*)</tbody>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+    private Pattern accountsAvanzaMini = Pattern.compile("<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	public AvanzaMini(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public AvanzaMini(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib(true, true);
+		String response = null;
+		try {
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("username", username));
+			postData.add(new BasicNameValuePair("password", password));
+
+			Log.d("BankAvanza", "Posting to https://www.avanza.se/aza/login/login.jsp");
+			response = urlopen.open("https://www.avanza.se/aza/login/login.jsp", postData);
+			Log.d("BankAvanza", "Url after post: "+urlopen.getCurrentURI());
+			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d("BankAvanza", "Opening: https://www.avanza.se/mini/mitt_konto/index.html");
+			response = urlopen.open("https://www.avanza.se/mini/mitt_konto/index.html");
+			matcher = reAvanzaMini.matcher(response);
+	        if (matcher.find()) {
+	            int count = 1;
+	            Matcher submatcher = accountsAvanzaMini.matcher(matcher.group(1));
+	            while (submatcher.find()){
+	                accounts.add(new Account(Html.fromHtml(submatcher.group(1)).toString().trim(), Helpers.parseBalance(submatcher.group(2)), Integer.toString(count)));
+	                balance = balance.add(Helpers.parseBalance(submatcher.group(2)));
+	                count++;
+	            }
+	        }
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 7c14daf..f0e34d5 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -50,13 +50,8 @@ public class Coop extends Bank {
 	}
 
 	@Override
-	public void update() throws BankException, LoginException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		Urllib urlopen = new Urllib();
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -78,11 +73,27 @@ public class Coop extends Bank {
 			if (response.contains("Felmeddelande")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
-			/*
-			for (String s : response.split("\n")) {
-				Log.d(TAG, s);
-			}
-			*/			
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;		
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
 			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/?t=MedMeraVisa");
 			matcher = reBalanceVisa.matcher(response);
 			if (matcher.find()) {
@@ -113,9 +124,5 @@ public class Coop extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 3172b25..78864f0 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -136,6 +136,7 @@ public class Handelsbanken extends Bank {
 	
 
 	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
 		String response = null;
 		Matcher matcher;
 		try {
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banks/ICA.java
index 88e6209..8dc5dd9 100644
--- src/com/liato/bankdroid/banks/ICA.java
+++ src/com/liato/bankdroid/banks/ICA.java
@@ -49,7 +49,7 @@ public class ICA extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -86,8 +86,6 @@ public class ICA extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}
 		return urlopen;
 	}
 
@@ -97,7 +95,7 @@ public class ICA extends Bank {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -124,9 +122,5 @@ public class ICA extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 }
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index e80c74a..65dc3de 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -52,7 +52,7 @@ public class ICABanken extends Bank {
 	}
 
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -88,8 +88,6 @@ public class ICABanken extends Bank {
 			Log.d(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}		
 		return urlopen;
 	}	
 	
@@ -100,7 +98,7 @@ public class ICABanken extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -127,22 +125,11 @@ public class ICABanken extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
-		super.updateTransactions(account, urlopened);
-		Urllib urlopen = null;
-		if (urlopened == null) {
-			urlopen = login();
-		}
-		else {
-			urlopen = urlopened;
-		}
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
 		String response = null;
 		Matcher matcher;
 		try {
@@ -162,8 +149,5 @@ public class ICABanken extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		if (urlopened == null) {
-			urlopen.close();
-		}
 	}		
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Lansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
index a9b4b80..93ae24e 100644
--- src/com/liato/bankdroid/banks/Lansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -34,7 +34,7 @@ public class Lansforsakringar extends Bank {
 	private Pattern reBalance = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-
+	private String accountsUrl = null;
 	public Lansforsakringar(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -49,14 +49,9 @@ public class Lansforsakringar extends Bank {
 		this.update(username, password);
 	}
 
-	@Override
-	public void update() throws BankException, LoginException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
-		Urllib urlopen = new Urllib();
+	
+	public Urllib login() throws LoginException, BankException {
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -100,10 +95,34 @@ public class Lansforsakringar extends Bank {
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
 			}
-			String accurl = Html.fromHtml(matcher.group(1)).toString();
-			accurl += "&_token=" + token;
-			Log.d("Bankdroid", "Account url: " + accurl);
-			response = urlopen.open(accurl);
+			accountsUrl = Html.fromHtml(matcher.group(1)).toString() + "&_token=" + token;
+			Log.d("Bankdroid", "Accounts url: " + accountsUrl);
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			if (accountsUrl == null) {
+				Log.d(TAG, "accountsUrl is null, unable to update.");
+				return;
+			}
+			response = urlopen.open(accountsUrl);
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
@@ -119,9 +138,5 @@ public class Lansforsakringar extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index 48c0b6e..cb35028 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -52,7 +52,7 @@ public class Nordea extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -84,17 +84,16 @@ public class Nordea extends Bank {
 		} catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}
 		return urlopen;
 	}
+	
 	@Override
 	public void update() throws BankException, LoginException {
 		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -140,22 +139,13 @@ public class Nordea extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
 	}
 
 	@Override
-	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
-		super.updateTransactions(account, urlopened);
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
 		if (account.getId().startsWith("l") || account.getId().startsWith("f")) return; //No transaction history for loans and funds
-		Urllib urlopen = null;
-		if (urlopened == null) {
-			urlopen = login();
-		}
-		else {
-			urlopen = urlopened;
-		}
+
 		String response = null;
 		Matcher matcher;
 		try {
@@ -181,9 +171,6 @@ public class Nordea extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		if (urlopened == null) {
-			urlopen.close();
-		}
 	}
 	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index b80c0d9..a9a2450 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -51,7 +51,7 @@ public class Statoil extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib(true);
+		urlopen = new Urllib(true);
 		String response = null;
 		try {
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -81,8 +81,6 @@ public class Statoil extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}
 		return urlopen;
 	}
 
@@ -92,7 +90,7 @@ public class Statoil extends Bank {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -112,23 +110,12 @@ public class Statoil extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 	
 	@Override
-	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
-		super.updateTransactions(account, urlopened);
-		Urllib urlopen = null;
-		if (urlopened == null) {
-			urlopen = login();
-		}
-		else {
-			urlopen = urlopened;
-		}
-		if (!urlopen.acceptsInvalidCertificates()) {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
+		if (!urlopen.acceptsInvalidCertificates()) { //Should never happen, but we'll check it anyway.
 			urlopen = login();
 		}
 		String response = null;
@@ -152,8 +139,5 @@ public class Statoil extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		if (urlopened == null) {
-			urlopen.close();
-		}
 	}	
 }
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index b6ed8de..678f5f5 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -50,7 +50,7 @@ public class Swedbank extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -76,8 +76,6 @@ public class Swedbank extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}
 		return urlopen;
 	}
 
@@ -87,7 +85,7 @@ public class Swedbank extends Bank {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -118,23 +116,13 @@ public class Swedbank extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 	
 	@Override
-	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
-		super.updateTransactions(account, urlopened);
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+		super.updateTransactions(account, urlopen);
 		if (account.getId().startsWith("l")) return; //No transaction history for loans
-		Urllib urlopen = null;
-		if (urlopened == null) {
-			urlopen = login();
-		}
-		else {
-			urlopen = urlopened;
-		}
+
 		String response = null;
 		Matcher matcher;
 		try {
@@ -153,8 +141,5 @@ public class Swedbank extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		if (urlopened == null) {
-			urlopen.close();
-		}
 	}	
 }
diff --git src/com/liato/bankdroid/banks/Villabanken.java src/com/liato/bankdroid/banks/Villabanken.java
index de90dbf..127ae09 100644
--- src/com/liato/bankdroid/banks/Villabanken.java
+++ src/com/liato/bankdroid/banks/Villabanken.java
@@ -51,7 +51,7 @@ public class Villabanken extends Bank {
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -121,8 +121,6 @@ public class Villabanken extends Bank {
 		} catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}
 		return urlopen;
 	}
 	@Override
@@ -131,7 +129,7 @@ public class Villabanken extends Bank {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -157,8 +155,5 @@ public class Villabanken extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
 	}
 }
\ No newline at end of file
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index 10da7f0..0f82761 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -38,12 +38,16 @@ public class Urllib {
 		this(false);
 	}
 	public Urllib(boolean acceptInvalidCertificates) {
+		this(acceptInvalidCertificates, false);
+	}	
+
+	public Urllib(boolean acceptInvalidCertificates, boolean allowCircularRedirects) {
 		this.acceptInvalidCertificates = acceptInvalidCertificates;
     	HttpParams params = new BasicHttpParams(); 
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, "UTF-8");
         params.setBooleanParameter("http.protocol.expect-continue", false);
-        params.setBooleanParameter("http.protocol.allow-circular-redirects", true);
+        if (allowCircularRedirects) params.setBooleanParameter("http.protocol.allow-circular-redirects", true);
 		if (acceptInvalidCertificates) {
 	        SchemeRegistry registry = new SchemeRegistry();
 	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
@@ -55,7 +59,6 @@ public class Urllib {
 			httpclient = new DefaultHttpClient();
 		}
     	context = new BasicHttpContext();
-
     }
     
     public String open(String url) throws ClientProtocolException, IOException {

commit 96bc9c6b2a75cea10ceb09187ae4f8235cd068ad
Merge: 1c40dcd 3461fc5
Author: liato <x@x00.us>
Date:   Thu Sep 23 01:00:35 2010 +0200

    Merge remote branch 'DEGE1/master'

commit 1c40dcd1e19e8c09c39238d9ed5009369f612987
Author: liato <x@x00.us>
Date:   Thu Sep 23 00:46:25 2010 +0200

    Bump to version 1.3.1

diff --git AndroidManifest.xml AndroidManifest.xml
index 6806c3a..4b763d0 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.3.1-RC1" android:versionCode="34">
+	package="com.liato.bankdroid" android:versionName="1.3.1" android:versionCode="34">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"

commit 3461fc539995907411badcb003cb8753006b3c3e
Author: DEGE1 <darko.guberina@gmail.com>
Date:   Wed Sep 22 15:33:20 2010 -0700

diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 982399c..3172b25 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -57,7 +57,7 @@ public class Handelsbanken extends Bank {
 	
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
 		try {
@@ -101,7 +101,7 @@ public class Handelsbanken extends Bank {
 			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 
-		Urllib urlopen = login();
+		urlopen = login();
 		String response = null;
 		Matcher matcher;
 		try {

commit d83ecc4be63395a0280688a4906e1fa50fa6c9b7
Author: DEGE1 <darko.guberina@gmail.com>
Date:   Wed Sep 22 12:56:28 2010 -0700

    Created urlopen member in order to skip duplicated recreation and logins.

diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index f7241ba..a99bf82 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -33,9 +33,18 @@ public abstract class Bank implements Comparable<Bank> {
 	protected ArrayList<Account> accounts = new ArrayList<Account>();
 	protected BigDecimal balance = new BigDecimal(0);
 	protected boolean disabled = false;
-	protected long dbid = -1;	
+	protected long dbid = -1;
+	protected Urllib urlopen = null;
 
 
+	public Urllib getUrlopen() {
+		return urlopen;
+	}
+
+	public void setUrlopen(Urllib urlopen) {
+		this.urlopen = urlopen;
+	}
+
 	public void setDbid(long dbid) {
 		this.dbid = dbid;
 	}
@@ -61,7 +70,9 @@ public abstract class Bank implements Comparable<Bank> {
 	}
 
 	public void updateAllTransactions() throws LoginException, BankException {
-		Urllib urlopen = login();
+		if (urlopen == null) {
+			urlopen = login();
+		}
 		for (Account account: accounts) {
 			updateTransactions(account, urlopen);
 		}

commit 3d808cc3c07d9060f8a0628f27394878c7c2fcdd
Author: DEGE1 <darko.guberina@gmail.com>
Date:   Wed Sep 22 12:52:57 2010 -0700

    Fixed transaction bug

diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index d797297..982399c 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -24,7 +24,7 @@ import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 /**
- * @author Darko
+ * @author DEGE
  *
  */
 public class Handelsbanken extends Bank {
@@ -91,8 +91,6 @@ public class Handelsbanken extends Bank {
 			Log.d(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
-		finally {
-		}		
 		return urlopen;
 	}
 	
@@ -122,7 +120,6 @@ public class Handelsbanken extends Bank {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 				accountIds.add(matcher.group(1));
-				updateShbTransactions((Account)accounts.get(accountId), urlopen);
 				accountId += 1;
 			}
 			if (accounts.isEmpty()) {
@@ -135,14 +132,10 @@ public class Handelsbanken extends Bank {
 		catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
-		finally {
-			urlopen.close();
-		}
-
 	}
 	
 
-	public void updateShbTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		String response = null;
 		Matcher matcher;
 		try {

commit e093052af6d64bb0a79bf557f202e6c869843983
Author: liato <x@x00.us>
Date:   Mon Sep 20 02:08:45 2010 +0200

    Added support for Villabanken and Avanza mini. Fixed Swedbank parsing bug.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8d3cd85..6806c3a 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionCode="33" android:versionName="1.3.0">
+	package="com.liato.bankdroid" android:versionName="1.3.1-RC1" android:versionCode="34">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index f7241ba..95bf306 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -19,6 +19,8 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int ICA = 7;
 	public final static int STATOIL = 8;
 	public final static int AVANZA = 9;
+	public final static int VILLABANKEN = 10;
+	
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 4b8022f..d9af4d5 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -15,6 +15,7 @@ import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
 import com.liato.bankdroid.banks.Statoil;
 import com.liato.bankdroid.banks.Swedbank;
+import com.liato.bankdroid.banks.Villabanken;
 
 public class BankFactory {
 
@@ -36,6 +37,10 @@ public class BankFactory {
 			return new ICA(context);
 		case Bank.STATOIL:
 			return new Statoil(context);
+		case Bank.AVANZA:
+			return new Avanza(context);
+		case Bank.VILLABANKEN:
+			return new Villabanken(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -53,6 +58,7 @@ public class BankFactory {
 		banks.add(new ICA(context));
 		banks.add(new Statoil(context));
 		banks.add(new Avanza(context));
+		banks.add(new Villabanken(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 27a5e61..e952f36 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -17,7 +17,14 @@ public class Helpers {
 			balance = balance.replace(".", "");
 			balance = balance+b;
 		}
-		return new BigDecimal(balance);
+		BigDecimal ret;
+		try {
+			ret = new BigDecimal(balance);
+		}
+		catch (NumberFormatException e) {
+			ret = new BigDecimal(0);
+		}
+		return ret;
 	}
 	public static String formatBalance(BigDecimal balance) {
 		DecimalFormatSymbols dfs = new DecimalFormatSymbols();
diff --git src/com/liato/bankdroid/banks/Avanza.java src/com/liato/bankdroid/banks/Avanza.java
index f835897..2443c15 100644
--- src/com/liato/bankdroid/banks/Avanza.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -34,7 +34,8 @@ public class Avanza extends Bank {
 	
 	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-
+	private Pattern reAvanzaMini = Pattern.compile("w100\\s+azatable\"[^>]+>\\s*<tr>\\s*<td>([^<]+)</td>\\s*<td\\s+class=\"tright\">([^<]+)</td.*?<td><strong>([^<]+)</strong></td>\\s+<td[^>]+>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private boolean avanzaMini = false;
 	public Avanza(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -63,10 +64,12 @@ public class Avanza extends Bank {
 			Log.d("BankAvanza", "Posting to https://www.avanza.se/aza/login/login.jsp");
 			response = urlopen.open("https://www.avanza.se/aza/login/login.jsp", postData);
 			Log.d("BankAvanza", "Url after post: "+urlopen.getCurrentURI());
-					
 			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
+			if (urlopen.getCurrentURI().equalsIgnoreCase("https://www.avanza.se/mini/hem/index.html")) {
+				avanzaMini = true;
+			}
 			
 		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
@@ -87,13 +90,26 @@ public class Avanza extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d("BankAvanza", "Opening: https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
-			response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
-						
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+			if (!avanzaMini) {
+				Log.d("BankAvanza", "Opening: https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
+				response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
+							
+				matcher = reAccounts.matcher(response);
+				while (matcher.find()) {
+					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
+					balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+				}
+			}
+			else {
+				Log.d("BankAvanza", "Opening: https://www.avanza.se/mini/mitt_konto/index.html");
+				response = urlopen.open("https://www.avanza.se/mini/mitt_konto/index.html");
+				matcher = reAvanzaMini.matcher(response);
+				if (matcher.find()) {
+					accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), "1"));
+					accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString().trim(), Helpers.parseBalance(matcher.group(4)), "2"));
+					balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+					balance = balance.add(Helpers.parseBalance(matcher.group(4)));
+				}
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -113,6 +129,7 @@ public class Avanza extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
 		super.updateTransactions(account, urlopened);
+		if (avanzaMini) return;
 		Urllib urlopen = null;
 		if (urlopened == null) {
 			urlopen = login();
diff --git src/com/liato/bankdroid/banks/Villabanken.java src/com/liato/bankdroid/banks/Villabanken.java
new file mode 100644
index 0000000..de90dbf
--- /dev/null
+++ src/com/liato/bankdroid/banks/Villabanken.java
@@ -0,0 +1,164 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class Villabanken extends Bank {
+	private static final String TAG = "Villabanken";
+	private static final String NAME = "Villabanken";
+	private static final String NAME_SHORT = "villabanken";
+	private static final String URL = "https://kundportal.cerdo.se/villabankenpub/card/default.aspx";
+	private static final int BANKTYPE_ID = Bank.VILLABANKEN;
+	
+	private Pattern reAccounts = Pattern.compile("<td[^>]+>((?:utnyttjad|kvar)[^:]+)[^>]+>([^<]+)</span>", Pattern.CASE_INSENSITIVE);
+	private Pattern reRequestDigest = Pattern.compile("__REQUESTDIGEST\".*?value=\"([^\"]+)\"");
+	private Pattern reViewState = Pattern.compile("__VIEWSTATE\".*?value=\"([^\"]+)\"");
+	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\".*?value=\"([^\"]+)\"");
+	private Pattern rePageHashCode = Pattern.compile("MSO_PageHashCode\".*?value=\"([^\"]+)\"");
+
+	public Villabanken(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Villabanken(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
+			matcher = reRequestDigest.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" request digest.");
+			}
+			String requestDigest = matcher.group(1);
+			
+			matcher = reViewState.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" view state.");
+			}
+			String viewState = matcher.group(1);
+			
+			matcher = reEventValidation.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" event validation.");
+			}
+			String eventValidation = matcher.group(1);
+
+			matcher = rePageHashCode.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" page hash code.");
+			}
+			String pageHashCode = matcher.group(1);
+
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("__spDummyText1", ""));
+			postData.add(new BasicNameValuePair("__spDummyText2", ""));
+			postData.add(new BasicNameValuePair("MSOWebPartPage_PostbackSource", ""));
+			postData.add(new BasicNameValuePair("MSOTlPn_SelectedWpId", ""));
+			postData.add(new BasicNameValuePair("MSOTlPn_View", "0"));
+			postData.add(new BasicNameValuePair("MSOTlPn_ShowSettings", "False"));
+			postData.add(new BasicNameValuePair("MSOGallery_SelectedLibrary", ""));
+			postData.add(new BasicNameValuePair("MSOGallery_FilterString", ""));
+			postData.add(new BasicNameValuePair("MSOTlPn_Button", "none"));
+			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+			postData.add(new BasicNameValuePair("MSOSPWebPartManager_DisplayModeName", "Browse"));
+			postData.add(new BasicNameValuePair("MSOWebPartPage_Shared", ""));
+			postData.add(new BasicNameValuePair("MSOLayout_LayoutChanges", ""));
+			postData.add(new BasicNameValuePair("MSOLayout_InDesignMode", ""));
+			postData.add(new BasicNameValuePair("MSOSPWebPartManager_OldDisplayModeName", "Browse"));
+			postData.add(new BasicNameValuePair("MSOSPWebPartManager_StartWebPartEditingName", "false"));
+			postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$ctl00", "Logga in"));
+			
+			postData.add(new BasicNameValuePair("__REQUESTDIGEST", requestDigest));
+			postData.add(new BasicNameValuePair("__VIEWSTATE", viewState));
+			postData.add(new BasicNameValuePair("__EVENTVALIDATION", eventValidation));
+			postData.add(new BasicNameValuePair("MSO_PageHashCode", pageHashCode));
+			postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$accountNumber", username));
+			postData.add(new BasicNameValuePair("ctl00$m$g_343be9ea_353d_40bc_bc55_184b89e22861$password", password));
+			
+			Log.d(TAG, "Posting to https://kundportal.cerdo.se/villabankenpub/card/default.aspx");
+			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/default.aspx", postData);
+			Log.d(TAG, "Url after post: "+urlopen.getCurrentURI());
+			
+			if (response.contains("misslyckades")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}
+		return urlopen;
+	}
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
+			response = urlopen.open("https://kundportal.cerdo.se/villabankenpub/card/secure/CardAccountOverview.aspx");
+
+			matcher = reAccounts.matcher(response);
+			Integer accountId = 0;
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2)), accountId.toString()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				accountId += 1;
+			}
+
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+	}
+}
\ No newline at end of file

commit 9354a9f19215aa19b3901df9e944dd34fb7505f5
Author: liato <x@x00.us>
Date:   Sun Sep 19 18:53:37 2010 +0200

    Bump version to 1.3.0

diff --git AndroidManifest.xml AndroidManifest.xml
index fb258c4..8d3cd85 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionCode="32" android:versionName="1.3.0-RC4">
+	package="com.liato.bankdroid" android:versionCode="33" android:versionName="1.3.0">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"

commit fbd600d1f6f13955f1ad586229adceaac1283817
Author: DEGE1 <darko.guberina@gmail.com>
Date:   Sun Sep 19 04:34:59 2010 -0700

    Fixed transaction history bug.

diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index afe687c..d797297 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -23,6 +23,10 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
+/**
+ * @author Darko
+ *
+ */
 public class Handelsbanken extends Bank {
 	private static final String TAG = "Handelsbanken";
 	private static final String NAME = "Handelsbanken";
@@ -118,6 +122,7 @@ public class Handelsbanken extends Bank {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 				accountIds.add(matcher.group(1));
+				updateShbTransactions((Account)accounts.get(accountId), urlopen);
 				accountId += 1;
 			}
 			if (accounts.isEmpty()) {
@@ -136,16 +141,8 @@ public class Handelsbanken extends Bank {
 
 	}
 	
-	@Override
-	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
-		super.updateTransactions(account, urlopened);
-		Urllib urlopen = null;
-		if (urlopened == null) {
-			urlopen = login();
-		}
-		else {
-			urlopen = urlopened;
-		}
+
+	public void updateShbTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
 		String response = null;
 		Matcher matcher;
 		try {
@@ -165,8 +162,5 @@ public class Handelsbanken extends Bank {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		if (urlopened == null) {
-			urlopen.close();
-		}
-	}	
+	}
 }
\ No newline at end of file

commit 557becd9f70ba7a52c7ea48196c46229c34f0827
Author: liato <x@x00.us>
Date:   Sun Sep 19 06:36:04 2010 +0200

    Added Avanza to dropdown list.

diff --git logos.psd logos.psd
index 28dbe72..83f0abe 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/villabanken.png res/drawable/villabanken.png
new file mode 100644
index 0000000..4621d48
Binary files /dev/null and res/drawable/villabanken.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 4ead881..d4cc561 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -78,7 +78,8 @@
     \nDustin (ICA)
     \ndimaZ (Statoil)
     \nOxygen (Statoil)
-    \Niclas Ljungstrand (Nordea)
-	\Ozzy (Avanza)
+    \nNiclas Ljungstrand (Nordea)
+	\nOzzy (Avanza)
+	\nasperon (Transparent widget)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 9be0ee5..6a2e7e1 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -79,7 +79,8 @@
     \nDustin (ICA)
     \ndimaZ (Statoil)
     \nOxygen (Statoil)
-    \Niclas Ljungstrand (Nordea)
-	\Ozzy (Avanza)
+    \nNiclas Ljungstrand (Nordea)
+	\nOzzy (Avanza)
+	\nasperon (Transparent widget)
      </string>
 </resources>
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 8a74204..4b8022f 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -6,6 +6,7 @@ import java.util.ArrayList;
 import android.content.Context;
 import android.database.Cursor;
 
+import com.liato.bankdroid.banks.Avanza;
 import com.liato.bankdroid.banks.Coop;
 import com.liato.bankdroid.banks.Handelsbanken;
 import com.liato.bankdroid.banks.ICA;
@@ -51,6 +52,7 @@ public class BankFactory {
 		banks.add(new Coop(context));
 		banks.add(new ICA(context));
 		banks.add(new Statoil(context));
+		banks.add(new Avanza(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index b6c81ad..48c0b6e 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -131,8 +131,8 @@ public class Nordea extends Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("568268.37"), "1"));
-			//accounts.add(new Account("Kapitalkonto", new BigDecimal("5789002.00"), "0"));
+			//accounts.add(new Account("Personkonto", Helpers.parseBalance("568268.37"), "1"));
+			//accounts.add(new Account("Kapitalkonto", Helpers.parseBalance("5789002.00"), "0"));
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 5d9644b..b6ed8de 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -92,6 +92,7 @@ public class Swedbank extends Bank {
 		Matcher matcher;
 		try {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
+			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l"+matcher.group(2).trim() : matcher.group(2).trim()));
@@ -108,8 +109,8 @@ public class Swedbank extends Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("85351"), "0"));
-			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
+			//accounts.add(new Account("Personkonto", Helpers.parseBalance("85351"), "0"));
+			//accounts.add(new Account("Sparkonto", Helpers.parseBalance("8590700"), "1"));
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
diff --git villabanken.psd villabanken.psd
new file mode 100644
index 0000000..2efedbb
Binary files /dev/null and villabanken.psd differ

commit bf136c7b0a92771418d1c44ae6d1326dee556c01
Author: liato <x@x00.us>
Date:   Sun Sep 19 04:52:51 2010 +0200

    Added transparent widgets. Added support for Avanza Bank. Retrieve Nordea funds and loans.

diff --git AndroidManifest.xml AndroidManifest.xml
index 7e5bb20..fb258c4 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.3.0-RC3" android:versionCode="31">
+	package="com.liato.bankdroid" android:versionCode="32" android:versionName="1.3.0-RC4">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git logos.psd logos.psd
index 6e0f108..28dbe72 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/avanza.png res/drawable/avanza.png
new file mode 100644
index 0000000..1d5b836
Binary files /dev/null and res/drawable/avanza.png differ
diff --git res/layout/main.xml res/layout/main.xml
index 04c774d..64e1097 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -5,6 +5,13 @@
 	android:layout_width="wrap_content"
 	android:layout_height="fill_parent"
 	android:background="@drawable/background_repeat">
+	<CheckBox
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:id="@+id/chkTransperantBackground"
+		android:visibility="gone"
+		android:layout_margin="10dp"
+		android:text="@string/transparent_background" />
 	<TextView
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
@@ -15,16 +22,18 @@
 	<ListView
 		android:layout_width="fill_parent"
 		android:id="@+id/lstAccountsList"
-		android:layout_height="fill_parent"
-		android:fitsSystemWindows="true"
-		android:layout_alignParentTop="true" android:cacheColorHint="#00000000" android:layout_above="@+id/layMainMenu"/>
+		android:layout_height="wrap_content"
+		android:cacheColorHint="#00000000"
+		android:layout_above="@+id/layMainMenu"
+		android:layout_below="@+id/chkTransperantBackground" android:layout_alignWithParentIfMissing="true"/>
 	<TableLayout
 		android:stretchColumns="0,2"
 		android:layout_height="wrap_content"
 		android:layout_alignParentBottom="true"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content" android:id="@+id/layMainMenu">
+		android:layout_width="wrap_content"
+		android:id="@+id/layMainMenu">
 		<TableRow
 			android:id="@+id/TableRow01"
 			android:layout_height="wrap_content"
diff --git res/layout/widget_large_transparent.xml res/layout/widget_large_transparent.xml
new file mode 100644
index 0000000..fcc3838
--- /dev/null
+++ res/layout/widget_large_transparent.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_gravity="center_horizontal"
+	android:layout_height="100dp"
+	android:id="@+id/layWidgetContainer" android:layout_width="320dp" >
+
+	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp" android:paddingTop="8dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="37dp"></TextView></RelativeLayout>
+</RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="15dp" android:paddingRight="11dp"><FrameLayout android:layout_height="wrap_content" android:id="@+id/frmWarning" android:layout_width="wrap_content" android:visibility="invisible">
+			<ImageView android:id="@+id/imgWarning" android:adjustViewBounds="true" android:layout_height="fill_parent" android:src="@drawable/indicator_input_error" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_gravity="top|right" android:maxWidth="17dp" android:maxHeight="17dp" android:minHeight="17dp" android:minWidth="17dp"></ImageView>
+		</FrameLayout></RelativeLayout><RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp" android:id="@+id/hitBox"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
+	
+	
+	
+
+
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/widget_transparent.xml res/layout/widget_transparent.xml
new file mode 100644
index 0000000..c3a18bb
--- /dev/null
+++ res/layout/widget_transparent.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_gravity="center_horizontal"
+	
+	android:layout_height="100dp"
+	android:layout_width="160dp" android:id="@+id/layWidgetContainer" android:paddingTop="22dp" android:paddingLeft="19dp" android:paddingRight="18dp" android:paddingBottom="20dp">
+
+	<FrameLayout android:layout_height="22dp" android:layout_width="fill_parent" android:id="@+id/hitBox" android:focusable="true"></FrameLayout><LinearLayout
+		android:layout_height="wrap_content"
+		android:layout_width="wrap_content"
+		android:id="@+id/layWidgetRow01"
+		android:layout_marginTop="0dp">
+		<ImageView
+			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+			android:layout_width="22dp"
+			android:layout_height="22dp"
+			android:id="@+id/imgWidgetIcon"
+			android:layout_gravity="center_vertical"
+			android:baselineAlignBottom="true"
+			android:src="@drawable/icon"
+			android:scaleType="fitXY"></ImageView>
+		<TextView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:id="@+id/txtWidgetAccountname"
+			android:layout_gravity="center_vertical"
+			android:textColor="#a8a3a3"
+			android:textSize="11dp"
+			android:inputType="none"
+			android:layout_marginLeft="2dp" android:text="Bankdroid"></TextView>
+	</LinearLayout>
+	<LinearLayout
+		android:id="@+id/layWidgetRow02"
+		android:layout_below="@+id/layWidgetRow01"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:layout_marginTop="7dp">
+		<TextView
+			android:textColor="#fff"
+			android:inputType="none"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent"
+			android:ellipsize="none"
+			android:gravity="center_vertical|center_horizontal"
+			android:textSize="15dp"
+			android:id="@+id/txtWidgetAccountbalance"
+			android:layout_height="fill_parent" android:text="Loading..."/>
+	</LinearLayout>
+	<LinearLayout
+		android:id="@+id/layWidgetRow03"
+		android:layout_below="@+id/layWidgetRow02"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:gravity="bottom"
+		android:layout_alignParentBottom="true"
+		android:visibility="visible">
+		
+		<FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:maxHeight="2dp" android:minHeight="2dp" android:minWidth="17dp" android:visibility="visible"></ProgressBar></FrameLayout>
+
+
+		<FrameLayout
+			android:layout_height="wrap_content"
+			android:id="@+id/frmWarning"
+			android:layout_width="fill_parent"
+			android:visibility="invisible">
+			<ImageView
+				android:id="@+id/imgWarning"
+				android:adjustViewBounds="true"
+				android:layout_gravity="bottom|right"
+				android:layout_height="fill_parent"
+				android:src="@drawable/indicator_input_error"
+				android:scaleType="fitXY"
+				android:layout_width="wrap_content"></ImageView>
+		</FrameLayout>
+	</LinearLayout>
+	
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index b038cec..4ead881 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -15,6 +15,7 @@
     <string name="invalid_username_password">Personnummer och lösenord stämmer ej.</string>
     <string name="unable_to_find">Kunde ej hitta</string>
     <string name="no_accounts_found">Inga konton funna</string>
+    <string name="transparent_background">Transparent bakgrund</string>
     
     <string name="username">Personnummer</string>
     <string name="password">Lösenord</string>
@@ -77,5 +78,7 @@
     \nDustin (ICA)
     \ndimaZ (Statoil)
     \nOxygen (Statoil)
+    \Niclas Ljungstrand (Nordea)
+	\Ozzy (Avanza)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 076ba19..9be0ee5 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -15,6 +15,7 @@
     <string name="invalid_username_password">Invalid username or password.</string>
     <string name="unable_to_find">Unable to find</string>
     <string name="no_accounts_found">No accounts found</string>
+    <string name="transparent_background">Transparent background</string>
     
     <string name="username">Username</string>
     <string name="password">Password</string>
@@ -78,5 +79,7 @@
     \nDustin (ICA)
     \ndimaZ (Statoil)
     \nOxygen (Statoil)
+    \Niclas Ljungstrand (Nordea)
+	\Ozzy (Avanza)
      </string>
 </resources>
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index db53d5e..f7241ba 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -18,6 +18,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int COOP = 6;
 	public final static int ICA = 7;
 	public final static int STATOIL = 8;
+	public final static int AVANZA = 9;
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 9b6e45b..91c0c76 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -7,6 +7,7 @@ import android.appwidget.AppWidgetProvider;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.IBinder;
@@ -67,6 +68,14 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Log.d("Widget", "Building widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
+		if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) {
+			if (providerInfo.initialLayout == R.layout.widget_large) {
+				layoutId = R.layout.widget_large_transparent;
+			} else {
+				layoutId = R.layout.widget_transparent;
+			}
+		}
 		Bank bank = account.getBank();
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
@@ -107,6 +116,14 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Log.d("Widget", "Disabling widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
+        SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);		
+		if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) {
+			if (providerInfo.initialLayout == R.layout.widget_large) {
+				layoutId=R.layout.widget_large_transparent;
+			} else {
+				layoutId=R.layout.widget_transparent;
+			}
+		}		
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
 		views.setTextViewText(R.id.txtWidgetAccountname, "");
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index 2e2db8c..7a7a48d 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -11,6 +11,7 @@ import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.widget.AdapterView;
+import android.widget.CheckBox;
 import android.widget.ListView;
 import android.widget.AdapterView.OnItemClickListener;
 
@@ -71,6 +72,9 @@ public class WidgetConfigureActivity extends Activity {
 				final Context context = WidgetConfigureActivity.this;
 	            Account account = (Account)parent.getItemAtPosition(position);
 	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, account.getId());
+	            SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+	            prefs.putBoolean("transperant_background" + mAppWidgetId, ((CheckBox)findViewById(R.id.chkTransperantBackground)).isChecked());
+	            prefs.commit();	            
 	            // Push widget update to surface with newly set prefix
 	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
 	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
@@ -113,6 +117,7 @@ public class WidgetConfigureActivity extends Activity {
 		ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
 
 		if (banks.size() > 0) {
+			findViewById(R.id.chkTransperantBackground).setVisibility(View.VISIBLE);
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
 			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 			adapter = new AccountsAdapter(this);
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Avanza.java
similarity index 53%
copy from src/com/liato/bankdroid/banks/Swedbank.java
copy to src/com/liato/bankdroid/banks/Avanza.java
index 8cd35ce..f835897 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Avanza.java
@@ -1,7 +1,9 @@
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -23,17 +25,17 @@ import com.liato.bankdroid.R;
 import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
-public class Swedbank extends Bank {
-	private static final String TAG = "Swedbank";
-	private static final String NAME = "Swedbank";
-	private static final String NAME_SHORT = "swedbank";
-	private static final String URL = "https://mobilbank.swedbank.se/";
-	private static final int BANKTYPE_ID = Bank.SWEDBANK;
+public class Avanza extends Bank {
+	private static final String TAG = "Avanza";
+	private static final String NAME = "Avanza";
+	private static final String NAME_SHORT = "avanza";
+	private static final String URL = "https://www.avanza.se/";
+	private static final int BANKTYPE_ID = Bank.AVANZA;
+	
+	private Pattern reAccounts = Pattern.compile("depa\\.jsp\\?depotnr=(\\d*).*?(?:width=\"235\">*?)(.*?)<.*?(?:looser|winner).*?>(.*?)<.*?(?:looser|winner).*?>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("(?:warrantguide\\.jsp|aktie\\.jsp)(?:.*?)orderbookId=(?:.*?)>(.*?)<(?:.*?)<nobr>(?:.*?)<nobr>(?:.*?)<nobr>(.*?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
-	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
-	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
-	public Swedbank(Context context) {
+	public Avanza(Context context) {
 		super(context);
 		super.TAG = TAG;
 		super.NAME = NAME;
@@ -42,44 +44,39 @@ public class Swedbank extends Bank {
 		super.URL = URL;
 	}
 
-	public Swedbank(String username, String password, Context context) throws BankException, LoginException {
+	public Avanza(String username, String password, Context context) throws BankException, LoginException {
 		this(context);
 		this.update(username, password);
 	}
 
 	@Override
 	public Urllib login() throws LoginException, BankException {
-		Urllib urlopen = new Urllib();
+		Urllib urlopen = new Urllib(true);
 		String response = null;
-		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
-			matcher = reCSRF.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-			}
-			String csrftoken = matcher.group(1);
+			//response = urlopen.open("https://www.avanza.se/aza/login/logout.jsp");
+
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("xyz", username));
-			postData.add(new BasicNameValuePair("zyx", password));
-			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
+			postData.add(new BasicNameValuePair("username", username));
+			postData.add(new BasicNameValuePair("password", password));
 
-			if (response.contains("misslyckats")) {
+			Log.d("BankAvanza", "Posting to https://www.avanza.se/aza/login/login.jsp");
+			response = urlopen.open("https://www.avanza.se/aza/login/login.jsp", postData);
+			Log.d("BankAvanza", "Url after post: "+urlopen.getCurrentURI());
+					
+			if (response.contains("Felaktigt") && !response.contains("Logga ut")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
-		}
-		catch (ClientProtocolException e) {
+			
+		} catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
+		} catch (IOException e) {
 			throw new BankException(e.getMessage());
 		}
 		finally {
 		}
 		return urlopen;
 	}
-
 	@Override
 	public void update() throws BankException, LoginException {
 		super.update();
@@ -90,18 +87,17 @@ public class Swedbank extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
+			Log.d("BankAvanza", "Opening: https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
+			response = urlopen.open("https://www.avanza.se/aza/depa/sammanfattning/sammanfattning.jsp");
+						
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l"+matcher.group(2).trim() : matcher.group(2).trim()));
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(4)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("85351"), "0"));
-			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
@@ -112,13 +108,11 @@ public class Swedbank extends Bank {
 		finally {
 			urlopen.close();
 		}
-
 	}
-	
+
 	@Override
 	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
 		super.updateTransactions(account, urlopened);
-		if (account.getId().startsWith("l")) return; //No transaction history for loans
 		Urllib urlopen = null;
 		if (urlopened == null) {
 			urlopen = login();
@@ -128,13 +122,18 @@ public class Swedbank extends Bank {
 		}
 		String response = null;
 		Matcher matcher;
-		try {
-			Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+		try {						
+			response = urlopen.open("https://www.avanza.se/aza/depa/depa.jsp?depotnr="+account.getId());
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			String strDate = null;
+			Calendar cal = Calendar.getInstance();
+			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+			strDate = sdf.format(cal.getTime());
+
 			while (matcher.find()) {
-				transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+				//Log.d(TAG, "Date: "+strDate+"; Trans: "+Html.fromHtml(matcher.group(2)).toString().trim()+"; Amount: "+Helpers.parseBalance(matcher.group(3)).toString());
+				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(2))));
 			}
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
@@ -147,5 +146,6 @@ public class Swedbank extends Bank {
 		if (urlopened == null) {
 			urlopen.close();
 		}
-	}	
-}
+	}
+	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
index c2a64b9..b6c81ad 100644
--- src/com/liato/bankdroid/banks/Nordea.java
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -31,7 +31,8 @@ public class Nordea extends Bank {
 	private static final String URL = "https://mobil.nordea.se/";
 	private static final int BANKTYPE_ID = Bank.NORDEA;
 	
-	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE );
+	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE);
+	private Pattern reFundsLoans = Pattern.compile("(?:fund|loan)\\.html\\?id=(?:fonder|lan):([^\"]+)\".*?>.*?>([^<]+).*?>([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reTransactions = Pattern.compile("(\\d{2}.\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 
@@ -108,6 +109,24 @@ public class Nordea extends Bank {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
+
+			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/funds/portfolio/funds.html");
+
+			matcher = reFundsLoans.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "f"+matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+
+			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html?type=lan");
+			
+			matcher = reFundsLoans.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), "l"+matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
@@ -129,6 +148,7 @@ public class Nordea extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
 		super.updateTransactions(account, urlopened);
+		if (account.getId().startsWith("l") || account.getId().startsWith("f")) return; //No transaction history for loans and funds
 		Urllib urlopen = null;
 		if (urlopened == null) {
 			urlopen = login();
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 8cd35ce..5d9644b 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -32,6 +32,7 @@ public class Swedbank extends Bank {
 
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
+	private Pattern reLinklessAccounts = Pattern.compile("<li>\\s*([^<]+)<br/?><span\\sclass=\"secondary\">([^<]+)</span>\\s*</li>", Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	public Swedbank(Context context) {
 		super(context);
@@ -96,6 +97,13 @@ public class Swedbank extends Bank {
 				accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l"+matcher.group(2).trim() : matcher.group(2).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
+			matcher = reLinklessAccounts.matcher(response);
+			int accid = 0;
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2)), "ll"+accid));
+				balance = balance.add(Helpers.parseBalance(matcher.group(2)));
+				accid++;
+			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index c8543f6..10da7f0 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -43,6 +43,7 @@ public class Urllib {
     	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, "UTF-8");
         params.setBooleanParameter("http.protocol.expect-continue", false);
+        params.setBooleanParameter("http.protocol.allow-circular-redirects", true);
 		if (acceptInvalidCertificates) {
 	        SchemeRegistry registry = new SchemeRegistry();
 	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

commit 0d3973cf559c5fa00af9b84f5b5650f474cd71a4
Author: liato <x@x00.us>
Date:   Mon Aug 16 16:10:28 2010 +0200

    Improved Swedbank loan regex. Fixed Statoil login.

diff --git AndroidManifest.xml AndroidManifest.xml
index 4e2121d..7e5bb20 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.3.0-RC2" android:versionCode="30">
+	package="com.liato.bankdroid" android:versionName="1.3.0-RC3" android:versionCode="31">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index cb92bf2..b80c0d9 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -54,14 +54,20 @@ public class Statoil extends Bank {
 		Urllib urlopen = new Urllib(true);
 		String response = null;
 		try {
-			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
+			List<NameValuePair> parameters = new ArrayList<NameValuePair>(3);
+            parameters.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
+            parameters.add(new BasicNameValuePair("referer", "login.jsp"));
+            response = urlopen.open("https://applications.sebkort.com/nis/external/hidden.jsp", postData);
+            
+			postData.clear();
 			postData.add(new BasicNameValuePair("choice", "PWD"));
-			postData.add(new BasicNameValuePair("uname", username));
+			postData.add(new BasicNameValuePair("uname", username.toUpperCase()));
 			postData.add(new BasicNameValuePair("PASSWORD", password));
 			postData.add(new BasicNameValuePair("target", "/nis/stse/main.do"));
 			postData.add(new BasicNameValuePair("prodgroup", "0122"));
-			postData.add(new BasicNameValuePair("USERNAME", "0122"+username));
+			postData.add(new BasicNameValuePair("USERNAME", "0122"+username.toUpperCase()));
 			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
 			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
 			response = urlopen.open("https://applications.sebkort.com/siteminderagent/forms/generic.fcc", postData);
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 9c0388f..8cd35ce 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -31,7 +31,7 @@ public class Swedbank extends Bank {
 	private static final int BANKTYPE_ID = Bank.SWEDBANK;
 
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
+	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*(?:<span.*?/span>)?([^<]+)<.*?secondary\">([^<]+)</span");
 	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	public Swedbank(Context context) {
 		super(context);

commit e36671f41d72fcec9dd5a547eeddaa2663297b83
Author: liato <x@x00.us>
Date:   Mon Aug 16 14:12:59 2010 +0200

    Fixed Statoil. Show loans on Swedbank.

diff --git AndroidManifest.xml AndroidManifest.xml
index 8b1d77f..4e2121d 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.2.1" android:versionCode="28">
+	package="com.liato.bankdroid" android:versionName="1.3.0-RC2" android:versionCode="30">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/Transaction.java src/com/liato/bankdroid/Transaction.java
index da90778..59be14f 100644
--- src/com/liato/bankdroid/Transaction.java
+++ src/com/liato/bankdroid/Transaction.java
@@ -2,7 +2,7 @@ package com.liato.bankdroid;
 
 import java.math.BigDecimal;
 
-public class Transaction {
+public class Transaction implements Comparable<Transaction> {
 	private String date;
 	private String transaction;
 	private BigDecimal amount;
@@ -36,4 +36,11 @@ public class Transaction {
 	public void setAmount(BigDecimal amount) {
 		this.amount = amount;
 	}
+
+	@Override
+	public int compareTo(Transaction another) {
+		Integer thisdate = Integer.parseInt(date.replaceAll("-", ""));
+		Integer thatdate = Integer.parseInt((another).getDate().replaceAll("-", ""));
+		return thisdate - thatdate;
+	}
 }
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
index 639d0b3..cb92bf2 100644
--- src/com/liato/bankdroid/banks/Statoil.java
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -1,7 +1,10 @@
 package com.liato.bankdroid.banks;
 
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -11,6 +14,8 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.text.Html;
+import android.util.Log;
 
 import com.liato.bankdroid.Account;
 import com.liato.bankdroid.Bank;
@@ -18,6 +23,7 @@ import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 public class Statoil extends Bank {
@@ -28,7 +34,7 @@ public class Statoil extends Bank {
 	private static final int BANKTYPE_ID = Bank.STATOIL;
 
 	private Pattern reAccounts = Pattern.compile("class=\"Right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
-	//private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("(?:7px\">|</a>)\\s*(\\d{2}-\\d{2})\\s*</td>\\s*<td>[^<]+</td>\\s*<[^>]+>([^<]+)</td>\\s*<[^>]+>([^<]+)<.*?nowrap>([^<]+)<", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	public Statoil(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -58,7 +64,7 @@ public class Statoil extends Bank {
 			postData.add(new BasicNameValuePair("USERNAME", "0122"+username));
 			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
 			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
-			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do", postData);
+			response = urlopen.open("https://applications.sebkort.com/siteminderagent/forms/generic.fcc", postData);
 			if (response.contains("du loggar in till")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -106,7 +112,7 @@ public class Statoil extends Bank {
 
 	}
 	
-	/*@Override
+	@Override
 	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
 		super.updateTransactions(account, urlopened);
 		Urllib urlopen = null;
@@ -122,13 +128,16 @@ public class Statoil extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+			Log.d(TAG, "Opening: https://applications.sebkort.com/nis/stse/getPendingTransactions.do");
+			response = urlopen.open("https://applications.sebkort.com/nis/stse/getPendingTransactions.do");
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			Calendar cal = Calendar.getInstance();
 			while (matcher.find()) {
-				transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+				transactions.add(new Transaction(""+cal.get(Calendar.YEAR)+"-"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim()+(Html.fromHtml(matcher.group(3)).toString().trim().length() > 1 ? " ("+Html.fromHtml(matcher.group(3)).toString().trim()+")" : ""), Helpers.parseBalance(matcher.group(4)).multiply(new BigDecimal(-1))));
 			}
+			Collections.sort(transactions);
+			Collections.reverse(transactions);
 			account.setTransactions(transactions);
 		} catch (ClientProtocolException e) {
 			// TODO Auto-generated catch block
@@ -140,5 +149,5 @@ public class Statoil extends Bank {
 		if (urlopened == null) {
 			urlopen.close();
 		}
-	}	*/
+	}	
 }
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
index 1b2a82c..9c0388f 100644
--- src/com/liato/bankdroid/banks/Swedbank.java
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -31,7 +31,7 @@ public class Swedbank extends Bank {
 	private static final int BANKTYPE_ID = Bank.SWEDBANK;
 
 	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
+	private Pattern reAccounts = Pattern.compile("(account|loan)\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
 	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
 	public Swedbank(Context context) {
 		super(context);
@@ -53,7 +53,7 @@ public class Swedbank extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html");
 			matcher = reCSRF.matcher(response);
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
@@ -90,11 +90,11 @@ public class Swedbank extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/accounts.html");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				accounts.add(new Account(Html.fromHtml(matcher.group(3)).toString(), Helpers.parseBalance(matcher.group(4)), matcher.group(2).trim() == "loan" ? "l"+matcher.group(2).trim() : matcher.group(2).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(4)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
@@ -118,6 +118,7 @@ public class Swedbank extends Bank {
 	@Override
 	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
 		super.updateTransactions(account, urlopened);
+		if (account.getId().startsWith("l")) return; //No transaction history for loans
 		Urllib urlopen = null;
 		if (urlopened == null) {
 			urlopen = login();

commit 4fdeac418385a7c5ca5f67ed60a2c075329ba083
Author: liato <x@x00.us>
Date:   Mon Aug 16 03:22:12 2010 +0200

    Added transaction history to "Handelsbanken". Increased refresh-hitbox size on widgets.

diff --git res/layout/widget.xml res/layout/widget.xml
index 4f757b1..883e9b2 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -6,7 +6,7 @@
 	android:layout_height="100dp"
 	android:layout_width="160dp" android:id="@+id/layWidgetContainer">
 
-	<LinearLayout
+	<FrameLayout android:layout_height="22dp" android:layout_width="fill_parent" android:id="@+id/hitBox" android:focusable="true"></FrameLayout><LinearLayout
 		android:layout_height="wrap_content"
 		android:layout_width="wrap_content"
 		android:id="@+id/layWidgetRow01"
@@ -76,4 +76,5 @@
 	</LinearLayout>
 	
 
+
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/widget_large.xml res/layout/widget_large.xml
index 4fd4168..13d4fe0 100644
--- res/layout/widget_large.xml
+++ res/layout/widget_large.xml
@@ -8,7 +8,7 @@
 	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp" android:paddingTop="8dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="37dp"></TextView></RelativeLayout>
 </RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="15dp" android:paddingRight="11dp"><FrameLayout android:layout_height="wrap_content" android:id="@+id/frmWarning" android:layout_width="wrap_content" android:visibility="invisible">
 			<ImageView android:id="@+id/imgWarning" android:adjustViewBounds="true" android:layout_height="fill_parent" android:src="@drawable/indicator_input_error" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_gravity="top|right" android:maxWidth="17dp" android:maxHeight="17dp" android:minHeight="17dp" android:minWidth="17dp"></ImageView>
-		</FrameLayout></RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
+		</FrameLayout></RelativeLayout><RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp" android:id="@+id/hitBox"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
 	
 	
 	
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 6bb64b5..9b6e45b 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -95,6 +95,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		intent.setData(Uri.parse("rofl://copter/"+appWidgetId+"/"+System.currentTimeMillis()));
 		pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 		views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent);
+		views.setOnClickPendingIntent(R.id.hitBox, pendingIntent);
 
 		//appWidgetManager.updateAppWidget(appWidgetId, views); 
 		return views;
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index d5689cb..afe687c 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -34,6 +34,8 @@ public class Handelsbanken extends Bank {
 	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
 	private Pattern reLoginUrl = Pattern.compile("_-([^\"]+)\"><img[^>]*><img[^>]*><span[^>]*>Logga",Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE);
+
+	private ArrayList<String> accountIds = new ArrayList<String>(); 
 	public Handelsbanken(Context context) {
 		super(context);
 		super.TAG = TAG;
@@ -111,10 +113,11 @@ public class Handelsbanken extends Bank {
 			Log.d("TAG", "Accounts url: "+strAccountsUrl);
 			response = urlopen.open(strAccountsUrl);
 			matcher = reBalance.matcher(response);
-			Integer accountId = 1;
+			Integer accountId = 0;
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				accountIds.add(matcher.group(1));
 				accountId += 1;
 			}
 			if (accounts.isEmpty()) {
@@ -146,8 +149,9 @@ public class Handelsbanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			Log.d(TAG, "Opening: https://m.handelsbanken.se/primary/_-"+account.getId());
-			response = urlopen.open("https://m.handelsbanken.se/primary/_-"+account.getId());
+			String accountWebId = accountIds.get(Integer.parseInt(account.getId()));
+			Log.d(TAG, "Opening: https://m.handelsbanken.se/primary/_-"+accountWebId);
+			response = urlopen.open("https://m.handelsbanken.se/primary/_-"+accountWebId);
 			matcher = reTransactions.matcher(response);
 			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
 			while (matcher.find()) {

commit a4f60594033f0b2bb23899d800230db8411b029e
Author: liato <x@x00.us>
Date:   Mon Aug 16 02:50:47 2010 +0200

    Added support for "Statoil MasterCard", closes #3.

diff --git res/drawable/statoil.png res/drawable/statoil.png
new file mode 100644
index 0000000..b1f7415
Binary files /dev/null and res/drawable/statoil.png differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 8aaec03..b038cec 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -73,5 +73,9 @@
     \nHund (Handelsbanken)
     \nTravolta (Coop)
     \nDaniel Malmgren (Coop)
+    \nisocron (ICA)
+    \nDustin (ICA)
+    \ndimaZ (Statoil)
+    \nOxygen (Statoil)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 6650467..076ba19 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -74,5 +74,9 @@
     \nHund (Handelsbanken)
     \nTravolta (Coop)
     \nDaniel Malmgren (Coop)
-    </string>
+    \nisocron (ICA)
+    \nDustin (ICA)
+    \ndimaZ (Statoil)
+    \nOxygen (Statoil)
+     </string>
 </resources>
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index a8d1cec..db53d5e 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -17,6 +17,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int HANDELSBANKEN = 5;
 	public final static int COOP = 6;
 	public final static int ICA = 7;
+	public final static int STATOIL = 8;
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 1d424de..8a74204 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -12,6 +12,7 @@ import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
 import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
+import com.liato.bankdroid.banks.Statoil;
 import com.liato.bankdroid.banks.Swedbank;
 
 public class BankFactory {
@@ -32,6 +33,8 @@ public class BankFactory {
 			return new Coop(context);
 		case Bank.ICA:
 			return new ICA(context);
+		case Bank.STATOIL:
+			return new Statoil(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -47,6 +50,7 @@ public class BankFactory {
 		banks.add(new Handelsbanken(context));
 		banks.add(new Coop(context));
 		banks.add(new ICA(context));
+		banks.add(new Statoil(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index a28c6c3..d5689cb 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -111,9 +111,11 @@ public class Handelsbanken extends Bank {
 			Log.d("TAG", "Accounts url: "+strAccountsUrl);
 			response = urlopen.open(strAccountsUrl);
 			matcher = reBalance.matcher(response);
+			Integer accountId = 1;
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), accountId.toString()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+				accountId += 1;
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git src/com/liato/bankdroid/banks/Statoil.java src/com/liato/bankdroid/banks/Statoil.java
new file mode 100644
index 0000000..639d0b3
--- /dev/null
+++ src/com/liato/bankdroid/banks/Statoil.java
@@ -0,0 +1,144 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class Statoil extends Bank {
+	private static final String TAG = "Statoil";
+	private static final String NAME = "Statoil";
+	private static final String NAME_SHORT = "statoil";
+	private static final String URL = "https://applications.sebkort.com/nis/external/stse/login.do";
+	private static final int BANKTYPE_ID = Bank.STATOIL;
+
+	private Pattern reAccounts = Pattern.compile("class=\"Right\">([^<]+)<", Pattern.CASE_INSENSITIVE);
+	//private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	public Statoil(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Statoil(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		Urllib urlopen = new Urllib(true);
+		String response = null;
+		try {
+			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do");
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("choice", "PWD"));
+			postData.add(new BasicNameValuePair("uname", username));
+			postData.add(new BasicNameValuePair("PASSWORD", password));
+			postData.add(new BasicNameValuePair("target", "/nis/stse/main.do"));
+			postData.add(new BasicNameValuePair("prodgroup", "0122"));
+			postData.add(new BasicNameValuePair("USERNAME", "0122"+username));
+			postData.add(new BasicNameValuePair("METHOD", "LOGIN"));
+			postData.add(new BasicNameValuePair("CURRENT_METHOD", "PWD"));
+			response = urlopen.open("https://applications.sebkort.com/nis/external/stse/login.do", postData);
+			if (response.contains("du loggar in till")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://applications.sebkort.com/nis/stse/main.do");
+			matcher = reAccounts.matcher(response);
+			if (matcher.find()) {
+				accounts.add(new Account("Statoil MasterCard" , Helpers.parseBalance(matcher.group(1)), "1"));
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+	
+	/*@Override
+	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
+		super.updateTransactions(account, urlopened);
+		Urllib urlopen = null;
+		if (urlopened == null) {
+			urlopen = login();
+		}
+		else {
+			urlopen = urlopened;
+		}
+		if (!urlopen.acceptsInvalidCertificates()) {
+			urlopen = login();
+		}
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (urlopened == null) {
+			urlopen.close();
+		}
+	}	*/
+}
diff --git src/com/liato/urllib/EasySSLSocketFactory.java src/com/liato/urllib/EasySSLSocketFactory.java
new file mode 100644
index 0000000..61d2d15
--- /dev/null
+++ src/com/liato/urllib/EasySSLSocketFactory.java
@@ -0,0 +1,147 @@
+package com.liato.urllib;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.scheme.LayeredSocketFactory;
+import org.apache.http.conn.scheme.SocketFactory;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+/**
+ * This socket factory will create ssl socket that accepts self signed
+ * certificate
+ * 
+ * @author olamy
+ * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
+ *          $
+ * @since 1.2.3
+ */
+public class EasySSLSocketFactory implements SocketFactory,
+		LayeredSocketFactory {
+
+	private SSLContext sslcontext = null;
+
+	private static SSLContext createEasySSLContext() throws IOException {
+		try {
+			SSLContext context = SSLContext.getInstance("TLS");
+			context.init(null, new TrustManager[] { new TrivialTrustManager() }, null);
+			return context;
+		} catch (Exception e) {
+			throw new IOException(e.getMessage());
+		}
+	}
+
+	private SSLContext getSSLContext() throws IOException {
+		if (this.sslcontext == null) {
+			this.sslcontext = createEasySSLContext();
+		}
+		return this.sslcontext;
+	}
+
+	/**
+	 * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
+	 *      java.lang.String, int, java.net.InetAddress, int,
+	 *      org.apache.http.params.HttpParams)
+	 */
+	public Socket connectSocket(Socket sock, String host, int port,
+			InetAddress localAddress, int localPort, HttpParams params)
+			throws IOException, UnknownHostException, ConnectTimeoutException {
+		int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
+		int soTimeout = HttpConnectionParams.getSoTimeout(params);
+
+		InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
+		SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
+
+		if ((localAddress != null) || (localPort > 0)) {
+			// we need to bind explicitly
+			if (localPort < 0) {
+				localPort = 0; // indicates "any"
+			}
+			InetSocketAddress isa = new InetSocketAddress(localAddress,
+					localPort);
+			sslsock.bind(isa);
+		}
+
+		sslsock.connect(remoteAddress, connTimeout);
+		sslsock.setSoTimeout(soTimeout);
+		return sslsock;
+
+	}
+
+	/**
+	 * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
+	 */
+	public Socket createSocket() throws IOException {
+		return getSSLContext().getSocketFactory().createSocket();
+		
+	}
+	
+
+
+	/**
+	 * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
+	 */
+	public boolean isSecure(Socket socket) throws IllegalArgumentException {
+		return true;
+	}
+
+	/**
+	 * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
+	 *      java.lang.String, int, boolean)
+	 */
+	/*public Socket createSocket(Socket socket, String host, int port,
+			boolean autoClose) throws IOException, UnknownHostException {
+		return getSSLContext().getSocketFactory().createSocket();
+	}*/
+    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
+                    throws IOException, UnknownHostException {
+            return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
+    }		
+
+	// -------------------------------------------------------------------
+	// javadoc in org.apache.http.conn.scheme.SocketFactory says :
+	// Both Object.equals() and Object.hashCode() must be overridden
+	// for the correct operation of some connection managers
+	// -------------------------------------------------------------------
+
+	public boolean equals(Object obj) {
+		return ((obj != null) && obj.getClass().equals(
+				EasySSLSocketFactory.class));
+	}
+
+	public int hashCode() {
+		return EasySSLSocketFactory.class.hashCode();
+	}
+
+
+	
+	
+}
diff --git src/com/liato/urllib/TrivialTrustManager.java src/com/liato/urllib/TrivialTrustManager.java
new file mode 100644
index 0000000..be57bc9
--- /dev/null
+++ src/com/liato/urllib/TrivialTrustManager.java
@@ -0,0 +1,21 @@
+package com.liato.urllib;
+
+public class TrivialTrustManager implements javax.net.ssl.X509TrustManager {
+    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+        return new java.security.cert.X509Certificate[0];
+    }
+	@Override
+	public void checkClientTrusted(
+			java.security.cert.X509Certificate[] chain, String authType)
+			throws java.security.cert.CertificateException {
+		// TODO Auto-generated method stub
+		
+	}
+	@Override
+	public void checkServerTrusted(
+			java.security.cert.X509Certificate[] chain, String authType)
+			throws java.security.cert.CertificateException {
+		// TODO Auto-generated method stub
+		
+	}
+}
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index c62622a..c8543f6 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -5,6 +5,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.http.HttpHost;
+import org.apache.http.HttpVersion;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.ResponseHandler;
@@ -12,8 +13,12 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
+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.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
@@ -27,13 +32,29 @@ public class Urllib {
 	private HttpContext context;
 	private String currentURI;
 	private final static String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+	private boolean acceptInvalidCertificates = false;
 	
-    public Urllib() {
-    	httpclient = new DefaultHttpClient();
-    	context = new BasicHttpContext();
+	public Urllib() {
+		this(false);
+	}
+	public Urllib(boolean acceptInvalidCertificates) {
+		this.acceptInvalidCertificates = acceptInvalidCertificates;
     	HttpParams params = new BasicHttpParams(); 
-        HttpProtocolParams.setContentCharset(params, "UTF-8");     	
-    	httpclient.setParams(params);
+    	HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+        HttpProtocolParams.setContentCharset(params, "UTF-8");
+        params.setBooleanParameter("http.protocol.expect-continue", false);
+		if (acceptInvalidCertificates) {
+	        SchemeRegistry registry = new SchemeRegistry();
+	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+	        registry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+	        ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
+	        httpclient = new DefaultHttpClient(manager, params);
+		}
+		else {
+			httpclient = new DefaultHttpClient();
+		}
+    	context = new BasicHttpContext();
+
     }
     
     public String open(String url) throws ClientProtocolException, IOException {
@@ -45,6 +66,7 @@ public class Urllib {
     	String response;
     	ResponseHandler<String> responseHandler = new BasicResponseHandler();
     	if (postData.isEmpty()) {
+    		//URL urli = new URL(url); 
     		HttpGet urlConnection = new HttpGet(url);
     		urlConnection.addHeader("User-Agent", USER_AGENT);
     		response = httpclient.execute(urlConnection, responseHandler, context); 
@@ -75,5 +97,7 @@ public class Urllib {
     	return currentURI;
     }
     
-    
+    public boolean acceptsInvalidCertificates() {
+    	return acceptInvalidCertificates;
+    }
 }
\ No newline at end of file

commit c4df7336a3d0ca6a04fb2a036f51de9fd7fe26ab
Author: liato <x@x00.us>
Date:   Sun Aug 15 15:33:18 2010 +0200

    Added "ICA". Added transaction history for "Coop MedMera Kort".

diff --git res/drawable/ica.png res/drawable/ica.png
new file mode 100644
index 0000000..798be0c
Binary files /dev/null and res/drawable/ica.png differ
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index bf0135a..a8d1cec 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -16,6 +16,7 @@ public abstract class Bank implements Comparable<Bank> {
 	public final static int LANSFORSAKRINGAR = 4;
 	public final static int HANDELSBANKEN = 5;
 	public final static int COOP = 6;
+	public final static int ICA = 7;
 
 	protected String TAG = "Bank";
 	protected String NAME = "Bank";
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
index 2bb3a69..1d424de 100644
--- src/com/liato/bankdroid/BankFactory.java
+++ src/com/liato/bankdroid/BankFactory.java
@@ -8,6 +8,7 @@ import android.database.Cursor;
 
 import com.liato.bankdroid.banks.Coop;
 import com.liato.bankdroid.banks.Handelsbanken;
+import com.liato.bankdroid.banks.ICA;
 import com.liato.bankdroid.banks.ICABanken;
 import com.liato.bankdroid.banks.Lansforsakringar;
 import com.liato.bankdroid.banks.Nordea;
@@ -29,6 +30,8 @@ public class BankFactory {
 			return new Handelsbanken(context);
 		case Bank.COOP:
 			return new Coop(context);
+		case Bank.ICA:
+			return new ICA(context);
 		default:
 			throw new BankException("BankType id not found.");
 		}
@@ -43,6 +46,7 @@ public class BankFactory {
 		banks.add(new Lansforsakringar(context));
 		banks.add(new Handelsbanken(context));
 		banks.add(new Coop(context));
+		banks.add(new ICA(context));
 		return banks;
 	}
 
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 4f521e2..7c14daf 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -11,6 +11,7 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
+import android.text.Html;
 import android.util.Log;
 
 import com.liato.bankdroid.Account;
@@ -19,6 +20,7 @@ import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 public class Coop extends Bank {
@@ -31,6 +33,7 @@ public class Coop extends Bank {
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reBalanceVisa = Pattern.compile("Disponibelt\\s*belopp:</td>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactionsKonto = Pattern.compile("<td>(\\d{4}-\\d{2}-\\d{2})</td>\\s*<td>([^<]+)</td>\\s*<td>[^<]*</td>\\s*<td>([^<]*)</td>\\s*<td[^>]*>([^<]+)</td>", Pattern.CASE_INSENSITIVE);
 
 	public Coop(Context context) {
 		super(context);
@@ -82,15 +85,23 @@ public class Coop extends Bank {
 			*/			
 			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/?t=MedMeraVisa");
 			matcher = reBalanceVisa.matcher(response);
-			while (matcher.find()) {
+			if (matcher.find()) {
 				accounts.add(new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1"));
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 			}
 			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
 			matcher = reBalanceKonto.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2"));
+			if (matcher.find()) {
+				Account account = new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2");
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+				matcher = reTransactionsKonto.matcher(response);
+				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+				while (matcher.find()) {
+					String title = matcher.group(4).length() > 0 ? matcher.group(4) : matcher.group(3);
+					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(title).toString().trim(), Helpers.parseBalance(matcher.group(4))));
+				}
+				account.setTransactions(transactions);
+				accounts.add(account);
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git src/com/liato/bankdroid/banks/ICA.java src/com/liato/bankdroid/banks/ICA.java
new file mode 100644
index 0000000..88e6209
--- /dev/null
+++ src/com/liato/bankdroid/banks/ICA.java
@@ -0,0 +1,132 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class ICA extends Bank {
+	private static final String TAG = "ICA";
+	private static final String NAME = "ICA";
+	private static final String NAME_SHORT = "ica";
+	private static final String URL = "http://mobil.ica.se/";
+	private static final int BANKTYPE_ID = Bank.ICA;
+
+	private Pattern reAccounts = Pattern.compile("lblAvaibleAmount\">([^<]+)<", Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("<td>\\s*(\\d{4}-\\d{2}-\\d{2})\\s*</td>\\s*<td>\\s*([^<]+).*?amount\">([^<]+)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+	private Pattern reLoginError = Pattern.compile("login-error[^>]+>(.+?)<");
+	public ICA(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public ICA(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.ica.se/Logga-in/");
+			matcher = reViewState.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+			}
+			String strViewState = matcher.group(1);
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+			postData.add(new BasicNameValuePair("ctl00$fakie", ""));
+			postData.add(new BasicNameValuePair("q", "Sök"));
+			postData.add(new BasicNameValuePair("appendUrlString", ""));
+			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$btnLogin", "Logga in"));
+			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$chbRememberMe", "on"));
+			postData.add(new BasicNameValuePair("footer-q", "Sök"));
+			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPersno", username));
+			postData.add(new BasicNameValuePair("ctl00$cphFullWidthContainer$ctl02$tbPasswd", password));
+			
+			response = urlopen.open("https://www.ica.se/Logga-in/", postData);
+			
+			matcher = reLoginError.matcher(response);
+			if (matcher.find()) {
+				throw new LoginException(Html.fromHtml(matcher.group(1)).toString().trim());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.ica.se/Mina-sidor/Konto--Saldo/");
+			matcher = reAccounts.matcher(response);
+			if (matcher.find()) {
+				Account account = new Account("ICA Kort", Helpers.parseBalance(matcher.group(1)), "1");
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+				matcher = reTransactions.matcher(response);
+				ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+				while (matcher.find()) {
+					transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+				}
+				account.setTransactions(transactions);
+				accounts.add(account);
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+}

commit d731e80f0f3e3692febb6c1b49a109bbdade48e5
Author: liato <x@x00.us>
Date:   Sun Aug 15 05:02:51 2010 +0200

    Coop: Retrieve account info for Visa and MedMera. ICABanken: Transaction history implemented, cloeses #4

diff --git logos.psd logos.psd
index 70a814d..6e0f108 100644
Binary files logos.psd and logos.psd differ
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 1889cd7..8aaec03 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -72,5 +72,6 @@
     \nAnders Widén (Länsförsäkringar)
     \nHund (Handelsbanken)
     \nTravolta (Coop)
+    \nDaniel Malmgren (Coop)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 70bf462..6650467 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -73,5 +73,6 @@
     \nAnders Widén (Länsförsäkringar)
     \nHund (Handelsbanken)
     \nTravolta (Coop)
+    \nDaniel Malmgren (Coop)
     </string>
 </resources>
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
index 5fd04ec..4f521e2 100644
--- src/com/liato/bankdroid/banks/Coop.java
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -29,7 +29,8 @@ public class Coop extends Bank {
 	private static final int BANKTYPE_ID = Bank.COOP;
 
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalance = Pattern.compile("Disponibelt\\s*belopp:</td>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceVisa = Pattern.compile("Disponibelt\\s*belopp:</td>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceKonto = Pattern.compile("Aktuellt\\s*saldo:</span>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
 	public Coop(Context context) {
 		super(context);
@@ -80,9 +81,15 @@ public class Coop extends Bank {
 			}
 			*/			
 			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/?t=MedMeraVisa");
-			matcher = reBalance.matcher(response);
+			matcher = reBalanceVisa.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account("Betalkort", Helpers.parseBalance(matcher.group(1).trim()), "1"));
+				accounts.add(new Account("MedMera Visa", Helpers.parseBalance(matcher.group(1).trim()), "1"));
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			}
+			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/Kontoutdrag-MedMera-Konto/");
+			matcher = reBalanceKonto.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account("MedMera Konto", Helpers.parseBalance(matcher.group(1).trim()), "2"));
 				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
 			}
 			if (accounts.isEmpty()) {
diff --git src/com/liato/bankdroid/banks/ICABanken.java src/com/liato/bankdroid/banks/ICABanken.java
index 50a7b9d..e80c74a 100644
--- src/com/liato/bankdroid/banks/ICABanken.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -20,6 +20,7 @@ import com.liato.bankdroid.BankException;
 import com.liato.bankdroid.Helpers;
 import com.liato.bankdroid.LoginException;
 import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
 import com.liato.urllib.Urllib;
 
 public class ICABanken extends Bank {
@@ -34,6 +35,7 @@ public class ICABanken extends Bank {
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reTransactions = Pattern.compile("<label>(.+?)</label>\\s*<[^>]+(.+?)</div>\\s*<[^>]+>-\\s*Belopp(.+?)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 
 	public ICABanken(Context context) {
 		super(context);
@@ -49,13 +51,7 @@ public class ICABanken extends Bank {
 		this.update(username, password);
 	}
 
-	@Override
-	public void update() throws BankException, LoginException {
-		super.update();
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
-		}
-
+	public Urllib login() throws LoginException, BankException {
 		Urllib urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
@@ -83,6 +79,31 @@ public class ICABanken extends Bank {
 			if (matcher.find()) {
 				throw new LoginException(Html.fromHtml(matcher.group(1).trim()).toString());
 			}
+		}
+		catch (ClientProtocolException e) {
+			Log.d(TAG, "ClientProtocolException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			Log.d(TAG, "IOException: "+e.getMessage());
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}		
+		return urlopen;
+	}	
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
 			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
 			Log.d("BankICA", urlopen.getCurrentURI());
 			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_oversikt.htm");
@@ -111,4 +132,38 @@ public class ICABanken extends Bank {
 		}
 
 	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
+		super.updateTransactions(account, urlopened);
+		Urllib urlopen = null;
+		if (urlopened == null) {
+			urlopen = login();
+		}
+		else {
+			urlopen = urlopened;
+		}
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://mobil.icabanken.se/account/account.aspx?id="+account.getId());
+			response = urlopen.open("https://mobil.icabanken.se/account/account.aspx?id="+account.getId());
+			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_kontoutdrag.htm");
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(matcher.group(2).trim().substring(8), Html.fromHtml(matcher.group(1)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (urlopened == null) {
+			urlopen.close();
+		}
+	}		
 }
\ No newline at end of file

commit 51903a13eadee0dc4138e73bc67791e344ad75ff
Author: liato <x@x00.us>
Date:   Tue Jul 13 04:00:46 2010 +0200

    Improved currency formater.

diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 655e063..6bb64b5 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -70,7 +70,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		Bank bank = account.getBank();
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
-		views.setTextViewText(R.id.txtWidgetAccountname, account.getName());
+		views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase());
 		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance()));
 		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+bank.getShortName(), null, context.getPackageName()));
 		Log.d("Disabled", ""+bank.isDisabled());
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index a2e8dc6..27a5e61 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -1,8 +1,8 @@
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
-import java.text.NumberFormat;
-import java.util.Locale;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
 
 public class Helpers {
 	public static BigDecimal parseBalance(String balance) {
@@ -20,10 +20,12 @@ public class Helpers {
 		return new BigDecimal(balance);
 	}
 	public static String formatBalance(BigDecimal balance) {
-		Locale locale = new Locale("sv", "SE");
-		String bs = NumberFormat.getCurrencyInstance(locale).format(balance);
-		bs = bs.replaceAll("[^0-9\\s,.-]*", "");
-		return bs.trim() + " SEK";
+		DecimalFormatSymbols dfs = new DecimalFormatSymbols();
+		dfs.setDecimalSeparator(',');
+		dfs.setGroupingSeparator(' ');
+		DecimalFormat currency = new DecimalFormat("#,##0.00 SEK");
+		currency.setDecimalFormatSymbols(dfs);
+		return currency.format(balance.doubleValue());
 	}
 	public static String formatBalance(Double balance) {
 		return formatBalance(new BigDecimal(balance));

commit edabbc838734d9a3531e792a95a32a8a28b533d2
Author: liato <x@x00.us>
Date:   Tue Jul 13 02:47:35 2010 +0200

    Fixed missing ICA Banken logo. Fixed balance format for devices without swedish locale.

diff --git AndroidManifest.xml AndroidManifest.xml
index b2b7de6..8b1d77f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.2.0-rc2" android:versionCode="26">
+	package="com.liato.bankdroid" android:versionName="1.2.1" android:versionCode="28">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git res/drawable/ica.png res/drawable/icabanken.png
similarity index 100%
rename from res/drawable/ica.png
rename to res/drawable/icabanken.png
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 81a728d..a2e8dc6 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -21,7 +21,9 @@ public class Helpers {
 	}
 	public static String formatBalance(BigDecimal balance) {
 		Locale locale = new Locale("sv", "SE");
-		return NumberFormat.getCurrencyInstance(locale).format(balance).replace("kr", "SEK");
+		String bs = NumberFormat.getCurrencyInstance(locale).format(balance);
+		bs = bs.replaceAll("[^0-9\\s,.-]*", "");
+		return bs.trim() + " SEK";
 	}
 	public static String formatBalance(Double balance) {
 		return formatBalance(new BigDecimal(balance));

commit 39652263817d35e23fc0b0156f0a4d1f63d6c166
Author: liato <x@x00.us>
Date:   Sat Jul 10 18:40:09 2010 +0200

    Fixed FC on widgetconfigure screen when clicking a bank header.

diff --git AndroidManifest.xml AndroidManifest.xml
index 27762b7..b2b7de6 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.2.0-rc1" android:versionCode="25">
+	package="com.liato.bankdroid" android:versionName="1.2.0-rc2" android:versionCode="26">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git res/layout/about.xml res/layout/about.xml
index b620b41..5e27d8b 100644
--- res/layout/about.xml
+++ res/layout/about.xml
@@ -2,13 +2,12 @@
 <LinearLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:orientation="vertical"
-	android:padding="20dp"
 	android:layout_height="fill_parent"
-	android:layout_width="fill_parent">
+	android:layout_width="fill_parent" android:paddingBottom="20dp">
 	<ScrollView
 		android:fillViewport="true"
 		android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1">
-		<LinearLayout android:id="@+id/LinearLayout03" android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="wrap_content"><TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:typeface="sans" android:gravity="center_horizontal" android:text="BANKDROID" android:layout_width="fill_parent" android:visibility="visible" android:textColor="#fff" android:textSize="42dp" android:ellipsize="none" android:inputType="none" android:layout_gravity="center_horizontal"></TextView><LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent">
+		<LinearLayout android:id="@+id/LinearLayout03" android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="wrap_content" android:paddingLeft="20dp" android:paddingRight="20dp"><TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:typeface="sans" android:gravity="center_horizontal" android:text="BANKDROID" android:layout_width="fill_parent" android:visibility="visible" android:textColor="#fff" android:textSize="42dp" android:ellipsize="none" android:inputType="none" android:layout_gravity="center_horizontal"></TextView><LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent">
 			<ImageView android:id="@+id/ImageView01" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:visibility="visible" android:src="@drawable/icon_large" android:maxHeight="100dp" android:maxWidth="100dp" android:minHeight="100dp" android:minWidth="100dp" android:scaleType="fitXY"></ImageView>
 			<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
 				<TextView android:layout_height="wrap_content" android:id="@+id/txtVersion" android:layout_width="fill_parent" android:textSize="17dp" android:text="@string/version"></TextView>
diff --git res/layout/main.xml res/layout/main.xml
index 2fa5ed9..04c774d 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -17,16 +17,14 @@
 		android:id="@+id/lstAccountsList"
 		android:layout_height="fill_parent"
 		android:fitsSystemWindows="true"
-		android:layout_above="@+id/TableLayout01"
-		android:layout_alignParentTop="true" android:cacheColorHint="#00000000"/>
+		android:layout_alignParentTop="true" android:cacheColorHint="#00000000" android:layout_above="@+id/layMainMenu"/>
 	<TableLayout
-		android:id="@+id/TableLayout01"
 		android:stretchColumns="0,2"
 		android:layout_height="wrap_content"
 		android:layout_alignParentBottom="true"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentRight="true"
-		android:layout_width="wrap_content">
+		android:layout_width="wrap_content" android:id="@+id/layMainMenu">
 		<TableRow
 			android:id="@+id/TableRow01"
 			android:layout_height="wrap_content"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index a172cf3..1889cd7 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -2,7 +2,7 @@
 <resources>
     
     <string name="about">Om</string>
-    <string name="version">Version 1.2.0-rc1 av liato</string>
+    <string name="version">Version $version av liato</string>
     <string name="widget_name_small">Bankdroid (Liten)</string>
     <string name="widget_name_large">Bankdroid (Stor)</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
diff --git res/values/strings.xml res/values/strings.xml
index 765e155..70bf462 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="version">Version 1.2.0-rc1 by liato</string>
+    <string name="version">Version $version by liato</string>
     <string name="app_name">Bankdroid</string>
     <string name="widget_name_small">Bankdroid (Small)</string>
     <string name="widget_name_large">Bankdroid (Large)</string>
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index f12201c..b665582 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -12,10 +12,11 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 public class AccountsAdapter extends BaseAdapter {
+	public final static int VIEWTYPE_BANK = 0;
+	public final static int VIEWTYPE_ACCOUNT = 1;
 	private ArrayList<Bank> groups;
 	private Context context;
 	private LayoutInflater inflater;
-	
 
 	public AccountsAdapter(Context context) {
 		this.context = context;
@@ -131,9 +132,9 @@ public class AccountsAdapter extends BaseAdapter {
 	public int getItemViewType(int position) {
 		Object item = getItem(position);
 		if (item instanceof Bank) {
-			return 0;
+			return VIEWTYPE_BANK;
 		}
-		return 1;
+		return VIEWTYPE_ACCOUNT;
 	}	
 }
 
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 2d91d8c..34c4108 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -7,6 +7,9 @@ import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
@@ -19,6 +22,7 @@ import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
 import android.widget.Button;
+import android.widget.TextView;
 import android.widget.ListView;
 import android.widget.AdapterView.OnItemClickListener;
 
@@ -107,6 +111,15 @@ public class MainActivity extends LockableActivity {
 		Dialog dialog = new Dialog(this);
 		dialog.setContentView(R.layout.about);
 		dialog.setTitle(getString(R.string.about));
+		PackageInfo pInfo;
+		String version = "v1.x.x";
+		try {
+			pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
+			version = pInfo.versionName;		
+		} catch (NameNotFoundException e) {
+			e.printStackTrace();
+		}
+		((TextView)dialog.findViewById(R.id.txtVersion)).setText(getText(R.string.version).toString().replace("$version", version));
 		return dialog;
 	}
 
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index 59f76dc..2e2db8c 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -11,15 +11,14 @@ import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.widget.AdapterView;
-import android.widget.Button;
 import android.widget.ListView;
 import android.widget.AdapterView.OnItemClickListener;
 
 public class WidgetConfigureActivity extends Activity {
     private static final String WIDGET_PREFIX = "widget_";
 	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
-	
 	private static final int LOGIN_ID = 1;
+	private AccountsAdapter adapter;
 	
 	public WidgetConfigureActivity() {
 		super();
@@ -54,7 +53,7 @@ public class WidgetConfigureActivity extends Activity {
 		setContentView(R.layout.main);
 		this.setTitle(this.getString(R.string.choose_an_account));
         setResult(RESULT_CANCELED);
-		((Button)findViewById(R.id.btnAccountsRefresh)).setVisibility(View.GONE);
+		((View)findViewById(R.id.layMainMenu)).setVisibility(View.GONE);
 
         Intent intent = getIntent();
         Bundle extras = intent.getExtras();
@@ -68,13 +67,10 @@ public class WidgetConfigureActivity extends Activity {
         ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 		lv.setOnItemClickListener(new OnItemClickListener() {
 			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-				Log.d("!", "CLICK!");
-				
-	            final Context context = WidgetConfigureActivity.this;
+				if (adapter.getItemViewType(position) != AccountsAdapter.VIEWTYPE_ACCOUNT) return;
+				final Context context = WidgetConfigureActivity.this;
 	            Account account = (Account)parent.getItemAtPosition(position);
-
 	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, account.getId());
-
 	            // Push widget update to surface with newly set prefix
 	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
 	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
@@ -119,7 +115,7 @@ public class WidgetConfigureActivity extends Activity {
 		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
 			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-			AccountsAdapter adapter = new AccountsAdapter(this);
+			adapter = new AccountsAdapter(this);
 			adapter.setGroups(banks);
 			lv.setAdapter(adapter);
 		}

commit ed2822dc56188f83613b1ed4a1cc769321a70adb
Author: liato <x@x00.us>
Date:   Fri Jul 9 09:47:44 2010 +0200

    Fixed login bug with handelsbanken.

diff --git AndroidManifest.xml AndroidManifest.xml
index 7ff6f85..27762b7 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.2.0-rc1" android:versionCode="24">
+	package="com.liato.bankdroid" android:versionName="1.2.0-rc1" android:versionCode="25">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
index 5a0134d..a28c6c3 100644
--- src/com/liato/bankdroid/banks/Handelsbanken.java
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -32,6 +32,7 @@ public class Handelsbanken extends Bank {
 
 	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
+	private Pattern reLoginUrl = Pattern.compile("_-([^\"]+)\"><img[^>]*><img[^>]*><span[^>]*>Logga",Pattern.CASE_INSENSITIVE);
 	private Pattern reTransactions = Pattern.compile("padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE);
 	public Handelsbanken(Context context) {
 		super(context);
@@ -52,25 +53,36 @@ public class Handelsbanken extends Bank {
 	public Urllib login() throws LoginException, BankException {
 		Urllib urlopen = new Urllib();
 		String response = null;
+		Matcher matcher;
 		try {
-			//Let the website set som cookies
-			response = urlopen.open("https://m.handelsbanken.se/primary/_-iseufea5");
-
+			response = urlopen.open("https://m.handelsbanken.se/primary/");
+			matcher = reLoginUrl.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" login url.");
+			}
+			String strLoginUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			postData.add(new BasicNameValuePair("username", username));
 			postData.add(new BasicNameValuePair("pin", password));
 			postData.add(new BasicNameValuePair("execute", "true"));
-			Log.d(TAG, "Posting data to: " + "https://m.handelsbanken.se/primary/_-iseufea5");
-			response = urlopen.open("https://m.handelsbanken.se/primary/_-iseufea5", postData);
+			Log.d(TAG, "Posting data to: " + strLoginUrl);
+			response = urlopen.open(strLoginUrl, postData);
+			/*
+			for (String s : response.split("<span")) {
+				Log.d(TAG, s);
+			}
+			*/
 
 			if (response.contains("ontrollera dina uppgifter")) {
 				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 		}
 		catch (ClientProtocolException e) {
+			Log.d(TAG, "ClientProtocolException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		catch (IOException e) {
+			Log.d(TAG, "IOException: "+e.getMessage());
 			throw new BankException(e.getMessage());
 		}
 		finally {
@@ -89,7 +101,7 @@ public class Handelsbanken extends Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://m.handelsbanken.se/primary/_-iseufea5");
+			response = urlopen.open(urlopen.getCurrentURI());
 			//Successful login, find accounts url and retrieve account info.
 			matcher = reAccountsUrl.matcher(response);
 			if (!matcher.find()) {

commit 2b0345b5c2b01670346307461bc45a676e3a55d5
Author: liato <x@x00.us>
Date:   Fri Jul 9 08:25:18 2010 +0200

    Added handelsbanken and coop, a few design changes.

diff --git AndroidManifest.xml AndroidManifest.xml
index fcd4f3e..7ff6f85 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.4" android:versionCode="23">
+	package="com.liato.bankdroid" android:versionName="1.2.0-rc1" android:versionCode="24">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
@@ -12,7 +12,7 @@
 		</activity>
 		<activity android:name=".MainActivity" android:label="@string/app_name">
 		</activity>
-		<activity android:name=".AccountsActivity" android:label="@string/app_name">
+		<activity android:name=".TransactionsActivity" android:label="@string/app_name">
 		</activity>
 		<activity android:name=".AccountActivity" android:label="@string/app_name">
 		</activity>
@@ -53,8 +53,13 @@
 			</intent-filter>
 		</receiver>
 	</application>
-	<uses-sdk android:minSdkVersion="3" />
+	<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="4" />
 	<uses-permission android:name="android.permission.INTERNET"></uses-permission>
 	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 	<uses-permission android:name="android.permission.VIBRATE" />
+	<supports-screens
+		android:largeScreens="true"
+		android:normalScreens="true"
+		android:smallScreens="true"
+		android:anyDensity="true" />
 </manifest> 
\ No newline at end of file
diff --git default.properties default.properties
index a1ef8e9..19c9665 100644
--- default.properties
+++ default.properties
@@ -10,4 +10,4 @@
 # Indicates whether an apk should be generated for each density.
 split.density=false
 # Project target.
-target=android-3
+target=android-4
diff --git logos.psd logos.psd
index 719f812..70a814d 100644
Binary files logos.psd and logos.psd differ
diff --git res/anim/grow_from_bottom.xml res/anim/grow_from_bottom.xml
new file mode 100644
index 0000000..d2a371d
--- /dev/null
+++ res/anim/grow_from_bottom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<scale
+		android:fromXScale="0.3" android:toXScale="1.0"
+		android:fromYScale="0.3" android:toYScale="1.0"
+		android:pivotX="50%" android:pivotY="100%"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+	<alpha
+		android:interpolator="@android:anim/decelerate_interpolator"
+		android:fromAlpha="0.0" android:toAlpha="1.0"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+</set>
diff --git res/anim/grow_from_top.xml res/anim/grow_from_top.xml
new file mode 100644
index 0000000..ffd722c
--- /dev/null
+++ res/anim/grow_from_top.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<scale
+		android:fromXScale="0.3" android:toXScale="1.0"
+		android:fromYScale="0.3" android:toYScale="1.0"
+		android:pivotX="50%" android:pivotY="0%"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+	<alpha
+		android:interpolator="@android:anim/decelerate_interpolator"
+		android:fromAlpha="0.0" android:toAlpha="1.0"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+</set>
diff --git res/anim/grow_from_topleft_to_bottomright.xml res/anim/grow_from_topleft_to_bottomright.xml
new file mode 100644
index 0000000..b67ebe5
--- /dev/null
+++ res/anim/grow_from_topleft_to_bottomright.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<scale
+		android:fromXScale="0.3" android:toXScale="1.0"
+		android:fromYScale="0.3" android:toYScale="1.0"
+		android:pivotX="0%" android:pivotY="0%"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+	<alpha
+		android:interpolator="@android:anim/decelerate_interpolator"
+		android:fromAlpha="0.0" android:toAlpha="1.0"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+</set>
diff --git res/anim/shrink_from_bottom.xml res/anim/shrink_from_bottom.xml
new file mode 100644
index 0000000..a98d592
--- /dev/null
+++ res/anim/shrink_from_bottom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<scale
+		android:fromXScale="1.0" android:toXScale="0.3"
+		android:fromYScale="1.0" android:toYScale="0.3"
+		android:pivotX="50%" android:pivotY="0%"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+	<alpha
+		android:interpolator="@android:anim/accelerate_interpolator"
+		android:fromAlpha="1.0" android:toAlpha="0.0"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+</set>
diff --git res/anim/shrink_from_bottomright_to_topleft.xml res/anim/shrink_from_bottomright_to_topleft.xml
new file mode 100644
index 0000000..d4ed513
--- /dev/null
+++ res/anim/shrink_from_bottomright_to_topleft.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<scale
+		android:fromXScale="1.0" android:toXScale="0.3"
+		android:fromYScale="1.0" android:toYScale="0.3"
+		android:pivotX="0%" android:pivotY="0%"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+	<alpha
+		android:interpolator="@android:anim/accelerate_interpolator"
+		android:fromAlpha="1.0" android:toAlpha="0.0"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+</set>
diff --git res/anim/shrink_from_top.xml res/anim/shrink_from_top.xml
new file mode 100644
index 0000000..89cd8f4
--- /dev/null
+++ res/anim/shrink_from_top.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+	<scale
+		android:fromXScale="1.0" android:toXScale="0.3"
+		android:fromYScale="1.0" android:toYScale="0.3"
+		android:pivotX="50%" android:pivotY="100%"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+	<alpha
+		android:interpolator="@android:anim/accelerate_interpolator"
+		android:fromAlpha="1.0" android:toAlpha="0.0"
+		android:duration="@android:integer/config_shortAnimTime"
+	/>
+</set>
diff --git res/drawable-hdpi-v4/background.png res/drawable-hdpi-v4/background.png
new file mode 100644
index 0000000..30d4a2d
Binary files /dev/null and res/drawable-hdpi-v4/background.png differ
diff --git res/drawable-hdpi-v4/button_add.png res/drawable-hdpi-v4/button_add.png
new file mode 100644
index 0000000..ba86dfb
Binary files /dev/null and res/drawable-hdpi-v4/button_add.png differ
diff --git res/drawable-hdpi-v4/button_bg.9.png res/drawable-hdpi-v4/button_bg.9.png
new file mode 100644
index 0000000..e367c4d
Binary files /dev/null and res/drawable-hdpi-v4/button_bg.9.png differ
diff --git res/drawable-hdpi-v4/button_bg_2.9.2010-07-02_1033.png res/drawable-hdpi-v4/button_bg_2.9.2010-07-02_1033.png
new file mode 100644
index 0000000..99aae62
Binary files /dev/null and res/drawable-hdpi-v4/button_bg_2.9.2010-07-02_1033.png differ
diff --git res/drawable-hdpi-v4/button_bg_pressed.9.png res/drawable-hdpi-v4/button_bg_pressed.9.png
new file mode 100644
index 0000000..c20da49
Binary files /dev/null and res/drawable-hdpi-v4/button_bg_pressed.9.png differ
diff --git res/drawable-hdpi-v4/button_bg_pressed__2.9.2010-07-02_1022.png res/drawable-hdpi-v4/button_bg_pressed__2.9.2010-07-02_1022.png
new file mode 100644
index 0000000..54ac66d
Binary files /dev/null and res/drawable-hdpi-v4/button_bg_pressed__2.9.2010-07-02_1022.png differ
diff --git res/drawable-hdpi-v4/button_cancel.png res/drawable-hdpi-v4/button_cancel.png
new file mode 100644
index 0000000..9fcfe15
Binary files /dev/null and res/drawable-hdpi-v4/button_cancel.png differ
diff --git res/drawable-hdpi-v4/button_edit.png res/drawable-hdpi-v4/button_edit.png
new file mode 100644
index 0000000..835cd12
Binary files /dev/null and res/drawable-hdpi-v4/button_edit.png differ
diff --git res/drawable-hdpi-v4/button_refresh.png res/drawable-hdpi-v4/button_refresh.png
new file mode 100644
index 0000000..0462b18
Binary files /dev/null and res/drawable-hdpi-v4/button_refresh.png differ
diff --git res/drawable-hdpi-v4/button_save.png res/drawable-hdpi-v4/button_save.png
new file mode 100644
index 0000000..dadcf27
Binary files /dev/null and res/drawable-hdpi-v4/button_save.png differ
diff --git res/drawable-hdpi-v4/button_www.png res/drawable-hdpi-v4/button_www.png
new file mode 100644
index 0000000..0de88a9
Binary files /dev/null and res/drawable-hdpi-v4/button_www.png differ
diff --git res/drawable-hdpi-v4/date_background.png res/drawable-hdpi-v4/date_background.png
new file mode 100644
index 0000000..a1d9225
Binary files /dev/null and res/drawable-hdpi-v4/date_background.png differ
diff --git res/drawable-hdpi-v4/date_bg.9.png res/drawable-hdpi-v4/date_bg.9.png
new file mode 100644
index 0000000..8912a99
Binary files /dev/null and res/drawable-hdpi-v4/date_bg.9.png differ
diff --git res/drawable-hdpi-v4/date_bg_2.9.png res/drawable-hdpi-v4/date_bg_2.9.png
new file mode 100644
index 0000000..1cb8b57
Binary files /dev/null and res/drawable-hdpi-v4/date_bg_2.9.png differ
diff --git res/drawable-hdpi-v4/group_bg.png res/drawable-hdpi-v4/group_bg.png
new file mode 100644
index 0000000..4c1722c
Binary files /dev/null and res/drawable-hdpi-v4/group_bg.png differ
diff --git res/drawable-hdpi-v4/icon.png res/drawable-hdpi-v4/icon.png
new file mode 100644
index 0000000..be6f807
Binary files /dev/null and res/drawable-hdpi-v4/icon.png differ
diff --git res/drawable-hdpi-v4/menu_separator.png res/drawable-hdpi-v4/menu_separator.png
new file mode 100644
index 0000000..9db2306
Binary files /dev/null and res/drawable-hdpi-v4/menu_separator.png differ
diff --git res/drawable-hdpi-v4/popup_bg_down.9.png res/drawable-hdpi-v4/popup_bg_down.9.png
new file mode 100644
index 0000000..47a00b4
Binary files /dev/null and res/drawable-hdpi-v4/popup_bg_down.9.png differ
diff --git res/drawable-hdpi-v4/popup_bg_down_o.png res/drawable-hdpi-v4/popup_bg_down_o.png
new file mode 100644
index 0000000..99efa53
Binary files /dev/null and res/drawable-hdpi-v4/popup_bg_down_o.png differ
diff --git res/drawable-hdpi-v4/popup_bg_regular.png res/drawable-hdpi-v4/popup_bg_regular.png
new file mode 100644
index 0000000..dbbedfe
Binary files /dev/null and res/drawable-hdpi-v4/popup_bg_regular.png differ
diff --git res/drawable-hdpi-v4/popup_bg_selected.png res/drawable-hdpi-v4/popup_bg_selected.png
new file mode 100644
index 0000000..500a830
Binary files /dev/null and res/drawable-hdpi-v4/popup_bg_selected.png differ
diff --git res/drawable-hdpi-v4/popup_bg_up.9.png res/drawable-hdpi-v4/popup_bg_up.9.png
new file mode 100644
index 0000000..257d975
Binary files /dev/null and res/drawable-hdpi-v4/popup_bg_up.9.png differ
diff --git res/drawable-hdpi-v4/popup_bg_up_o.png res/drawable-hdpi-v4/popup_bg_up_o.png
new file mode 100644
index 0000000..414cc6f
Binary files /dev/null and res/drawable-hdpi-v4/popup_bg_up_o.png differ
diff --git res/drawable-hdpi-v4/popup_separator.png res/drawable-hdpi-v4/popup_separator.png
new file mode 100644
index 0000000..2755c20
Binary files /dev/null and res/drawable-hdpi-v4/popup_separator.png differ
diff --git res/drawable-hdpi-v4/transaction_negative.png res/drawable-hdpi-v4/transaction_negative.png
new file mode 100644
index 0000000..7ff2d6c
Binary files /dev/null and res/drawable-hdpi-v4/transaction_negative.png differ
diff --git res/drawable-hdpi-v4/transaction_positive.png res/drawable-hdpi-v4/transaction_positive.png
new file mode 100644
index 0000000..5367823
Binary files /dev/null and res/drawable-hdpi-v4/transaction_positive.png differ
diff --git res/drawable/background_repeat.xml res/drawable/background_repeat.xml
new file mode 100644
index 0000000..5beea90
--- /dev/null
+++ res/drawable/background_repeat.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/background" 
+    android:tileMode="repeat" />
\ No newline at end of file
diff --git res/drawable/coop.png res/drawable/coop.png
new file mode 100644
index 0000000..467fec0
Binary files /dev/null and res/drawable/coop.png differ
diff --git res/drawable/handelsbanken.png res/drawable/handelsbanken.png
new file mode 100644
index 0000000..6f2313c
Binary files /dev/null and res/drawable/handelsbanken.png differ
diff --git res/drawable/menu_button.xml res/drawable/menu_button.xml
new file mode 100644
index 0000000..6d60713
--- /dev/null
+++ res/drawable/menu_button.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/button_bg_pressed" >
+    </item>
+
+    <item android:state_focused="true"
+        android:drawable="@drawable/button_bg_pressed" >
+    </item>
+
+    <item 
+        android:drawable="@drawable/button_bg" >
+    </item>
+</selector>
diff --git res/drawable/popup_button.xml res/drawable/popup_button.xml
new file mode 100644
index 0000000..87b47e8
--- /dev/null
+++ res/drawable/popup_button.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/popup_bg_selected" >
+    </item>
+
+    <item android:state_focused="true"
+        android:drawable="@drawable/popup_bg_selected" >
+    </item>
+
+    <item 
+        android:drawable="@drawable/popup_bg_regular" >
+    </item>
+</selector>
\ No newline at end of file
diff --git res/layout/about.xml res/layout/about.xml
index 0df1bec..b620b41 100644
--- res/layout/about.xml
+++ res/layout/about.xml
@@ -1,64 +1,37 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
-	android:id="@+id/RelativeLayout01"
+<LinearLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:padding="10dp">
-	<LinearLayout
-		android:orientation="vertical"
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:paddingLeft="10dp"
-		android:paddingRight="10dp"
-		android:paddingTop="10dp"
-		android:layout_gravity="center_vertical"
-		android:fitsSystemWindows="true">
+	android:orientation="vertical"
+	android:padding="20dp"
+	android:layout_height="fill_parent"
+	android:layout_width="fill_parent">
+	<ScrollView
+		android:fillViewport="true"
+		android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1">
+		<LinearLayout android:id="@+id/LinearLayout03" android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="wrap_content"><TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:typeface="sans" android:gravity="center_horizontal" android:text="BANKDROID" android:layout_width="fill_parent" android:visibility="visible" android:textColor="#fff" android:textSize="42dp" android:ellipsize="none" android:inputType="none" android:layout_gravity="center_horizontal"></TextView><LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent">
+			<ImageView android:id="@+id/ImageView01" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:visibility="visible" android:src="@drawable/icon_large" android:maxHeight="100dp" android:maxWidth="100dp" android:minHeight="100dp" android:minWidth="100dp" android:scaleType="fitXY"></ImageView>
+			<LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
+				<TextView android:layout_height="wrap_content" android:id="@+id/txtVersion" android:layout_width="fill_parent" android:textSize="17dp" android:text="@string/version"></TextView>
 
 
-		<TextView
-			android:id="@+id/TextView01"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:gravity="center_horizontal"
-			android:layout_gravity="center_horizontal"
-			android:text="BANKDROID"
-			android:layout_width="fill_parent"
-			android:visibility="visible"
-			android:textColor="#fff"
-			android:textSize="42dp"></TextView>
-		<LinearLayout
-			android:id="@+id/LinearLayout01"
-			android:layout_height="wrap_content"
-			android:orientation="horizontal"
-			android:layout_width="fill_parent">
-			<ImageView
-				android:id="@+id/ImageView01"
-				android:background="@drawable/icon_large"
-				android:layout_width="100dp"
-				android:layout_height="100dp"
-				android:layout_gravity="center_horizontal"
-				android:visibility="visible"></ImageView>
-			<LinearLayout
-				android:id="@+id/LinearLayout02"
-				android:layout_height="wrap_content"
-				android:orientation="vertical"
-				android:layout_width="fill_parent"><TextView android:layout_height="wrap_content" android:id="@+id/txtVersion" android:layout_width="fill_parent" android:textSize="17dp" android:text="@string/version"></TextView>
-				
-				
-			<TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="http://liato.github.com/android-bankdroid/" android:autoLink="web" android:fitsSystemWindows="false"></TextView></LinearLayout>
+				<TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="http://liato.github.com/android-bankdroid/" android:autoLink="web" android:fitsSystemWindows="false"></TextView>
+			</LinearLayout>
+
+
+		</LinearLayout><TextView android:id="@+id/TextView04" android:layout_height="wrap_content" android:text="@string/thanks_to" android:textSize="20sp" android:textStyle="bold" android:layout_marginTop="10dp" android:layout_width="fill_parent"></TextView><TextView android:id="@+id/TextView03" android:layout_height="wrap_content" android:text="@string/thanks" android:layout_width="fill_parent" android:paddingLeft="10dp" android:typeface="serif" android:textSize="12sp"></TextView></LinearLayout>
 		
 
-</LinearLayout>
 
 
 
 
 
 
+
+		
 		
 
-	<TextView android:id="@+id/TextView04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/thanks_to" android:textSize="20sp" android:textStyle="bold" android:layout_marginTop="10dp"></TextView><ScrollView android:id="@+id/ScrollView01" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:id="@+id/TextView03" android:layout_height="wrap_content" android:text="@string/thanks" android:layout_width="fill_parent" android:paddingLeft="10dp" android:typeface="serif" android:textSize="12sp"></TextView></ScrollView>
 
+	</ScrollView>
 
 </LinearLayout>
-</RelativeLayout>
diff --git res/layout/bank.xml res/layout/bank.xml
index fe25167..07251e8 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -1,83 +1,102 @@
 <?xml version="1.0" encoding="utf-8"?>
-<ScrollView
+
+<RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
 	android:layout_height="fill_parent"
-	android:layout_width="fill_parent" android:fillViewport="true">
-	<LinearLayout
-		android:orientation="vertical"
-		android:layout_width="fill_parent"
-		android:layout_height="fill_parent"
-		android:paddingLeft="10dp"
-		android:paddingRight="10dp"
-		android:paddingTop="10dp">
-		<TextView
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:textSize="20sp"
-			android:text="@string/username" />
-
-		<EditText
-			android:layout_height="wrap_content"
-			android:layout_width="fill_parent"
-			android:id="@+id/edtBankeditUsername"
-			android:digits="0123456789-"
-			android:inputType="phone"></EditText>
-		<TextView
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:textSize="20sp"
-			android:text="@string/password" />
-		<EditText
-			android:layout_height="wrap_content"
-			android:layout_width="fill_parent"
-			android:id="@+id/edtBankeditPassword"
-			android:inputType="textPassword"></EditText>
-		<TextView
-			android:layout_width="fill_parent"
-			android:layout_height="wrap_content"
-			android:typeface="sans"
-			android:textSize="20sp"
-			android:text="@string/bank" />
+	android:background="@drawable/background_repeat"
+	android:layout_width="fill_parent">
 
+	<ScrollView
 
-		<Spinner
+		android:layout_height="fill_parent"
+		android:layout_width="fill_parent"
+		android:fillViewport="true" android:layout_above="@+id/TableLayout01">
+		<LinearLayout
+			android:id="@+id/LinearLayout01"
 			android:layout_height="wrap_content"
-			android:layout_width="fill_parent"
-			android:id="@+id/spnBankeditBanklist"></Spinner>
-		<TextView
+			android:layout_below="@+id/txtErrorDesc"
 			android:layout_width="wrap_content"
+			android:orientation="vertical"
+			android:layout_alignParentTop="true"
+			android:padding="10dp">
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/username" />
+			<EditText
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/edtBankeditUsername"></EditText>
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/password" />
+			<EditText
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/edtBankeditPassword"
+				android:inputType="textPassword"></EditText>
+			<TextView
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:typeface="sans"
+				android:textSize="20sp"
+				android:text="@string/bank" />
+			<Spinner
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent"
+				android:id="@+id/spnBankeditBanklist"></Spinner>
+			<TextView
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:drawableLeft="@drawable/indicator_input_error"
+				android:text="@string/error_desc"
+				android:textSize="12sp"
+				android:drawablePadding="5dp"
+				android:id="@+id/txtErrorDesc"
+				android:visibility="invisible"></TextView>
+		</LinearLayout>
+	</ScrollView>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:stretchColumns="0,2"
+		android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentRight="true"
+		android:layout_width="wrap_content"
+		android:layout_below="@+id/LinearLayout01"
+		android:gravity="bottom">
+		<TableRow
+			android:id="@+id/TableRow01"
 			android:layout_height="wrap_content"
-			android:drawableLeft="@drawable/indicator_input_error"
-			android:text="@string/error_desc"
-			android:textSize="12sp"
-			android:drawablePadding="5dp"
-			android:id="@+id/txtErrorDesc"
-			android:visibility="invisible"></TextView>
-		<TableLayout
-			android:id="@+id/TableLayout01"
-			android:layout_width="fill_parent"
-			android:stretchColumns="*"
-			android:gravity="bottom"
-			android:layout_height="fill_parent">
-			<TableRow
-				android:id="@+id/TableRow01"
+			android:gravity="center_vertical|center_horizontal"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent">
+			<Button
+				android:text="@string/cancel"
+				android:drawableLeft="@drawable/button_cancel"
+				android:id="@+id/btnSettingsCancel"
+				style="@style/Menu_Button"></Button>
+			<ImageView
 				android:layout_height="wrap_content"
-				android:layout_width="fill_parent">
-				<Button
-					android:layout_height="wrap_content"
-					android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
-					android:layout_width="fill_parent"
-					android:id="@+id/btnSettingsCancel"
-					android:text="@string/cancel"></Button>
-				<Button
-					android:layout_height="wrap_content"
-					android:drawableLeft="@android:drawable/ic_menu_save"
-					android:layout_width="fill_parent"
-					android:id="@+id/btnSettingsOk"
-					android:text="@string/save"></Button>
-			</TableRow>
-		</TableLayout>
-	</LinearLayout>
-</ScrollView>
\ No newline at end of file
+				android:focusable="false"
+				android:src="@drawable/menu_separator"
+				android:adjustViewBounds="true"
+				android:scaleType="fitXY"
+				android:minWidth="3dp"
+				android:maxWidth="3dp"
+				android:layout_width="wrap_content"></ImageView>
+			<Button
+				android:id="@+id/btnSettingsOk"
+				android:drawableLeft="@drawable/button_save"
+				android:text="@string/save"
+				style="@style/Menu_Button"></Button>
+		</TableRow>
+	</TableLayout>
+</RelativeLayout>
diff --git res/layout/listitem_accounts_group.xml res/layout/listitem_accounts_group.xml
index 1cd8ddf..abfbb02 100644
--- res/layout/listitem_accounts_group.xml
+++ res/layout/listitem_accounts_group.xml
@@ -2,13 +2,11 @@
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent"
-	android:background="@drawable/title_bar_medium"
 	android:layout_height="62dp"
-	android:clickable="false"
 	android:paddingBottom="5dp"
 	android:paddingLeft="5dp"
 	android:paddingTop="5dp"
-	android:paddingRight="10dp">
+	android:paddingRight="10dp" android:background="@drawable/group_bg" android:id="@+id/layBankHeader">
 
 	<ImageView
 		android:id="@+id/imgListitemAccountsGroup"
diff --git res/layout/listitem_accounts_item.xml res/layout/listitem_accounts_item.xml
index a548307..b880c6c 100644
--- res/layout/listitem_accounts_item.xml
+++ res/layout/listitem_accounts_item.xml
@@ -2,7 +2,6 @@
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent"
-	android:background="#000"
 	android:layout_height="35dp"
 	android:layout_gravity="center_horizontal"
 	android:paddingLeft="15dp"
diff --git res/layout/main.xml res/layout/main.xml
index 48b183d..2fa5ed9 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -3,7 +3,8 @@
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:id="@+id/RelativeLayout01"
 	android:layout_width="wrap_content"
-	android:layout_height="fill_parent">
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat">
 	<TextView
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
@@ -16,21 +17,41 @@
 		android:id="@+id/lstAccountsList"
 		android:layout_height="fill_parent"
 		android:fitsSystemWindows="true"
-		android:layout_above="@+id/LinearLayout02" />
-	<LinearLayout
-		android:id="@+id/LinearLayout02"
-		android:gravity="bottom"
-		android:layout_width="fill_parent"
-		android:layout_weight="1"
+		android:layout_above="@+id/TableLayout01"
+		android:layout_alignParentTop="true" android:cacheColorHint="#00000000"/>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:stretchColumns="0,2"
 		android:layout_height="wrap_content"
-		android:layout_alignParentBottom="true">
-		<Button
-			android:layout_width="fill_parent"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentRight="true"
+		android:layout_width="wrap_content">
+		<TableRow
+			android:id="@+id/TableRow01"
 			android:layout_height="wrap_content"
-			android:layout_gravity="bottom"
-			android:id="@+id/btnAccountsRefresh"
-			android:visibility="gone"
-			android:text="@string/refresh_balance"
-			android:drawableLeft="@drawable/ic_menu_refresh" />
-	</LinearLayout>
+			android:gravity="center_vertical|center_horizontal"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent">
+			<Button
+				android:text="@string/add_new_account"
+				android:drawableLeft="@drawable/button_add"
+				android:id="@+id/btnAddBank"
+				style="@style/Menu_Button"></Button>
+			<ImageView
+				android:layout_height="wrap_content"
+				android:focusable="false"
+				android:src="@drawable/menu_separator"
+				android:adjustViewBounds="true"
+				android:scaleType="fitXY"
+				android:minWidth="3dp"
+				android:maxWidth="3dp"
+				android:layout_width="wrap_content"></ImageView>
+			<Button
+				android:id="@+id/btnAccountsRefresh"
+				android:drawableLeft="@drawable/button_refresh"
+				android:text="@string/refresh_balance"
+				style="@style/Menu_Button"></Button>
+		</TableRow>
+	</TableLayout>
 </RelativeLayout>
diff --git res/layout/popup.xml res/layout/popup.xml
new file mode 100644
index 0000000..edabf1d
--- /dev/null
+++ res/layout/popup.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_height="wrap_content"
+	android:background="@drawable/popup_bg_down"
+	android:layout_width="fill_parent"
+	android:layout_gravity="fill_horizontal"
+	android:id="@+id/layPopupCont">
+	<Button style="@style/Popup_Button"
+		android:id="@+id/btnRefresh"
+		android:drawableTop="@drawable/button_refresh"
+		android:text="Refresh"
+		></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		android:id="@+id/btnEdit"
+		android:drawableTop="@drawable/button_edit"
+		android:text="Edit"
+		style="@style/Popup_Button"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		android:id="@+id/btnWWW"
+		android:drawableTop="@drawable/button_www"
+		android:text="WWW"
+		style="@style/Popup_Button"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+	<Button
+		android:id="@+id/btnRemove"
+		android:drawableTop="@drawable/button_cancel"
+		android:text="Remove"
+		style="@style/Popup_Button"></Button>
+	<ImageView style="@style/Popup_Separator"></ImageView>		
+</LinearLayout>
\ No newline at end of file
diff --git res/layout/settings.xml res/layout/settings.xml
index 00db108..d41c055 100644
--- res/layout/settings.xml
+++ res/layout/settings.xml
@@ -1,17 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat"
+	android:layout_width="fill_parent">
 
+	<ScrollView
 
-<ScrollView
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true">
+		android:layout_height="fill_parent"
+		android:layout_width="fill_parent"
+		android:fillViewport="true" android:layout_above="@+id/TableLayout01">
 	<LinearLayout
-
 		android:orientation="vertical"
 		android:layout_width="fill_parent"
 		android:layout_height="fill_parent"
-		android:paddingLeft="10dp"
-		android:paddingRight="10dp"
-		android:paddingTop="10dp">
+		android:padding="10dp"
+		android:background="@drawable/background_repeat">
 		<TextView
 			android:layout_width="fill_parent"
 			android:layout_height="wrap_content"
@@ -23,6 +28,17 @@
 			android:layout_width="fill_parent"
 			android:inputType="textPassword"
 			android:id="@+id/edtAccessCode"></EditText>
+		<TextView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:typeface="sans"
+			android:textSize="20sp"
+			android:text="@string/access_code_repeat" />
+		<EditText
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent"
+			android:inputType="textPassword"
+			android:id="@+id/edtAccessCodeRepeat"></EditText>
 
 		<TextView
 			android:layout_width="wrap_content"
@@ -78,29 +94,44 @@
 				android:text="@string/vibrate"
 				android:layout_marginLeft="10dp"></CheckBox>
 		</LinearLayout>
-		<TableLayout
-			android:id="@+id/TableLayout01"
-			android:layout_width="fill_parent"
-			android:stretchColumns="*"
-			android:gravity="bottom"
-			android:layout_height="fill_parent">
-			<TableRow
-				android:id="@+id/TableRow01"
-				android:layout_height="wrap_content"
-				android:layout_width="fill_parent">
-				<Button
-					android:layout_height="wrap_content"
-					android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
-					android:layout_width="fill_parent"
-					android:id="@+id/btnSettingsCancel"
-					android:text="@string/cancel"></Button>
-				<Button
-					android:layout_height="wrap_content"
-					android:drawableLeft="@android:drawable/ic_menu_save"
-					android:layout_width="fill_parent"
-					android:id="@+id/btnSettingsOk"
-					android:text="@string/save"></Button>
-			</TableRow>
-		</TableLayout>
+		
 	</LinearLayout>
-</ScrollView>
\ No newline at end of file
+	</ScrollView>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:stretchColumns="0,2"
+		android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentRight="true"
+		android:layout_width="wrap_content"
+		android:layout_below="@+id/LinearLayout01"
+		android:gravity="bottom">
+		<TableRow
+			android:id="@+id/TableRow01"
+			android:layout_height="wrap_content"
+			android:gravity="center_vertical|center_horizontal"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent">
+			<Button
+				android:text="@string/cancel"
+				android:drawableLeft="@drawable/button_cancel"
+				android:id="@+id/btnSettingsCancel"
+				style="@style/Menu_Button"></Button>
+			<ImageView
+				android:layout_height="wrap_content"
+				android:focusable="false"
+				android:src="@drawable/menu_separator"
+				android:adjustViewBounds="true"
+				android:scaleType="fitXY"
+				android:minWidth="3dp"
+				android:maxWidth="3dp"
+				android:layout_width="wrap_content"></ImageView>
+			<Button
+				android:id="@+id/btnSettingsOk"
+				android:drawableLeft="@drawable/button_save"
+				android:text="@string/save"
+				style="@style/Menu_Button"></Button>
+		</TableRow>
+	</TableLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/transaction_date.xml res/layout/transaction_date.xml
new file mode 100644
index 0000000..a5f6236
--- /dev/null
+++ res/layout/transaction_date.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:paddingLeft="10dp" android:paddingRight="0dp" android:clickable="true" android:background="@drawable/date_bg" android:layout_height="28dp" android:gravity="center_vertical">
+
+	<TextView
+		android:inputType="none"
+		android:scrollHorizontally="true" android:layout_width="fill_parent" android:layout_toLeftOf="@+id/txtAmount" android:textStyle="bold" android:text="2010-11-12" android:typeface="sans" android:shadowColor="#000" android:id="@+id/txtDate" android:shadowDx="0" android:shadowDy="0" android:shadowRadius="1" android:textSize="16dp" android:layout_height="wrap_content" android:gravity="center_vertical" android:paddingTop="1dp" android:textColor="#fff"/>
+
+
+	
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/listitem_accounts_item.xml res/layout/transaction_item.xml
similarity index 58%
copy from res/layout/listitem_accounts_item.xml
copy to res/layout/transaction_item.xml
index a548307..2ec52d7 100644
--- res/layout/listitem_accounts_item.xml
+++ res/layout/transaction_item.xml
@@ -2,26 +2,20 @@
 <RelativeLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent"
-	android:background="#000"
 	android:layout_height="35dp"
 	android:layout_gravity="center_horizontal"
-	android:paddingLeft="15dp"
-	android:paddingRight="10dp">
+	android:paddingLeft="10dp" android:paddingRight="0dp" android:clickable="true">
 
 	<TextView
 		android:layout_alignParentBottom="true"
 		android:ellipsize="marquee"
 		android:gravity="center_vertical"
-		android:layout_width="wrap_content"
 		android:layout_alignParentRight="false"
 		android:textColor="#fff"
 		android:layout_alignParentLeft="true"
 		android:layout_alignParentTop="true"
-		android:id="@+id/txtListitemAccountsItemAccountname"
 		android:inputType="none"
-		android:text="Kontonamn"
-		android:textStyle="bold"
-		android:layout_height="fill_parent" />
+		android:layout_height="fill_parent" android:id="@+id/txtTransaction" android:scrollHorizontally="true" android:layout_width="fill_parent" android:layout_toLeftOf="@+id/txtAmount"/>
 
 
 	<TextView
@@ -29,13 +23,12 @@
 		android:ellipsize="marquee"
 		android:text="00000 SEK"
 		android:layout_width="wrap_content"
-		android:layout_alignParentRight="true"
 		android:textColor="#fff"
 		android:layout_alignParentTop="true"
-		android:id="@+id/txtListitemAccountsItemBalance"
 		android:inputType="none"
 		android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname"
 		android:gravity="right|center_vertical"
-		android:layout_height="fill_parent" />
+		android:layout_height="fill_parent" android:layout_toLeftOf="@+id/imgColor" android:id="@+id/txtAmount" android:paddingLeft="5dp"/>
 
+<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/imgColor" android:background="@drawable/transaction_negative" android:layout_alignParentRight="true" android:layout_marginLeft="5dp"></ImageView>
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/transactions.xml res/layout/transactions.xml
new file mode 100644
index 0000000..442b1e4
--- /dev/null
+++ res/layout/transactions.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_width="wrap_content"
+	android:layout_height="fill_parent"
+	android:background="@drawable/background_repeat">
+	<include android:id="@+id/layBankHeader" layout="@layout/listitem_accounts_group" />
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:visibility="visible"
+		android:layout_margin="10dp"
+		android:layout_below="@+id/layBankHeader" android:id="@+id/txtTranDesc" android:text="@string/tran_desc"/>
+	<ListView
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:fitsSystemWindows="true"
+		android:cacheColorHint="#00000000" android:layout_below="@+id/layBankHeader" android:layout_alignParentBottom="true" android:id="@+id/lstTransactionsList" android:footerDividersEnabled="true" android:clickable="false" android:scrollbarStyle="outsideInset"/>
+	
+</RelativeLayout>
diff --git res/menu-sv/menu.xml res/menu-sv/menu.xml
index 1e97cb5..ccee6c8 100644
--- res/menu-sv/menu.xml
+++ res/menu-sv/menu.xml
@@ -1,10 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu
 	xmlns:android="http://schemas.android.com/apk/res/android">
-	<item
-		android:id="@+id/accounts"
-		android:title="Konton"
-		android:icon="@android:drawable/ic_menu_agenda" />
 	<item
 		android:id="@+id/settings"
 		android:title="Inställningar"
diff --git res/menu/menu.xml res/menu/menu.xml
index 9d44df9..5f3e08b 100644
--- res/menu/menu.xml
+++ res/menu/menu.xml
@@ -1,10 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu
 	xmlns:android="http://schemas.android.com/apk/res/android">
-	<item
-		android:id="@+id/accounts"
-		android:title="Accounts"
-		android:icon="@android:drawable/ic_menu_agenda" />
 	<item
 		android:id="@+id/settings"
 		android:title="Settings"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 5a9de78..a172cf3 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -2,7 +2,7 @@
 <resources>
     
     <string name="about">Om</string>
-    <string name="version">Version 1.1.4 av liato</string>
+    <string name="version">Version 1.2.0-rc1 av liato</string>
     <string name="widget_name_small">Bankdroid (Liten)</string>
     <string name="widget_name_large">Bankdroid (Stor)</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
@@ -21,20 +21,23 @@
     <string name="bank">Bank</string>
     <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
-    <string name="cancel">Avbryt</string>
-    <string name="save">Spara</string>
+    <string name="cancel">AVBRYT</string>
+    <string name="save">SPARA</string>
     
-	<string name="add_new_account">Lägg till ett nytt bankkonto</string>
+	<string name="add_new_account">LÄGG TILL BANK</string>
 	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
 	
 	<string name="main_instructions">Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto.</string>
-	<string name="refresh_balance">Uppdatera saldoinformation</string>
+	<string name="refresh_balance">UPPDATERA</string>
 
 	<string name="choose_an_account">Välj ett konto</string>
 	
 	<string name="update_frequency">Uppdateringsfrekvens</string>
-	<string name="access_code">PIN-kod</string>
-	<string name="pin_desc">Ange en PIN-kod om du vill lösenordsskydda applikationen och tillhörande widgets.</string>
+	<string name="access_code">Lösenord</string>
+	<string name="access_code_repeat">Upprepa lösenord</string>
+	<string name="passwords_mismatch">Du har angivit två olika lösenord. Skriv samma lösenord i båda fälten.</string>
+	<string name="passwords_mismatch_title">Felaktigt lösenord</string>
+	<string name="pin_desc">Ange ett lösenord om du vill lösenordsskydda applikationen och tillhörande widgets.</string>
 	<string name="notify_on_change">Notifiera vid kontohändelser</string>
 	<string name="with_sound">Med ljud</string>
 	<string name="vibrate">Vibrera</string>
@@ -48,6 +51,17 @@
     <string name="hours">timmar</string>
     <string name="daily">Dagligen</string>
 
+    <string name="popup_refresh">Uppdatera</string>
+    <string name="popup_edit">Redigera</string>
+    <string name="popup_www">WWW</string>
+    <string name="popup_remove">Radera</string>
+
+    <string name="remove_bank_msg">Är du säker på att du vill ta bort denna bank?</string>
+    <string name="remove_bank_title">Radera bank?</string>
+    <string name="yes">Ja</string>
+    <string name="no">Nej</string>
+    
+    <string name="tran_desc">Inget kontoutdrag tillgängligt för detta konto.</string>
 
     <string name="thanks_to">Tack till</string>
     <string name="thanks"> 
@@ -56,5 +70,7 @@
     \ngrief (Länsförsäkringar)
     \neinand (Länsförsäkringar)
     \nAnders Widén (Länsförsäkringar)
+    \nHund (Handelsbanken)
+    \nTravolta (Coop)
     </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 32e5562..765e155 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="version">Version 1.1.4 by liato</string>
+    <string name="version">Version 1.2.0-rc1 by liato</string>
     <string name="app_name">Bankdroid</string>
     <string name="widget_name_small">Bankdroid (Small)</string>
     <string name="widget_name_large">Bankdroid (Large)</string>
@@ -21,19 +21,22 @@
     <string name="bank">Bank</string>
     <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
 
-    <string name="cancel">Cancel</string>
-    <string name="save">Save</string>
+    <string name="cancel">CANCEL</string>
+    <string name="save">SAVE</string>
     
-	<string name="add_new_account">Add new bank account</string>
+	<string name="add_new_account">ADD BANK</string>
 	<string name="banks_instructions">You have not added any bank accounts yet. Press the button to add a new account.</string>
 	
 	<string name="main_instructions">You have not added any bank accounts yet, press the "Accounts" button in the menu to add a new account.</string>
-	<string name="refresh_balance">Refresh account balance</string>
+	<string name="refresh_balance">REFRESH</string>
 
 	<string name="choose_an_account">Choose an account</string>
 	
 	<string name="update_frequency">Update frequency</string>
 	<string name="access_code">Access code</string>
+	<string name="access_code_repeat">Repeat access code</string>
+	<string name="passwords_mismatch">You\'ve entered two different access codes. Enter the same password in both password fields.</string>
+	<string name="passwords_mismatch_title">Access code mismatch</string>
 	<string name="pin_desc">Enter an access code if you want to password protect the application and widgets.</string>
 	<string name="notify_on_change">Notify on changes</string>
 	<string name="with_sound">With sound</string>
@@ -49,6 +52,18 @@
     <string name="hours">hours</string>
     <string name="daily">Daily</string>
     
+    <string name="popup_refresh">Refresh</string>
+    <string name="popup_edit">Edit</string>
+    <string name="popup_www">WWW</string>
+    <string name="popup_remove">Remove</string>
+    
+    <string name="remove_bank_msg">Are you sure you want to remove this bank?</string>
+    <string name="remove_bank_title">Remove bank?</string>
+    <string name="yes">Yes</string>
+    <string name="no">No</string>
+
+    <string name="tran_desc">No transaction history available for this account.</string>
+    
     <string name="thanks_to">Thanks to</string>
     <string name="thanks"> 
     Wendell Fernandes (Icon)
@@ -56,5 +71,7 @@
     \ngrief (Länsförsäkringar)
     \neinand (Länsförsäkringar)
     \nAnders Widén (Länsförsäkringar)
+    \nHund (Handelsbanken)
+    \nTravolta (Coop)
     </string>
 </resources>
diff --git res/values/styles.xml res/values/styles.xml
index 81ac7a0..321aeaf 100644
--- res/values/styles.xml
+++ res/values/styles.xml
@@ -13,4 +13,50 @@
 		<item
 			name="android:maxHeight">2dip</item>
 	</style>
+  <style name="Menu_Button" parent="@android:style/Widget.Button">
+	<item name="android:layout_height">wrap_content</item>
+	<item name="android:paddingTop">10dp</item>
+	<item name="android:paddingBottom">4dp</item>
+	<item name="android:paddingLeft">5dp</item>
+	<item name="android:textColor">#fff</item>
+	<item name="android:background">@drawable/menu_button</item>
+	<item name="android:gravity">center_vertical|center_horizontal</item>
+	<item name="android:drawablePadding">0dp</item>
+	<item name="android:layout_width">fill_parent</item>    
+  </style>
+  <style name="Popup_Button" parent="@android:style/Widget.Button">
+	<item name="android:layout_width">wrap_content</item>    
+	<item name="android:layout_height">fill_parent</item>
+	<item name="android:paddingTop">4dp</item>
+	<item name="android:paddingBottom">4dp</item>
+	<item name="android:paddingLeft">4dp</item>
+	<item name="android:paddingRight">4dp</item>
+	<item name="android:textColor">#fff</item>
+	<item name="android:textSize">12dp</item>
+	<item name="android:minWidth">50dp</item>
+	<item name="android:background">@drawable/popup_button</item>
+	<item name="android:gravity">center_vertical|center_horizontal</item>
+  </style>
+  <style name="Popup_Separator">
+		<item name="android:layout_width">wrap_content</item>
+		<item name="android:background">@drawable/popup_separator</item>
+		<item name="android:layout_height">fill_parent</item>  	
+  </style>  
+  
+	<style name="Animations" />
+
+	<style name="Animations.GrowFromBottom">
+		<item name="@android:windowEnterAnimation">@anim/grow_from_bottom</item>
+		<item name="@android:windowExitAnimation">@anim/shrink_from_top</item>
+	</style>
+	
+	<style name="Animations.GrowFromTop">
+		<item name="@android:windowEnterAnimation">@anim/grow_from_top</item>
+		<item name="@android:windowExitAnimation">@anim/shrink_from_bottom</item>
+	</style>
+	
+	<style name="Animations.PopDownMenu">
+		<item name="@android:windowEnterAnimation">@anim/grow_from_topleft_to_bottomright</item>
+		<item name="@android:windowExitAnimation">@anim/shrink_from_bottomright_to_topleft</item>
+	</style>  
 </resources>
diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
index f2b1bdf..9459cb5 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/Account.java
@@ -1,18 +1,35 @@
 package com.liato.bankdroid;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 
 public class Account {
 	private String name;
 	private BigDecimal balance;
 	private String id;
+	private Bank bank = null;
+	private long bankId = -1;
+	private ArrayList<Transaction> transactions;
 
-	public Account(String name, BigDecimal balance, String id) {
+	public ArrayList<Transaction> getTransactions() {
+		return transactions;
+	}
+
+	public void setTransactions(ArrayList<Transaction> transactions) {
+		this.transactions = transactions;
+	}
+
+	public Account(String name, BigDecimal balance, String id, long bankId) {
 		this.name = name;
 		this.balance = balance;
 		this.id = id;
+		this.bankId = bankId;
 	}
 
+	public Account(String name, BigDecimal balance, String id) {
+		this(name, balance, id, -1);
+	}	
+
 	public void setBalance(BigDecimal balance) {
 		this.balance = balance;
 	}
@@ -28,4 +45,16 @@ public class Account {
 	public String getId() {
 		return id;
 	}
+	
+	public Bank getBank() {
+		return bank;
+	}
+	
+	public void setBank(Bank bank) {
+		this.bank = bank;
+	}
+	
+	public long getBankDbId() {
+		return bankId;
+	}
 }
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index f200978..c6ffb54 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -2,15 +2,19 @@ package com.liato.bankdroid;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.Resources;
-import android.database.Cursor;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
@@ -20,22 +24,19 @@ import android.widget.TextView;
 import android.widget.AdapterView.OnItemSelectedListener;
 
 public class AccountActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
-	private String SELECTED_BANK;
-	private String BANKID;
+	private final static String TAG = "AccountActivity";
+	private Bank SELECTED_BANK;
+	private long BANKID = -1;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.bank);
-		ArrayList<String> items = new ArrayList<String>();
-		for(Banks bank: Banks.values()) {
-			items.add(bank.toString());
-		}
+		ArrayList<Bank> items = BankFactory.listBanks(this);
 		Collections.sort(items);
 		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);
-		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
-				android.R.layout.simple_spinner_item, items);
-		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+		BankSpinnerAdapter<Bank> adapter = new BankSpinnerAdapter<Bank>(this, android.R.layout.simple_spinner_item, items);
+		//adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		spnBanks.setAdapter(adapter);
 		spnBanks.setOnItemSelectedListener(this);
 
@@ -44,26 +45,28 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 
 		Bundle extras = getIntent().getExtras(); 
 		if (extras != null) {
-			BANKID = extras.getString("id");
-			if (BANKID != null) {
-				DBAdapter db = new DBAdapter(this);
-				db.open();
-				Cursor c = db.getBank(BANKID);
-				if (c != null) {
-					((EditText)findViewById(R.id.edtBankeditUsername)).setText(c.getString(c.getColumnIndex("username")));
-					((EditText)findViewById(R.id.edtBankeditPassword)).setText(c.getString(c.getColumnIndex("password")));
+			BANKID = extras.getLong("id", -1);
+			if (BANKID != -1) {
+				Bank bank = BankFactory.bankFromDb(BANKID, this, false);
+				if (bank != null) {
+					((EditText)findViewById(R.id.edtBankeditUsername)).setText(bank.getUsername());
+					((EditText)findViewById(R.id.edtBankeditPassword)).setText(bank.getPassword());
+					
 					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
-					if (c.getInt(c.getColumnIndex("disabled")) == 1 ? true : false) {
+					if (bank.isDisabled()) {
 						errorDesc.setVisibility(View.VISIBLE);
 					}
 					else {
 						errorDesc.setVisibility(View.INVISIBLE);
-					}					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
-					int i = items.indexOf(SELECTED_BANK);
-					spnBanks.setSelection(i);
-					c.close();
+					}
+					SELECTED_BANK = bank;
+					for (int i = 0; i < items.size(); i++) {
+						if (bank.getBanktypeId() == items.get(i).getBanktypeId()) {
+							spnBanks.setSelection(i);
+							break;
+						}
+					}
 				}
-				db.close();
 			}
 		}
 	}
@@ -74,32 +77,62 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 			this.finish();
 		}
 		else if (v.getId() == R.id.btnSettingsOk){
-			new DataRetrieverTask(this).execute(SELECTED_BANK, ((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim(), ((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+			SELECTED_BANK.setUsername(((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim());
+			SELECTED_BANK.setPassword(((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+			SELECTED_BANK.setDbid(BANKID);
+			new DataRetrieverTask(this, SELECTED_BANK).execute();
 		}
 
 	}
 
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-		SELECTED_BANK = parentView.getItemAtPosition(pos).toString();
+		SELECTED_BANK = (Bank) parentView.getItemAtPosition(pos);
 	}
 
 	@Override
 	public void onNothingSelected(AdapterView<?> arg) {
 	}
 
+	private class BankSpinnerAdapter<T> extends ArrayAdapter<T> {
+		private int resource;
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent) {
+			if (convertView == null) {
+				convertView = ((LayoutInflater)super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(resource, parent, false);
+			}
+			((TextView)convertView).setText(((Bank)getItem(position)).getName());
+			return convertView;			
+		}
+
+		public BankSpinnerAdapter(Context context, int textViewResourceId, List<T> items) {
+			super(context, textViewResourceId, items);
+			resource = textViewResourceId;
+		}
+
+		@Override
+		public View getDropDownView(int position, View convertView,
+				ViewGroup parent) {
+			if (convertView == null) {
+				convertView = ((LayoutInflater)super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
+			}
+			((TextView)convertView).setText(((Bank)getItem(position)).getName());
+			return convertView;
+		}
+
+
+	}
 	private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
 		private final ProgressDialog dialog = new ProgressDialog(AccountActivity.this);
-		private Class<?> cls;
 		private Exception exc = null;
 		private Bank bank;
-		private AccountActivity parent;
+		private AccountActivity context;
 		private Resources res;
 
-		public DataRetrieverTask(AccountActivity parent) {
-			this.parent = parent;
-			this.res = parent.getResources();
-			
+		public DataRetrieverTask(AccountActivity context, Bank bank) {
+			this.context = context;
+			this.res = context.getResources();
+			this.bank = bank;
 		}
 		protected void onPreExecute() {
 			this.dialog.setMessage(res.getText(R.string.logging_in));
@@ -108,37 +141,23 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 
 		protected Void doInBackground(final String... args) {
 			try {
-				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(args[0]));
-				bank = (Bank) cls.newInstance();
-				bank.update(args[1], args[2], parent);
-				DBAdapter dba = new DBAdapter(AccountActivity.this);
-				dba.open();
-				if (BANKID != null) {
-					dba.updateBank(bank, new Long(BANKID));
-				}
-				else {
-					dba.createBank(bank);
-				}
-				dba.close();
+				Log.d(TAG, "Updating "+bank);
+				bank.update();
+				bank.updateAllTransactions();
+				Log.d(TAG, "Saving "+bank);
+				bank.save();
+				Log.d(TAG, "Disabled: "+bank.isDisabled());
 			} 
 			catch (BankException e) {
 				this.exc = e;
-			}
-			catch (ClassNotFoundException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (InstantiationException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
+			} catch (LoginException e) {
+				this.exc = e;
 			}
 			return null;
 		}
 
 		protected void onPostExecute(final Void unused) {
-			AutoRefreshService.sendWidgetRefresh(parent);
+			AutoRefreshService.sendWidgetRefresh(context);
 			if (this.dialog.isShowing()) {
 				this.dialog.dismiss();
 			}
@@ -155,11 +174,11 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 				alert.show();
 			}
 			else {
-				parent.finish();
+				context.finish();
 			}
 		}
 	}
-	
+
 	@Override
 	protected void onResume() {
 		super.onResume();
diff --git src/com/liato/bankdroid/AccountsActivity.java src/com/liato/bankdroid/AccountsActivity.java
deleted file mode 100644
index c596a5b..0000000
--- src/com/liato/bankdroid/AccountsActivity.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package com.liato.bankdroid;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.view.ContextMenu;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.OnCreateContextMenuListener;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.CursorAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemClickListener;
-
-public class AccountsActivity extends LockableActivity {
-	private DBAdapter dba;
-	private Cursor c;
-	private ListView lv;
-	private Resources res;
-	@Override
-	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.banks);
-		Button btnNewacc = (Button)findViewById(R.id.btnBanksNewaccount);
-		res = this.getResources();
-		btnNewacc.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				Intent intentAccount = new Intent(AccountsActivity.this, AccountActivity.class);
-				startActivity(intentAccount);
-			}
-		});
-	}
-
-	public void onResume() {
-		super.onResume();
-		lv = (ListView)findViewById(R.id.lstvBanksList);
-
-		refreshView();
-		lv.setOnItemClickListener(new OnItemClickListener() {
-			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-				view.showContextMenu();
-			}
-		});
-		lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
-			@Override
-			public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-				AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
-				menu.setHeaderTitle(((TextView)info.targetView.findViewById(R.id.txtListitemBankname)).getText());
-				menu.add(0, 0, 0, res.getText(R.string.menu_edit));
-				menu.add(0, 1, 0, res.getText(R.string.menu_remove));
-			}
-		});
-	}
-
-	private void refreshView() {
-		dba = new DBAdapter(this);
-		dba.open();
-		c = dba.fetchBanks();
-		if (c != null && !c.isLast() && !c.isAfterLast()) {
-			findViewById(R.id.txtBanksDesc).setVisibility(View.GONE);
-			startManagingCursor(c);
-			BanksCursorAdapter bca = new BanksCursorAdapter(this, c);
-			lv.setAdapter(bca);
-		}
-		dba.close();
-	}
-
-	public boolean onContextItemSelected(MenuItem item) {
-		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
-		View v = (View)info.targetView;
-
-		switch (item.getItemId()) { 
-		case 0: 
-			Intent intent = new Intent(AccountsActivity.this, AccountActivity.class);
-			intent.putExtra("id", v.getTag().toString());
-			startActivity(intent);
-			return true; 
-		case 1: 
-			DBAdapter db = new DBAdapter(this);
-			db.open();
-			db.deleteBank(new Long(v.getTag().toString()));
-			db.close();
-			refreshView();
-			return true; 
-		} 
-		return false; 
-	}	
-
-	public void onDestroy() {
-		if (!c.isClosed()) {
-			c.close();
-		}
-		dba.close();
-		super.onDestroy();
-	}
-	private class BanksCursorAdapter extends CursorAdapter {
-		public BanksCursorAdapter(Context context, Cursor c) {
-			super(context, c);
-		}
-
-		public void bindView(View view, Context context, Cursor cursor) {
-			ImageView icon = (ImageView)view.findViewById(R.id.imgListitemBanks);
-			((TextView)view.findViewById(R.id.txtListitemAccountname)).setText(cursor.getString(cursor.getColumnIndex("username")));
-			((TextView)view.findViewById(R.id.txtListitemBankname)).setText(cursor.getString(cursor.getColumnIndex("banktype")));
-			icon.setImageResource(getResources().getIdentifier("drawable/"+Helpers.toAscii(cursor.getString(cursor.getColumnIndex("banktype")).toLowerCase()), null, getPackageName()));
-			view.setTag(cursor.getInt(cursor.getColumnIndex("_id")));
-			ImageView warning = (ImageView)view.findViewById(R.id.imgWarning);
-			if (cursor.getInt(cursor.getColumnIndex("disabled")) == 1 ? true : false) {
-				warning.setVisibility(View.VISIBLE);
-			}
-			else {
-				warning.setVisibility(View.INVISIBLE);
-			}
-		}
-
-		@Override
-		public View newView(Context context, Cursor cursor, ViewGroup parent) {
-			LayoutInflater inflater = LayoutInflater.from(context);
-			View v = inflater.inflate(R.layout.listitem_banks, parent, false);
-			bindView(v, context, cursor);
-			return v;
-		}
-	}
-}
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index c62c710..f12201c 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -1,8 +1,6 @@
 package com.liato.bankdroid;
 
-import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.List;
 
 import android.content.Context;
 import android.util.Log;
@@ -14,51 +12,65 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 public class AccountsAdapter extends BaseAdapter {
-	private ArrayList<Group> groups;
+	private ArrayList<Bank> groups;
 	private Context context;
+	private LayoutInflater inflater;
+	
 
 	public AccountsAdapter(Context context) {
 		this.context = context;
-		this.groups = new ArrayList<Group>();
+		this.groups = new ArrayList<Bank>();
+		inflater = LayoutInflater.from(context);
+		
 	}
 
-	public void addGroup(Group group) {
+	public void addGroup(Bank group) {
 		groups.add(group);
 	}
+	
+	public void setGroups(ArrayList<Bank> banks) {
+		groups = banks;
+	}
 
-	public View newGroupView(Group group, ViewGroup parent) {
-		LayoutInflater inflater = LayoutInflater.from(context);
-		View v = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
-		ImageView icon = (ImageView)v.findViewById(R.id.imgListitemAccountsGroup);
-		((TextView)v.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getName());
-		((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
-		((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
-		icon.setImageResource(context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
-		ImageView warning = (ImageView)v.findViewById(R.id.imgWarning);
-		Log.d("AccountsAdapter", ""+group.getDisabled());
-		if (group.getDisabled()) {
+	public View newGroupView(Bank group, ViewGroup parent, View convertView) {
+		if (convertView == null) {
+			convertView = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
+		}
+		//Log.d("Convertview", ""+convertView);
+		//Log.d("Missing view?", ""+convertView.findViewById(R.id.txtListitemAccountsGroupAccountname));
+		ImageView icon = (ImageView)convertView.findViewById(R.id.imgListitemAccountsGroup);
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getUsername());
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getName());
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getBalance()));
+		icon.setImageResource(context.getResources().getIdentifier("drawable/"+group.getShortName(), null, context.getPackageName()));
+		ImageView warning = (ImageView)convertView.findViewById(R.id.imgWarning);
+		Log.d("AccountsAdapter", ""+group.isDisabled());
+		if (group.isDisabled()) {
 			warning.setVisibility(View.VISIBLE);
 		}
 		else {
 			warning.setVisibility(View.INVISIBLE);
 		}
-		return v;
+		return convertView;
 	}
 
-	public View newItemView(Item item, ViewGroup parent) {
-		LayoutInflater inflater = LayoutInflater.from(context);
-		View v = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
-		((TextView)v.findViewById(R.id.txtListitemAccountsItemAccountname)).setText(item.getName());
-		((TextView)v.findViewById(R.id.txtListitemAccountsItemBalance)).setText(Helpers.formatBalance(item.getBalance()));
-		//v.setOnClickListener(this);
-		return v;
+	public View newItemView(Account item, ViewGroup parent, View convertView) {
+		if (convertView == null) {
+			convertView = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
+		}
+		//Log.d("Convertview", ""+convertView);
+		//Log.d("Missing view?", ""+convertView.findViewById(R.id.txtListitemAccountsItemAccountname));
+		
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsItemAccountname)).setText(item.getName());
+		((TextView)convertView.findViewById(R.id.txtListitemAccountsItemBalance)).setText(Helpers.formatBalance(item.getBalance()));
+		return convertView;
 	}
 
 	@Override
 	public int getCount() {
 		int c = 0;
-		for(Group g : groups) {
-			c += g.getItems().size()+1;
+		for(Bank g : groups) {
+			c += g.getAccounts().size()+1;
 		}
 		return c;
 	}
@@ -73,14 +85,14 @@ public class AccountsAdapter extends BaseAdapter {
 		}
 
 		int i = 0;
-		for (Group g : groups) {
+		for (Bank g : groups) {
 			if (position == i) {
 				return g;
 			}
-			else if (position <= (g.getItems().size()+i)) {
-				return g.getItems().get(position-i-1);
+			else if (position <= (g.getAccounts().size()+i)) {
+				return g.getAccounts().get(position-i-1);
 			}
-			i += g.getItems().size()+1;
+			i += g.getAccounts().size()+1;
 		}
 
 		return(null);
@@ -97,92 +109,32 @@ public class AccountsAdapter extends BaseAdapter {
 		if (item == null) {
 			return null;
 		}
-		if (item instanceof Group) {
-			return newGroupView((Group)item, parent);
+		if (item instanceof Bank) {
+			return newGroupView((Bank)item, parent, convertView);
 		}
-		else if (item instanceof Item) {
-			return newItemView((Item)item, parent);
+		else if (item instanceof Account) {
+			return newItemView((Account)item, parent, convertView);
 		}
 		return null;
 	}
 
 	public boolean isEnabled(int position) {
-		if (getItem(position) instanceof Item) {
-			return true;
-		}
-		return false;
+		return true;
 	}
 
-	public final static class Group {
-		private String name;
-		private String type;
-		private BigDecimal total;
-		private List<Item> items;
-		private Boolean disabled;
-		public Group(String name, String type, Double total, List<Item> items, Boolean disabled) {
-			this.name = name;
-			this.type = type;
-			this.total = new BigDecimal(total);
-			for(Item item : items) {
-				item.setGroup(this);
-			}
-			this.items = items;
-			this.disabled = disabled;
-		}
-		public Group(String name, String type, Double total, Item item, Boolean disabled) {
-			ArrayList<Item> items = new ArrayList<Item>();
-			items.add(item);
-			this.name = name;
-			this.type = type;
-			this.total = new BigDecimal(total);
-			this.items = items;
-			this.disabled = disabled;
-		}
-		public String getName() {
-			return name;
-		}
-		public String getType() {
-			return type;
-		}
-		public BigDecimal getTotal() {
-			return total;
-		}
-		public List<Item> getItems() {
-			return items;
-		}
-		public Boolean getDisabled() {
-			return disabled;
-		}
-
+	@Override
+	public int getViewTypeCount () {
+		return 2;
 	}
 
-	public final static class Item {
-		private String name;
-		private BigDecimal balance;
-		private String id;
-		private Group group;
-		public Item (String name, Double balance, String id) {
-			this.name = name;
-			this.balance = new BigDecimal(balance);
-			this.id = id;
-		}
-		public String getName() {
-			return name;
-		}
-		public BigDecimal getBalance() {
-			return balance;
-		}
-		public String getId() {
-			return id;
-		}
-		public Group getGroup() {
-			return group;
+	@Override
+	public int getItemViewType(int position) {
+		Object item = getItem(position);
+		if (item instanceof Bank) {
+			return 0;
 		}
-		public void setGroup(Group group) {
-			this.group = group;
-		}		
+		return 1;
 	}	
-
 }
 
 
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index df2b4ae..af2aa36 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -1,8 +1,6 @@
 package com.liato.bankdroid;
 
-import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Random;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -13,16 +11,13 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
-import android.database.Cursor;
 import android.os.AsyncTask;
-import android.os.Binder;
 import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
 import android.preference.PreferenceManager;
 import android.util.Log;
 
 public class AutoRefreshService extends Service {
+	private final static String TAG = "AutoRefreshService";
 	final static String WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
     NotificationManager notificationManager;
 
@@ -48,6 +43,7 @@ public class AutoRefreshService extends Service {
 		
         Notification notification = new Notification(R.drawable.icon, text,
                 System.currentTimeMillis());
+        notification.flags |= Notification.FLAG_AUTO_CANCEL;
 		if (prefs.getBoolean("notify_with_sound", true)) {
 	        notification.defaults |= Notification.DEFAULT_SOUND;
 		}
@@ -66,10 +62,7 @@ public class AutoRefreshService extends Service {
     }
     
     private class DataRetrieverTask extends AsyncTask<String, String, Void> {
-    	private Class<?> cls;
     	private ArrayList<String> errors;
-    	private Bank bank;
-    	private int bankcount;
     	private Resources res;
 
     	public DataRetrieverTask() {
@@ -81,69 +74,44 @@ public class AutoRefreshService extends Service {
     		Log.d("doinback", "round");
     		errors = new ArrayList<String>();
     		Boolean refreshWidgets = false;
-    		DBAdapter db;
-    		Cursor c;
-    		db = new DBAdapter(AutoRefreshService.this);
-    		db.open();
-    		c = db.fetchBanks();
-    		if (c == null) {
+    		ArrayList<Bank> banks = BankFactory.banksFromDb(AutoRefreshService.this, false);
+    		if (banks.isEmpty()) {
     			return null;
     		}
-    		bankcount = c.getCount();
-    		
+    		DBAdapter db = new DBAdapter(AutoRefreshService.this);
+    		db.open();    		
     		Double currentBalance;
-    		int clmId = c.getColumnIndex("_id");
-    		int clmBanktype = c.getColumnIndex("banktype");
-    		int clmBalance = c.getColumnIndex("balance");
-    		int clmUsername = c.getColumnIndex("username");
-    		int clmPassword = c.getColumnIndex("password");
-    		int clmDisabled = c.getColumnIndex("disabled");
-    		int i = 0; 
-    		while (!c.isLast() && !c.isAfterLast()) {
-    			c.moveToNext();
-    			//publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
-    			//showNotification("Uppdaterar "+c.getString(clmBanktype));
-    			if (c.getInt(clmDisabled) == 1) {
-    				Log.d("AA", c.getString(clmBanktype)+" ("+c.getString(clmUsername)+") is disabled. Skipping refresh.");
+    		Double diff;
+    		
+    		for (Bank bank : banks) {
+    			if (bank.isDisabled()) {
+    				Log.d("AA", bank.getName()+" ("+bank.getUsername()+") is disabled. Skipping refresh.");
     				continue;
     			}
-				Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
+				Log.d("AA", "Refreshing "+bank.getName()+" ("+bank.getUsername()+").");
     			try {
-    				currentBalance = c.getDouble(clmBalance);
-    				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
-    				bank = (Bank) cls.newInstance();
-    				bank.update(c.getString(clmUsername), c.getString(clmPassword), AutoRefreshService.this);
-    				Log.d("aa",bank.getBalance().toString());
-					Double diff =  bank.getBalance().doubleValue() - currentBalance;
+    				currentBalance = bank.getBalance().doubleValue();
+    				bank.update();
+					diff =  bank.getBalance().doubleValue() - currentBalance;
     				if (diff != 0) {
-    					showNotification(c.getString(clmBanktype)+ ": "+ ((diff > 0) ? "+" : "") + Helpers.formatBalance(diff) + " ("+Helpers.formatBalance(bank.getBalance())+")");
+    					showNotification(bank.getName()+ ": "+ ((diff > 0) ? "+" : "") + Helpers.formatBalance(diff) + " ("+Helpers.formatBalance(bank.getBalance())+")");
     					refreshWidgets = true;
+    					bank.updateAllTransactions();
     				}
-    				db.updateBank(bank, c.getLong(clmId));
-    				i++;
+    				db.updateBank(bank);
     			} 
     			catch (BankException e) {
+    				// Refresh widgets if an update fails
+    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+    			} catch (LoginException e) {
     				refreshWidgets = true;
-    				db.disableBank(c.getLong(clmId));
-    			}
-    			catch (ClassNotFoundException e) {
-    				// TODO Auto-generated catch block
-    				e.printStackTrace();
-    			} catch (IllegalAccessException e) {
-    				// TODO Auto-generated catch block
-    				e.printStackTrace();
-    			} catch (InstantiationException e) {
-    				// TODO Auto-generated catch block
-    				e.printStackTrace();
-    			}
-    			
+    				db.disableBank(bank.getDbId());
+				}
     		}
     		
 			if (refreshWidgets) {
 				sendWidgetRefresh(AutoRefreshService.this);
 			}
-    		publishProgress(new String[] {new Integer(i).toString(), ""});
-    		c.close();
     		db.close();
     		return null;
     	}
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index de0658f..bf0135a 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -4,13 +4,159 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
 
-public interface Bank {
-	ArrayList<Account> getAccounts();
-	String getUsername();
-	String getPassword();
-	Banks getType();
-	BigDecimal getBalance();
-	void update() throws BankException;
-	void update(String username, String password, Context context) throws BankException;
+import com.liato.urllib.Urllib;
+
+public abstract class Bank implements Comparable<Bank> {
+	public final static int SWEDBANK = 1;
+	public final static int NORDEA = 2;
+	public final static int ICABANKEN = 3;
+	public final static int LANSFORSAKRINGAR = 4;
+	public final static int HANDELSBANKEN = 5;
+	public final static int COOP = 6;
+
+	protected String TAG = "Bank";
+	protected String NAME = "Bank";
+	protected String NAME_SHORT = "bank";
+	protected int BANKTYPE_ID = 0;
+	protected String URL;
+
+	protected Context context;
+	protected Resources res;
+	protected String username;
+	protected String password;
+	protected ArrayList<Account> accounts = new ArrayList<Account>();
+	protected BigDecimal balance = new BigDecimal(0);
+	protected boolean disabled = false;
+	protected long dbid = -1;	
+
+
+	public void setDbid(long dbid) {
+		this.dbid = dbid;
+	}
+
+	public Bank(Context context) {
+		Log.d(TAG, "Constructing bank...");
+		this.context = context;
+		this.res = this.context.getResources();
+	}
+
+	public void update(String username, String password) throws BankException, LoginException {
+		this.username = username;
+		this.password = password;
+		this.update();
+	}
+
+	public void update() throws BankException, LoginException {
+		balance = new BigDecimal(0);
+		accounts = new ArrayList<Account>();
+	}
+
+	public void updateTransactions(Account account, Urllib urlopen) throws LoginException, BankException {
+	}
+
+	public void updateAllTransactions() throws LoginException, BankException {
+		Urllib urlopen = login();
+		for (Account account: accounts) {
+			updateTransactions(account, urlopen);
+		}
+		if (urlopen != null) {
+			urlopen.close();
+		}
+		
+	}
+	
+	public Urllib login() throws LoginException, BankException {
+		return null;
+	}
+
+	public ArrayList<Account> getAccounts() {
+		return this.accounts;
+	}
+	
+	public void setAccounts(ArrayList<Account> accounts) {
+		this.accounts = accounts;
+		for (Account a : this.accounts) {
+			a.setBank(this);
+		}
+	}
+
+	public String getPassword() {
+		return password;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public BigDecimal getBalance() {
+		return balance;
+	}
+
+	public int getBanktypeId() {
+		return BANKTYPE_ID;
+	}
+
+	public String getName() {
+		return NAME;
+	}
+
+	public String getShortName() {
+		return NAME_SHORT;
+	}
+
+	public void setData(String username, String password, BigDecimal balance,
+			boolean disabled, long dbid) {
+		this.username = username;
+		this.password = password;
+		this.balance = balance;
+		this.disabled = disabled;
+		this.dbid = dbid;
+	}
+	
+	public long getDbId() {
+		return dbid;
+	}
+
+	public boolean isDisabled() {
+		return disabled;
+	}
+	
+	public void disable() {
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		db.disableBank(dbid);
+		db.close();
+	}
+	
+	public void setDisabled(boolean disabled) {
+		this.disabled = disabled;
+	}
+
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+	
+	public void save() {
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		db.updateBank(this);
+		db.close();
+	}
+	
+	public String getURL() {
+		return URL;
+	}
+
+	public int compareTo(Bank another) {
+		return this.toString().compareToIgnoreCase(another.toString());
+	}	
+	
 }
diff --git src/com/liato/bankdroid/BankFactory.java src/com/liato/bankdroid/BankFactory.java
new file mode 100644
index 0000000..2bb3a69
--- /dev/null
+++ src/com/liato/bankdroid/BankFactory.java
@@ -0,0 +1,151 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.database.Cursor;
+
+import com.liato.bankdroid.banks.Coop;
+import com.liato.bankdroid.banks.Handelsbanken;
+import com.liato.bankdroid.banks.ICABanken;
+import com.liato.bankdroid.banks.Lansforsakringar;
+import com.liato.bankdroid.banks.Nordea;
+import com.liato.bankdroid.banks.Swedbank;
+
+public class BankFactory {
+
+	public static Bank fromBanktypeId(int id, Context context) throws BankException {
+		switch (id) {
+		case Bank.SWEDBANK:
+			return new Swedbank(context);
+		case Bank.NORDEA:
+			return new Nordea(context);
+		case Bank.LANSFORSAKRINGAR:
+			return new Lansforsakringar(context);
+		case Bank.ICABANKEN:
+			return new ICABanken(context);
+		case Bank.HANDELSBANKEN:
+			return new Handelsbanken(context);
+		case Bank.COOP:
+			return new Coop(context);
+		default:
+			throw new BankException("BankType id not found.");
+		}
+	}
+	
+
+	public static ArrayList<Bank> listBanks(Context context) {
+		ArrayList<Bank> banks = new ArrayList<Bank>();
+		banks.add(new Swedbank(context));
+		banks.add(new Nordea(context));
+		banks.add(new ICABanken(context));
+		banks.add(new Lansforsakringar(context));
+		banks.add(new Handelsbanken(context));
+		banks.add(new Coop(context));
+		return banks;
+	}
+
+	public static Bank bankFromDb(long id, Context context, boolean loadAccounts) {
+		Bank bank = null;
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.getBank(id);
+
+		if (c != null) {
+			try {
+				bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+				bank.setData(c.getString(c.getColumnIndex("username")), c.getString(c.getColumnIndex("password")),
+						new BigDecimal(c.getDouble(c.getColumnIndex("username"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
+				if (loadAccounts) {
+					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+				}
+			} catch (BankException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			finally {
+				c.close();
+			}
+		}
+		db.close();
+		return bank;
+	}
+
+	public static ArrayList<Bank> banksFromDb(Context context, boolean loadAccounts) {
+		ArrayList<Bank> banks = new ArrayList<Bank>();
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.fetchBanks();
+		if (c == null) {
+			db.close();
+			return banks;
+		}
+		while (!c.isLast() && !c.isAfterLast()) {
+			c.moveToNext();
+			//Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
+			try {
+				Bank bank = fromBanktypeId(c.getInt(c.getColumnIndex("banktype")), context);
+				bank.setData(c.getString(c.getColumnIndex("username")), c.getString(c.getColumnIndex("password")),
+						new BigDecimal(c.getDouble(c.getColumnIndex("balance"))), (c.getInt(c.getColumnIndex("disabled")) == 0 ? false : true), c.getLong(c.getColumnIndex("_id")));
+				if (loadAccounts) {
+					bank.setAccounts(accountsFromDb(context, bank.getDbId()));
+				}
+				banks.add(bank);
+			} catch (BankException e) {
+				//e.printStackTrace();
+			}
+		}
+		c.close();
+		db.close();
+		return banks;
+	}
+	
+	public static Account accountFromDb(Context context, String accountId, boolean loadTransactions) {
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.getAccount(accountId);
+		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
+			db.close();
+			return null;
+		}
+
+		Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getDouble(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")), c.getLong(c.getColumnIndex("bankid")));
+		c.close();
+		if (loadTransactions) {
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			//"transdate", "btransaction", "amount"}			
+			c = db.fetchTransactions(accountId);
+			if (!(c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast()))) {
+				while (!c.isLast() && !c.isAfterLast()) {
+					c.moveToNext();
+					transactions.add(new Transaction(c.getString(c.getColumnIndex("transdate")), c.getString(c.getColumnIndex("btransaction")), new BigDecimal(c.getDouble(c.getColumnIndex("amount")))));
+				}
+			}
+			account.setTransactions(transactions);
+		}
+		
+		db.close();
+		return account;
+	}
+	
+	public static ArrayList<Account> accountsFromDb(Context context, long bankId) {
+		ArrayList<Account> accounts = new ArrayList<Account>();
+		DBAdapter db = new DBAdapter(context);
+		db.open();
+		Cursor c = db.fetchAccounts(bankId);
+		if (c == null) {
+			db.close();
+			return accounts;
+		}
+		while (!c.isLast() && !c.isAfterLast()) {
+			c.moveToNext();
+			Account account = new Account(c.getString(c.getColumnIndex("name")), new BigDecimal(c.getDouble(c.getColumnIndex("balance"))), c.getString(c.getColumnIndex("id")), c.getLong(c.getColumnIndex("bankid")));
+			accounts.add(account);
+		}
+		c.close();
+		db.close();
+		return accounts;
+	}
+	
+}
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
deleted file mode 100644
index 7c064d5..0000000
--- src/com/liato/bankdroid/BankNordea.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.liato.bankdroid;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.Html;
-import android.util.Log;
-
-import com.liato.urllib.Urllib;
-
-public class BankNordea implements Bank {
-
-	private Context context;
-	private Resources res;
-	private String username;
-	private String password;
-	private Banks banktype = Banks.NORDEA;
-	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE );
-	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private ArrayList<Account> accounts = new ArrayList<Account>();
-	private BigDecimal balance = new BigDecimal(0);
-
-	public BankNordea() {
-	}
-
-	public BankNordea(String username, String password, Context context) throws BankException {
-		this.update(username, password, context);
-	}
-
-	public void update(String username, String password, Context context) throws BankException {
-		this.context = context;
-		this.res = this.context.getResources();
-
-		this.username = username;
-		this.password = password;
-		this.update();
-	}
-	public void update() throws BankException {
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException(res.getText(R.string.invalid_username_password).toString());
-		}
-		Urllib urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
-		try {
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-			matcher = reCSRF.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-			}
-			String csrftoken = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("xyz", username));
-			postData.add(new BasicNameValuePair("zyx", password));
-			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html", postData);
-			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
-			for (String s : response.split("\n")) {
-				Log.d("BankNordea-ResponseData", s);
-			}
-			
-			if (!response.contains("logout.html")) {
-				throw new BankException(res.getText(R.string.invalid_username_password).toString());
-			}
-			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
-			for (String s : response.split("\n")) {
-				Log.d("BankNordea-ResponseData", s);
-			}
-			
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("568268.37"), "1"));
-			//accounts.add(new Account("Kapitalkonto", new BigDecimal("5789002.00"), "0"));
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		finally {
-			urlopen.close();
-		}
-
-	}
-
-
-	@Override
-	public ArrayList<Account> getAccounts() {
-		return this.accounts;
-	}
-
-	@Override
-	public String getPassword() {
-		return password;
-	}
-
-	@Override
-	public Banks getType() {
-		return banktype;
-	}
-
-	@Override
-	public String getUsername() {
-		return username;
-	}
-
-	@Override
-	public BigDecimal getBalance() {
-		return balance;
-	}	
-}
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
deleted file mode 100644
index 8b75f57..0000000
--- src/com/liato/bankdroid/BankSwedbank.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.liato.bankdroid;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.message.BasicNameValuePair;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.Html;
-import com.liato.urllib.Urllib;
-
-public class BankSwedbank implements Bank {
-
-	private Context context;
-	private Resources res;
-	private String username;
-	private String password;
-	private Banks banktype = Banks.SWEDBANK;
-	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
-	private ArrayList<Account> accounts = new ArrayList<Account>();
-	private BigDecimal balance = new BigDecimal(0);
-
-	public BankSwedbank() {
-	}
-
-	public BankSwedbank(String username, String password, Context context) throws BankException {
-		this.update(username, password, context);
-	}
-
-	public void update(String username, String password, Context context) throws BankException {
-		this.context = context;
-		this.res = this.context.getResources();
-
-		this.username = username;
-		this.password = password;
-		this.update();
-	}
-
-	public void update() throws BankException {
-		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException(res.getText(R.string.invalid_username_password).toString());
-		}        Urllib urlopen = new Urllib();
-		String response = null;
-		Matcher matcher;
-		try {
-			balance = new BigDecimal(0);
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
-			matcher = reCSRF.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
-			}
-			String csrftoken = matcher.group(1);
-			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("xyz", username));
-			postData.add(new BasicNameValuePair("zyx", password));
-			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
-
-			if (response.contains("misslyckats")) {
-				throw new BankException(res.getText(R.string.invalid_username_password).toString());
-			}
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
-			//response = urlopen.open("http://x.x00.us/android/bankdroid/swedbank_oversikt.htm");
-			matcher = reAccounts.matcher(response);
-			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
-				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
-			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
-			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("85351"), "0"));
-			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
-		}
-		catch (ClientProtocolException e) {
-			throw new BankException(e.getMessage());
-		}
-		catch (IOException e) {
-			throw new BankException(e.getMessage());
-		}
-		finally {
-			urlopen.close();
-		}
-
-	}
-
-
-	@Override
-	public ArrayList<Account> getAccounts() {
-		return this.accounts;
-	}
-
-	@Override
-	public String getPassword() {
-		return password;
-	}
-
-	@Override
-	public Banks getType() {
-		return banktype;
-	}
-
-	@Override
-	public String getUsername() {
-		return username;
-	}
-
-	@Override
-	public BigDecimal getBalance() {
-		return balance;
-	}
-
-}
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index cb65447..655e063 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -1,16 +1,12 @@
 package com.liato.bankdroid;
 
-import java.net.URI;
-
 import android.app.PendingIntent;
 import android.app.Service;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
 import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.database.Cursor;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.IBinder;
@@ -19,10 +15,11 @@ import android.view.View;
 import android.widget.RemoteViews;
 
 public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
+	private final static String TAG = "BankdroidWidgetProvider";
 	
 	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId, AccountsAdapter.Item item) {
-		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, item);
+			int appWidgetId, Account account) {
+		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, account);
 		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
 	}
 
@@ -42,50 +39,23 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 					appWidgetId);
 		}
 		Log.d("BankdroidWidgetProvider", "Account ID: "+accountId);
-		DBAdapter dba = new DBAdapter(context);
-		dba.open();
-		Cursor c = dba.getAccount(accountId);
-
-		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
+		Account account = BankFactory.accountFromDb(context, accountId, false);
+		if (account == null) {
 			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
-			c.close();
-			dba.close();
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
+			
 		}
-		int clmBalance = c.getColumnIndex("balance");
-		int clmId = c.getColumnIndex("id");
-		int clmName = c.getColumnIndex("name");
-		int clmBankId = c.getColumnIndex("bankid");
-		Double balance = c.getDouble(clmBalance);
-		String name = c.getString(clmName);
-		String id = c.getString(clmId);
-		Long bankId = c.getLong(clmBankId);
-		AccountsAdapter.Item account = new AccountsAdapter.Item(name, balance, id);
-		c.close();
-		c = dba.getBank(bankId);
-		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
-			Log.d("BankdroidWidgetProvider", "Bank not found: " + bankId);
-			c.close();
-			dba.close();
+
+		Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false);
+		if (bank == null) {
+			Log.d("BankdroidWidgetProvider", "Bank not found: " + account.getBankDbId());
 			return disableAppWidget(context, appWidgetManager,
 					appWidgetId);
+			
 		}
-
-		int clmType = c.getColumnIndex("banktype");
-		int clmDisabled = c.getColumnIndex("disabled");
-		clmBalance = c.getColumnIndex("balance");
-		clmName = c.getColumnIndex("username");
-		name = c.getString(clmName);
-		String type = c.getString(clmType);
-		balance = c.getDouble(clmBalance);
-		Log.d("dbdisabled", ""+c.getInt(clmDisabled));
-		Boolean isDisabled = (c.getInt(clmDisabled) == 1 ? true : false);
-
-		AccountsAdapter.Group group = new AccountsAdapter.Group(name, type, balance, account, isDisabled);
-		account.setGroup(group);
-		c.close();
-		dba.close();
+		
+		account.setBank(bank);
 		return buildAppWidget(context, appWidgetManager,
 				appWidgetId, account);
 	}	
@@ -93,18 +63,18 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 
 
 	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
-			int appWidgetId, AccountsAdapter.Item item) {
+			int appWidgetId, Account account) {
 		Log.d("Widget", "Building widget: "+appWidgetId);
 		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
 		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
-		AccountsAdapter.Group group = item.getGroup();
+		Bank bank = account.getBank();
 		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
 		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
-		views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
-		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
-		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
-		Log.d("Disabled", ""+group.getDisabled());
-		if (group.getDisabled()) {
+		views.setTextViewText(R.id.txtWidgetAccountname, account.getName());
+		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance()));
+		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+bank.getShortName(), null, context.getPackageName()));
+		Log.d("Disabled", ""+bank.isDisabled());
+		if (bank.isDisabled()) {
 			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
 		}
 		else {
@@ -115,7 +85,7 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
 		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
 
-		intent = new Intent(context, AccountsActivity.class);
+		//intent = new Intent(context, AccountsActivity.class);
 		pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
 		views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent);
 		
@@ -236,48 +206,26 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 					Log.d("WidgetService", "Widget not found in db: "+appWidgetId);
 					return null;
 				}
-				DBAdapter db = new DBAdapter(context);
-				db.open();
 				String bankId = accountId.split("_")[0];
-				Cursor c = db.getBank(bankId);
-				if (c == null) {
+				Bank bank = BankFactory.bankFromDb(new Long(bankId), context, false);
+				if (bank == null) {
 					return null;
 				}
 
-				int clmId = c.getColumnIndex("_id");
-				int clmBanktype = c.getColumnIndex("banktype");
-				int clmBalance = c.getColumnIndex("balance");
-				int clmUsername = c.getColumnIndex("username");
-				int clmPassword = c.getColumnIndex("password");
-				int clmDisabled = c.getColumnIndex("disabled");
 				try {
-					if (c.getInt(clmDisabled) == 0) {
-						Class cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
-						Bank bank = (Bank) cls.newInstance();
-						bank.update(c.getString(clmUsername), c.getString(clmPassword), context);
-						db.updateBank(bank, new Long(c.getString(clmId)));
+					if (!bank.isDisabled()) {
+						bank.update();
+						bank.save();
 					}
 					else {
-						Log.d("BankdroidWidgetProvider", "Bank is disabled, skipping refresh on "+c.getLong(clmId));
+						Log.d("BankdroidWidgetProvider", "Bank is disabled, skipping refresh on "+bank.getDbId());
 					}
 				} 
 				catch (BankException e) {
-					Log.d("", "Disabling bank: "+c.getLong(clmId));
-					db.disableBank(c.getLong(clmId));
-				}
-				catch (ClassNotFoundException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				} catch (IllegalAccessException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				} catch (InstantiationException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-				finally {
-					c.close();
-					db.close();
+    				Log.d(TAG, "Error while updating bank '"+bank.getDbId()+"'; "+e.getMessage());
+				} catch (LoginException e) {
+					Log.d("", "Disabling bank: "+bank.getDbId());
+					bank.disable();
 				}
 
 				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
index 6196830..2b2d478 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
@@ -1,10 +1,5 @@
 package com.liato.bankdroid;
 
-import android.appwidget.AppWidgetManager;
-import android.content.Context;
-import android.util.Log;
-import android.widget.RemoteViews;
 
 public class BankdroidWidgetProvider_4x1 extends BankdroidWidgetProvider {
-
 }
diff --git src/com/liato/bankdroid/Banks.java src/com/liato/bankdroid/Banks.java
deleted file mode 100644
index 1ccf90a..0000000
--- src/com/liato/bankdroid/Banks.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.liato.bankdroid;
-
-public enum Banks {
-	SWEDBANK 			("Swedbank"),
-	NORDEA				("Nordea"),
-	ICA					("ICA"),
-	LANSFORSAKRINGAR 	("Länsförsäkringar");
-
-	private String value;
-	private Banks(String value) {
-		this.value = value;
-	}
-	public String toString() {
-		return value;
-	}
-	public String getId() {
-		return value.toLowerCase();
-	}
-}
diff --git src/com/liato/bankdroid/BetterPopupWindow.java src/com/liato/bankdroid/BetterPopupWindow.java
new file mode 100644
index 0000000..6c3d71d
--- /dev/null
+++ src/com/liato/bankdroid/BetterPopupWindow.java
@@ -0,0 +1,200 @@
+package com.liato.bankdroid;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.PopupWindow;
+
+/**
+ * This class does most of the work of wrapping the {@link PopupWindow} so it's simpler to use.
+ * 
+ * @author qberticus
+ * 
+ */
+public class BetterPopupWindow {
+	protected final View anchor;
+	private final PopupWindow window;
+	private View root;
+	private Drawable background = null;
+	private final WindowManager windowManager;
+
+	/**
+	 * Create a BetterPopupWindow
+	 * 
+	 * @param anchor
+	 *            the view that the BetterPopupWindow will be displaying 'from'
+	 */
+	public BetterPopupWindow(View anchor) {
+		this.anchor = anchor;
+		this.window = new PopupWindow(anchor.getContext());
+
+		// when a touch even happens outside of the window
+		// make the window go away
+		this.window.setTouchInterceptor(new OnTouchListener() {
+			@Override
+			public boolean onTouch(View v, MotionEvent event) {
+				if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+					BetterPopupWindow.this.window.dismiss();
+					return true;
+				}
+				return false;
+			}
+		});
+
+		this.windowManager = (WindowManager) this.anchor.getContext().getSystemService(Context.WINDOW_SERVICE);
+		onCreate();
+	}
+
+	/**
+	 * Anything you want to have happen when created. Probably should create a view and setup the event listeners on
+	 * child views.
+	 */
+	protected void onCreate() {}
+
+	/**
+	 * In case there is stuff to do right before displaying.
+	 */
+	protected void onShow() {}
+
+	private void preShow() {
+		if(this.root == null) {
+			throw new IllegalStateException("setContentView was not called with a view to display.");
+		}
+		onShow();
+
+		if(this.background == null) {
+			this.window.setBackgroundDrawable(new BitmapDrawable());
+		} else {
+			this.window.setBackgroundDrawable(this.background);
+		}
+
+		// if using PopupWindow#setBackgroundDrawable this is the only values of the width and hight that make it work
+		// otherwise you need to set the background of the root viewgroup
+		// and set the popupwindow background to an empty BitmapDrawable
+		this.window.setWidth(WindowManager.LayoutParams.FILL_PARENT);
+		this.window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
+		this.window.setTouchable(true);
+		this.window.setFocusable(true);
+		this.window.setOutsideTouchable(true);
+
+		this.window.setContentView(this.root);
+	}
+
+	public void setBackgroundDrawable(Drawable background) {
+		this.background = background;
+	}
+
+	/**
+	 * Sets the content view. Probably should be called from {@link onCreate}
+	 * 
+	 * @param root
+	 *            the view the popup will display
+	 */
+	public void setContentView(View root) {
+		this.root = root;
+		this.window.setContentView(root);
+	}
+
+	/**
+	 * Will inflate and set the view from a resource id
+	 * 
+	 * @param layoutResID
+	 */
+	public void setContentView(int layoutResID) {
+		LayoutInflater inflator =
+				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+		this.setContentView(inflator.inflate(layoutResID, null));
+	}
+
+	/**
+	 * If you want to do anything when {@link dismiss} is called
+	 * 
+	 * @param listener
+	 */
+	public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
+		this.window.setOnDismissListener(listener);
+	}
+
+	/**
+	 * Displays like a popdown menu from the anchor view
+	 */
+	public void showLikePopDownMenu() {
+		this.showLikePopDownMenu(0, 0);
+	}
+
+	/**
+	 * Displays like a popdown menu from the anchor view.
+	 * 
+	 * @param xOffset
+	 *            offset in X direction
+	 * @param yOffset
+	 *            offset in Y direction
+	 */
+	public void showLikePopDownMenu(int xOffset, int yOffset) {
+		this.preShow();
+
+		this.window.setAnimationStyle(R.style.Animations_PopDownMenu);
+
+		this.window.showAsDropDown(this.anchor, xOffset, yOffset);
+	}
+
+	/**
+	 * Displays like a QuickAction from the anchor view.
+	 */
+	public void showLikeQuickAction() {
+		this.showLikeQuickAction(0, 0);
+	}
+
+	/**
+	 * Displays like a QuickAction from the anchor view.
+	 * 
+	 * @param xOffset
+	 *            offset in the X direction
+	 * @param yOffset
+	 *            offset in the Y direction
+	 */
+	public void showLikeQuickAction(int xOffset, int yOffset) {
+		this.preShow();
+
+		this.window.setAnimationStyle(R.style.Animations_GrowFromBottom);
+
+		int[] location = new int[2];
+		this.anchor.getLocationOnScreen(location);
+
+		Rect anchorRect =
+				new Rect(location[0], location[1], location[0] + this.anchor.getWidth(), location[1]
+					+ this.anchor.getHeight());
+
+		this.root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+		int rootWidth = this.root.getMeasuredWidth();
+		int rootHeight = this.root.getMeasuredHeight();
+
+		int screenWidth = this.windowManager.getDefaultDisplay().getWidth();
+		int screenHeight = this.windowManager.getDefaultDisplay().getHeight();
+
+		int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
+		int yPos = anchorRect.top - rootHeight + yOffset;
+
+		// display on bottom
+		if(rootHeight > anchorRect.top) {
+			yPos = anchorRect.bottom - yOffset;
+			this.window.setAnimationStyle(R.style.Animations_GrowFromTop);
+			this.root.findViewById(R.id.layPopupCont).setBackgroundResource(R.drawable.popup_bg_up);
+		}
+
+		this.window.showAtLocation(this.anchor, Gravity.NO_GRAVITY, xPos, yPos);
+	}
+
+	public void dismiss() {
+		this.window.dismiss();
+	}
+}
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index 06376a1..180ba64 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -18,7 +18,7 @@ public class DBAdapter {
     private SQLiteDatabase mDb;
     
     private static final String DATABASE_NAME = "data";
-    private static final int DATABASE_VERSION = 3;
+    private static final int DATABASE_VERSION = 7;
 
     private final Context mCtx;
 
@@ -32,9 +32,10 @@ public class DBAdapter {
         public void onCreate(SQLiteDatabase db) {
             db.execSQL("create table banks (_id integer primary key autoincrement, "
             		+ "balance real not null, "
-                    + "banktype text not null, username text not null, "
+                    + "banktype integer not null, username text not null, "
                     + "password text not null, disabled integer);");
             db.execSQL("create table accounts (bankid integer not null, id text not null, balance real not null, name text not null);");
+            db.execSQL("create table transactions (_id integer primary key autoincrement, transdate text not null, btransaction text not null, amount real not null, account text not null);");
         }
 
         @Override
@@ -43,6 +44,7 @@ public class DBAdapter {
                     + newVersion + ", which will destroy all old data");
             db.execSQL("DROP TABLE IF EXISTS banks;");
             db.execSQL("DROP TABLE IF EXISTS accounts;");
+            db.execSQL("DROP TABLE IF EXISTS transactions;");
             onCreate(db);
         }
     }
@@ -79,7 +81,7 @@ public class DBAdapter {
 
 
     public long createBank(Bank bank) {
-    	return updateBank(bank, -1);
+    	return updateBank(bank);
     }
 
     
@@ -104,6 +106,11 @@ public class DBAdapter {
         return c;
     }
 
+    
+    public int deleteTransactions(String account) {
+        int c = mDb.delete("transactions", "account='" + account + "'", null);
+        return c;
+    }    
     		
     /**
      * Return a Cursor over the list of all banks in the database
@@ -123,25 +130,34 @@ public class DBAdapter {
     public Cursor fetchAccounts(long bankId) {
         return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id"}, "bankid="+bankId, null, null, null, null);
     }
+    
+    public Cursor fetchTransactions(String account) {
+        return mDb.query("transactions", new String[] {"transdate", "btransaction", "amount"}, "account='"+account+"'", null, null, null, null);
+    }    
 
-    public long updateBank(Bank bank, long bankId) {
+    public long updateBank(Bank bank) {
+    	Log.d(TAG, "Updating bank");
     	ContentValues initialValues = new ContentValues();
-        initialValues.put("banktype", bank.getType().toString());
+        initialValues.put("banktype", bank.getBanktypeId());
         initialValues.put("username", bank.getUsername());
         initialValues.put("password", bank.getPassword());
         initialValues.put("disabled", 0);
         initialValues.put("balance", 0);
         BigDecimal total = new BigDecimal(0);
-        
+        long bankId = bank.getDbId();
+        Log.d(TAG, "Bankid: "+bankId);
         if (bankId == -1) {
+            Log.d(TAG, "Inserting new bank");
         	bankId = mDb.insert("banks", null, initialValues);
         }
         else {
+            Log.d(TAG, "Updating existing bank");
         	mDb.update("banks", initialValues, "_id="+bankId, null);
             deleteAccounts(bankId);
         }
         if (bankId != -1) {
 	        ArrayList<Account> accounts = bank.getAccounts();
+            Log.d(TAG, "Bank accounts: "+bank.getAccounts().size());
 	        for(Account acc : accounts) {
 	        	total = total.add(acc.getBalance());
 	            ContentValues vals = new ContentValues();
@@ -149,16 +165,30 @@ public class DBAdapter {
 	            vals.put("balance", acc.getBalance().doubleValue());
 	            vals.put("name", acc.getName());
 	            vals.put("id", new Long(bankId).toString()+"_"+acc.getId());
-	            mDb.insert("accounts", null, vals);	        	
+	            mDb.insert("accounts", null, vals);
+	            ArrayList<Transaction> transactions = acc.getTransactions();
+	            if (transactions != null && !transactions.isEmpty()) {
+	                deleteTransactions(new Long(bankId).toString()+"_"+acc.getId());
+		            for(Transaction transaction : transactions) {
+			            ContentValues transvals = new ContentValues();
+			            transvals.put("transdate", transaction.getDate());
+			            transvals.put("btransaction", transaction.getTransaction());
+			            transvals.put("amount", transaction.getAmount().doubleValue());
+			            transvals.put("account", new Long(bankId).toString()+"_"+acc.getId());
+			            mDb.insert("transactions", null, transvals);
+		            }
+	            }
 	        }
 	        ContentValues v = new ContentValues();
 	        v.put("balance", total.doubleValue());
 	        mDb.update("banks", v, "_id="+bankId, null);
         }
+        Log.d(TAG, "Updated bank: "+bankId);
         return bankId;
     }
     
     public void disableBank(long bankId) {
+    	if (bankId == -1) return;
         ContentValues initialValues = new ContentValues();
         initialValues.put("disabled", 1);
     	mDb.update("banks", initialValues, "_id="+bankId, null);
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index ebe715d..e91d935 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -6,24 +6,26 @@ import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.DialogInterface;
 import android.content.res.Resources;
-import android.database.Cursor;
 import android.os.AsyncTask;
 import android.util.Log;
 
 public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 	private ProgressDialog dialog;
-	private Class<?> cls;
 	private ArrayList<String> errors;
-	private Bank bank;
 	private MainActivity parent;
 	private int bankcount;
 	private Resources res;
+	private long bankId = -1;
 
 	public DataRetrieverTask(MainActivity parent) {
 		this.parent = parent;
 		this.res = parent.getResources();
 		this.dialog =  new ProgressDialog(parent);
 	}
+	public DataRetrieverTask(MainActivity parent, long bankId) {
+		this(parent);
+		this.bankId = bankId;
+	}	
 	protected void onPreExecute() {
 		this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n ");
 		this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
@@ -33,54 +35,37 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 
 	protected Void doInBackground(final String... args) {
 		errors = new ArrayList<String>();
-		DBAdapter db;
-		Cursor c;
-		db = new DBAdapter(parent);
-		db.open();
-		c = db.fetchBanks();
-		if (c == null) {
-			return null;
+		ArrayList<Bank> banks;
+		if (bankId != -1) {
+			banks = new ArrayList<Bank>();
+			banks.add(BankFactory.bankFromDb(bankId, parent, true));
 		}
-		bankcount = c.getCount();
+		else {
+			banks = BankFactory.banksFromDb(parent, true);	
+		}
+		bankcount = banks.size();
 		this.dialog.setMax(bankcount);
-		int clmId = c.getColumnIndex("_id");
-		int clmBanktype = c.getColumnIndex("banktype");
-		int clmBalance = c.getColumnIndex("balance");
-		int clmUsername = c.getColumnIndex("username");
-		int clmPassword = c.getColumnIndex("password");
-		int clmDisabled = c.getColumnIndex("disabled");
-		int i = 0; 
-		while (!c.isLast() && !c.isAfterLast()) {
-			c.moveToNext();
-			publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
-			if (c.getInt(clmDisabled) == 1) {
-				Log.d("AA", c.getString(clmBanktype)+" ("+c.getString(clmUsername)+") is disabled. Skipping refresh.");
+		int i = 0;
+		for (Bank bank : banks) {
+			publishProgress(new String[] {new Integer(i).toString(), bank.getName()+" ("+bank.getUsername()+")"});
+			if (bank.isDisabled()) {
+				Log.d("AA", bank.getName()+" ("+bank.getUsername()+") is disabled. Skipping refresh.");
 				continue;
 			}
-			Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
-			try {				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
-				bank = (Bank) cls.newInstance();
-				bank.update(c.getString(clmUsername), c.getString(clmPassword), parent);
-				db.updateBank(bank, new Long(c.getString(clmId)));
+			Log.d("AA", "Refreshing "+bank.getName()+" ("+bank.getUsername()+").");
+			try {
+				bank.update();
+				bank.updateAllTransactions();
+				bank.save();
 				i++;
 			} 
 			catch (BankException e) {
-				this.errors.add(c.getString(clmBanktype)+" ("+c.getString(clmUsername));
-				db.disableBank(c.getLong(clmId));
-			}
-			catch (ClassNotFoundException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (InstantiationException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
+				this.errors.add(bank.getName()+" ("+bank.getUsername()+")");
+			} catch (LoginException e) {
+				this.errors.add(bank.getName()+" ("+bank.getUsername()+")");
+				bank.disable();
 			}
 		}
-		c.close();
-		db.close();
 		publishProgress(new String[] {new Integer(i).toString(), ""});
 		return null;
 	}
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 988c104..81a728d 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -6,9 +6,17 @@ import java.util.Locale;
 
 public class Helpers {
 	public static BigDecimal parseBalance(String balance) {
-		balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
-		balance = balance.replaceAll("[a-zA-Z]*", "");
+		//balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
+		//balance = balance.replaceAll("[a-zA-Z]*", "");
+		//balance = balance.replaceAll("\\s*", "");
+		balance = balance.replaceAll("[^0-9,.-]*", "");
 		balance = balance.replace(",", ".");
+		if (balance.indexOf(".") != balance.lastIndexOf(".")) {
+			String b = balance.substring(balance.lastIndexOf("."));
+			balance = balance.substring(0, balance.lastIndexOf("."));
+			balance = balance.replace(".", "");
+			balance = balance+b;
+		}
 		return new BigDecimal(balance);
 	}
 	public static String formatBalance(BigDecimal balance) {
@@ -18,9 +26,4 @@ public class Helpers {
 	public static String formatBalance(Double balance) {
 		return formatBalance(new BigDecimal(balance));
 	}
-	public static String toAscii(String s) {
-		s = s.replaceAll("[åÅ]", "a").replaceAll("[äÄ]", "a").replaceAll("[öÖ]", "o").replaceAll(" ", "_");
-		s = s.replaceAll("[^a-zA-Z0-9_]", "");
-		return s;
-	}
 }
diff --git src/com/liato/bankdroid/LoginException.java src/com/liato/bankdroid/LoginException.java
new file mode 100644
index 0000000..6f7b550
--- /dev/null
+++ src/com/liato/bankdroid/LoginException.java
@@ -0,0 +1,8 @@
+package com.liato.bankdroid;
+
+public class LoginException extends Exception {
+	private static final long serialVersionUID = 1L;
+	public LoginException(String message) {
+		super(message);
+	}
+}
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index a3341a7..2d91d8c 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -1,39 +1,36 @@
 package com.liato.bankdroid;
 
-import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.List;
-
-import com.liato.bankdroid.AccountsAdapter.Group;
-import com.liato.bankdroid.AccountsAdapter.Item;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.database.Cursor;
+import android.net.Uri;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.BaseAdapter;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
 import android.widget.Button;
-import android.widget.ImageView;
 import android.widget.ListView;
-import android.widget.TextView;
+import android.widget.AdapterView.OnItemClickListener;
 
 public class MainActivity extends LockableActivity {
-	/** Called when the activity is first created. */
-	private DBAdapter dba;
+	private final static String TAG = "MainActivity";
+	protected AccountsAdapter adapter = null;
+	private static Bank selected_bank = null;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-	
+
 		setContentView(R.layout.main);
 		Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
 		btnRefresh.setOnClickListener(new View.OnClickListener() {
@@ -41,6 +38,37 @@ public class MainActivity extends LockableActivity {
 				new DataRetrieverTask(MainActivity.this).execute();
 			}
 		});		
+		Button btnAddBank = (Button)findViewById(R.id.btnAddBank);
+		btnAddBank.setOnClickListener(new View.OnClickListener() {
+			public void onClick(View v) {
+				Intent intentAccount = new Intent(MainActivity.this, AccountActivity.class);
+				startActivity(intentAccount);
+			}
+		});
+
+		ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+		adapter = new AccountsAdapter(this);
+		ArrayList<Bank> banks = new ArrayList<Bank>();//BankFactory.banksFromDb(this, true);
+		adapter.setGroups(banks);
+		lv.setAdapter(adapter);
+		lv.setOnItemClickListener(new OnItemClickListener() {
+			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+				//view.showContextMenu();
+				Log.d("itemclick", "Parent: "+parent+ "; View: "+view+"; Pos: "+position+"; ID: "+id);
+				if (adapter.getItem(position) instanceof Bank) {
+					selected_bank = (Bank) adapter.getItem(position);
+					PopupMenu pmenu = new PopupMenu(view, MainActivity.this);
+					pmenu.showLikeQuickAction(0, 12);					
+				}
+				else {
+					Intent intent = new Intent(MainActivity.this, TransactionsActivity.class);
+					Account account = (Account) adapter.getItem(position);
+					intent.putExtra("account", account.getId());
+					intent.putExtra("bank", account.getBankDbId());
+					MainActivity.this.startActivity(intent);
+				}
+			}
+		});
 	}
 
 	public void onResume() {
@@ -49,49 +77,22 @@ public class MainActivity extends LockableActivity {
 	}
 
 	public void refreshView() {
-		dba = new DBAdapter(this);
-		dba.open();
-		Cursor curBanks = dba.fetchBanks();
-		Cursor curAccounts;
-
-		if (curBanks != null && !curBanks.isLast() && !curBanks.isAfterLast()) {
+		Log.d(TAG, "refreshView()");
+		ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
+		Log.d(TAG, "Bank count: "+banks.size());
+		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-			findViewById(R.id.btnAccountsRefresh).setVisibility(View.VISIBLE);
-			startManagingCursor(curBanks);
-			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
-			AccountsAdapter adapter = new AccountsAdapter(this);
-
-			int clmId = curBanks.getColumnIndex("_id"); 
-			int clmBanktype = curBanks.getColumnIndex("banktype");
-			int clmUsername = curBanks.getColumnIndex("username");
-			int clmBankbalance = curBanks.getColumnIndex("balance");
-			int clmDisabled = curBanks.getColumnIndex("disabled");
-			List<Item> items;
-			Group bank;
-
-			while (!curBanks.isLast() && !curBanks.isAfterLast()) {
-				items = new ArrayList<Item>();
-				curBanks.moveToNext();
-				curAccounts = dba.fetchAccounts(curBanks.getLong(clmId));
-				int clmBalance = curAccounts.getColumnIndex("balance"); 
-				int clmName = curAccounts.getColumnIndex("name");
-				int clmAccId = curAccounts.getColumnIndex("id");
-				int acc_count = curAccounts.getCount();
-				if (curAccounts != null && acc_count != 0) {
-					while (!curAccounts.isLast()) {
-						curAccounts.moveToNext();
-						items.add(new Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance),curAccounts.getString(clmAccId)));
-					}
-				}
-				bank = new Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items, (curBanks.getInt(clmDisabled) == 1 ? true : false));
-				adapter.addGroup(bank);
-				curAccounts.close();
-			}
-			lv.setAdapter(adapter);
+			//findViewById(R.id.btnAccountsRefresh).setClickable(true);
+		}
+		else {
+			findViewById(R.id.txtAccountsDesc).setVisibility(View.VISIBLE);
+			//findViewById(R.id.btnAccountsRefresh).setClickable(false);
 		}
-		curBanks.close();
-		dba.close();
+
+		adapter.setGroups(banks);
+		adapter.notifyDataSetChanged();
 	}
+
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
 		MenuInflater inflater = new MenuInflater(this);
@@ -115,10 +116,6 @@ public class MainActivity extends LockableActivity {
 		case R.id.exit:
 			this.finish();
 			return true;
-		case R.id.accounts:
-			intent = new Intent(this, AccountsActivity.class);
-			this.startActivity(intent);
-			return true;
 		case R.id.settings:
 			intent = new Intent(this, SettingsActivity.class);
 			this.startActivity(intent);
@@ -134,6 +131,87 @@ public class MainActivity extends LockableActivity {
 		super.onDestroy();
 	}
 
+	/**
+	 * Extends {@link BetterPopupWindow}
+	 * <p>
+	 * Overrides onCreate to create the view and register the button listeners
+	 * 
+	 * @author qbert
+	 * 
+	 */
+	private static class PopupMenu extends BetterPopupWindow implements OnClickListener {
+		MainActivity parent = null;
+		public PopupMenu(View anchor, MainActivity parent) {
+			super(anchor);
+			this.parent = parent;
+		}
+
+		@Override
+		protected void onCreate() {
+			// inflate layout
+			LayoutInflater inflater =
+				(LayoutInflater) this.anchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+			ViewGroup root = (ViewGroup) inflater.inflate(R.layout.popup, null);
+			root.findViewById(R.id.btnRefresh).setOnClickListener(this);
+			root.findViewById(R.id.btnWWW).setOnClickListener(this);
+			root.findViewById(R.id.btnEdit).setOnClickListener(this);
+			root.findViewById(R.id.btnRemove).setOnClickListener(this);
+
+
+			this.setContentView(root);
+		}
+
+		@Override
+		public void onClick(View v) {
+			final Context context = this.anchor.getContext();
+			int id = v.getId();
+			switch (id) {
+			case R.id.btnWWW:
+				if (selected_bank != null) {
+					Uri uri = Uri.parse(selected_bank.getURL());
+					Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+					context.startActivity(intent);
+				}
+				this.dismiss();
+				return; 
+			case R.id.btnEdit:
+				Intent intent = new Intent(context, AccountActivity.class);
+				intent.putExtra("id", selected_bank.getDbId());
+				context.startActivity(intent);
+				this.dismiss();
+				return; 
+			case R.id.btnRefresh:
+				this.dismiss();
+				new DataRetrieverTask(parent, selected_bank.getDbId()).execute();
+				return; 
+			case R.id.btnRemove:
+				this.dismiss();
+				AlertDialog.Builder builder = new AlertDialog.Builder(context);
+				//builder.setMessage(getText(R.string.passwords_mismatch)).setTitle(getText(R.string.passwords_mismatch_title))
+				builder.setMessage(context.getText(R.string.remove_bank_msg)).setTitle(context.getText(R.string.remove_bank_title))
+				.setIcon(android.R.drawable.ic_dialog_alert)
+				.setPositiveButton(context.getText(R.string.yes), new DialogInterface.OnClickListener() {
+					public void onClick(DialogInterface dialog, int id) {
+						DBAdapter db = new DBAdapter(context);
+						db.open();
+						db.deleteBank(selected_bank.getDbId());
+						db.close();
+						dialog.cancel();
+						parent.refreshView();
+					}
+				})
+				.setNegativeButton(context.getText(R.string.no), new DialogInterface.OnClickListener() {
+					public void onClick(DialogInterface dialog, int id) {
+						dialog.cancel();
+					}
+				});				
+				AlertDialog alert = builder.create();
+				alert.show();
+				return;
+			}
 
+		}
+	}
 
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 00e31b0..d177054 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -2,6 +2,8 @@ package com.liato.bankdroid;
 
 import java.util.ArrayList;
 
+import android.app.AlertDialog;
+import android.content.DialogInterface;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
@@ -82,15 +84,29 @@ public class SettingsActivity extends LockableActivity implements OnClickListene
 			this.finish();
 		}
 		else if (v.getId() == R.id.btnSettingsOk){
-			Editor editor = prefs.edit();
-			editor.putString("access_code", ((EditText)findViewById(R.id.edtAccessCode)).getText().toString());
-			editor.putBoolean("notify_on_change", ((CheckBox)findViewById(R.id.chkNotifyOnChange)).isChecked());
-			editor.putBoolean("notify_with_sound", ((CheckBox)findViewById(R.id.chkWithSound)).isChecked());
-			editor.putBoolean("notify_with_vibration", ((CheckBox)findViewById(R.id.chkWithVibration)).isChecked());
-			editor.putInt("refreshrate", refreshrate);
-			editor.commit();
-			StartupReceiver.setAlarm(this);
-			this.finish();
+			if (!(((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(((EditText)findViewById(R.id.edtAccessCodeRepeat)).getText().toString()))) {
+				AlertDialog.Builder builder = new AlertDialog.Builder(this);
+				builder.setMessage(getText(R.string.passwords_mismatch)).setTitle(getText(R.string.passwords_mismatch_title))
+				.setIcon(android.R.drawable.ic_dialog_alert)
+				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+					public void onClick(DialogInterface dialog, int id) {
+						dialog.cancel();
+					}
+				});
+				AlertDialog alert = builder.create();
+				alert.show();
+			}
+			else {
+				Editor editor = prefs.edit();
+				editor.putString("access_code", ((EditText)findViewById(R.id.edtAccessCode)).getText().toString());
+				editor.putBoolean("notify_on_change", ((CheckBox)findViewById(R.id.chkNotifyOnChange)).isChecked());
+				editor.putBoolean("notify_with_sound", ((CheckBox)findViewById(R.id.chkWithSound)).isChecked());
+				editor.putBoolean("notify_with_vibration", ((CheckBox)findViewById(R.id.chkWithVibration)).isChecked());
+				editor.putInt("refreshrate", refreshrate);
+				editor.commit();
+				StartupReceiver.setAlarm(this);
+				this.finish();
+			}
 		}
 		else if (v.getId() == R.id.chkNotifyOnChange) {
 			findViewById(R.id.chkWithSound).setEnabled(((CheckBox)v).isChecked());
@@ -114,6 +130,7 @@ public class SettingsActivity extends LockableActivity implements OnClickListene
 	protected void onResume() {
 		super.onResume();
 		((EditText)findViewById(R.id.edtAccessCode)).setText(prefs.getString("access_code", ""));
+		((EditText)findViewById(R.id.edtAccessCodeRepeat)).setText(prefs.getString("access_code", ""));
 		((CheckBox)findViewById(R.id.chkNotifyOnChange)).setChecked(prefs.getBoolean("notify_on_change", true));
 		((CheckBox)findViewById(R.id.chkWithSound)).setChecked(prefs.getBoolean("notify_with_sound", true));
 		((CheckBox)findViewById(R.id.chkWithSound)).setEnabled(prefs.getBoolean("notify_on_change", true));
diff --git src/com/liato/bankdroid/Transaction.java src/com/liato/bankdroid/Transaction.java
new file mode 100644
index 0000000..da90778
--- /dev/null
+++ src/com/liato/bankdroid/Transaction.java
@@ -0,0 +1,39 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+
+public class Transaction {
+	private String date;
+	private String transaction;
+	private BigDecimal amount;
+	
+	public Transaction(String date, String transaction, BigDecimal amount) {
+		this.date = date;
+		this.transaction = transaction;
+		this.amount = amount;
+	}
+
+	public String getDate() {
+		return date;
+	}
+
+	public void setDate(String date) {
+		this.date = date;
+	}
+
+	public String getTransaction() {
+		return transaction;
+	}
+
+	public void setTransaction(String transaction) {
+		this.transaction = transaction;
+	}
+
+	public BigDecimal getAmount() {
+		return amount;
+	}
+
+	public void setAmount(BigDecimal amount) {
+		this.amount = amount;
+	}
+}
diff --git src/com/liato/bankdroid/TransactionsActivity.java src/com/liato/bankdroid/TransactionsActivity.java
new file mode 100644
index 0000000..590f5cf
--- /dev/null
+++ src/com/liato/bankdroid/TransactionsActivity.java
@@ -0,0 +1,148 @@
+package com.liato.bankdroid;
+
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class TransactionsActivity extends LockableActivity {
+	final static String TAG = "TransactionActivity";
+	
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.transactions);
+		Bundle extras = getIntent().getExtras();
+		Bank bank = BankFactory.bankFromDb(extras.getLong("bank"), this, false);
+		Account account = BankFactory.accountFromDb(this, extras.getString("account"), true);
+		TextView viewBankName = (TextView)findViewById(R.id.txtListitemAccountsGroupAccountname);
+		TextView viewAccountName = (TextView)findViewById(R.id.txtListitemAccountsGroupBankname);
+		TextView viewAccountBalance = (TextView)findViewById(R.id.txtListitemAccountsGroupTotal);
+		ListView viewTransactionsList = (ListView)findViewById(R.id.lstTransactionsList);
+		ImageView icon = (ImageView)findViewById(R.id.imgListitemAccountsGroup);
+		viewBankName.setText(bank.getUsername());
+		viewAccountName.setText(account.getName());
+		viewAccountBalance.setText(Helpers.formatBalance(account.getBalance()));
+		icon.setImageResource(getResources().getIdentifier("drawable/"+bank.getShortName(), null, getPackageName()));
+		ArrayList<Transaction> transactions = account.getTransactions();
+		Log.d(TAG, "Transactions: "+transactions.size());
+		if (transactions.size() > 0) {
+			findViewById(R.id.txtTranDesc).setVisibility(View.GONE);
+			TransactionsAdapter adapter = new TransactionsAdapter(transactions);
+			viewTransactionsList.setAdapter(adapter);
+		}
+	}
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+	}
+
+	private class TransactionsAdapter extends BaseAdapter {
+		private LayoutInflater inflater;
+		private ArrayList<Object> items = new ArrayList<Object>();
+
+		public TransactionsAdapter(ArrayList<Transaction> transactions) {
+			inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+			if (!transactions.isEmpty()) {
+				String date = transactions.get(0).getDate();
+				items.add(date);
+				for (Transaction transaction : transactions) {
+					if (!date.equals(transaction.getDate())) {
+						date = transaction.getDate();
+						items.add(date);
+					}
+					items.add(transaction);
+				}
+				
+			}
+		}
+
+		public View newTransactionView(Transaction transaction, ViewGroup parent, View convertView) {
+			if (convertView == null) {
+				convertView = inflater.inflate(R.layout.transaction_item, parent, false);
+			}
+			((TextView)convertView.findViewById(R.id.txtTransaction)).setText(transaction.getTransaction());
+			((TextView)convertView.findViewById(R.id.txtAmount)).setText(Helpers.formatBalance(transaction.getAmount()));
+			if (transaction.getAmount().signum() == 1) {
+				((ImageView)convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_positive);
+			}
+			else {
+				((ImageView)convertView.findViewById(R.id.imgColor)).setBackgroundResource(R.drawable.transaction_negative);
+			}
+			return convertView;
+		}
+
+		public View newDateView(String date, ViewGroup parent, View convertView) {
+			if (convertView == null) {
+				convertView = inflater.inflate(R.layout.transaction_date, parent, false);
+			}
+			((TextView)convertView.findViewById(R.id.txtDate)).setText(date);
+			return convertView;
+		}		
+
+		@Override
+		public int getCount() {
+			return items.size();
+		}
+
+		@Override
+		public Object getItem(int position) {
+			return items.get(position);
+		}
+
+		@Override
+		public long getItemId(int position) {
+			return position;
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent) {
+			Object item = getItem(position);
+			if (item == null) {
+				return null;
+			}
+			if (item instanceof Transaction) {
+				return newTransactionView((Transaction)item, parent, convertView);
+			}
+			else if (item instanceof String) {
+				return newDateView((String)item, parent, convertView);
+			}
+			return null;
+		}
+
+		@Override
+		public boolean areAllItemsEnabled() {
+			return true;
+		}
+
+		@Override
+		public boolean isEnabled(int position) {
+			return true;
+		}
+		
+		@Override
+		public int getViewTypeCount () {
+			return 2;
+		}
+
+		@Override
+		public int getItemViewType(int position) {
+			Object item = getItem(position);
+			if (item instanceof Transaction) {
+				return 0;
+			}
+			return 1;
+		}
+
+	}
+	
+}
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index fd5a858..59f76dc 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -1,26 +1,22 @@
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
-import java.util.List;
 
 import android.app.Activity;
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.database.Cursor;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.Button;
 import android.widget.ListView;
-import android.widget.Toast;
 import android.widget.AdapterView.OnItemClickListener;
 
 public class WidgetConfigureActivity extends Activity {
     private static final String WIDGET_PREFIX = "widget_";
-    private DBAdapter dba;
 	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
 	
 	private static final int LOGIN_ID = 1;
@@ -75,14 +71,14 @@ public class WidgetConfigureActivity extends Activity {
 				Log.d("!", "CLICK!");
 				
 	            final Context context = WidgetConfigureActivity.this;
-	            AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
+	            Account account = (Account)parent.getItemAtPosition(position);
 
-	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, item.getId());
+	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, account.getId());
 
 	            // Push widget update to surface with newly set prefix
 	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
 	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
-	                    mAppWidgetId, item);
+	                    mAppWidgetId, account);
 
 	            Intent resultValue = new Intent();
 	            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
@@ -118,47 +114,15 @@ public class WidgetConfigureActivity extends Activity {
 	
 	
 	private void refreshView() {
-		dba = new DBAdapter(this);
-		dba.open();
-		Cursor curBanks = dba.fetchBanks();
-		Cursor curAccounts;
+		ArrayList<Bank> banks = BankFactory.banksFromDb(this, true);
 
-		if (curBanks != null && !curBanks.isLast() && !curBanks.isAfterLast()) {
+		if (banks.size() > 0) {
 			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
-			startManagingCursor(curBanks);
 			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 			AccountsAdapter adapter = new AccountsAdapter(this);
-
-			int clmId = curBanks.getColumnIndex("_id"); 
-			int clmBanktype = curBanks.getColumnIndex("banktype");
-			int clmUsername = curBanks.getColumnIndex("username");
-			int clmBankbalance = curBanks.getColumnIndex("balance");
-			int clmDisabled = curBanks.getColumnIndex("disabled");
-			List<AccountsAdapter.Item> items;
-			AccountsAdapter.Group bank;
-
-			while (!curBanks.isLast() && !curBanks.isAfterLast()) {
-				items = new ArrayList<AccountsAdapter.Item>();
-				curBanks.moveToNext();
-				curAccounts = dba.fetchAccounts(curBanks.getLong(clmId));
-				int clmBalance = curAccounts.getColumnIndex("balance"); 
-				int clmName = curAccounts.getColumnIndex("name");
-				int clmAccId = curAccounts.getColumnIndex("id");
-				int acc_count = curAccounts.getCount();
-				if (curAccounts != null && acc_count != 0) {
-					while (!curAccounts.isLast()) {
-						curAccounts.moveToNext();
-						items.add(new AccountsAdapter.Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance), curAccounts.getString(clmAccId)));
-					}
-				}
-				bank = new AccountsAdapter.Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items, (curBanks.getInt(clmDisabled) == 1 ? true : false));
-				adapter.addGroup(bank);
-				curAccounts.close();
-			}
+			adapter.setGroups(banks);
 			lv.setAdapter(adapter);
 		}
-		curBanks.close();
-		dba.close();
 	}
 
 	public void onDestroy() {
diff --git src/com/liato/bankdroid/banks/Coop.java src/com/liato/bankdroid/banks/Coop.java
new file mode 100644
index 0000000..5fd04ec
--- /dev/null
+++ src/com/liato/bankdroid/banks/Coop.java
@@ -0,0 +1,103 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.urllib.Urllib;
+
+public class Coop extends Bank {
+	private static final String TAG = "Coop";
+	private static final String NAME = "Coop";
+	private static final String NAME_SHORT = "coop";
+	private static final String URL = "https://www.coop.se/mina-sidor/oversikt/";
+	private static final int BANKTYPE_ID = Bank.COOP;
+
+	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+	private Pattern reBalance = Pattern.compile("Disponibelt\\s*belopp:</td>[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+	public Coop(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Coop(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/");
+			matcher = reViewState.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
+			}
+			String strViewState = matcher.group(1);
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxUserName", username));
+			postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$TextBoxPassword", password));
+			postData.add(new BasicNameValuePair("ctl00$ContentPlaceHolderTodo$ContentPlaceHolderMainPageContainer$ContentPlaceHolderMainPageWithNavigationAndGlobalTeaser$ContentPlaceHolderPreContent$RegisterMediumUserForm$ButtonLogin", "Logga in"));
+			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/", postData);
+			Log.d(TAG, urlopen.getCurrentURI());
+			if (response.contains("Felmeddelande")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			/*
+			for (String s : response.split("\n")) {
+				Log.d(TAG, s);
+			}
+			*/			
+			response = urlopen.open("https://www.coop.se/Mina-sidor/Oversikt/?t=MedMeraVisa");
+			matcher = reBalance.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account("Betalkort", Helpers.parseBalance(matcher.group(1).trim()), "1"));
+				balance = balance.add(Helpers.parseBalance(matcher.group(1)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Handelsbanken.java src/com/liato/bankdroid/banks/Handelsbanken.java
new file mode 100644
index 0000000..5a0134d
--- /dev/null
+++ src/com/liato/bankdroid/banks/Handelsbanken.java
@@ -0,0 +1,154 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class Handelsbanken extends Bank {
+	private static final String TAG = "Handelsbanken";
+	private static final String NAME = "Handelsbanken";
+	private static final String NAME_SHORT = "handelsbanken";
+	private static final String URL = "https://m.handelsbanken.se/";
+	private static final int BANKTYPE_ID = Bank.HANDELSBANKEN;
+
+	private Pattern reBalance = Pattern.compile("block-link\\s*\"\\s*href=\"/primary/_-([^\"]+)\"><span>([^<]+)</span>.*?SEK([0-9\\s.,-ÃÂ]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccountsUrl = Pattern.compile("_-([^\"]+)\"><img[^>]+><span[^>]+>Konton<",Pattern.CASE_INSENSITIVE);
+	private Pattern reTransactions = Pattern.compile("padding-left\">([^<]+)</span><span[^>]*><span[^>]*>([^<]+)</span><span[^>]*>([^<]+)<", Pattern.CASE_INSENSITIVE);
+	public Handelsbanken(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Handelsbanken(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		Urllib urlopen = new Urllib();
+		String response = null;
+		try {
+			//Let the website set som cookies
+			response = urlopen.open("https://m.handelsbanken.se/primary/_-iseufea5");
+
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("username", username));
+			postData.add(new BasicNameValuePair("pin", password));
+			postData.add(new BasicNameValuePair("execute", "true"));
+			Log.d(TAG, "Posting data to: " + "https://m.handelsbanken.se/primary/_-iseufea5");
+			response = urlopen.open("https://m.handelsbanken.se/primary/_-iseufea5", postData);
+
+			if (response.contains("ontrollera dina uppgifter")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}		
+		return urlopen;
+	}
+	
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://m.handelsbanken.se/primary/_-iseufea5");
+			//Successful login, find accounts url and retrieve account info.
+			matcher = reAccountsUrl.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
+			}
+			String strAccountsUrl = "https://m.handelsbanken.se/primary/_-"+matcher.group(1);			
+			Log.d("TAG", "Accounts url: "+strAccountsUrl);
+			response = urlopen.open(strAccountsUrl);
+			matcher = reBalance.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+	
+	@Override
+	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
+		super.updateTransactions(account, urlopened);
+		Urllib urlopen = null;
+		if (urlopened == null) {
+			urlopen = login();
+		}
+		else {
+			urlopen = urlopened;
+		}
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://m.handelsbanken.se/primary/_-"+account.getId());
+			response = urlopen.open("https://m.handelsbanken.se/primary/_-"+account.getId());
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction(matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (urlopened == null) {
+			urlopen.close();
+		}
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/banks/ICABanken.java
similarity index 72%
rename from src/com/liato/bankdroid/BankICA.java
rename to src/com/liato/bankdroid/banks/ICABanken.java
index afbf8aa..50a7b9d 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/banks/ICABanken.java
@@ -1,7 +1,6 @@
-package com.liato.bankdroid;
+package com.liato.bankdroid.banks;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -12,45 +11,49 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.text.Html;
 import android.util.Log;
 
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
 import com.liato.urllib.Urllib;
 
-public class BankICA implements Bank {
+public class ICABanken extends Bank {
+	private static final String TAG = "ICABanken";
+	private static final String NAME = "ICA Banken";
+	private static final String NAME_SHORT = "icabanken";
+	private static final String URL = "https://mobil.icabanken.se/";
+	private static final int BANKTYPE_ID = Bank.ICABANKEN;
 
-	private Context context;
-	private Resources res;
-	private String username;
-	private String password;
-	private Banks banktype = Banks.ICA;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private ArrayList<Account> accounts = new ArrayList<Account>();
-	private BigDecimal balance = new BigDecimal(0);
 
-	public BankICA() {
+	public ICABanken(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
 	}
 
-	public BankICA(String username, String password, Context context) throws BankException {
-		this.update(username, password, context);
+	public ICABanken(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
 	}
 
-	public void update(String username, String password, Context context) throws BankException {
-		this.context = context;
-		this.res = this.context.getResources();
-
-		this.username = username;
-		this.password = password;
-		this.update();
-	}
-	public void update() throws BankException {
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException(res.getText(R.string.invalid_username_password).toString());
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 
 		Urllib urlopen = new Urllib();
@@ -78,7 +81,7 @@ public class BankICA implements Bank {
 			Log.d("BankICA", urlopen.getCurrentURI());
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
-				throw new BankException(Html.fromHtml(matcher.group(1).trim()).toString());
+				throw new LoginException(Html.fromHtml(matcher.group(1).trim()).toString());
 			}
 			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
 			Log.d("BankICA", urlopen.getCurrentURI());
@@ -108,30 +111,4 @@ public class BankICA implements Bank {
 		}
 
 	}
-
-
-	@Override
-	public ArrayList<Account> getAccounts() {
-		return this.accounts;
-	}
-
-	@Override
-	public String getPassword() {
-		return password;
-	}
-
-	@Override
-	public Banks getType() {
-		return banktype;
-	}
-
-	@Override
-	public String getUsername() {
-		return username;
-	}
-
-	@Override
-	public BigDecimal getBalance() {
-		return balance;
-	}	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/banks/Lansforsakringar.java
similarity index 73%
rename from src/com/liato/bankdroid/BankLansforsakringar.java
rename to src/com/liato/bankdroid/banks/Lansforsakringar.java
index 40067f1..a9b4b80 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/banks/Lansforsakringar.java
@@ -1,7 +1,6 @@
-package com.liato.bankdroid;
+package com.liato.bankdroid.banks;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -12,45 +11,49 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.text.Html;
 import android.util.Log;
 
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
 import com.liato.urllib.Urllib;
 
-public class BankLansforsakringar implements Bank {
+public class Lansforsakringar extends Bank {
+	private static final String TAG = "Lansforsakringar";
+	private static final String NAME = "Länsförsäkringar";
+	private static final String NAME_SHORT = "lansforsakringar";
+	private static final String URL = "https://secure246.lansforsakringar.se/lfportal/login/privat";
+	private static final int BANKTYPE_ID = Bank.LANSFORSAKRINGAR;
 
-	private Context context;
-	private Resources res;
-	private String username;
-	private String password;
-	private Banks banktype = Banks.LANSFORSAKRINGAR;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reBalance = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-	private ArrayList<Account> accounts = new ArrayList<Account>();
-	private BigDecimal balance = new BigDecimal(0);
 
-	public BankLansforsakringar() {
+	public Lansforsakringar(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
 	}
 
-	public BankLansforsakringar(String username, String password, Context context) throws BankException {
-		this.update(username, password, context);
+	public Lansforsakringar(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
 	}
 
-	public void update(String username, String password, Context context) throws BankException {
-		this.context = context;
-		this.res = this.context.getResources();
-
-		this.username = username;
-		this.password = password;
-		this.update();
-	}
-	public void update() throws BankException {
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException(res.getText(R.string.invalid_username_password).toString());
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 		}
 
 		Urllib urlopen = new Urllib();
@@ -84,7 +87,7 @@ public class BankLansforsakringar implements Bank {
 			response = urlopen.open(urlopen.getCurrentURI(), postData);
 
 			if (response.contains("Felaktig inloggning")) {
-				throw new BankException(res.getText(R.string.invalid_username_password).toString());
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
 			}
 
 			matcher = reToken.matcher(response);
@@ -121,30 +124,4 @@ public class BankLansforsakringar implements Bank {
 		}
 
 	}
-
-
-	@Override
-	public ArrayList<Account> getAccounts() {
-		return this.accounts;
-	}
-
-	@Override
-	public String getPassword() {
-		return password;
-	}
-
-	@Override
-	public Banks getType() {
-		return banktype;
-	}
-
-	@Override
-	public String getUsername() {
-		return username;
-	}
-
-	@Override
-	public BigDecimal getBalance() {
-		return balance;
-	}	
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Nordea.java src/com/liato/bankdroid/banks/Nordea.java
new file mode 100644
index 0000000..c2a64b9
--- /dev/null
+++ src/com/liato/bankdroid/banks/Nordea.java
@@ -0,0 +1,169 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class Nordea extends Bank {
+	private static final String TAG = "Nordea";
+	private static final String NAME = "Nordea";
+	private static final String NAME_SHORT = "nordea";
+	private static final String URL = "https://mobil.nordea.se/";
+	private static final int BANKTYPE_ID = Bank.NORDEA;
+	
+	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE );
+	private Pattern reTransactions = Pattern.compile("(\\d{2}.\\d{2})\\s</dt>[^>]+>([^<]+)[^>]+>.*?(?:Positive|Negative)\">([^<]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
+
+	public Nordea(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Nordea(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+			matcher = reCSRF.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+			}
+			String csrftoken = matcher.group(1);
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("xyz", username));
+			postData.add(new BasicNameValuePair("zyx", password));
+			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html", postData);
+			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
+			/*
+			for (String s : response.split("\n")) {
+				Log.d("BankNordea-ResponseData", s);
+			}
+			*/
+			
+			if (response.contains("felaktiga uppgifter")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+			
+		} catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		} catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}
+		return urlopen;
+	}
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+			/*for (String s : response.split("\n")) {
+				Log.d("BankNordea-ResponseData", s);
+			}*/
+			
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+			// Konungens konto
+			//accounts.add(new Account("Personkonto", new BigDecimal("568268.37"), "1"));
+			//accounts.add(new Account("Kapitalkonto", new BigDecimal("5789002.00"), "0"));
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+	}
+
+	@Override
+	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
+		super.updateTransactions(account, urlopened);
+		Urllib urlopen = null;
+		if (urlopened == null) {
+			urlopen = login();
+		}
+		else {
+			urlopen = urlopened;
+		}
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+			Log.d(TAG, "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/account.html?id=konton:"+account.getId());
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			String strDate = null;
+			String[] strMonthDay = null;
+			Calendar cal = Calendar.getInstance();
+			while (matcher.find()) {
+				strMonthDay = Html.fromHtml(matcher.group(1)).toString().trim().split("\\.");
+				strDate = ""+cal.get(Calendar.YEAR)+"-"+strMonthDay[1]+"-"+strMonthDay[0];
+				//Log.d(TAG, "Date: "+strDate+"; Trans: "+Html.fromHtml(matcher.group(2)).toString().trim()+"; Amount: "+Helpers.parseBalance(matcher.group(3)).toString());
+				transactions.add(new Transaction(strDate, Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (urlopened == null) {
+			urlopen.close();
+		}
+	}
+	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/banks/Swedbank.java src/com/liato/bankdroid/banks/Swedbank.java
new file mode 100644
index 0000000..1b2a82c
--- /dev/null
+++ src/com/liato/bankdroid/banks/Swedbank.java
@@ -0,0 +1,150 @@
+package com.liato.bankdroid.banks;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.content.Context;
+import android.text.Html;
+import android.util.Log;
+
+import com.liato.bankdroid.Account;
+import com.liato.bankdroid.Bank;
+import com.liato.bankdroid.BankException;
+import com.liato.bankdroid.Helpers;
+import com.liato.bankdroid.LoginException;
+import com.liato.bankdroid.R;
+import com.liato.bankdroid.Transaction;
+import com.liato.urllib.Urllib;
+
+public class Swedbank extends Bank {
+	private static final String TAG = "Swedbank";
+	private static final String NAME = "Swedbank";
+	private static final String NAME_SHORT = "swedbank";
+	private static final String URL = "https://mobilbank.swedbank.se/";
+	private static final int BANKTYPE_ID = Bank.SWEDBANK;
+
+	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
+	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
+	private Pattern reTransactions = Pattern.compile("trans-date\">([^<]+)</div>.*?trans-subject\">([^<]+)</div>.*?trans-amount\">([^<]+)</div>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
+	public Swedbank(Context context) {
+		super(context);
+		super.TAG = TAG;
+		super.NAME = NAME;
+		super.NAME_SHORT = NAME_SHORT;
+		super.BANKTYPE_ID = BANKTYPE_ID;
+		super.URL = URL;
+	}
+
+	public Swedbank(String username, String password, Context context) throws BankException, LoginException {
+		this(context);
+		this.update(username, password);
+	}
+
+	@Override
+	public Urllib login() throws LoginException, BankException {
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
+			matcher = reCSRF.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+			}
+			String csrftoken = matcher.group(1);
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("xyz", username));
+			postData.add(new BasicNameValuePair("zyx", password));
+			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
+
+			if (response.contains("misslyckats")) {
+				throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+			}
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+		}
+		return urlopen;
+	}
+
+	@Override
+	public void update() throws BankException, LoginException {
+		super.update();
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new LoginException(res.getText(R.string.invalid_username_password).toString());
+		}
+		Urllib urlopen = login();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
+			// Konungens konto
+			//accounts.add(new Account("Personkonto", new BigDecimal("85351"), "0"));
+			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+	
+	@Override
+	public void updateTransactions(Account account, Urllib urlopened) throws LoginException, BankException {
+		super.updateTransactions(account, urlopened);
+		Urllib urlopen = null;
+		if (urlopened == null) {
+			urlopen = login();
+		}
+		else {
+			urlopen = urlopened;
+		}
+		String response = null;
+		Matcher matcher;
+		try {
+			Log.d(TAG, "Opening: https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/account.html?id="+account.getId());
+			matcher = reTransactions.matcher(response);
+			ArrayList<Transaction> transactions = new ArrayList<Transaction>();
+			while (matcher.find()) {
+				transactions.add(new Transaction("20"+matcher.group(1).trim(), Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3))));
+			}
+			account.setTransactions(transactions);
+		} catch (ClientProtocolException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (urlopened == null) {
+			urlopen.close();
+		}
+	}	
+}
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index 4a91561..c62622a 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -14,21 +14,26 @@ import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 
-import android.util.Log;
-
 public class Urllib {
 	private DefaultHttpClient httpclient;
 	private HttpContext context;
 	private String currentURI;
+	private final static String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
 	
     public Urllib() {
     	httpclient = new DefaultHttpClient();
     	context = new BasicHttpContext();
+    	HttpParams params = new BasicHttpParams(); 
+        HttpProtocolParams.setContentCharset(params, "UTF-8");     	
+    	httpclient.setParams(params);
     }
     
     public String open(String url) throws ClientProtocolException, IOException {
@@ -41,11 +46,13 @@ public class Urllib {
     	ResponseHandler<String> responseHandler = new BasicResponseHandler();
     	if (postData.isEmpty()) {
     		HttpGet urlConnection = new HttpGet(url);
+    		urlConnection.addHeader("User-Agent", USER_AGENT);
     		response = httpclient.execute(urlConnection, responseHandler, context); 
     	}
     	else {
     		HttpPost urlConnection = new HttpPost(url);
     		urlConnection.setEntity(new UrlEncodedFormEntity(postData, HTTP.UTF_8));
+    		urlConnection.addHeader("User-Agent", USER_AGENT);
     		response = httpclient.execute(urlConnection, responseHandler, context); 
     	}
 

commit b89e412d39f1e6f0e1226baee082e60840f1d8f6
Author: liato <x@x00.us>
Date:   Sat Jun 5 22:31:32 2010 +0200

    Get accounts from Nordea even if an "e-faktura" hasnt been paid.

diff --git AndroidManifest.xml AndroidManifest.xml
index 50a17b0..fcd4f3e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.4" android:versionCode="20">
+	package="com.liato.bankdroid" android:versionName="1.1.4" android:versionCode="23">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index dd0e799..7c064d5 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -14,6 +14,8 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.content.res.Resources;
 import android.text.Html;
+import android.util.Log;
+
 import com.liato.urllib.Urllib;
 
 public class BankNordea implements Bank {
@@ -61,12 +63,22 @@ public class BankNordea implements Bank {
 			postData.add(new BasicNameValuePair("xyz", username));
 			postData.add(new BasicNameValuePair("zyx", password));
 			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+			Log.d("BankNordea", "Posting to https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
 			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html", postData);
-
-			if (!response.contains("accounts.html")) {
+			Log.d("BankNordea", "Url after post: "+urlopen.getCurrentURI());
+			for (String s : response.split("\n")) {
+				Log.d("BankNordea-ResponseData", s);
+			}
+			
+			if (!response.contains("logout.html")) {
 				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
-
+			Log.d("BankNordea", "Opening: https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/accounts.html");
+			for (String s : response.split("\n")) {
+				Log.d("BankNordea-ResponseData", s);
+			}
+			
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));

commit 06d7606598dca4b77f822117f84648a800f66c86
Author: liato <x@x00.us>
Date:   Thu Jun 3 16:37:38 2010 +0200

    Fixed Nordea

diff --git AndroidManifest.xml AndroidManifest.xml
index 2d7f369..50a17b0 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.3" android:versionCode="19">
+	package="com.liato.bankdroid" android:versionName="1.1.4" android:versionCode="20">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git res/layout/about.xml res/layout/about.xml
index b7286d3..0df1bec 100644
--- res/layout/about.xml
+++ res/layout/about.xml
@@ -3,7 +3,7 @@
 	android:id="@+id/RelativeLayout01"
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	android:layout_width="fill_parent"
-	android:layout_height="fill_parent">
+	android:layout_height="fill_parent" android:padding="10dp">
 	<LinearLayout
 		android:orientation="vertical"
 		android:layout_width="fill_parent"
diff --git res/layout/widget_large.xml res/layout/widget_large.xml
index f6ed569..4fd4168 100644
--- res/layout/widget_large.xml
+++ res/layout/widget_large.xml
@@ -5,7 +5,7 @@
 	android:layout_height="100dp"
 	android:id="@+id/layWidgetContainer" android:layout_width="320dp" android:background="@drawable/widget_4x1">
 
-	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:paddingTop="11dp" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="40dp"></TextView></RelativeLayout>
+	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp" android:paddingTop="8dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="37dp"></TextView></RelativeLayout>
 </RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="15dp" android:paddingRight="11dp"><FrameLayout android:layout_height="wrap_content" android:id="@+id/frmWarning" android:layout_width="wrap_content" android:visibility="invisible">
 			<ImageView android:id="@+id/imgWarning" android:adjustViewBounds="true" android:layout_height="fill_parent" android:src="@drawable/indicator_input_error" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_gravity="top|right" android:maxWidth="17dp" android:maxHeight="17dp" android:minHeight="17dp" android:minWidth="17dp"></ImageView>
 		</FrameLayout></RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index a21b72c..5a9de78 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -2,7 +2,7 @@
 <resources>
     
     <string name="about">Om</string>
-    <string name="version">Version 1.1.1 av liato</string>
+    <string name="version">Version 1.1.4 av liato</string>
     <string name="widget_name_small">Bankdroid (Liten)</string>
     <string name="widget_name_large">Bankdroid (Stor)</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
diff --git res/values/strings.xml res/values/strings.xml
index 647f94d..32e5562 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="version">Version 1.1.1 by liato</string>
+    <string name="version">Version 1.1.4 by liato</string>
     <string name="app_name">Bankdroid</string>
     <string name="widget_name_small">Bankdroid (Small)</string>
     <string name="widget_name_large">Bankdroid (Large)</string>
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index a70ac18..df2b4ae 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -123,6 +123,7 @@ public class AutoRefreshService extends Service {
     				i++;
     			} 
     			catch (BankException e) {
+    				refreshWidgets = true;
     				db.disableBank(c.getLong(clmId));
     			}
     			catch (ClassNotFoundException e) {
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index ffd909b..dd0e799 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -23,8 +23,8 @@ public class BankNordea implements Bank {
 	private String username;
 	private String password;
 	private Banks banktype = Banks.NORDEA;
-	private Pattern reBalance = Pattern.compile("(?is)nowrap>(.+?)SEK<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("sendAccount\\('SEK',\\s*'[^']+',\\s*'[^']+',\\s*'([^']+)',\\s*'([^']+)'\\)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=konton:([^\"]+)\"[^>]+>\\s*<div[^>]+>([^<]+)<span[^>]+>([^<]+)</span", Pattern.CASE_INSENSITIVE );
+	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -49,28 +49,28 @@ public class BankNordea implements Bank {
 		}
 		Urllib urlopen = new Urllib();
 		String response = null;
-		Matcher matcherBalance;
-		Matcher matcherAccounts;
+		Matcher matcher;
 		try {
-			response = urlopen.open("https://gfs.nb.se/bin2/gfskod?OBJECT=KK20");
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html");
+			matcher = reCSRF.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
+			}
+			String csrftoken = matcher.group(1);
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("kundnr", username));
-			postData.add(new BasicNameValuePair("pinkod", password));
-			postData.add(new BasicNameValuePair("OBJECT", "TT00"));
-			postData.add(new BasicNameValuePair("prev_link", "https://gfs.nb.se/privat/bank/login_kod2.html"));
-			postData.add(new BasicNameValuePair("CHECKCODE", "checkcode"));
-			response = urlopen.open("https://gfs.nb.se/bin2/gfskod", postData);
-
-			if (!response.contains("reDirect")) {
+			postData.add(new BasicNameValuePair("xyz", username));
+			postData.add(new BasicNameValuePair("zyx", password));
+			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+			response = urlopen.open("https://mobil.nordea.se/banking-nordea/nordea-c3/login.html", postData);
+
+			if (!response.contains("accounts.html")) {
 				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
 
-			response = urlopen.open("https://gfs.nb.se/bin2/gfskod?OBJECT=KF00T&show_button=No");
-			matcherBalance = reBalance.matcher(response);
-			matcherAccounts = reAccounts.matcher(response);
-			while (matcherAccounts.find() && matcherBalance.find()) {
-				accounts.add(new Account(Html.fromHtml(matcherAccounts.group(2)).toString(), Helpers.parseBalance(matcherBalance.group(1)), matcherAccounts.group(2).trim()));
-				balance = balance.add(Helpers.parseBalance(matcherBalance.group(1)));
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 			if (accounts.isEmpty()) {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 0bca700..cb65447 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -38,14 +38,20 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
 		if (accountId == null) {
 			Log.d("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
-			return null;
+			return disableAppWidget(context, appWidgetManager,
+					appWidgetId);
 		}
+		Log.d("BankdroidWidgetProvider", "Account ID: "+accountId);
 		DBAdapter dba = new DBAdapter(context);
 		dba.open();
 		Cursor c = dba.getAccount(accountId);
-		if (c == null) {
+
+		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
 			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
-			return null;
+			c.close();
+			dba.close();
+			return disableAppWidget(context, appWidgetManager,
+					appWidgetId);
 		}
 		int clmBalance = c.getColumnIndex("balance");
 		int clmId = c.getColumnIndex("id");
@@ -58,9 +64,12 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		AccountsAdapter.Item account = new AccountsAdapter.Item(name, balance, id);
 		c.close();
 		c = dba.getBank(bankId);
-		if (c == null) {
+		if (c == null || c.isClosed() || (c.isBeforeFirst() && c.isAfterLast())) {
 			Log.d("BankdroidWidgetProvider", "Bank not found: " + bankId);
-			return null;
+			c.close();
+			dba.close();
+			return disableAppWidget(context, appWidgetManager,
+					appWidgetId);
 		}
 
 		int clmType = c.getColumnIndex("banktype");
@@ -121,6 +130,26 @@ public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
 		return views;
 	}
 	
+
+	static RemoteViews disableAppWidget(Context context, AppWidgetManager appWidgetManager,
+			int appWidgetId) {
+		Log.d("Widget", "Disabling widget: "+appWidgetId);
+		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
+		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
+		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
+		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
+		views.setTextViewText(R.id.txtWidgetAccountname, "");
+		views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR");
+		views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large);
+		views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
+
+		Intent intent = new Intent(context, LoginActivity.class);
+		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
+		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
+
+		return views;
+	}	
 	
 	
 	

commit bb65f97c7c29f699f37b1c6fcaf9e1626be416fd
Author: liato <x@x00.us>
Date:   Wed Jun 2 06:02:38 2010 +0200

    New widget size. Fixed bug where widgets didnt update on boot.

diff --git AndroidManifest.xml AndroidManifest.xml
index b81a7e3..2d7f369 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.2" android:versionCode="18">
+	package="com.liato.bankdroid" android:versionName="1.1.3" android:versionCode="19">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
-			android:alwaysRetainTaskState="true" android:theme="@android:style/Theme.Dialog">
+			android:alwaysRetainTaskState="false" android:theme="@android:style/Theme.Dialog">
 			<intent-filter>
 				<action android:name="android.intent.action.MAIN" />
 				<category android:name="android.intent.category.LAUNCHER" />
@@ -25,7 +25,7 @@
 				<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
 			</intent-filter>
 		</activity>
-		<receiver android:name="BankdroidWidgetProvider">
+		<receiver android:name="BankdroidWidgetProvider_2x1" android:label="@string/widget_name_small">
 			<intent-filter>
 				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
 				<action android:name="com.liato.bankdroid.WIDGET_REFRESH" />
@@ -34,6 +34,15 @@
 				android:resource="@xml/appwidget_info" />
 		</receiver>
 
+		<receiver android:name="BankdroidWidgetProvider_4x1" android:label="@string/widget_name_large">
+			<intent-filter>
+				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+				<action android:name="com.liato.bankdroid.WIDGET_REFRESH" />
+			</intent-filter>
+			<meta-data android:name="android.appwidget.provider"
+				android:resource="@xml/appwidget_info_large" />
+		</receiver>
+
 		<service android:enabled="true" android:name=".AutoRefreshService" />
 		<service android:enabled="true" android:name=".BankdroidWidgetProvider$WidgetService" />
 		<receiver android:name="StartupReceiver">
@@ -41,7 +50,6 @@
 				<action android:name="android.intent.action.BOOT_COMPLETED" />
 				<action android:name="android.intent.action.PACKAGE_REPLACED" />
 				<data android:scheme="package" android:path="com.liato.bankdroid" />
-				<category android:name="android.intent.category.HOME" />
 			</intent-filter>
 		</receiver>
 	</application>
diff --git res/drawable/widget_4x1.png res/drawable/widget_4x1.png
new file mode 100644
index 0000000..2dbc8ba
Binary files /dev/null and res/drawable/widget_4x1.png differ
diff --git res/layout/widget.xml res/layout/widget.xml
index e62fab4..4f757b1 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -24,12 +24,11 @@
 			android:layout_height="wrap_content"
 			android:layout_width="wrap_content"
 			android:id="@+id/txtWidgetAccountname"
-			android:text="Kapitalkonto"
 			android:layout_gravity="center_vertical"
 			android:textColor="#a8a3a3"
 			android:textSize="11dp"
 			android:inputType="none"
-			android:layout_marginLeft="2dp"></TextView>
+			android:layout_marginLeft="2dp" android:text="Bankdroid"></TextView>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow02"
@@ -45,9 +44,8 @@
 			android:ellipsize="none"
 			android:gravity="center_vertical|center_horizontal"
 			android:textSize="15dp"
-			android:text="129 500,00 SEK"
 			android:id="@+id/txtWidgetAccountbalance"
-			android:layout_height="fill_parent" />
+			android:layout_height="fill_parent" android:text="Loading..."/>
 	</LinearLayout>
 	<LinearLayout
 		android:id="@+id/layWidgetRow03"
diff --git res/layout/widget_large.xml res/layout/widget_large.xml
new file mode 100644
index 0000000..f6ed569
--- /dev/null
+++ res/layout/widget_large.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_gravity="center_horizontal"
+	android:layout_height="100dp"
+	android:id="@+id/layWidgetContainer" android:layout_width="320dp" android:background="@drawable/widget_4x1">
+
+	<RelativeLayout android:id="@+id/RelativeLayout02" android:paddingLeft="17dp" android:paddingTop="24dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="fill_parent" android:paddingRight="28dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:scaleType="fitXY" android:layout_height="52dp" android:layout_width="52dp" android:src="@drawable/icon_large"></ImageView><RelativeLayout android:id="@+id/RelativeLayout01" android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_gravity="center_vertical|center_horizontal" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:id="@+id/txtWidgetAccountbalance" android:layout_height="wrap_content" android:layout_toRightOf="@+id/imgWidgetIcon" android:layout_width="wrap_content" android:paddingTop="11dp" android:layout_centerInParent="false" android:layout_centerHorizontal="true" android:text="Loading..." android:textSize="27dp" android:paddingRight="1dp"/><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_alignRight="@+id/txtWidgetAccountbalance" android:gravity="right" android:layout_alignTop="@+id/txtWidgetAccountbalance" android:paddingTop="40dp"></TextView></RelativeLayout>
+</RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:paddingTop="15dp" android:paddingRight="11dp"><FrameLayout android:layout_height="wrap_content" android:id="@+id/frmWarning" android:layout_width="wrap_content" android:visibility="invisible">
+			<ImageView android:id="@+id/imgWarning" android:adjustViewBounds="true" android:layout_height="fill_parent" android:src="@drawable/indicator_input_error" android:scaleType="fitXY" android:layout_width="wrap_content" android:layout_gravity="top|right" android:maxWidth="17dp" android:maxHeight="17dp" android:minHeight="17dp" android:minWidth="17dp"></ImageView>
+		</FrameLayout></RelativeLayout><RelativeLayout android:id="@+id/RelativeLayout04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/RelativeLayout02" android:paddingTop="75dp" android:paddingLeft="34dp"><FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:minWidth="17dp" android:visibility="visible" android:minHeight="6dp" android:maxHeight="6dp" android:layout_gravity="top|center_horizontal"></ProgressBar></FrameLayout></RelativeLayout>
+	
+	
+	
+
+
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 9b776cc..a21b72c 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -3,6 +3,8 @@
     
     <string name="about">Om</string>
     <string name="version">Version 1.1.1 av liato</string>
+    <string name="widget_name_small">Bankdroid (Liten)</string>
+    <string name="widget_name_large">Bankdroid (Stor)</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
     <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
     <string name="errors_when_updating">Fel vid uppdatering</string>
diff --git res/values/strings.xml res/values/strings.xml
index 7644983..647f94d 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -2,6 +2,8 @@
 <resources>
     <string name="version">Version 1.1.1 by liato</string>
     <string name="app_name">Bankdroid</string>
+    <string name="widget_name_small">Bankdroid (Small)</string>
+    <string name="widget_name_large">Bankdroid (Large)</string>
     <string name="about">About</string>
     <string name="accounts_were_not_updated">Balance for the following accounts could not be updated</string>
     <string name="updating_account_balance">Refreshing account balance...</string>
diff --git res/xml/appwidget_info_large.xml res/xml/appwidget_info_large.xml
new file mode 100644
index 0000000..564461a
--- /dev/null
+++ res/xml/appwidget_info_large.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="294dp"
+    android:minHeight="72dp"
+    android:updatePeriodMillis="0"
+    android:initialLayout="@layout/widget_large"
+    android:configure="com.liato.bankdroid.WidgetConfigureActivity" >
+</appwidget-provider>
\ No newline at end of file
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index 421a916..a70ac18 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -166,6 +166,7 @@ public class AutoRefreshService extends Service {
 
     
     public static void sendWidgetRefresh(Context context) {
+    	//Send intent to BankdroidWidgetProvider
         Intent updateIntent = new Intent(WIDGET_REFRESH);
         PendingIntent pendingIntent = PendingIntent.getBroadcast(
         		context, 0, updateIntent,
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index 6c89de8..ffd909b 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -76,8 +76,8 @@ public class BankNordea implements Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("568269.37"), "1"));
-			//accounts.add(new Account("Kapitalkonto", new BigDecimal("25789000.00"), "1"));
+			//accounts.add(new Account("Personkonto", new BigDecimal("568268.37"), "1"));
+			//accounts.add(new Account("Kapitalkonto", new BigDecimal("5789002.00"), "0"));
 		}
 		catch (ClientProtocolException e) {
 			throw new BankException(e.getMessage());
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index b15f982..8b75f57 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -78,7 +78,7 @@ public class BankSwedbank implements Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			// Konungens konto
-			//accounts.add(new Account("Personkonto", new BigDecimal("1485351"), "0"));
+			//accounts.add(new Account("Personkonto", new BigDecimal("85351"), "0"));
 			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
 		}
 		catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 4ef3dfd..0bca700 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -6,6 +6,7 @@ import android.app.PendingIntent;
 import android.app.Service;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
+import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -17,8 +18,8 @@ import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
 
-public class BankdroidWidgetProvider extends AppWidgetProvider {
-
+public abstract class BankdroidWidgetProvider extends AppWidgetProvider {
+	
 	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId, AccountsAdapter.Item item) {
 		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, item);
@@ -30,7 +31,7 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
 		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
 	}
-	
+
 	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
 		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
@@ -82,12 +83,14 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 
 
 
-	
 	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId, AccountsAdapter.Item item) {
 		Log.d("Widget", "Building widget: "+appWidgetId);
+		AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
+		int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout;
 		AccountsAdapter.Group group = item.getGroup();
-		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
+		RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
+		Log.d("buildAppWidget", "WidgetLayout: "+layoutId);
 		views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
 		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
 		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
@@ -114,7 +117,7 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 		pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 		views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent);
 
-		//appWidgetManager.updateAppWidget(appWidgetId, views);
+		//appWidgetManager.updateAppWidget(appWidgetId, views); 
 		return views;
 	}
 	
@@ -135,11 +138,10 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 		}
 
 
-		Log.d("BankdroidWidgetProvider", "intent=" + intent);
-
-		if (action.equals(AutoRefreshService.WIDGET_REFRESH)) {
+		Log.d("BankdroidWidgetProvider", "intent=" + intent+"; action="+action);
+		if (action.equals(AutoRefreshService.WIDGET_REFRESH) || action.equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
 			AppWidgetManager appWM = AppWidgetManager.getInstance(context);
-			int[] appWidgetIds = appWM.getAppWidgetIds(new ComponentName(context, BankdroidWidgetProvider.class));
+			int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent());
 			final int N = appWidgetIds.length;
 			for (int i = 0; i < N; i++) {
 				int appWidgetId = appWidgetIds[i];
@@ -260,6 +262,7 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 					views.setViewVisibility(R.id.frmProgress, View.INVISIBLE);
 					appWidgetManager.updateAppWidget(appWidgetId, views);
 				}
+				WidgetService.this.stopSelf();
 			}
 
 			
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
new file mode 100644
index 0000000..89fadd2
--- /dev/null
+++ src/com/liato/bankdroid/BankdroidWidgetProvider_2x1.java
@@ -0,0 +1,4 @@
+package com.liato.bankdroid;
+
+public class BankdroidWidgetProvider_2x1 extends BankdroidWidgetProvider {
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
new file mode 100644
index 0000000..6196830
--- /dev/null
+++ src/com/liato/bankdroid/BankdroidWidgetProvider_4x1.java
@@ -0,0 +1,10 @@
+package com.liato.bankdroid;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+public class BankdroidWidgetProvider_4x1 extends BankdroidWidgetProvider {
+
+}
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index 08884f2..f4ad6d6 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -9,15 +9,12 @@ import android.content.SharedPreferences;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
-import android.widget.Toast;
 
 public class StartupReceiver extends BroadcastReceiver{
 	@Override
 	public void onReceive(Context context, Intent intent) {
-		//Intent serviceIntent = new Intent();
-		//serviceIntent.setAction("AutoRefreshService");
-		//Log.d("","starting service");
-		//context.startService(serviceIntent);
+		//Set alarms for auto updates on boot
+		Log.d("StartupReceiever", "Intent action: "+intent.getAction());
 		setAlarm(context);
 	}
 	
@@ -27,7 +24,7 @@ public class StartupReceiver extends BroadcastReceiver{
 		
 		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
 		Integer refreshrate = prefs.getInt("refreshrate", -1);
-        AlarmManager am = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
+        AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         if (refreshrate < 0) {
         	am.cancel(alarmSender);
         	Log.d("","Alarm disabled.");
@@ -35,7 +32,7 @@ public class StartupReceiver extends BroadcastReceiver{
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
 	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*60*1000, refreshrate*60*1000, alarmSender);
-        	Log.d("","Alarm set to "+refreshrate.toString()+" minutes.");
+        	Log.d("StartupReceiever.SetAlarm","Alarm set to "+refreshrate.toString()+" minutes.");
         }
 	
 	}
diff --git widgets.psd widgets.psd
index 86a01c5..e9a0d7a 100644
Binary files widgets.psd and widgets.psd differ

commit da907d0e353fd438b37d48fe1b5eaf7bbc2de1d4
Author: liato <x@x00.us>
Date:   Mon May 31 21:35:08 2010 +0200

    Fixed ICA Banken.

diff --git AndroidManifest.xml AndroidManifest.xml
index 331faef..b81a7e3 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.1" android:versionCode="15">
-	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
+	package="com.liato.bankdroid" android:versionName="1.1.2" android:versionCode="18">
+	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="false">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
 			android:alwaysRetainTaskState="true" android:theme="@android:style/Theme.Dialog">
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
index 4643cfc..afbf8aa 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankICA.java
@@ -14,6 +14,8 @@ import org.apache.http.message.BasicNameValuePair;
 import android.content.Context;
 import android.content.res.Resources;
 import android.text.Html;
+import android.util.Log;
+
 import com.liato.urllib.Urllib;
 
 public class BankICA implements Bank {
@@ -73,15 +75,13 @@ public class BankICA implements Bank {
 			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
 			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
 			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx", postData);
-
+			Log.d("BankICA", urlopen.getCurrentURI());
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
 				throw new BankException(Html.fromHtml(matcher.group(1).trim()).toString());
 			}
-			if (accounts.isEmpty()) {
-				throw new BankException(res.getText(R.string.no_accounts_found).toString());
-			}
 			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
+			Log.d("BankICA", urlopen.getCurrentURI());
 			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_oversikt.htm");
 			matcher = reBalanceSald.matcher(response);
 			while (matcher.find()) {

commit f5fce4a411a237362ac68e6132e1febd456b6a65
Author: liato <x@x00.us>
Date:   Mon May 31 18:16:04 2010 +0200

    version 1.1.1

diff --git AndroidManifest.xml AndroidManifest.xml
index 278a73f..331faef 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.1" android:versionCode="14">
+	package="com.liato.bankdroid" android:versionName="1.1.1" android:versionCode="15">
 	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index ae852ea..9b776cc 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     
-     <string name="about">Om</string>
+    <string name="about">Om</string>
+    <string name="version">Version 1.1.1 av liato</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
     <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
     <string name="errors_when_updating">Fel vid uppdatering</string>
diff --git res/values/strings.xml res/values/strings.xml
index fc29a3c..7644983 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="version">Version 1.1.0 by liato</string>
+    <string name="version">Version 1.1.1 by liato</string>
     <string name="app_name">Bankdroid</string>
     <string name="about">About</string>
     <string name="accounts_were_not_updated">Balance for the following accounts could not be updated</string>

commit e4e9d68a9adea21cc34db2bc3b864424d1e62aea
Author: liato <x@x00.us>
Date:   Mon May 31 18:14:46 2010 +0200

    Fixed FC bug in widget. Fixed ICA Banken hopefully.

diff --git AndroidManifest.xml AndroidManifest.xml
index 1c8a34f..278a73f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.1.0" android:versionCode="13">
-	<application android:icon="@drawable/icon" android:label="@string/app_name">
+	package="com.liato.bankdroid" android:versionName="1.1.1" android:versionCode="14">
+	<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
 			android:alwaysRetainTaskState="true" android:theme="@android:style/Theme.Dialog">
diff --git res/layout/bank.xml res/layout/bank.xml
index 3e17edd..fe25167 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -1,80 +1,83 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
+<ScrollView
 	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="vertical"
-	android:layout_width="fill_parent"
 	android:layout_height="fill_parent"
-	android:paddingLeft="10dp"
-	android:paddingRight="10dp"
-	android:paddingTop="10dp">
-	<TextView
+	android:layout_width="fill_parent" android:fillViewport="true">
+	<LinearLayout
+		android:orientation="vertical"
 		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:typeface="sans"
-		android:textSize="20sp"
-		android:text="@string/username" />
+		android:layout_height="fill_parent"
+		android:paddingLeft="10dp"
+		android:paddingRight="10dp"
+		android:paddingTop="10dp">
+		<TextView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:typeface="sans"
+			android:textSize="20sp"
+			android:text="@string/username" />
 
-	<EditText
-		android:layout_height="wrap_content"
-		android:layout_width="fill_parent"
-		android:id="@+id/edtBankeditUsername"
-		android:digits="0123456789-"
-		android:inputType="phone"></EditText>
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:typeface="sans"
-		android:textSize="20sp"
-		android:text="@string/password" />
-	<EditText
-		android:layout_height="wrap_content"
-		android:layout_width="fill_parent"
-		android:id="@+id/edtBankeditPassword"
-		android:inputType="textPassword"></EditText>
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:typeface="sans"
-		android:textSize="20sp"
-		android:text="@string/bank" />
+		<EditText
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent"
+			android:id="@+id/edtBankeditUsername"
+			android:digits="0123456789-"
+			android:inputType="phone"></EditText>
+		<TextView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:typeface="sans"
+			android:textSize="20sp"
+			android:text="@string/password" />
+		<EditText
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent"
+			android:id="@+id/edtBankeditPassword"
+			android:inputType="textPassword"></EditText>
+		<TextView
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:typeface="sans"
+			android:textSize="20sp"
+			android:text="@string/bank" />
 
 
-	<Spinner
-		android:layout_height="wrap_content"
-		android:layout_width="fill_parent"
-		android:id="@+id/spnBankeditBanklist"></Spinner>
-	<TextView
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:drawableLeft="@drawable/indicator_input_error"
-		android:text="@string/error_desc"
-		android:textSize="12sp"
-		android:drawablePadding="5dp"
-		android:id="@+id/txtErrorDesc"
-		android:visibility="invisible"></TextView>
-	<TableLayout
-		android:id="@+id/TableLayout01"
-		android:layout_width="fill_parent"
-		android:stretchColumns="*"
-		android:gravity="bottom"
-		android:layout_height="fill_parent">
-		<TableRow
-			android:id="@+id/TableRow01"
+		<Spinner
 			android:layout_height="wrap_content"
-			android:layout_width="fill_parent">
-			<Button
-				android:layout_height="wrap_content"
-				android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
-				android:layout_width="fill_parent"
-				android:id="@+id/btnSettingsCancel"
-				android:text="@string/cancel"></Button>
-			<Button
+			android:layout_width="fill_parent"
+			android:id="@+id/spnBankeditBanklist"></Spinner>
+		<TextView
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:drawableLeft="@drawable/indicator_input_error"
+			android:text="@string/error_desc"
+			android:textSize="12sp"
+			android:drawablePadding="5dp"
+			android:id="@+id/txtErrorDesc"
+			android:visibility="invisible"></TextView>
+		<TableLayout
+			android:id="@+id/TableLayout01"
+			android:layout_width="fill_parent"
+			android:stretchColumns="*"
+			android:gravity="bottom"
+			android:layout_height="fill_parent">
+			<TableRow
+				android:id="@+id/TableRow01"
 				android:layout_height="wrap_content"
-				android:drawableLeft="@android:drawable/ic_menu_save"
-				android:layout_width="fill_parent"
-				android:id="@+id/btnSettingsOk"
-				android:text="@string/save"></Button>
-		</TableRow>
-	</TableLayout>
-
-</LinearLayout>
+				android:layout_width="fill_parent">
+				<Button
+					android:layout_height="wrap_content"
+					android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
+					android:layout_width="fill_parent"
+					android:id="@+id/btnSettingsCancel"
+					android:text="@string/cancel"></Button>
+				<Button
+					android:layout_height="wrap_content"
+					android:drawableLeft="@android:drawable/ic_menu_save"
+					android:layout_width="fill_parent"
+					android:id="@+id/btnSettingsOk"
+					android:text="@string/save"></Button>
+			</TableRow>
+		</TableLayout>
+	</LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git res/layout/settings.xml res/layout/settings.xml
index 55dbfae..00db108 100644
--- res/layout/settings.xml
+++ res/layout/settings.xml
@@ -1,106 +1,106 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="vertical"
-	android:layout_width="fill_parent"
-	android:layout_height="fill_parent"
-	android:paddingLeft="10dp"
-	android:paddingRight="10dp"
-	android:paddingTop="10dp">
-
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:typeface="sans"
-		android:textSize="20sp"
-		android:text="@string/access_code" />
-	<EditText
-		android:layout_height="wrap_content"
-		android:layout_width="fill_parent"
-		android:inputType="textPassword"
-		android:id="@+id/edtAccessCode"></EditText>
-
-	<TextView
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:id="@+id/txtSettingsPinDesc"
-		android:text="@string/pin_desc"
-		android:textSize="12sp"
-		android:textColor="#A4A4A4"
-		android:drawableLeft="@android:drawable/ic_dialog_info"
-		android:drawablePadding="5dp"
-		android:layout_marginBottom="3dp"></TextView>
-	<TextView
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:typeface="sans"
-		android:textSize="20sp"
-		android:text="@string/update_frequency"
-		android:visibility="visible" />
-	<Spinner
-		android:layout_height="wrap_content"
-		android:layout_width="fill_parent"
-		android:id="@+id/spnUpdateFrequency"
-		android:visibility="visible"></Spinner>
-
-
-
 
 
+<ScrollView
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true">
 	<LinearLayout
-		android:id="@+id/LinearLayout01"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
+
 		android:orientation="vertical"
-		android:paddingLeft="10dp">
-		<CheckBox
-			android:layout_width="wrap_content"
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:paddingLeft="10dp"
+		android:paddingRight="10dp"
+		android:paddingTop="10dp">
+		<TextView
+			android:layout_width="fill_parent"
 			android:layout_height="wrap_content"
-			android:text="@string/notify_on_change"
-			android:id="@+id/chkNotifyOnChange"
-			android:visibility="visible"></CheckBox>
-		<CheckBox
-			android:layout_width="wrap_content"
+			android:typeface="sans"
+			android:textSize="20sp"
+			android:text="@string/access_code" />
+		<EditText
 			android:layout_height="wrap_content"
-			android:text="@string/with_sound"
-			android:id="@+id/chkWithSound"
-			android:textSize="14sp"
-			android:layout_marginLeft="10dp"></CheckBox>
-		<CheckBox
+			android:layout_width="fill_parent"
+			android:inputType="textPassword"
+			android:id="@+id/edtAccessCode"></EditText>
+
+		<TextView
 			android:layout_width="wrap_content"
 			android:layout_height="wrap_content"
-			android:textSize="14sp"
-			android:id="@+id/chkWithVibration"
-			android:text="@string/vibrate"
-			android:layout_marginLeft="10dp"></CheckBox>
-	</LinearLayout>
-	<TableLayout
-		android:id="@+id/TableLayout01"
-		android:layout_width="fill_parent"
-		android:stretchColumns="*"
-		android:gravity="bottom"
-		android:layout_height="fill_parent">
-		<TableRow
-			android:id="@+id/TableRow01"
+			android:id="@+id/txtSettingsPinDesc"
+			android:text="@string/pin_desc"
+			android:textSize="12sp"
+			android:textColor="#A4A4A4"
+			android:drawableLeft="@android:drawable/ic_dialog_info"
+			android:drawablePadding="5dp"
+			android:layout_marginBottom="3dp"></TextView>
+		<TextView
+			android:layout_width="fill_parent"
 			android:layout_height="wrap_content"
-			android:layout_width="fill_parent">
-			<Button
-				android:layout_height="wrap_content"
-				android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
-				android:layout_width="fill_parent"
-				android:id="@+id/btnSettingsCancel"
-				android:text="@string/cancel"></Button>
-			<Button
-				android:layout_height="wrap_content"
-				android:drawableLeft="@android:drawable/ic_menu_save"
-				android:layout_width="fill_parent"
-				android:id="@+id/btnSettingsOk"
-				android:text="@string/save"></Button>
-		</TableRow>
-	</TableLayout>
+			android:typeface="sans"
+			android:textSize="20sp"
+			android:text="@string/update_frequency"
+			android:visibility="visible" />
+		<Spinner
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent"
+			android:id="@+id/spnUpdateFrequency"
+			android:visibility="visible"></Spinner>
 
 
 
 
 
-</LinearLayout>
+		<LinearLayout
+			android:id="@+id/LinearLayout01"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:orientation="vertical"
+			android:paddingLeft="10dp">
+			<CheckBox
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:text="@string/notify_on_change"
+				android:id="@+id/chkNotifyOnChange"
+				android:visibility="visible"></CheckBox>
+			<CheckBox
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:text="@string/with_sound"
+				android:id="@+id/chkWithSound"
+				android:textSize="14sp"
+				android:layout_marginLeft="10dp"></CheckBox>
+			<CheckBox
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:textSize="14sp"
+				android:id="@+id/chkWithVibration"
+				android:text="@string/vibrate"
+				android:layout_marginLeft="10dp"></CheckBox>
+		</LinearLayout>
+		<TableLayout
+			android:id="@+id/TableLayout01"
+			android:layout_width="fill_parent"
+			android:stretchColumns="*"
+			android:gravity="bottom"
+			android:layout_height="fill_parent">
+			<TableRow
+				android:id="@+id/TableRow01"
+				android:layout_height="wrap_content"
+				android:layout_width="fill_parent">
+				<Button
+					android:layout_height="wrap_content"
+					android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
+					android:layout_width="fill_parent"
+					android:id="@+id/btnSettingsCancel"
+					android:text="@string/cancel"></Button>
+				<Button
+					android:layout_height="wrap_content"
+					android:drawableLeft="@android:drawable/ic_menu_save"
+					android:layout_width="fill_parent"
+					android:id="@+id/btnSettingsOk"
+					android:text="@string/save"></Button>
+			</TableRow>
+		</TableLayout>
+	</LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git res/layout/widget.xml res/layout/widget.xml
index ef4105d..e62fab4 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -4,7 +4,7 @@
 	android:layout_gravity="center_horizontal"
 	android:background="@drawable/widget_2x1"
 	android:layout_height="100dp"
-	android:layout_width="160dp">
+	android:layout_width="160dp" android:id="@+id/layWidgetContainer">
 
 	<LinearLayout
 		android:layout_height="wrap_content"
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
index 59548ba..421a916 100644
--- src/com/liato/bankdroid/AutoRefreshService.java
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -52,10 +52,9 @@ public class AutoRefreshService extends Service {
 	        notification.defaults |= Notification.DEFAULT_SOUND;
 		}
 		if (prefs.getBoolean("notify_with_vibration", true)) {
-			/*long[] vib = {23,28,27,143,20,30,26,364,22,26,
-						  28,26,28,26,28,26,29,25,27,27,
-						  27,27,28,28,28,28,28,27,27,26,27};
-			notification.vibrate = vib;*/
+			//long[] vib = {23,28,27,143,20,30,26,364,22,26,28,26,28,26,28,26,29,25,27,27,27,27,28,28,28,28,28,27,27,26,27};
+			//long[] vib = {46, 56, 54, 286, 40, 60, 52, 728, 44, 52, 56, 52, 56, 52, 56, 52, 58, 50, 54, 54, 54, 54, 56, 56, 56, 56, 56, 54, 54, 52, 54};
+			//notification.vibrate = vib;
 			notification.defaults |= Notification.DEFAULT_VIBRATE;
 		}
         PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
index 2e8e327..4643cfc 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankICA.java
@@ -26,7 +26,8 @@ public class BankICA implements Bank {
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt\\s*([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceDisp = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalanceSald = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a[^D]*Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -81,7 +82,13 @@ public class BankICA implements Bank {
 				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
-			matcher = reBalance.matcher(response);
+			//response = urlopen.open("http://x.x00.us/android/bankdroid/icabanken_oversikt.htm");
+			matcher = reBalanceSald.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			matcher = reBalanceDisp.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index fbd6339..4ef3dfd 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -101,6 +101,7 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 		Intent intent = new Intent(context, LoginActivity.class);
 		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
 		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
+		views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent);
 
 		intent = new Intent(context, AccountsActivity.class);
 		pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
diff --git src/com/liato/bankdroid/LoginActivity.java src/com/liato/bankdroid/LoginActivity.java
index e64023f..ffe9e79 100644
--- src/com/liato/bankdroid/LoginActivity.java
+++ src/com/liato/bankdroid/LoginActivity.java
@@ -19,7 +19,7 @@ public class LoginActivity extends Activity {
 
 	public void onCreate(Bundle savedInstanceState) {
 		String widgetAction = getIntent().getAction();
-		if (!widgetAction.equals("widgetLogin")) {
+		if ("widgetLogin".equals(widgetAction)) {
 		    setTheme(android.R.style.Theme);
 		}
 		super.onCreate(savedInstanceState);
@@ -34,7 +34,7 @@ public class LoginActivity extends Activity {
 					if (((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(access_code)) {
 						Log.d("LoginActivity", "Success");
 						String widgetAction = getIntent().getAction();
-						if (widgetAction.equals("widgetLogin")) {
+						if ("widgetLogin".equals(widgetAction)) {
 							Log.d("LoginActivity", "unLockOnly");
 							setResult(Activity.RESULT_OK);
 							finish();
@@ -56,8 +56,8 @@ public class LoginActivity extends Activity {
 			});	
 		}
 		else {
-			Log.d("LoginActivity", widgetAction);
-			if (widgetAction.equals("widgetLogin")) {
+			Log.d("LoginActivity", "Action:"+ widgetAction);
+			if ("widgetLogin".equals(widgetAction)) {
 				Log.d("LoginActivity", "unLockOnly");
 				setResult(Activity.RESULT_OK);
 				finish();

commit 8ed24e30421a9c07691dad68ecf3794ef304c661
Author: liato <x@x00.us>
Date:   Mon May 31 11:04:22 2010 +0200

    Improved widget locking (thanks to Anders Widen). Added error indicator on widgets and activitys. Added about dialog.

diff --git AndroidManifest.xml AndroidManifest.xml
index 387c13e..1c8a34f 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,11 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.0.4"
-	android:versionCode="12">
+	package="com.liato.bankdroid" android:versionName="1.1.0" android:versionCode="13">
 	<application android:icon="@drawable/icon" android:label="@string/app_name">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
-			android:alwaysRetainTaskState="true">
+			android:alwaysRetainTaskState="true" android:theme="@android:style/Theme.Dialog">
 			<intent-filter>
 				<action android:name="android.intent.action.MAIN" />
 				<category android:name="android.intent.category.LAUNCHER" />
@@ -36,6 +35,7 @@
 		</receiver>
 
 		<service android:enabled="true" android:name=".AutoRefreshService" />
+		<service android:enabled="true" android:name=".BankdroidWidgetProvider$WidgetService" />
 		<receiver android:name="StartupReceiver">
 			<intent-filter>
 				<action android:name="android.intent.action.BOOT_COMPLETED" />
diff --git res/drawable/indicator_input_error.png res/drawable/indicator_input_error.png
new file mode 100644
index 0000000..fea7c4d
Binary files /dev/null and res/drawable/indicator_input_error.png differ
diff --git res/drawable/widget_progress.xml res/drawable/widget_progress.xml
new file mode 100644
index 0000000..c86cae8
--- /dev/null
+++ res/drawable/widget_progress.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animation-list
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:oneshot="false">
+	<item
+		android:drawable="@drawable/widget_progress_1"
+		android:duration="200" />
+	<item
+		android:drawable="@drawable/widget_progress_2"
+		android:duration="200" />
+	<item
+		android:drawable="@drawable/widget_progress_3"
+		android:duration="200" />
+	<item
+		android:drawable="@drawable/widget_progress_4"
+		android:duration="200" />
+	<item
+		android:drawable="@drawable/widget_progress_3"
+		android:duration="200" />
+	<item
+		android:drawable="@drawable/widget_progress_2"
+		android:duration="200" />
+</animation-list>
diff --git res/drawable/widget_progress_1.png res/drawable/widget_progress_1.png
new file mode 100644
index 0000000..1dbb003
Binary files /dev/null and res/drawable/widget_progress_1.png differ
diff --git res/drawable/widget_progress_2.png res/drawable/widget_progress_2.png
new file mode 100644
index 0000000..0a8481e
Binary files /dev/null and res/drawable/widget_progress_2.png differ
diff --git res/drawable/widget_progress_3.png res/drawable/widget_progress_3.png
new file mode 100644
index 0000000..14c0324
Binary files /dev/null and res/drawable/widget_progress_3.png differ
diff --git res/drawable/widget_progress_4.png res/drawable/widget_progress_4.png
new file mode 100644
index 0000000..cf90589
Binary files /dev/null and res/drawable/widget_progress_4.png differ
diff --git res/layout/about.xml res/layout/about.xml
new file mode 100644
index 0000000..b7286d3
--- /dev/null
+++ res/layout/about.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	android:id="@+id/RelativeLayout01"
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	<LinearLayout
+		android:orientation="vertical"
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:paddingLeft="10dp"
+		android:paddingRight="10dp"
+		android:paddingTop="10dp"
+		android:layout_gravity="center_vertical"
+		android:fitsSystemWindows="true">
+
+
+		<TextView
+			android:id="@+id/TextView01"
+			android:layout_height="wrap_content"
+			android:typeface="sans"
+			android:gravity="center_horizontal"
+			android:layout_gravity="center_horizontal"
+			android:text="BANKDROID"
+			android:layout_width="fill_parent"
+			android:visibility="visible"
+			android:textColor="#fff"
+			android:textSize="42dp"></TextView>
+		<LinearLayout
+			android:id="@+id/LinearLayout01"
+			android:layout_height="wrap_content"
+			android:orientation="horizontal"
+			android:layout_width="fill_parent">
+			<ImageView
+				android:id="@+id/ImageView01"
+				android:background="@drawable/icon_large"
+				android:layout_width="100dp"
+				android:layout_height="100dp"
+				android:layout_gravity="center_horizontal"
+				android:visibility="visible"></ImageView>
+			<LinearLayout
+				android:id="@+id/LinearLayout02"
+				android:layout_height="wrap_content"
+				android:orientation="vertical"
+				android:layout_width="fill_parent"><TextView android:layout_height="wrap_content" android:id="@+id/txtVersion" android:layout_width="fill_parent" android:textSize="17dp" android:text="@string/version"></TextView>
+				
+				
+			<TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="http://liato.github.com/android-bankdroid/" android:autoLink="web" android:fitsSystemWindows="false"></TextView></LinearLayout>
+		
+
+</LinearLayout>
+
+
+
+
+
+
+		
+
+	<TextView android:id="@+id/TextView04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/thanks_to" android:textSize="20sp" android:textStyle="bold" android:layout_marginTop="10dp"></TextView><ScrollView android:id="@+id/ScrollView01" android:layout_height="wrap_content" android:layout_width="fill_parent"><TextView android:id="@+id/TextView03" android:layout_height="wrap_content" android:text="@string/thanks" android:layout_width="fill_parent" android:paddingLeft="10dp" android:typeface="serif" android:textSize="12sp"></TextView></ScrollView>
+
+
+</LinearLayout>
+</RelativeLayout>
diff --git res/layout/bank.xml res/layout/bank.xml
index 0b0c9a1..3e17edd 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -1,21 +1,80 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp">
-<TextView  
-    android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/username"/>
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	android:paddingLeft="10dp"
+	android:paddingRight="10dp"
+	android:paddingTop="10dp">
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:typeface="sans"
+		android:textSize="20sp"
+		android:text="@string/username" />
 
-<EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditUsername" android:digits="0123456789-" android:inputType="phone"></EditText><TextView  
-    android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/password"/><EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/bank"/>
+	<EditText
+		android:layout_height="wrap_content"
+		android:layout_width="fill_parent"
+		android:id="@+id/edtBankeditUsername"
+		android:digits="0123456789-"
+		android:inputType="phone"></EditText>
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:typeface="sans"
+		android:textSize="20sp"
+		android:text="@string/password" />
+	<EditText
+		android:layout_height="wrap_content"
+		android:layout_width="fill_parent"
+		android:id="@+id/edtBankeditPassword"
+		android:inputType="textPassword"></EditText>
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:typeface="sans"
+		android:textSize="20sp"
+		android:text="@string/bank" />
 
 
-<Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:stretchColumns="*" android:gravity="bottom" android:layout_height="fill_parent">
-			<TableRow android:id="@+id/TableRow01" android:layout_height="wrap_content" android:layout_width="fill_parent">
-				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel" android:layout_width="fill_parent" android:id="@+id/btnSettingsCancel" android:text="@string/cancel"></Button>
-				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_save" android:layout_width="fill_parent" android:id="@+id/btnSettingsOk" android:text="@string/save"></Button>
-			</TableRow>
-		</TableLayout>
+	<Spinner
+		android:layout_height="wrap_content"
+		android:layout_width="fill_parent"
+		android:id="@+id/spnBankeditBanklist"></Spinner>
+	<TextView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:drawableLeft="@drawable/indicator_input_error"
+		android:text="@string/error_desc"
+		android:textSize="12sp"
+		android:drawablePadding="5dp"
+		android:id="@+id/txtErrorDesc"
+		android:visibility="invisible"></TextView>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:layout_width="fill_parent"
+		android:stretchColumns="*"
+		android:gravity="bottom"
+		android:layout_height="fill_parent">
+		<TableRow
+			android:id="@+id/TableRow01"
+			android:layout_height="wrap_content"
+			android:layout_width="fill_parent">
+			<Button
+				android:layout_height="wrap_content"
+				android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
+				android:layout_width="fill_parent"
+				android:id="@+id/btnSettingsCancel"
+				android:text="@string/cancel"></Button>
+			<Button
+				android:layout_height="wrap_content"
+				android:drawableLeft="@android:drawable/ic_menu_save"
+				android:layout_width="fill_parent"
+				android:id="@+id/btnSettingsOk"
+				android:text="@string/save"></Button>
+		</TableRow>
+	</TableLayout>
+
 </LinearLayout>
diff --git res/layout/banks.xml res/layout/banks.xml
index cff98b1..ed4e9ba 100644
--- res/layout/banks.xml
+++ res/layout/banks.xml
@@ -1,2 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:tag="rv"><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtBanksDesc" android:visibility="visible" android:layout_margin="10dp" android:text="@string/banks_instructions"/><ListView android:layout_width="fill_parent" android:id="@+id/lstvBanksList" android:layout_height="fill_parent" android:fitsSystemWindows="true" android:layout_above="@+id/LinearLayout01"></ListView><LinearLayout android:id="@+id/LinearLayout01" android:gravity="bottom" android:layout_width="fill_parent" android:layout_weight="1" android:layout_height="wrap_content" android:layout_alignParentBottom="true"><Button android:id="@+id/btnBanksNewaccount" android:drawableLeft="@android:drawable/ic_menu_add" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:text="@string/add_new_account"></Button></LinearLayout></RelativeLayout>
+<RelativeLayout
+	android:id="@+id/RelativeLayout01"
+	android:layout_width="wrap_content"
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_height="fill_parent"
+	android:tag="rv">
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:id="@+id/txtBanksDesc"
+		android:visibility="visible"
+		android:layout_margin="10dp"
+		android:text="@string/banks_instructions" />
+	<ListView
+		android:layout_width="fill_parent"
+		android:id="@+id/lstvBanksList"
+		android:layout_height="fill_parent"
+		android:fitsSystemWindows="true"
+		android:layout_above="@+id/LinearLayout01"></ListView>
+	<LinearLayout
+		android:id="@+id/LinearLayout01"
+		android:gravity="bottom"
+		android:layout_width="fill_parent"
+		android:layout_weight="1"
+		android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true">
+		<Button
+			android:id="@+id/btnBanksNewaccount"
+			android:drawableLeft="@android:drawable/ic_menu_add"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:layout_gravity="bottom"
+			android:layout_marginLeft="10dp"
+			android:layout_marginRight="10dp"
+			android:text="@string/add_new_account"></Button>
+	</LinearLayout>
+</RelativeLayout>
diff --git res/layout/listitem_accounts_group.xml res/layout/listitem_accounts_group.xml
index 170c6fa..1cd8ddf 100644
--- res/layout/listitem_accounts_group.xml
+++ res/layout/listitem_accounts_group.xml
@@ -1,48 +1,83 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:background="@drawable/title_bar_medium" android:layout_height="62dp" android:clickable="false" android:paddingBottom="5dp" android:paddingLeft="5dp" android:paddingTop="5dp" android:paddingRight="10dp">
-
-    <ImageView
-        android:id="@+id/imgListitemAccountsGroup"
-
-        android:layout_height="fill_parent"
-
-        android:layout_alignParentTop="true"
-        android:layout_alignParentBottom="true"
-        android:layout_marginRight="2dp"
-
-        android:src="@drawable/icon" android:layout_alignParentLeft="true" android:padding="0dp" android:layout_marginLeft="0dp" android:layout_width="48dp" android:maxHeight="48dp" android:maxWidth="48dp" android:minHeight="48dp" android:minWidth="48dp"/>
-
-    <TextView
-        android:id="@+id/txtListitemAccountsGroupBankname"
-
-        android:layout_height="26dip" 
-
-        android:layout_toRightOf="@id/imgListitemAccountsGroup"
-        android:layout_alignParentBottom="true"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:gravity="center_vertical" android:text="Banknamn" android:textColor="#000" android:layout_width="wrap_content" android:layout_alignParentRight="false"/>
-
-    <TextView
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-
-        android:layout_toRightOf="@id/imgListitemAccountsGroup"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentTop="true"
-        android:layout_above="@id/txtListitemAccountsGroupBankname"
-        android:layout_alignWithParentIfMissing="true"
-
-        android:gravity="center_vertical"
-        android:id="@+id/txtListitemAccountsGroupAccountname" android:textSize="23sp" android:text="Personnummer" android:textColor="#000"/>
-    <TextView
-        android:id="@+id/txtListitemAccountsGroupTotal"
-        android:layout_height="26dip" 
-        android:layout_alignParentBottom="true"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:gravity="center_vertical" android:text="00000 SEK" android:layout_width="wrap_content" android:layout_alignParentRight="true" android:textColor="#333"/>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:background="@drawable/title_bar_medium"
+	android:layout_height="62dp"
+	android:clickable="false"
+	android:paddingBottom="5dp"
+	android:paddingLeft="5dp"
+	android:paddingTop="5dp"
+	android:paddingRight="10dp">
+
+	<ImageView
+		android:id="@+id/imgListitemAccountsGroup"
+
+		android:layout_height="fill_parent"
+
+		android:layout_alignParentTop="true"
+		android:layout_alignParentBottom="true"
+		android:layout_marginRight="2dp"
+
+		android:src="@drawable/icon"
+		android:layout_alignParentLeft="true"
+		android:padding="0dp"
+		android:layout_marginLeft="0dp"
+		android:layout_width="48dp"
+		android:maxHeight="48dp"
+		android:maxWidth="48dp"
+		android:minHeight="48dp"
+		android:minWidth="48dp" />
+
+	<TextView
+		android:id="@+id/txtListitemAccountsGroupBankname"
+
+		android:layout_height="26dip"
+
+		android:layout_toRightOf="@id/imgListitemAccountsGroup"
+		android:layout_alignParentBottom="true"
+		android:singleLine="true"
+		android:ellipsize="marquee"
+		android:gravity="center_vertical"
+		android:text="Banknamn"
+		android:textColor="#000"
+		android:layout_width="wrap_content"
+		android:layout_alignParentRight="false" />
+
+	<TextView
+		android:layout_height="wrap_content"
+
+		android:layout_toRightOf="@id/imgListitemAccountsGroup"
+		android:layout_alignParentTop="true"
+		android:layout_above="@id/txtListitemAccountsGroupBankname"
+		android:layout_alignWithParentIfMissing="true"
+
+		android:gravity="center_vertical"
+		android:id="@+id/txtListitemAccountsGroupAccountname"
+		android:textSize="23sp"
+		android:text="Personnummer"
+		android:textColor="#000"
+		android:layout_width="wrap_content"
+		android:layout_alignParentRight="false" />
+	<ImageView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:id="@+id/imgWarning"
+		android:src="@drawable/indicator_input_error"
+		android:layout_alignParentRight="true"
+		android:layout_above="@id/txtListitemAccountsGroupBankname"
+		android:visibility="invisible"></ImageView>
+	<TextView
+		android:id="@+id/txtListitemAccountsGroupTotal"
+		android:layout_height="26dip"
+		android:layout_alignParentBottom="true"
+		android:singleLine="true"
+		android:ellipsize="marquee"
+		android:gravity="center_vertical"
+		android:text="00000 SEK"
+		android:layout_width="wrap_content"
+		android:layout_alignParentRight="true"
+		android:textColor="#333" />
         
+
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/listitem_accounts_item.xml res/layout/listitem_accounts_item.xml
index 25f1022..a548307 100644
--- res/layout/listitem_accounts_item.xml
+++ res/layout/listitem_accounts_item.xml
@@ -1,17 +1,41 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:background="#000" android:layout_height="35dp" android:layout_gravity="center_horizontal" android:paddingLeft="15dp" android:paddingRight="10dp">
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:background="#000"
+	android:layout_height="35dp"
+	android:layout_gravity="center_horizontal"
+	android:paddingLeft="15dp"
+	android:paddingRight="10dp">
 
-    <TextView
-        android:layout_alignParentBottom="true"
-        android:ellipsize="marquee"
-        android:gravity="center_vertical" android:layout_width="wrap_content" android:layout_alignParentRight="false" android:textColor="#fff" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:id="@+id/txtListitemAccountsItemAccountname" android:inputType="none" android:text="Kontonamn" android:textStyle="bold" android:layout_height="fill_parent"/>
+	<TextView
+		android:layout_alignParentBottom="true"
+		android:ellipsize="marquee"
+		android:gravity="center_vertical"
+		android:layout_width="wrap_content"
+		android:layout_alignParentRight="false"
+		android:textColor="#fff"
+		android:layout_alignParentLeft="true"
+		android:layout_alignParentTop="true"
+		android:id="@+id/txtListitemAccountsItemAccountname"
+		android:inputType="none"
+		android:text="Kontonamn"
+		android:textStyle="bold"
+		android:layout_height="fill_parent" />
+
+
+	<TextView
+		android:layout_alignParentBottom="true"
+		android:ellipsize="marquee"
+		android:text="00000 SEK"
+		android:layout_width="wrap_content"
+		android:layout_alignParentRight="true"
+		android:textColor="#fff"
+		android:layout_alignParentTop="true"
+		android:id="@+id/txtListitemAccountsItemBalance"
+		android:inputType="none"
+		android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname"
+		android:gravity="right|center_vertical"
+		android:layout_height="fill_parent" />
 
-    
-    <TextView
-        android:layout_alignParentBottom="true"
-        android:ellipsize="marquee"
-        android:text="00000 SEK" android:layout_width="wrap_content" android:layout_alignParentRight="true" android:textColor="#fff" android:layout_alignParentTop="true" android:id="@+id/txtListitemAccountsItemBalance" android:inputType="none" android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname" android:gravity="right|center_vertical" android:layout_height="fill_parent"/>
-        
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/listitem_banks.xml res/layout/listitem_banks.xml
index d9a1bbc..7017dcf 100644
--- res/layout/listitem_banks.xml
+++ res/layout/listitem_banks.xml
@@ -1,45 +1,63 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight" android:paddingBottom="5dp" android:paddingTop="5dp">
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="?android:attr/listPreferredItemHeight"
+	android:paddingBottom="5dp"
+	android:paddingTop="5dp">
+
+	<ImageView
+		android:id="@+id/imgListitemBanks"
+
+		android:layout_width="wrap_content"
+		android:layout_height="fill_parent"
+
+		android:layout_alignParentTop="true"
+		android:layout_alignParentBottom="true"
+		android:layout_marginRight="2dp"
+
+		android:src="@drawable/icon"
+		android:maxHeight="32dp"
+		android:maxWidth="32dp" />
+
+	<TextView
+		android:id="@+id/txtListitemBankname"
+
+		android:layout_width="fill_parent"
+		android:layout_height="26dip"
+
+		android:layout_toRightOf="@id/imgListitemBanks"
+		android:layout_alignParentBottom="true"
+		android:layout_alignParentRight="true"
+
+		android:singleLine="true"
+		android:ellipsize="marquee"
+		android:gravity="center_vertical"
+		android:text="Banknamn" />
+
+	<TextView
+		android:layout_height="wrap_content"
+
+		android:layout_toRightOf="@id/imgListitemBanks"
+		android:layout_alignParentTop="true"
+		android:layout_above="@id/txtListitemBankname"
+		android:layout_alignWithParentIfMissing="true"
+
+		android:gravity="center_vertical"
+		android:id="@+id/txtListitemAccountname"
+		android:textSize="23sp"
+		android:text="Personnummer"
+		android:layout_width="wrap_content"
+		android:layout_alignParentRight="false" />
+	<ImageView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:background="@drawable/indicator_input_error"
+		android:layout_alignParentRight="true"
+		android:layout_marginRight="15dp"
+		android:layout_marginTop="6dp"
+		android:visibility="invisible"
+		android:id="@+id/imgWarning"></ImageView>
 
-    <ImageView
-        android:id="@+id/imgListitemBanks"
-
-        android:layout_width="wrap_content"
-        android:layout_height="fill_parent"
-
-        android:layout_alignParentTop="true"
-        android:layout_alignParentBottom="true"
-        android:layout_marginRight="2dp"
-
-        android:src="@drawable/icon" android:maxHeight="32dp" android:maxWidth="32dp"/>
-
-    <TextView
-        android:id="@+id/txtListitemBankname"
-
-        android:layout_width="fill_parent"
-        android:layout_height="26dip" 
-
-        android:layout_toRightOf="@id/imgListitemBanks"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
-
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:gravity="center_vertical" android:text="Banknamn"/>
-
-    <TextView
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-
-        android:layout_toRightOf="@id/imgListitemBanks"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentTop="true"
-        android:layout_above="@id/txtListitemBankname"
-        android:layout_alignWithParentIfMissing="true"
-
-        android:gravity="center_vertical"
-        android:id="@+id/txtListitemAccountname" android:textSize="23sp" android:text="Personnummer"/>
 
 </RelativeLayout>
\ No newline at end of file
diff --git res/layout/login.xml res/layout/login.xml
index e6307d4..e9a1c01 100644
--- res/layout/login.xml
+++ res/layout/login.xml
@@ -1,35 +1,61 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout android:id="@+id/RelativeLayout01"
+<RelativeLayout
+	android:id="@+id/RelativeLayout01"
 	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="fill_parent" android:layout_height="fill_parent">
-	<LinearLayout android:orientation="vertical"
-		android:layout_width="fill_parent" android:layout_height="fill_parent"
-		android:paddingLeft="10dp" android:paddingRight="10dp"
-		android:paddingTop="10dp" android:layout_gravity="center_vertical"
-		android:gravity="center_vertical" android:fitsSystemWindows="true">
-
-
-		<TextView android:id="@+id/TextView01" android:layout_height="wrap_content"
-			android:typeface="sans" android:gravity="center_horizontal"
-			android:layout_gravity="center_horizontal" android:text="BANKDROID"
-			android:layout_width="fill_parent" android:visibility="visible"
-			android:textColor="#fff" android:textSize="42dp"></TextView>
-		<LinearLayout android:id="@+id/LinearLayout01"
-			android:layout_height="wrap_content" android:orientation="horizontal"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	<LinearLayout
+		android:orientation="vertical"
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent"
+		android:paddingLeft="10dp"
+		android:paddingRight="10dp"
+		android:paddingTop="10dp"
+		android:layout_gravity="center_vertical"
+		android:gravity="center_vertical"
+		android:fitsSystemWindows="true">
+
+
+		<TextView
+			android:id="@+id/TextView01"
+			android:layout_height="wrap_content"
+			android:typeface="sans"
+			android:gravity="center_horizontal"
+			android:layout_gravity="center_horizontal"
+			android:text="BANKDROID"
+			android:layout_width="fill_parent"
+			android:visibility="visible"
+			android:textColor="#fff"
+			android:textSize="42dp"></TextView>
+		<LinearLayout
+			android:id="@+id/LinearLayout01"
+			android:layout_height="wrap_content"
+			android:orientation="horizontal"
 			android:layout_width="fill_parent">
-			<ImageView android:id="@+id/ImageView01"
-				android:background="@drawable/icon_large" android:layout_width="100dp"
-				android:layout_height="100dp" android:layout_gravity="center_horizontal"
+			<ImageView
+				android:id="@+id/ImageView01"
+				android:background="@drawable/icon_large"
+				android:layout_width="100dp"
+				android:layout_height="100dp"
+				android:layout_gravity="center_horizontal"
 				android:visibility="visible"></ImageView>
-			<LinearLayout android:id="@+id/LinearLayout02"
-				android:layout_height="wrap_content" android:orientation="vertical"
+			<LinearLayout
+				android:id="@+id/LinearLayout02"
+				android:layout_height="wrap_content"
+				android:orientation="vertical"
 				android:layout_width="fill_parent">
-				<EditText android:layout_height="wrap_content"
-					android:layout_width="fill_parent" android:inputType="textPassword"
-					android:layout_gravity="center_vertical" android:hint="@string/access_code"
+				<EditText
+					android:layout_height="wrap_content"
+					android:layout_width="fill_parent"
+					android:inputType="textPassword"
+					android:layout_gravity="center_vertical"
+					android:hint="@string/access_code"
 					android:id="@+id/edtAccessCode"></EditText>
-				<Button android:id="@+id/btnLogin" android:layout_gravity="right|center_vertical"
-					android:layout_width="fill_parent" android:layout_height="52dp"
+				<Button
+					android:id="@+id/btnLogin"
+					android:layout_gravity="right|center_vertical"
+					android:layout_width="fill_parent"
+					android:layout_height="52dp"
 					android:drawableRight="@drawable/ic_menu_forward"></Button>
 			</LinearLayout>
 		</LinearLayout>
@@ -39,11 +65,16 @@
 
 
 
-		<TextView android:layout_width="wrap_content"
-			android:layout_height="wrap_content" android:id="@+id/txtResult"
-			android:textColor="#CC4B28" android:text="@string/invalid_access_code"
-			android:gravity="center_vertical" android:drawableLeft="@drawable/ic_bullet_key_permission"
-			android:layout_gravity="center_horizontal" android:visibility="invisible"></TextView>
+		<TextView
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:id="@+id/txtResult"
+			android:textColor="#CC4B28"
+			android:text="@string/invalid_access_code"
+			android:gravity="center_vertical"
+			android:drawableLeft="@drawable/ic_bullet_key_permission"
+			android:layout_gravity="center_horizontal"
+			android:visibility="invisible"></TextView>
 
-</LinearLayout>
+	</LinearLayout>
 </RelativeLayout>
diff --git res/layout/main.xml res/layout/main.xml
index 078eac5..48b183d 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -9,7 +9,8 @@
 		android:layout_height="wrap_content"
 		android:id="@+id/txtAccountsDesc"
 		android:visibility="visible"
-		android:layout_margin="10dp" android:text="@string/main_instructions"/>
+		android:layout_margin="10dp"
+		android:text="@string/main_instructions" />
 	<ListView
 		android:layout_width="fill_parent"
 		android:id="@+id/lstAccountsList"
@@ -18,13 +19,18 @@
 		android:layout_above="@+id/LinearLayout02" />
 	<LinearLayout
 		android:id="@+id/LinearLayout02"
-		android:gravity="bottom" android:layout_width="fill_parent"
-		android:layout_weight="1" android:layout_height="wrap_content"
+		android:gravity="bottom"
+		android:layout_width="fill_parent"
+		android:layout_weight="1"
+		android:layout_height="wrap_content"
 		android:layout_alignParentBottom="true">
 		<Button
 			android:layout_width="fill_parent"
 			android:layout_height="wrap_content"
 			android:layout_gravity="bottom"
-			android:id="@+id/btnAccountsRefresh" android:visibility="gone" android:text="@string/refresh_balance" android:drawableLeft="@drawable/ic_menu_refresh"/>
+			android:id="@+id/btnAccountsRefresh"
+			android:visibility="gone"
+			android:text="@string/refresh_balance"
+			android:drawableLeft="@drawable/ic_menu_refresh" />
 	</LinearLayout>
 </RelativeLayout>
diff --git res/layout/settings.xml res/layout/settings.xml
index f4a1d9e..55dbfae 100644
--- res/layout/settings.xml
+++ res/layout/settings.xml
@@ -1,51 +1,100 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="vertical" android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:paddingLeft="10dp"
-	android:paddingRight="10dp" android:paddingTop="10dp">
-
-	<TextView android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:typeface="sans"
-		android:textSize="20sp" android:text="@string/access_code" />
-	<EditText android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:inputType="textPassword"
+<LinearLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent"
+	android:paddingLeft="10dp"
+	android:paddingRight="10dp"
+	android:paddingTop="10dp">
+
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:typeface="sans"
+		android:textSize="20sp"
+		android:text="@string/access_code" />
+	<EditText
+		android:layout_height="wrap_content"
+		android:layout_width="fill_parent"
+		android:inputType="textPassword"
 		android:id="@+id/edtAccessCode"></EditText>
 
-	<TextView android:layout_width="wrap_content"
-		android:layout_height="wrap_content" android:id="@+id/txtSettingsPinDesc"
-		android:text="@string/pin_desc" android:textSize="12sp"
-		android:textColor="#A4A4A4" android:drawableLeft="@android:drawable/ic_dialog_info"
-		android:drawablePadding="5dp" android:layout_marginBottom="3dp"></TextView>
-	<TextView android:layout_width="fill_parent"
-		android:layout_height="wrap_content" android:typeface="sans"
-		android:textSize="20sp" android:text="@string/update_frequency" android:visibility="visible"/>
-	<Spinner android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/spnUpdateFrequency" android:visibility="visible"></Spinner>
+	<TextView
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:id="@+id/txtSettingsPinDesc"
+		android:text="@string/pin_desc"
+		android:textSize="12sp"
+		android:textColor="#A4A4A4"
+		android:drawableLeft="@android:drawable/ic_dialog_info"
+		android:drawablePadding="5dp"
+		android:layout_marginBottom="3dp"></TextView>
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:typeface="sans"
+		android:textSize="20sp"
+		android:text="@string/update_frequency"
+		android:visibility="visible" />
+	<Spinner
+		android:layout_height="wrap_content"
+		android:layout_width="fill_parent"
+		android:id="@+id/spnUpdateFrequency"
+		android:visibility="visible"></Spinner>
 
 
 
 
 
-	<LinearLayout android:id="@+id/LinearLayout01"
-		android:layout_width="wrap_content" android:layout_height="wrap_content"
-		android:orientation="vertical" android:paddingLeft="10dp">
-		<CheckBox android:layout_width="wrap_content"
-			android:layout_height="wrap_content" android:text="@string/notify_on_change"
-			android:id="@+id/chkNotifyOnChange" android:visibility="visible"></CheckBox>
-	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/with_sound" android:id="@+id/chkWithSound" android:textSize="14sp" android:layout_marginLeft="10dp"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkWithVibration" android:text="@string/vibrate" android:layout_marginLeft="10dp"></CheckBox>
-</LinearLayout>
-	<TableLayout android:id="@+id/TableLayout01"
-		android:layout_width="fill_parent" android:stretchColumns="*"
-		android:gravity="bottom" android:layout_height="fill_parent">
-		<TableRow android:id="@+id/TableRow01" android:layout_height="wrap_content"
+	<LinearLayout
+		android:id="@+id/LinearLayout01"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:orientation="vertical"
+		android:paddingLeft="10dp">
+		<CheckBox
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:text="@string/notify_on_change"
+			android:id="@+id/chkNotifyOnChange"
+			android:visibility="visible"></CheckBox>
+		<CheckBox
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:text="@string/with_sound"
+			android:id="@+id/chkWithSound"
+			android:textSize="14sp"
+			android:layout_marginLeft="10dp"></CheckBox>
+		<CheckBox
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:textSize="14sp"
+			android:id="@+id/chkWithVibration"
+			android:text="@string/vibrate"
+			android:layout_marginLeft="10dp"></CheckBox>
+	</LinearLayout>
+	<TableLayout
+		android:id="@+id/TableLayout01"
+		android:layout_width="fill_parent"
+		android:stretchColumns="*"
+		android:gravity="bottom"
+		android:layout_height="fill_parent">
+		<TableRow
+			android:id="@+id/TableRow01"
+			android:layout_height="wrap_content"
 			android:layout_width="fill_parent">
-			<Button android:layout_height="wrap_content"
+			<Button
+				android:layout_height="wrap_content"
 				android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
-				android:layout_width="fill_parent" android:id="@+id/btnSettingsCancel"
+				android:layout_width="fill_parent"
+				android:id="@+id/btnSettingsCancel"
 				android:text="@string/cancel"></Button>
-			<Button android:layout_height="wrap_content"
+			<Button
+				android:layout_height="wrap_content"
 				android:drawableLeft="@android:drawable/ic_menu_save"
-				android:layout_width="fill_parent" android:id="@+id/btnSettingsOk"
+				android:layout_width="fill_parent"
+				android:id="@+id/btnSettingsOk"
 				android:text="@string/save"></Button>
 		</TableRow>
 	</TableLayout>
diff --git res/layout/widget.xml res/layout/widget.xml
index 59bee3a..ef4105d 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -1,14 +1,81 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_gravity="center_horizontal" android:background="@drawable/widget_2x1" android:layout_height="100dp" android:layout_width="160dp">
-
-    <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/layWidgetRow01" android:layout_marginTop="0dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_width="22dp" android:layout_height="22dp" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:src="@drawable/icon" android:scaleType="fitXY"></ImageView><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:text="Kapitalkonto" android:layout_gravity="center_vertical" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_marginLeft="2dp"></TextView></LinearLayout><LinearLayout android:id="@+id/layWidgetRow02" android:layout_below="@+id/layWidgetRow01" android:layout_width="fill_parent" android:layout_height="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_height="fill_parent" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="fill_parent" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:textSize="15dp" android:text="129 500,00 SEK" android:id="@+id/txtWidgetAccountbalance" android:layout_marginTop="-6dp"/></LinearLayout>
-
-    
-    
-        
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_gravity="center_horizontal"
+	android:background="@drawable/widget_2x1"
+	android:layout_height="100dp"
+	android:layout_width="160dp">
 
+	<LinearLayout
+		android:layout_height="wrap_content"
+		android:layout_width="wrap_content"
+		android:id="@+id/layWidgetRow01"
+		android:layout_marginTop="0dp">
+		<ImageView
+			android:layout_above="@+id/txtListitemAccountsItemAccountname"
+			android:layout_width="22dp"
+			android:layout_height="22dp"
+			android:id="@+id/imgWidgetIcon"
+			android:layout_gravity="center_vertical"
+			android:baselineAlignBottom="true"
+			android:src="@drawable/icon"
+			android:scaleType="fitXY"></ImageView>
+		<TextView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:id="@+id/txtWidgetAccountname"
+			android:text="Kapitalkonto"
+			android:layout_gravity="center_vertical"
+			android:textColor="#a8a3a3"
+			android:textSize="11dp"
+			android:inputType="none"
+			android:layout_marginLeft="2dp"></TextView>
+	</LinearLayout>
+	<LinearLayout
+		android:id="@+id/layWidgetRow02"
+		android:layout_below="@+id/layWidgetRow01"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:layout_marginTop="7dp">
+		<TextView
+			android:textColor="#fff"
+			android:inputType="none"
+			android:layout_gravity="center_vertical|center_horizontal"
+			android:layout_width="fill_parent"
+			android:ellipsize="none"
+			android:gravity="center_vertical|center_horizontal"
+			android:textSize="15dp"
+			android:text="129 500,00 SEK"
+			android:id="@+id/txtWidgetAccountbalance"
+			android:layout_height="fill_parent" />
+	</LinearLayout>
+	<LinearLayout
+		android:id="@+id/layWidgetRow03"
+		android:layout_below="@+id/layWidgetRow02"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:gravity="bottom"
+		android:layout_alignParentBottom="true"
+		android:visibility="visible">
+		
+		<FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/frmProgress" android:visibility="invisible"><ProgressBar android:layout_width="wrap_content" android:indeterminateOnly="true" android:indeterminateBehavior="repeat" android:indeterminate="true" android:layout_height="wrap_content" style="@style/Widget_Progress" android:id="@+id/prgProgress" android:maxHeight="2dp" android:minHeight="2dp" android:minWidth="17dp" android:visibility="visible"></ProgressBar></FrameLayout>
 
 
+		<FrameLayout
+			android:layout_height="wrap_content"
+			android:id="@+id/frmWarning"
+			android:layout_width="fill_parent"
+			android:visibility="invisible">
+			<ImageView
+				android:id="@+id/imgWarning"
+				android:adjustViewBounds="true"
+				android:layout_gravity="bottom|right"
+				android:layout_height="fill_parent"
+				android:src="@drawable/indicator_input_error"
+				android:scaleType="fitXY"
+				android:layout_width="wrap_content"></ImageView>
+		</FrameLayout>
+	</LinearLayout>
+	
 
 </RelativeLayout>
\ No newline at end of file
diff --git res/menu-sv/menu.xml res/menu-sv/menu.xml
index 00d8188..1e97cb5 100644
--- res/menu-sv/menu.xml
+++ res/menu-sv/menu.xml
@@ -1,7 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-	<item android:id="@+id/accounts" android:title="Konton" android:icon="@android:drawable/ic_menu_agenda"/>
-	<item android:id="@+id/settings" android:title="Inställningar" android:icon="@android:drawable/ic_menu_preferences"/>
-	<item android:id="@+id/about" android:title="Om" android:icon="@android:drawable/ic_menu_info_details" />
-	<item android:id="@+id/exit" android:title="Avsluta" android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+<menu
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<item
+		android:id="@+id/accounts"
+		android:title="Konton"
+		android:icon="@android:drawable/ic_menu_agenda" />
+	<item
+		android:id="@+id/settings"
+		android:title="Inställningar"
+		android:icon="@android:drawable/ic_menu_preferences" />
+	<item
+		android:id="@+id/about"
+		android:title="Om"
+		android:icon="@android:drawable/ic_menu_info_details" />
+	<item
+		android:id="@+id/exit"
+		android:title="Avsluta"
+		android:icon="@android:drawable/ic_menu_close_clear_cancel" />
 </menu>
\ No newline at end of file
diff --git res/menu/menu.xml res/menu/menu.xml
index 71d8be9..9d44df9 100644
--- res/menu/menu.xml
+++ res/menu/menu.xml
@@ -1,7 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-	<item android:id="@+id/accounts" android:title="Accounts" android:icon="@android:drawable/ic_menu_agenda"/>
-	<item android:id="@+id/settings" android:title="Settings" android:icon="@android:drawable/ic_menu_preferences"/>
-	<item android:id="@+id/about" android:title="About" android:icon="@android:drawable/ic_menu_info_details" />
-	<item android:id="@+id/exit" android:title="Exit" android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+<menu
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<item
+		android:id="@+id/accounts"
+		android:title="Accounts"
+		android:icon="@android:drawable/ic_menu_agenda" />
+	<item
+		android:id="@+id/settings"
+		android:title="Settings"
+		android:icon="@android:drawable/ic_menu_preferences" />
+	<item
+		android:id="@+id/about"
+		android:title="About"
+		android:icon="@android:drawable/ic_menu_info_details" />
+	<item
+		android:id="@+id/exit"
+		android:title="Exit"
+		android:icon="@android:drawable/ic_menu_close_clear_cancel" />
 </menu>
\ No newline at end of file
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index 52c40fb..ae852ea 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     
+     <string name="about">Om</string>
     <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
     <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
     <string name="errors_when_updating">Fel vid uppdatering</string>
@@ -10,10 +11,12 @@
     <string name="menu_remove">Radera</string>
     <string name="invalid_username_password">Personnummer och lösenord stämmer ej.</string>
     <string name="unable_to_find">Kunde ej hitta</string>
+    <string name="no_accounts_found">Inga konton funna</string>
     
     <string name="username">Personnummer</string>
     <string name="password">Lösenord</string>
     <string name="bank">Bank</string>
+    <string name="error_desc">Senaste uppdateringsförsöket misslyckades och uppdateringar för detta konto har inaktiverats. Se till att lösenord och användarnamn är korrekt angivet och tryck på spara-knappen.</string>
 
     <string name="cancel">Avbryt</string>
     <string name="save">Spara</string>
@@ -41,5 +44,14 @@
     <string name="hour">timme</string>
     <string name="hours">timmar</string>
     <string name="daily">Dagligen</string>
-	    
+
+
+    <string name="thanks_to">Tack till</string>
+    <string name="thanks"> 
+    Wendell Fernandes (Ikon)
+    \nKingcool (ICA Banken)
+    \ngrief (Länsförsäkringar)
+    \neinand (Länsförsäkringar)
+    \nAnders Widén (Länsförsäkringar)
+    </string>	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index fe63a53..fc29a3c 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+    <string name="version">Version 1.1.0 by liato</string>
     <string name="app_name">Bankdroid</string>
+    <string name="about">About</string>
     <string name="accounts_were_not_updated">Balance for the following accounts could not be updated</string>
     <string name="updating_account_balance">Refreshing account balance...</string>
     <string name="errors_when_updating">Errors while refreshing</string>
@@ -10,10 +12,12 @@
     <string name="menu_remove">Remove</string>
     <string name="invalid_username_password">Invalid username or password.</string>
     <string name="unable_to_find">Unable to find</string>
+    <string name="no_accounts_found">No accounts found</string>
     
     <string name="username">Username</string>
     <string name="password">Password</string>
     <string name="bank">Bank</string>
+    <string name="error_desc">The last update was unsuccessful and updates for this account have been disabled. Make sure you\'ve entered your username and password correctly and press the save button.</string>
 
     <string name="cancel">Cancel</string>
     <string name="save">Save</string>
@@ -42,5 +46,13 @@
     <string name="hour">hour</string>
     <string name="hours">hours</string>
     <string name="daily">Daily</string>
-	    
+    
+    <string name="thanks_to">Thanks to</string>
+    <string name="thanks"> 
+    Wendell Fernandes (Icon)
+    \nKingcool (ICA Banken)
+    \ngrief (Länsförsäkringar)
+    \neinand (Länsförsäkringar)
+    \nAnders Widén (Länsförsäkringar)
+    </string>
 </resources>
diff --git res/values/styles.xml res/values/styles.xml
new file mode 100644
index 0000000..81ac7a0
--- /dev/null
+++ res/values/styles.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+	<style
+		name="Widget_Progress">
+		<item
+			name="android:indeterminateDrawable">@drawable/widget_progress</item>
+		<item
+			name="android:minWidth">17dip</item>
+		<item
+			name="android:maxWidth">17dip</item>
+		<item
+			name="android:minHeight">2dip</item>
+		<item
+			name="android:maxHeight">2dip</item>
+	</style>
+</resources>
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index d322cb6..f200978 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -16,6 +16,7 @@ import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.Spinner;
+import android.widget.TextView;
 import android.widget.AdapterView.OnItemSelectedListener;
 
 public class AccountActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
@@ -51,7 +52,13 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 				if (c != null) {
 					((EditText)findViewById(R.id.edtBankeditUsername)).setText(c.getString(c.getColumnIndex("username")));
 					((EditText)findViewById(R.id.edtBankeditPassword)).setText(c.getString(c.getColumnIndex("password")));
-					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
+					TextView errorDesc = (TextView)findViewById(R.id.txtErrorDesc);
+					if (c.getInt(c.getColumnIndex("disabled")) == 1 ? true : false) {
+						errorDesc.setVisibility(View.VISIBLE);
+					}
+					else {
+						errorDesc.setVisibility(View.INVISIBLE);
+					}					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
 					int i = items.indexOf(SELECTED_BANK);
 					spnBanks.setSelection(i);
 					c.close();
@@ -131,6 +138,7 @@ public class AccountActivity extends LockableActivity implements OnClickListener
 		}
 
 		protected void onPostExecute(final Void unused) {
+			AutoRefreshService.sendWidgetRefresh(parent);
 			if (this.dialog.isShowing()) {
 				this.dialog.dismiss();
 			}
diff --git src/com/liato/bankdroid/AccountsActivity.java src/com/liato/bankdroid/AccountsActivity.java
index f0c5eb0..c596a5b 100644
--- src/com/liato/bankdroid/AccountsActivity.java
+++ src/com/liato/bankdroid/AccountsActivity.java
@@ -113,6 +113,13 @@ public class AccountsActivity extends LockableActivity {
 			((TextView)view.findViewById(R.id.txtListitemBankname)).setText(cursor.getString(cursor.getColumnIndex("banktype")));
 			icon.setImageResource(getResources().getIdentifier("drawable/"+Helpers.toAscii(cursor.getString(cursor.getColumnIndex("banktype")).toLowerCase()), null, getPackageName()));
 			view.setTag(cursor.getInt(cursor.getColumnIndex("_id")));
+			ImageView warning = (ImageView)view.findViewById(R.id.imgWarning);
+			if (cursor.getInt(cursor.getColumnIndex("disabled")) == 1 ? true : false) {
+				warning.setVisibility(View.VISIBLE);
+			}
+			else {
+				warning.setVisibility(View.INVISIBLE);
+			}
 		}
 
 		@Override
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index d0e0c5e..c62c710 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -5,6 +5,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import android.content.Context;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -33,6 +34,14 @@ public class AccountsAdapter extends BaseAdapter {
 		((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
 		((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
 		icon.setImageResource(context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
+		ImageView warning = (ImageView)v.findViewById(R.id.imgWarning);
+		Log.d("AccountsAdapter", ""+group.getDisabled());
+		if (group.getDisabled()) {
+			warning.setVisibility(View.VISIBLE);
+		}
+		else {
+			warning.setVisibility(View.INVISIBLE);
+		}
 		return v;
 	}
 
@@ -109,7 +118,8 @@ public class AccountsAdapter extends BaseAdapter {
 		private String type;
 		private BigDecimal total;
 		private List<Item> items;
-		public Group(String name, String type, Double total, List<Item> items) {
+		private Boolean disabled;
+		public Group(String name, String type, Double total, List<Item> items, Boolean disabled) {
 			this.name = name;
 			this.type = type;
 			this.total = new BigDecimal(total);
@@ -117,14 +127,16 @@ public class AccountsAdapter extends BaseAdapter {
 				item.setGroup(this);
 			}
 			this.items = items;
+			this.disabled = disabled;
 		}
-		public Group(String name, String type, Double total, Item item) {
+		public Group(String name, String type, Double total, Item item, Boolean disabled) {
 			ArrayList<Item> items = new ArrayList<Item>();
 			items.add(item);
 			this.name = name;
 			this.type = type;
 			this.total = new BigDecimal(total);
 			this.items = items;
+			this.disabled = disabled;
 		}
 		public String getName() {
 			return name;
@@ -138,6 +150,9 @@ public class AccountsAdapter extends BaseAdapter {
 		public List<Item> getItems() {
 			return items;
 		}
+		public Boolean getDisabled() {
+			return disabled;
+		}
 
 	}
 
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
index a4836ff..2e8e327 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankICA.java
@@ -26,8 +26,7 @@ public class BankICA implements Bank {
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
 	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
+	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Disponibelt\\s*([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -73,21 +72,29 @@ public class BankICA implements Bank {
 			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
 			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
 			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx", postData);
-			
+
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
 				throw new BankException(Html.fromHtml(matcher.group(1).trim()).toString());
 			}
-
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
 			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		} catch (ClientProtocolException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
 		}
 		finally {
 			urlopen.close();
@@ -115,7 +122,7 @@ public class BankICA implements Bank {
 	public String getUsername() {
 		return username;
 	}
-	
+
 	@Override
 	public BigDecimal getBalance() {
 		return balance;
diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/BankLansforsakringar.java
index 0535d7b..40067f1 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -30,7 +30,6 @@ public class BankLansforsakringar implements Bank {
 	private Pattern reBalance = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
-	
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -69,7 +68,7 @@ public class BankLansforsakringar implements Bank {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
 			}
 			String strEventValidation = matcher.group(1);
-			
+
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			postData.add(new BasicNameValuePair("inputPersonalNumber", username));
 			postData.add(new BasicNameValuePair("inputPinCode", password));
@@ -83,7 +82,7 @@ public class BankLansforsakringar implements Bank {
 			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
 			Log.d("Bankdroid", "Posting data to: " + urlopen.getCurrentURI());
 			response = urlopen.open(urlopen.getCurrentURI(), postData);
-			
+
 			if (response.contains("Felaktig inloggning")) {
 				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
@@ -105,11 +104,17 @@ public class BankLansforsakringar implements Bank {
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
-		} catch (ClientProtocolException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
 		}
 		finally {
 			urlopen.close();
@@ -137,7 +142,7 @@ public class BankLansforsakringar implements Bank {
 	public String getUsername() {
 		return username;
 	}
-	
+
 	@Override
 	public BigDecimal getBalance() {
 		return balance;
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index e677c19..6c89de8 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -24,9 +24,7 @@ public class BankNordea implements Bank {
 	private String password;
 	private Banks banktype = Banks.NORDEA;
 	private Pattern reBalance = Pattern.compile("(?is)nowrap>(.+?)SEK<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	//private Pattern reAccounts = Pattern.compile("(?is)Kontoutdraget';.*?>(.*?)</a></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reAccounts = Pattern.compile("sendAccount\\('SEK',\\s*'[^']+',\\s*'[^']+',\\s*'([^']+)',\\s*'([^']+)'\\)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -40,7 +38,7 @@ public class BankNordea implements Bank {
 	public void update(String username, String password, Context context) throws BankException {
 		this.context = context;
 		this.res = this.context.getResources();
-		
+
 		this.username = username;
 		this.password = password;
 		this.update();
@@ -72,14 +70,20 @@ public class BankNordea implements Bank {
 			matcherAccounts = reAccounts.matcher(response);
 			while (matcherAccounts.find() && matcherBalance.find()) {
 				accounts.add(new Account(Html.fromHtml(matcherAccounts.group(2)).toString(), Helpers.parseBalance(matcherBalance.group(1)), matcherAccounts.group(2).trim()));
+				balance = balance.add(Helpers.parseBalance(matcherBalance.group(1)));
+			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
 			}
 			// Konungens konto
 			//accounts.add(new Account("Personkonto", new BigDecimal("568269.37"), "1"));
 			//accounts.add(new Account("Kapitalkonto", new BigDecimal("25789000.00"), "1"));
-		} catch (ClientProtocolException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
 		}
 		finally {
 			urlopen.close();
@@ -107,7 +111,7 @@ public class BankNordea implements Bank {
 	public String getUsername() {
 		return username;
 	}
-	
+
 	@Override
 	public BigDecimal getBalance() {
 		return balance;
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index 182ac64..b15f982 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -17,7 +17,7 @@ import android.text.Html;
 import com.liato.urllib.Urllib;
 
 public class BankSwedbank implements Bank {
-	
+
 	private Context context;
 	private Resources res;
 	private String username;
@@ -38,7 +38,7 @@ public class BankSwedbank implements Bank {
 	public void update(String username, String password, Context context) throws BankException {
 		this.context = context;
 		this.res = this.context.getResources();
-		
+
 		this.username = username;
 		this.password = password;
 		this.update();
@@ -52,7 +52,7 @@ public class BankSwedbank implements Bank {
 		Matcher matcher;
 		try {
 			balance = new BigDecimal(0);
-			/*response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
 			matcher = reCSRF.matcher(response);
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
@@ -67,20 +67,25 @@ public class BankSwedbank implements Bank {
 			if (response.contains("misslyckats")) {
 				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");*/
-			response = urlopen.open("http://x.x00.us/android/bankdroid/swedbank_oversikt.htm");
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
+			//response = urlopen.open("http://x.x00.us/android/bankdroid/swedbank_oversikt.htm");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
+			if (accounts.isEmpty()) {
+				throw new BankException(res.getText(R.string.no_accounts_found).toString());
+			}
 			// Konungens konto
 			//accounts.add(new Account("Personkonto", new BigDecimal("1485351"), "0"));
 			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
-		} catch (ClientProtocolException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
+		}
+		catch (ClientProtocolException e) {
+			throw new BankException(e.getMessage());
+		}
+		catch (IOException e) {
+			throw new BankException(e.getMessage());
 		}
 		finally {
 			urlopen.close();
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index b7336d4..fbd6339 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -1,66 +1,50 @@
 package com.liato.bankdroid;
 
+import java.net.URI;
+
 import android.app.PendingIntent;
+import android.app.Service;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.IBinder;
 import android.util.Log;
+import android.view.View;
 import android.widget.RemoteViews;
 
 public class BankdroidWidgetProvider extends AppWidgetProvider {
 
-	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
-		final int N = appWidgetIds.length;
-
-        // Perform this loop procedure for each App Widget that belongs to this provider
-        for (int i=0; i<N; i++) {
-            int appWidgetId = appWidgetIds[i];
-            Log.d("Widget", "onUpdate: "+i);
-            // Create an Intent to launch ExampleActivity
-            //Intent intent = new Intent(context, ExampleActivity.class);
-            //PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-
-            // Get the layout for the App Widget and attach an on-click listener to the button
-            //RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
-            //views.setOnClickPendingIntent(R.id.button, pendingIntent);
-
-            // Tell the AppWidgetManager to perform an update on the current App Widget
-            //appWidgetManager.updateAppWidget(appWidgetId, views);
-        }
-	}
-
 	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId, AccountsAdapter.Item item) {
-		Log.d("Widget", "Widget created");
-		AccountsAdapter.Group group = item.getGroup();
-		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
-		views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
-		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
-		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
-
-        Intent intent = new Intent(context, LoginActivity.class);
-        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
-        views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
-		appWidgetManager.updateAppWidget(appWidgetId, views);
+		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, item);
+		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
 	}
 
 	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
 			int appWidgetId) {
+		RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+		if (views != null) appWidgetManager.updateAppWidget(appWidgetId, views);
+	}
+	
+	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
+			int appWidgetId) {
 		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
 		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
 		if (accountId == null) {
 			Log.d("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
-			return;
+			return null;
 		}
 		DBAdapter dba = new DBAdapter(context);
 		dba.open();
 		Cursor c = dba.getAccount(accountId);
 		if (c == null) {
 			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
-			return;
+			return null;
 		}
 		int clmBalance = c.getColumnIndex("balance");
 		int clmId = c.getColumnIndex("id");
@@ -71,27 +55,71 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 		String id = c.getString(clmId);
 		Long bankId = c.getLong(clmBankId);
 		AccountsAdapter.Item account = new AccountsAdapter.Item(name, balance, id);
+		c.close();
 		c = dba.getBank(bankId);
 		if (c == null) {
 			Log.d("BankdroidWidgetProvider", "Bank not found: " + bankId);
-			return;
+			return null;
 		}
-		
+
 		int clmType = c.getColumnIndex("banktype");
+		int clmDisabled = c.getColumnIndex("disabled");
 		clmBalance = c.getColumnIndex("balance");
 		clmName = c.getColumnIndex("username");
 		name = c.getString(clmName);
 		String type = c.getString(clmType);
 		balance = c.getDouble(clmBalance);
-		AccountsAdapter.Group group = new AccountsAdapter.Group(name, type, balance, account);
+		Log.d("dbdisabled", ""+c.getInt(clmDisabled));
+		Boolean isDisabled = (c.getInt(clmDisabled) == 1 ? true : false);
+
+		AccountsAdapter.Group group = new AccountsAdapter.Group(name, type, balance, account, isDisabled);
 		account.setGroup(group);
 		c.close();
 		dba.close();
-		updateAppWidget(context, appWidgetManager,
+		return buildAppWidget(context, appWidgetManager,
 				appWidgetId, account);
+	}	
+
+
+
+	
+	static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager,
+			int appWidgetId, AccountsAdapter.Item item) {
+		Log.d("Widget", "Building widget: "+appWidgetId);
+		AccountsAdapter.Group group = item.getGroup();
+		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
+		views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
+		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
+		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
+		Log.d("Disabled", ""+group.getDisabled());
+		if (group.getDisabled()) {
+			views.setViewVisibility(R.id.frmWarning, View.VISIBLE);
+		}
+		else {
+			views.setViewVisibility(R.id.frmWarning, View.INVISIBLE);
+		}
+		Intent intent = new Intent(context, LoginActivity.class);
+		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+		views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
+
+		intent = new Intent(context, AccountsActivity.class);
+		pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+		views.setOnClickPendingIntent(R.id.imgWarning, pendingIntent);
+		
+		intent = new Intent(context, WidgetService.class);
+		intent.setAction(AutoRefreshService.WIDGET_REFRESH);
+		intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+		intent.setData(Uri.parse("rofl://copter/"+appWidgetId+"/"+System.currentTimeMillis()));
+		pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+		views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent);
+
+		//appWidgetManager.updateAppWidget(appWidgetId, views);
+		return views;
 	}
 	
 	
+	
+	
 	public void onReceive(Context context, Intent intent) {
 		// v1.5 fix that doesn't call onDelete Action
 		final String action = intent.getAction();
@@ -105,26 +133,135 @@ public class BankdroidWidgetProvider extends AppWidgetProvider {
 			super.onReceive(context, intent);
 		}
 
-		
+
 		Log.d("BankdroidWidgetProvider", "intent=" + intent);
-		
+
 		if (action.equals(AutoRefreshService.WIDGET_REFRESH)) {
-            AppWidgetManager appWM = AppWidgetManager.getInstance(context);
-        	int[] appWidgetIds = appWM.getAppWidgetIds(new ComponentName(context, BankdroidWidgetProvider.class));
-        	final int N = appWidgetIds.length;
-    		for (int i = 0; i < N; i++) {
-    			int appWidgetId = appWidgetIds[i];
-    			updateAppWidget(context, appWM, appWidgetId);
-    		}
+			AppWidgetManager appWM = AppWidgetManager.getInstance(context);
+			int[] appWidgetIds = appWM.getAppWidgetIds(new ComponentName(context, BankdroidWidgetProvider.class));
+			final int N = appWidgetIds.length;
+			for (int i = 0; i < N; i++) {
+				int appWidgetId = appWidgetIds[i];
+				updateAppWidget(context, appWM, appWidgetId);
+			}
 		}
-    }	
+	}	
 
 	@Override
 	public void onDeleted(Context context, int[] appWidgetIds) {
+		super.onDeleted(context, appWidgetIds);
 		final int N = appWidgetIds.length;
 		for (int i = 0; i < N; i++) {
+			Log.d("Widget", "Widget deleted: " + appWidgetIds[i]);
 			WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]);
 		}
 	}
 
+	public static class WidgetService extends Service {
+		@Override
+		public void onStart(Intent intent, int startId) {
+			int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
+			Log.d("WidgetService", "Updating widget: " + appWidgetId);
+
+			String action = intent.getAction();
+			if (action.equals(AutoRefreshService.WIDGET_REFRESH)) {
+				Context context = getApplicationContext();
+				new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId).execute();
+			}
+		}
+
+		@Override
+		public IBinder onBind(Intent arg0) {
+			// TODO Auto-generated method stub
+			return null;
+		}
+
+		protected class WidgetUpdateTask extends AsyncTask<Void, Void, Void> {
+			@Override
+			protected void onPreExecute() {
+				super.onPreExecute();
+				RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+				if (views != null) {
+					views.setViewVisibility(R.id.frmProgress, View.VISIBLE);
+					appWidgetManager.updateAppWidget(appWidgetId, views);
+				}
+			}
+
+			private Context context;
+			private AppWidgetManager appWidgetManager;
+			private int appWidgetId;
+
+			public WidgetUpdateTask(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
+				this.context = context;
+				this.appWidgetManager = appWidgetManager;
+				this.appWidgetId = appWidgetId;
+			}
+
+			@Override
+			protected Void doInBackground(Void... params) {
+				String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
+				if (accountId == null) {
+					Log.d("WidgetService", "Widget not found in db: "+appWidgetId);
+					return null;
+				}
+				DBAdapter db = new DBAdapter(context);
+				db.open();
+				String bankId = accountId.split("_")[0];
+				Cursor c = db.getBank(bankId);
+				if (c == null) {
+					return null;
+				}
+
+				int clmId = c.getColumnIndex("_id");
+				int clmBanktype = c.getColumnIndex("banktype");
+				int clmBalance = c.getColumnIndex("balance");
+				int clmUsername = c.getColumnIndex("username");
+				int clmPassword = c.getColumnIndex("password");
+				int clmDisabled = c.getColumnIndex("disabled");
+				try {
+					if (c.getInt(clmDisabled) == 0) {
+						Class cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
+						Bank bank = (Bank) cls.newInstance();
+						bank.update(c.getString(clmUsername), c.getString(clmPassword), context);
+						db.updateBank(bank, new Long(c.getString(clmId)));
+					}
+					else {
+						Log.d("BankdroidWidgetProvider", "Bank is disabled, skipping refresh on "+c.getLong(clmId));
+					}
+				} 
+				catch (BankException e) {
+					Log.d("", "Disabling bank: "+c.getLong(clmId));
+					db.disableBank(c.getLong(clmId));
+				}
+				catch (ClassNotFoundException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (IllegalAccessException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (InstantiationException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				finally {
+					c.close();
+					db.close();
+				}
+
+				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId);
+				return null;
+			}
+			@Override
+			protected void onPostExecute(Void result) {
+				super.onPostExecute(result);
+				RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId);
+				if (views != null) {
+					views.setViewVisibility(R.id.frmProgress, View.INVISIBLE);
+					appWidgetManager.updateAppWidget(appWidgetId, views);
+				}
+			}
+
+			
+		}
+	}
 }
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index 3b20c9f..06376a1 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -74,6 +74,7 @@ public class DBAdapter {
     
     public void close() {
         mDbHelper.close();
+        mDb.close();
     }
 
 
@@ -159,11 +160,12 @@ public class DBAdapter {
     
     public void disableBank(long bankId) {
         ContentValues initialValues = new ContentValues();
-        initialValues.put("disabled", 1);    	
+        initialValues.put("disabled", 1);
+    	mDb.update("banks", initialValues, "_id="+bankId, null);
     }
     
     public Cursor getBank(String bankId) {
-    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password"}, "_id="+bankId, null, null, null, null);
+    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled"}, "_id="+bankId, null, null, null, null);
     	if (c != null) {
     		c.moveToFirst();
     	}
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
index 986374e..ebe715d 100644
--- src/com/liato/bankdroid/DataRetrieverTask.java
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -79,9 +79,9 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 				e.printStackTrace();
 			}
 		}
-		publishProgress(new String[] {new Integer(i).toString(), ""});
 		c.close();
 		db.close();
+		publishProgress(new String[] {new Integer(i).toString(), ""});
 		return null;
 	}
 
@@ -91,6 +91,7 @@ public class DataRetrieverTask extends AsyncTask<String, String, Void> {
 	}
 	protected void onPostExecute(final Void unused) {
 		parent.refreshView();
+		AutoRefreshService.sendWidgetRefresh(parent);
 		if (this.dialog.isShowing()) {
 			this.dialog.dismiss();
 		}
diff --git src/com/liato/bankdroid/LoginActivity.java src/com/liato/bankdroid/LoginActivity.java
index 0c96ef5..e64023f 100644
--- src/com/liato/bankdroid/LoginActivity.java
+++ src/com/liato/bankdroid/LoginActivity.java
@@ -6,6 +6,7 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.util.Log;
 import android.view.View;
 import android.view.animation.AlphaAnimation;
 import android.widget.Button;
@@ -17,16 +18,29 @@ public class LoginActivity extends Activity {
 	private String access_code;
 
 	public void onCreate(Bundle savedInstanceState) {
+		String widgetAction = getIntent().getAction();
+		if (!widgetAction.equals("widgetLogin")) {
+		    setTheme(android.R.style.Theme);
+		}
 		super.onCreate(savedInstanceState);
 	
 		prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		access_code = prefs.getString("access_code", "");
+		setResult(Activity.RESULT_CANCELED); // default
 		if (access_code.length() > 0) {
 			setContentView(R.layout.login);
 			((Button)findViewById(R.id.btnLogin)).setOnClickListener(new View.OnClickListener() {
 				public void onClick(View v) {
 					if (((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(access_code)) {
-						loginSuccess();
+						Log.d("LoginActivity", "Success");
+						String widgetAction = getIntent().getAction();
+						if (widgetAction.equals("widgetLogin")) {
+							Log.d("LoginActivity", "unLockOnly");
+							setResult(Activity.RESULT_OK);
+							finish();
+						} else {
+							loginSuccess();
+						}
 					}
 					else {
 						TextView txtResult = (TextView)findViewById(R.id.txtResult);
@@ -42,18 +56,27 @@ public class LoginActivity extends Activity {
 			});	
 		}
 		else {
-			loginSuccess();
+			Log.d("LoginActivity", widgetAction);
+			if (widgetAction.equals("widgetLogin")) {
+				Log.d("LoginActivity", "unLockOnly");
+				setResult(Activity.RESULT_OK);
+				finish();
+			} else {
+				loginSuccess();
+			}
 		}
 	}
 	
 	private void loginSuccess() {
+		unLock();
+		Intent intent = new Intent(this, MainActivity.class);
+		startActivity(intent);
+		this.finish();
+	}
+	
+	private void unLock() {
 		Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
 		editor.putLong("locked_at", System.currentTimeMillis());
 		editor.commit();
-
-		Intent intent = new Intent(this, MainActivity.class);
-		this.startActivity(intent);
-		this.finish();
-		return;
 	}
 }
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 241c8db..a3341a7 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -4,7 +4,11 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.liato.bankdroid.AccountsAdapter.Group;
+import com.liato.bankdroid.AccountsAdapter.Item;
+
 import android.app.AlertDialog;
+import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -61,6 +65,7 @@ public class MainActivity extends LockableActivity {
 			int clmBanktype = curBanks.getColumnIndex("banktype");
 			int clmUsername = curBanks.getColumnIndex("username");
 			int clmBankbalance = curBanks.getColumnIndex("balance");
+			int clmDisabled = curBanks.getColumnIndex("disabled");
 			List<Item> items;
 			Group bank;
 
@@ -70,14 +75,15 @@ public class MainActivity extends LockableActivity {
 				curAccounts = dba.fetchAccounts(curBanks.getLong(clmId));
 				int clmBalance = curAccounts.getColumnIndex("balance"); 
 				int clmName = curAccounts.getColumnIndex("name");
+				int clmAccId = curAccounts.getColumnIndex("id");
 				int acc_count = curAccounts.getCount();
 				if (curAccounts != null && acc_count != 0) {
 					while (!curAccounts.isLast()) {
 						curAccounts.moveToNext();
-						items.add(new Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance)));
+						items.add(new Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance),curAccounts.getString(clmAccId)));
 					}
 				}
-				bank = new Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items);
+				bank = new Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items, (curBanks.getInt(clmDisabled) == 1 ? true : false));
 				adapter.addGroup(bank);
 				curAccounts.close();
 			}
@@ -85,7 +91,6 @@ public class MainActivity extends LockableActivity {
 		}
 		curBanks.close();
 		dba.close();
-		AutoRefreshService.sendWidgetRefresh(this);
 	}
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
@@ -95,6 +100,15 @@ public class MainActivity extends LockableActivity {
 	}
 
 
+	@Override
+	protected Dialog onCreateDialog(int id) {
+		super.onCreateDialog(id);
+		Dialog dialog = new Dialog(this);
+		dialog.setContentView(R.layout.about);
+		dialog.setTitle(getString(R.string.about));
+		return dialog;
+	}
+
 	public boolean onOptionsItemSelected (MenuItem item){
 		Intent intent;
 		switch (item.getItemId()) {
@@ -110,16 +124,7 @@ public class MainActivity extends LockableActivity {
 			this.startActivity(intent);
 			return true;
 		case R.id.about:
-			AlertDialog.Builder builder = new AlertDialog.Builder(this);
-			builder.setMessage("Omnomnomnom")
-			.setCancelable(true)
-			.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-				public void onClick(DialogInterface dialog, int id) {
-					dialog.cancel();
-				}
-			});
-			AlertDialog alert = builder.create();
-			alert.show();
+			showDialog(0);
 			return true;
 		}
 		return false;
@@ -129,136 +134,6 @@ public class MainActivity extends LockableActivity {
 		super.onDestroy();
 	}
 
-	private class AccountsAdapter extends BaseAdapter {
-		private ArrayList<Group> groups;
-		private Context context;
-
-		public AccountsAdapter(Context context) {
-			this.context = context;
-			this.groups = new ArrayList<Group>();
-		}
-
-		public void addGroup(Group group) {
-			groups.add(group);
-		}
-
-		public View newGroupView(Group group, ViewGroup parent) {
-			LayoutInflater inflater = LayoutInflater.from(context);
-			View v = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
-			ImageView icon = (ImageView)v.findViewById(R.id.imgListitemAccountsGroup);
-			((TextView)v.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getName());
-			((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
-			((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
-			icon.setImageResource(getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, getPackageName()));
-			return v;
-		}
-
-		public View newItemView(Item item, ViewGroup parent) {
-			LayoutInflater inflater = LayoutInflater.from(context);
-			View v = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
-			((TextView)v.findViewById(R.id.txtListitemAccountsItemAccountname)).setText(item.getName());
-			((TextView)v.findViewById(R.id.txtListitemAccountsItemBalance)).setText(Helpers.formatBalance(item.getBalance()));
-			return v;
-		}
-
-		@Override
-		public int getCount() {
-			int c = 0;
-			for(Group g : groups) {
-				c += g.getItems().size()+1;
-			}
-			return c;
-		}
-
-		@Override
-		public Object getItem(int position) {
-			if (groups.size() == 0) {
-				return null;
-			}
-			if (position == 0) {
-				return groups.get(0);
-			}
-
-			int i = 0;
-			for (Group g : groups) {
-				if (position == i) {
-					return g;
-				}
-				else if (position <= (g.getItems().size()+i)) {
-					return g.getItems().get(position-i-1);
-				}
-				i += g.getItems().size()+1;
-			}
-
-			return(null);
-		}
-
-		@Override
-		public long getItemId(int position) {
-			return position;
-		}
-
-		@Override
-		public View getView(int position, View convertView, ViewGroup parent) {
-			Object item = getItem(position);
-			if (item == null) {
-				return null;
-			}
-			if (item instanceof Group) {
-				return newGroupView((Group)item, parent);
-			}
-			else if (item instanceof Item) {
-				return newItemView((Item)item, parent);
-			}
-			return null;
-		}
-
-		public boolean isEnabled(int position) {
-			return false;
-		}		
-	}
-
-
-	
-	private class Group {
-		private String name;
-		private String type;
-		private BigDecimal total;
-		private List<Item> items;
-		public Group(String name, String type, Double total, List<Item> items) {
-			this.name = name;
-			this.type = type;
-			this.items = items;
-			this.total = new BigDecimal(total);
-		}
-		public String getName() {
-			return name;
-		}
-		public String getType() {
-			return type;
-		}
-		public BigDecimal getTotal() {
-			return total;
-		}
-		public List<Item> getItems() {
-			return items;
-		}
 
-	}
-
-	private class Item {
-		private String name;
-		private BigDecimal balance;
-		public Item (String name, Double balance) {
-			this.name = name;
-			this.balance = new BigDecimal(balance);
-		}
-		public String getName() {
-			return name;
-		}
-		public BigDecimal getBalance() {
-			return balance;
-		}
-	}
 
 }
\ No newline at end of file
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
index aea19e5..08884f2 100644
--- src/com/liato/bankdroid/StartupReceiver.java
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -34,7 +34,7 @@ public class StartupReceiver extends BroadcastReceiver{
         }
         else {
 	        long firstTime = SystemClock.elapsedRealtime();
-	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*1000, refreshrate*1000, alarmSender);
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*60*1000, refreshrate*60*1000, alarmSender);
         	Log.d("","Alarm set to "+refreshrate.toString()+" minutes.");
         }
 	
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index f171e19..fd5a858 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -10,123 +10,113 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.os.Bundle;
-import android.preference.PreferenceManager;
 import android.util.Log;
 import android.view.View;
-import android.view.animation.AlphaAnimation;
 import android.widget.AdapterView;
 import android.widget.Button;
-import android.widget.EditText;
 import android.widget.ListView;
-import android.widget.TextView;
+import android.widget.Toast;
 import android.widget.AdapterView.OnItemClickListener;
 
 public class WidgetConfigureActivity extends Activity {
-	private static final String WIDGET_PREFIX = "widget_";
-	private DBAdapter dba;
+    private static final String WIDGET_PREFIX = "widget_";
+    private DBAdapter dba;
 	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
-	private String access_code;
-	private SharedPreferences prefs;
-
+	
+	private static final int LOGIN_ID = 1;
+	
 	public WidgetConfigureActivity() {
 		super();
+		
 	}
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
-		prefs = PreferenceManager.getDefaultSharedPreferences(this);
-		access_code = prefs.getString("access_code", "");
-	}	
-
-	public void onResume() {
-		super.onResume();
-		if (access_code.length() > 0) {
-			handleLogin();
-		}
-		else {
-			handleSelect();
-		}
-	}
-
-	private void handleLogin() {
-		setContentView(R.layout.login);
-		((Button)findViewById(R.id.btnLogin)).setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				if (((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(access_code)) {
-					handleSelect();
-				}
-				else {
-					TextView txtResult = (TextView)findViewById(R.id.txtResult);
-					txtResult.setVisibility(TextView.VISIBLE);
-					AlphaAnimation anim = new AlphaAnimation(1, 0);
-					anim.setFillAfter(true);
-					anim.setStartOffset(5000);
-					anim.setDuration(1000);
-					txtResult.startAnimation(anim);
-				}
-			}
-		});	
-	}
 
+		Log.d("Widget Configre", "##########################");
+		Intent login = new Intent(this, LoginActivity.class);
+		login.setAction("widgetLogin");
+		startActivityForResult(login, LOGIN_ID);
+	}	
+	
+	public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+        case LOGIN_ID:
+            if (resultCode == Activity.RESULT_OK) {
+            	Log.d("RESULT OK", "WHOOOOO #############");
+            	firstDraw();
+            } else {
+            	finish();
+            }
+            break;
+        }
+    }
+	
+	private void firstDraw() {
 
-	private void handleSelect() {
 		setContentView(R.layout.main);
 		this.setTitle(this.getString(R.string.choose_an_account));
-		setResult(RESULT_CANCELED);
+        setResult(RESULT_CANCELED);
 		((Button)findViewById(R.id.btnAccountsRefresh)).setVisibility(View.GONE);
 
-		Intent intent = getIntent();
-		Bundle extras = intent.getExtras();
-		if (extras != null) {
-			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
-		}
-		if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
-			finish();
-		}		
+        Intent intent = getIntent();
+        Bundle extras = intent.getExtras();
+        if (extras != null) {
+            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+        }
+        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+            finish();
+        }		
 
-		ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+        ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 		lv.setOnItemClickListener(new OnItemClickListener() {
 			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 				Log.d("!", "CLICK!");
+				
+	            final Context context = WidgetConfigureActivity.this;
+	            AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
 
-				final Context context = WidgetConfigureActivity.this;
-				AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
-
-				WidgetConfigureActivity.setAccountId(context, mAppWidgetId, item.getId());
+	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, item.getId());
 
-				// Push widget update to surface with newly set prefix
-				AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
-				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
-						mAppWidgetId, item);
+	            // Push widget update to surface with newly set prefix
+	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
+	                    mAppWidgetId, item);
 
-				Intent resultValue = new Intent();
-				resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
-				setResult(RESULT_OK, resultValue);
-				finish();
+	            Intent resultValue = new Intent();
+	            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+	            setResult(RESULT_OK, resultValue);
+	            finish();
 			}
 		});
+		
 		refreshView();
-
 	}
+	
+//	public void onResume() {
+//		super.onResume();
+//		refreshView();
+//	}
+	
 	public static String getAccountId(Context context, int appWidgetId) {
 		SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
 		return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
 	}
 
 	public static void setAccountId(Context context, int appWidgetId, String value) {
-		SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-		prefs.putString(WIDGET_PREFIX + appWidgetId, value);
-		prefs.commit();
+        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+        prefs.putString(WIDGET_PREFIX + appWidgetId, value);
+        prefs.commit();
 	}
 
 	public static void delAccountId(Context context, int appWidgetId) {
-		SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-		prefs.remove(WIDGET_PREFIX + appWidgetId);
-		prefs.commit();
+        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+        prefs.remove(WIDGET_PREFIX + appWidgetId);
+        prefs.commit();
 	}
-
-
+	
+	
 	private void refreshView() {
 		dba = new DBAdapter(this);
 		dba.open();
@@ -143,6 +133,7 @@ public class WidgetConfigureActivity extends Activity {
 			int clmBanktype = curBanks.getColumnIndex("banktype");
 			int clmUsername = curBanks.getColumnIndex("username");
 			int clmBankbalance = curBanks.getColumnIndex("balance");
+			int clmDisabled = curBanks.getColumnIndex("disabled");
 			List<AccountsAdapter.Item> items;
 			AccountsAdapter.Group bank;
 
@@ -160,7 +151,7 @@ public class WidgetConfigureActivity extends Activity {
 						items.add(new AccountsAdapter.Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance), curAccounts.getString(clmAccId)));
 					}
 				}
-				bank = new AccountsAdapter.Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items);
+				bank = new AccountsAdapter.Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items, (curBanks.getInt(clmDisabled) == 1 ? true : false));
 				adapter.addGroup(bank);
 				curAccounts.close();
 			}
@@ -174,5 +165,9 @@ public class WidgetConfigureActivity extends Activity {
 		super.onDestroy();
 	}
 
+	
+	public void onActivityResult() {
+		
+	}
 
 }
diff --git widgets.psd widgets.psd
index e4711fb..86a01c5 100644
Binary files widgets.psd and widgets.psd differ

commit 325a4e6f1ffb38556edc183fb32231a799591803
Author: liato <x@x00.us>
Date:   Mon May 31 00:43:29 2010 +0200

    Password protect widgets.

diff --git res/layout/login.xml res/layout/login.xml
index 96e081f..e6307d4 100644
--- res/layout/login.xml
+++ res/layout/login.xml
@@ -1,43 +1,49 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="vertical" android:layout_width="fill_parent"
-	android:layout_height="fill_parent" android:paddingLeft="10dp"
-	android:paddingRight="10dp" android:paddingTop="10dp"
-	android:layout_gravity="center_vertical" android:gravity="center_vertical">
-
-
-	<TextView android:id="@+id/TextView01" android:layout_height="wrap_content"
-		android:typeface="sans" android:gravity="center_horizontal"
-		android:layout_gravity="center_horizontal" android:text="BANKDROID"
-		android:layout_width="fill_parent" android:visibility="visible"
-		android:textColor="#fff" android:textSize="42dp"></TextView>
-	<LinearLayout android:id="@+id/LinearLayout01"
-		android:layout_height="wrap_content" android:orientation="horizontal"
-		android:layout_width="fill_parent">
-		<ImageView android:id="@+id/ImageView01" android:background="@drawable/icon_large"
-			android:layout_width="100dp" android:layout_height="100dp"
-			android:layout_gravity="center_horizontal" android:visibility="visible"></ImageView>
-		<LinearLayout android:id="@+id/LinearLayout02"
-			android:layout_height="wrap_content" android:orientation="vertical"
+<RelativeLayout android:id="@+id/RelativeLayout01"
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent" android:layout_height="fill_parent">
+	<LinearLayout android:orientation="vertical"
+		android:layout_width="fill_parent" android:layout_height="fill_parent"
+		android:paddingLeft="10dp" android:paddingRight="10dp"
+		android:paddingTop="10dp" android:layout_gravity="center_vertical"
+		android:gravity="center_vertical" android:fitsSystemWindows="true">
+
+
+		<TextView android:id="@+id/TextView01" android:layout_height="wrap_content"
+			android:typeface="sans" android:gravity="center_horizontal"
+			android:layout_gravity="center_horizontal" android:text="BANKDROID"
+			android:layout_width="fill_parent" android:visibility="visible"
+			android:textColor="#fff" android:textSize="42dp"></TextView>
+		<LinearLayout android:id="@+id/LinearLayout01"
+			android:layout_height="wrap_content" android:orientation="horizontal"
 			android:layout_width="fill_parent">
-			<EditText android:layout_height="wrap_content"
-				android:layout_width="fill_parent" android:inputType="textPassword"
-				android:layout_gravity="center_vertical" android:hint="@string/access_code"
-				android:id="@+id/edtAccessCode"></EditText>
-			<Button android:id="@+id/btnLogin" android:layout_gravity="right|center_vertical"
-				android:layout_width="fill_parent" android:layout_height="52dp"
-				android:drawableRight="@drawable/ic_menu_forward"></Button>
+			<ImageView android:id="@+id/ImageView01"
+				android:background="@drawable/icon_large" android:layout_width="100dp"
+				android:layout_height="100dp" android:layout_gravity="center_horizontal"
+				android:visibility="visible"></ImageView>
+			<LinearLayout android:id="@+id/LinearLayout02"
+				android:layout_height="wrap_content" android:orientation="vertical"
+				android:layout_width="fill_parent">
+				<EditText android:layout_height="wrap_content"
+					android:layout_width="fill_parent" android:inputType="textPassword"
+					android:layout_gravity="center_vertical" android:hint="@string/access_code"
+					android:id="@+id/edtAccessCode"></EditText>
+				<Button android:id="@+id/btnLogin" android:layout_gravity="right|center_vertical"
+					android:layout_width="fill_parent" android:layout_height="52dp"
+					android:drawableRight="@drawable/ic_menu_forward"></Button>
+			</LinearLayout>
 		</LinearLayout>
-	</LinearLayout>
 
 
 
 
 
 
-	<TextView android:layout_width="wrap_content"
-		android:layout_height="wrap_content" android:id="@+id/txtResult"
-		android:textColor="#CC4B28" android:text="@string/invalid_access_code"
-		android:gravity="center_vertical" android:drawableLeft="@drawable/ic_bullet_key_permission"
-		android:layout_gravity="center_horizontal" android:visibility="invisible"></TextView>
+		<TextView android:layout_width="wrap_content"
+			android:layout_height="wrap_content" android:id="@+id/txtResult"
+			android:textColor="#CC4B28" android:text="@string/invalid_access_code"
+			android:gravity="center_vertical" android:drawableLeft="@drawable/ic_bullet_key_permission"
+			android:layout_gravity="center_horizontal" android:visibility="invisible"></TextView>
+
 </LinearLayout>
+</RelativeLayout>
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index 39ef7cc..f171e19 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -10,18 +10,24 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.os.Bundle;
+import android.preference.PreferenceManager;
 import android.util.Log;
 import android.view.View;
+import android.view.animation.AlphaAnimation;
 import android.widget.AdapterView;
 import android.widget.Button;
+import android.widget.EditText;
 import android.widget.ListView;
+import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
 
 public class WidgetConfigureActivity extends Activity {
-    private static final String WIDGET_PREFIX = "widget_";
-    private DBAdapter dba;
+	private static final String WIDGET_PREFIX = "widget_";
+	private DBAdapter dba;
 	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
-	
+	private String access_code;
+	private SharedPreferences prefs;
+
 	public WidgetConfigureActivity() {
 		super();
 	}
@@ -29,68 +35,98 @@ public class WidgetConfigureActivity extends Activity {
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
+		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		access_code = prefs.getString("access_code", "");
+	}	
+
+	public void onResume() {
+		super.onResume();
+		if (access_code.length() > 0) {
+			handleLogin();
+		}
+		else {
+			handleSelect();
+		}
+	}
+
+	private void handleLogin() {
+		setContentView(R.layout.login);
+		((Button)findViewById(R.id.btnLogin)).setOnClickListener(new View.OnClickListener() {
+			public void onClick(View v) {
+				if (((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(access_code)) {
+					handleSelect();
+				}
+				else {
+					TextView txtResult = (TextView)findViewById(R.id.txtResult);
+					txtResult.setVisibility(TextView.VISIBLE);
+					AlphaAnimation anim = new AlphaAnimation(1, 0);
+					anim.setFillAfter(true);
+					anim.setStartOffset(5000);
+					anim.setDuration(1000);
+					txtResult.startAnimation(anim);
+				}
+			}
+		});	
+	}
+
+
+	private void handleSelect() {
 		setContentView(R.layout.main);
 		this.setTitle(this.getString(R.string.choose_an_account));
-        setResult(RESULT_CANCELED);
+		setResult(RESULT_CANCELED);
 		((Button)findViewById(R.id.btnAccountsRefresh)).setVisibility(View.GONE);
 
-        Intent intent = getIntent();
-        Bundle extras = intent.getExtras();
-        if (extras != null) {
-            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
-        }
-        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
-            finish();
-        }		
+		Intent intent = getIntent();
+		Bundle extras = intent.getExtras();
+		if (extras != null) {
+			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+		}
+		if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+			finish();
+		}		
 
-        ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+		ListView lv = (ListView)findViewById(R.id.lstAccountsList);
 		lv.setOnItemClickListener(new OnItemClickListener() {
 			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 				Log.d("!", "CLICK!");
-				
-	            final Context context = WidgetConfigureActivity.this;
-	            AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
 
-	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, item.getId());
+				final Context context = WidgetConfigureActivity.this;
+				AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
+
+				WidgetConfigureActivity.setAccountId(context, mAppWidgetId, item.getId());
 
-	            // Push widget update to surface with newly set prefix
-	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
-	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
-	                    mAppWidgetId, item);
+				// Push widget update to surface with newly set prefix
+				AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+				BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
+						mAppWidgetId, item);
 
-	            Intent resultValue = new Intent();
-	            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
-	            setResult(RESULT_OK, resultValue);
-	            finish();
+				Intent resultValue = new Intent();
+				resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+				setResult(RESULT_OK, resultValue);
+				finish();
 			}
 		});
-
-	
-	}	
-	
-	public void onResume() {
-		super.onResume();
 		refreshView();
+
 	}
-	
 	public static String getAccountId(Context context, int appWidgetId) {
 		SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
 		return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
 	}
 
 	public static void setAccountId(Context context, int appWidgetId, String value) {
-        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-        prefs.putString(WIDGET_PREFIX + appWidgetId, value);
-        prefs.commit();
+		SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+		prefs.putString(WIDGET_PREFIX + appWidgetId, value);
+		prefs.commit();
 	}
 
 	public static void delAccountId(Context context, int appWidgetId) {
-        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-        prefs.remove(WIDGET_PREFIX + appWidgetId);
-        prefs.commit();
+		SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+		prefs.remove(WIDGET_PREFIX + appWidgetId);
+		prefs.commit();
 	}
-	
-	
+
+
 	private void refreshView() {
 		dba = new DBAdapter(this);
 		dba.open();

commit 14bda0c768a38c48bc99f58ecb1120cbad1620fc
Author: liato <x@x00.us>
Date:   Sun May 30 23:09:47 2010 +0200

    Fixed lansforsakringar and lockscreen bug.

diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/BankLansforsakringar.java
index 6d85943..0535d7b 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -27,7 +27,7 @@ public class BankLansforsakringar implements Bank {
 	private Banks banktype = Banks.LANSFORSAKRINGAR;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalance = Pattern.compile("&AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalance = Pattern.compile("AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
 	
@@ -102,7 +102,6 @@ public class BankLansforsakringar implements Bank {
 			accurl += "&_token=" + token;
 			Log.d("Bankdroid", "Account url: " + accurl);
 			response = urlopen.open(accurl);
-			Log.d("Bankdroid", "Response: "+ response);
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
diff --git src/com/liato/bankdroid/LoginActivity.java src/com/liato/bankdroid/LoginActivity.java
index 362fd37..0c96ef5 100644
--- src/com/liato/bankdroid/LoginActivity.java
+++ src/com/liato/bankdroid/LoginActivity.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid;
 import android.app.Activity;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.view.View;
@@ -46,6 +47,10 @@ public class LoginActivity extends Activity {
 	}
 	
 	private void loginSuccess() {
+		Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
+		editor.putLong("locked_at", System.currentTimeMillis());
+		editor.commit();
+
 		Intent intent = new Intent(this, MainActivity.class);
 		this.startActivity(intent);
 		this.finish();

commit a3bb88271ed437b08569d18d73c020b9c80d32d1
Author: liato <x@x00.us>
Date:   Sun May 30 21:30:46 2010 +0200

    Added auto refresh and widgets.

diff --git .settings/org.eclipse.core.resources.prefs .settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..37b5c65
--- /dev/null
+++ .settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Wed May 26 03:27:34 CEST 2010
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git AndroidManifest.xml AndroidManifest.xml
index e7f8d03..387c13e 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.0.4" android:versionCode="10">
+	package="com.liato.bankdroid" android:versionName="1.0.4"
+	android:versionCode="12">
 	<application android:icon="@drawable/icon" android:label="@string/app_name">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
@@ -18,8 +19,9 @@
 		</activity>
 		<activity android:name=".SettingsActivity" android:label="@string/app_name">
 		</activity>
-		<!--
-		<activity android:name=".WidgetConfigureActivity" android:theme="@android:style/Theme.Dialog">
+
+		<activity android:name=".WidgetConfigureActivity"
+			android:theme="@android:style/Theme.Dialog">
 			<intent-filter>
 				<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
 			</intent-filter>
@@ -27,12 +29,24 @@
 		<receiver android:name="BankdroidWidgetProvider">
 			<intent-filter>
 				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+				<action android:name="com.liato.bankdroid.WIDGET_REFRESH" />
 			</intent-filter>
 			<meta-data android:name="android.appwidget.provider"
 				android:resource="@xml/appwidget_info" />
 		</receiver>
-		-->
+
+		<service android:enabled="true" android:name=".AutoRefreshService" />
+		<receiver android:name="StartupReceiver">
+			<intent-filter>
+				<action android:name="android.intent.action.BOOT_COMPLETED" />
+				<action android:name="android.intent.action.PACKAGE_REPLACED" />
+				<data android:scheme="package" android:path="com.liato.bankdroid" />
+				<category android:name="android.intent.category.HOME" />
+			</intent-filter>
+		</receiver>
 	</application>
 	<uses-sdk android:minSdkVersion="3" />
 	<uses-permission android:name="android.permission.INTERNET"></uses-permission>
+	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+	<uses-permission android:name="android.permission.VIBRATE" />
 </manifest> 
\ No newline at end of file
diff --git res/drawable/icon_large.png res/drawable/icon_large.png
new file mode 100644
index 0000000..a6bafd4
Binary files /dev/null and res/drawable/icon_large.png differ
diff --git res/layout/login.xml res/layout/login.xml
index b52a009..96e081f 100644
--- res/layout/login.xml
+++ res/layout/login.xml
@@ -1,17 +1,43 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp" android:layout_gravity="center_vertical" android:gravity="center_vertical">
-
-
-<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:typeface="sans" android:gravity="center_horizontal" android:layout_gravity="center_horizontal" android:text="BANKDROID" android:layout_width="fill_parent" android:visibility="visible" android:textColor="#fff" android:textSize="42dp"></TextView><LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent"><ImageView android:id="@+id/ImageView01" android:background="@drawable/icon_large" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:visibility="visible"></ImageView><LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent"><EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:inputType="textPassword" android:layout_gravity="center_vertical" android:hint="@string/access_code" android:id="@+id/edtAccessCode"></EditText><Button android:id="@+id/btnLogin" android:layout_gravity="right|center_vertical" android:layout_width="fill_parent" android:layout_height="52dp" android:drawableRight="@drawable/ic_menu_forward"></Button></LinearLayout>
-</LinearLayout>
-
-
-
-
-
-
-<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/txtResult" android:textColor="#CC4B28" android:text="@string/invalid_access_code" android:gravity="center_vertical" android:drawableLeft="@drawable/ic_bullet_key_permission" android:layout_gravity="center_horizontal" android:visibility="invisible"></TextView>
+	android:orientation="vertical" android:layout_width="fill_parent"
+	android:layout_height="fill_parent" android:paddingLeft="10dp"
+	android:paddingRight="10dp" android:paddingTop="10dp"
+	android:layout_gravity="center_vertical" android:gravity="center_vertical">
+
+
+	<TextView android:id="@+id/TextView01" android:layout_height="wrap_content"
+		android:typeface="sans" android:gravity="center_horizontal"
+		android:layout_gravity="center_horizontal" android:text="BANKDROID"
+		android:layout_width="fill_parent" android:visibility="visible"
+		android:textColor="#fff" android:textSize="42dp"></TextView>
+	<LinearLayout android:id="@+id/LinearLayout01"
+		android:layout_height="wrap_content" android:orientation="horizontal"
+		android:layout_width="fill_parent">
+		<ImageView android:id="@+id/ImageView01" android:background="@drawable/icon_large"
+			android:layout_width="100dp" android:layout_height="100dp"
+			android:layout_gravity="center_horizontal" android:visibility="visible"></ImageView>
+		<LinearLayout android:id="@+id/LinearLayout02"
+			android:layout_height="wrap_content" android:orientation="vertical"
+			android:layout_width="fill_parent">
+			<EditText android:layout_height="wrap_content"
+				android:layout_width="fill_parent" android:inputType="textPassword"
+				android:layout_gravity="center_vertical" android:hint="@string/access_code"
+				android:id="@+id/edtAccessCode"></EditText>
+			<Button android:id="@+id/btnLogin" android:layout_gravity="right|center_vertical"
+				android:layout_width="fill_parent" android:layout_height="52dp"
+				android:drawableRight="@drawable/ic_menu_forward"></Button>
+		</LinearLayout>
+	</LinearLayout>
+
+
+
+
+
+
+	<TextView android:layout_width="wrap_content"
+		android:layout_height="wrap_content" android:id="@+id/txtResult"
+		android:textColor="#CC4B28" android:text="@string/invalid_access_code"
+		android:gravity="center_vertical" android:drawableLeft="@drawable/ic_bullet_key_permission"
+		android:layout_gravity="center_horizontal" android:visibility="invisible"></TextView>
 </LinearLayout>
diff --git res/layout/settings.xml res/layout/settings.xml
index 61e9299..f4a1d9e 100644
--- res/layout/settings.xml
+++ res/layout/settings.xml
@@ -8,19 +8,33 @@
 		android:layout_height="wrap_content" android:typeface="sans"
 		android:textSize="20sp" android:text="@string/access_code" />
 	<EditText android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:inputType="textPassword" android:id="@+id/edtAccessCode"></EditText>
-
-	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/txtSettingsPinDesc" android:text="@string/pin_desc" android:textSize="12sp" android:textColor="#A4A4A4" android:drawableLeft="@android:drawable/ic_dialog_info" android:drawablePadding="5dp" android:layout_marginBottom="3dp"></TextView><TextView android:layout_width="fill_parent"
+		android:layout_width="fill_parent" android:inputType="textPassword"
+		android:id="@+id/edtAccessCode"></EditText>
+
+	<TextView android:layout_width="wrap_content"
+		android:layout_height="wrap_content" android:id="@+id/txtSettingsPinDesc"
+		android:text="@string/pin_desc" android:textSize="12sp"
+		android:textColor="#A4A4A4" android:drawableLeft="@android:drawable/ic_dialog_info"
+		android:drawablePadding="5dp" android:layout_marginBottom="3dp"></TextView>
+	<TextView android:layout_width="fill_parent"
 		android:layout_height="wrap_content" android:typeface="sans"
-		android:textSize="20sp" android:text="@string/update_frequency" android:visibility="invisible"/>
+		android:textSize="20sp" android:text="@string/update_frequency" android:visibility="visible"/>
 	<Spinner android:layout_height="wrap_content"
-		android:layout_width="fill_parent" android:id="@+id/spnUpdateFrequency" android:visibility="invisible"></Spinner>
+		android:layout_width="fill_parent" android:id="@+id/spnUpdateFrequency" android:visibility="visible"></Spinner>
+
 
 
-	
-	
 
-	<LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="10dp"><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/notify_on_change" android:id="@+id/chkNotifyOnChange" android:visibility="invisible"></CheckBox></LinearLayout><TableLayout android:id="@+id/TableLayout01"
+
+	<LinearLayout android:id="@+id/LinearLayout01"
+		android:layout_width="wrap_content" android:layout_height="wrap_content"
+		android:orientation="vertical" android:paddingLeft="10dp">
+		<CheckBox android:layout_width="wrap_content"
+			android:layout_height="wrap_content" android:text="@string/notify_on_change"
+			android:id="@+id/chkNotifyOnChange" android:visibility="visible"></CheckBox>
+	<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/with_sound" android:id="@+id/chkWithSound" android:textSize="14sp" android:layout_marginLeft="10dp"></CheckBox><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="14sp" android:id="@+id/chkWithVibration" android:text="@string/vibrate" android:layout_marginLeft="10dp"></CheckBox>
+</LinearLayout>
+	<TableLayout android:id="@+id/TableLayout01"
 		android:layout_width="fill_parent" android:stretchColumns="*"
 		android:gravity="bottom" android:layout_height="fill_parent">
 		<TableRow android:id="@+id/TableRow01" android:layout_height="wrap_content"
diff --git res/layout/widget.xml res/layout/widget.xml
index 1137d0b..59bee3a 100644
--- res/layout/widget.xml
+++ res/layout/widget.xml
@@ -2,7 +2,7 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_gravity="center_horizontal" android:background="@drawable/widget_2x1" android:layout_height="100dp" android:layout_width="160dp">
 
-    <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/layWidgetRow01" android:layout_marginTop="-5dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_width="22dp" android:layout_height="22dp" android:background="@drawable/nordea" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical"></ImageView><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:text="Kapitalkonto" android:layout_gravity="center_vertical" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_marginLeft="2dp"></TextView></LinearLayout><LinearLayout android:id="@+id/layWidgetRow02" android:layout_below="@+id/layWidgetRow01" android:layout_width="fill_parent" android:layout_height="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_height="fill_parent" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="fill_parent" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:textSize="15dp" android:text="129 500,00 SEK" android:layout_marginTop="-4dp" android:id="@+id/txtWidgetAccountbalance"/></LinearLayout>
+    <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/layWidgetRow01" android:layout_marginTop="0dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_width="22dp" android:layout_height="22dp" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical" android:baselineAlignBottom="true" android:src="@drawable/icon" android:scaleType="fitXY"></ImageView><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:text="Kapitalkonto" android:layout_gravity="center_vertical" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_marginLeft="2dp"></TextView></LinearLayout><LinearLayout android:id="@+id/layWidgetRow02" android:layout_below="@+id/layWidgetRow01" android:layout_width="fill_parent" android:layout_height="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_height="fill_parent" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="fill_parent" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:textSize="15dp" android:text="129 500,00 SEK" android:id="@+id/txtWidgetAccountbalance" android:layout_marginTop="-6dp"/></LinearLayout>
 
     
     
diff --git res/values-sv/strings.xml res/values-sv/strings.xml
index bba8df5..52c40fb 100644
--- res/values-sv/strings.xml
+++ res/values-sv/strings.xml
@@ -30,8 +30,16 @@
 	<string name="access_code">PIN-kod</string>
 	<string name="pin_desc">Ange en PIN-kod om du vill lösenordsskydda applikationen och tillhörande widgets.</string>
 	<string name="notify_on_change">Notifiera vid kontohändelser</string>
+	<string name="with_sound">Med ljud</string>
+	<string name="vibrate">Vibrera</string>
 	
     <string name="login">Logga in</string>
     <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
+    
+    <string name="disabled">Inaktiverat</string>
+ 	<string name="minutes">minuter</string>
+    <string name="hour">timme</string>
+    <string name="hours">timmar</string>
+    <string name="daily">Dagligen</string>
 	    
 </resources>
diff --git res/values/strings.xml res/values/strings.xml
index 9cea6b6..fe63a53 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -30,8 +30,17 @@
 	<string name="access_code">Access code</string>
 	<string name="pin_desc">Enter an access code if you want to password protect the application and widgets.</string>
 	<string name="notify_on_change">Notify on changes</string>
+	<string name="with_sound">With sound</string>
+	<string name="vibrate">Vibrate</string>
 	
     <string name="login">Login</string>
     <string name="invalid_access_code">Invalid access code. Try again.</string>
+    
+
+    <string name="disabled">Disabled</string>
+    <string name="minutes">minutes</string>
+    <string name="hour">hour</string>
+    <string name="hours">hours</string>
+    <string name="daily">Daily</string>
 	    
 </resources>
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index c0d3583..d322cb6 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -3,7 +3,6 @@ package com.liato.bankdroid;
 import java.util.ArrayList;
 import java.util.Collections;
 
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.DialogInterface;
@@ -19,7 +18,7 @@ import android.widget.EditText;
 import android.widget.Spinner;
 import android.widget.AdapterView.OnItemSelectedListener;
 
-public class AccountActivity extends Activity implements OnClickListener, OnItemSelectedListener {
+public class AccountActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private String SELECTED_BANK;
 	private String BANKID;
 
diff --git src/com/liato/bankdroid/AccountsActivity.java src/com/liato/bankdroid/AccountsActivity.java
index 260d656..f0c5eb0 100644
--- src/com/liato/bankdroid/AccountsActivity.java
+++ src/com/liato/bankdroid/AccountsActivity.java
@@ -1,6 +1,5 @@
 package com.liato.bankdroid;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -22,7 +21,7 @@ import android.widget.TextView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.AdapterView.OnItemClickListener;
 
-public class AccountsActivity extends Activity {
+public class AccountsActivity extends LockableActivity {
 	private DBAdapter dba;
 	private Cursor c;
 	private ListView lv;
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index 4329c4d..d0e0c5e 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -112,8 +112,19 @@ public class AccountsAdapter extends BaseAdapter {
 		public Group(String name, String type, Double total, List<Item> items) {
 			this.name = name;
 			this.type = type;
+			this.total = new BigDecimal(total);
+			for(Item item : items) {
+				item.setGroup(this);
+			}
 			this.items = items;
+		}
+		public Group(String name, String type, Double total, Item item) {
+			ArrayList<Item> items = new ArrayList<Item>();
+			items.add(item);
+			this.name = name;
+			this.type = type;
 			this.total = new BigDecimal(total);
+			this.items = items;
 		}
 		public String getName() {
 			return name;
@@ -134,6 +145,7 @@ public class AccountsAdapter extends BaseAdapter {
 		private String name;
 		private BigDecimal balance;
 		private String id;
+		private Group group;
 		public Item (String name, Double balance, String id) {
 			this.name = name;
 			this.balance = new BigDecimal(balance);
@@ -148,6 +160,12 @@ public class AccountsAdapter extends BaseAdapter {
 		public String getId() {
 			return id;
 		}
+		public Group getGroup() {
+			return group;
+		}
+		public void setGroup(Group group) {
+			this.group = group;
+		}		
 	}	
 
 }
diff --git src/com/liato/bankdroid/AutoRefreshService.java src/com/liato/bankdroid/AutoRefreshService.java
new file mode 100644
index 0000000..59548ba
--- /dev/null
+++ src/com/liato/bankdroid/AutoRefreshService.java
@@ -0,0 +1,182 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Random;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.app.PendingIntent.CanceledException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class AutoRefreshService extends Service {
+	final static String WIDGET_REFRESH = "com.liato.bankdroid.WIDGET_REFRESH";
+    NotificationManager notificationManager;
+
+    @Override
+    public void onCreate() {
+        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+        new DataRetrieverTask().execute();
+    }
+
+    @Override
+    public void onDestroy() {
+    }
+
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    private void showNotification(String text) {
+    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		if (!prefs.getBoolean("notify_on_change", true)) return;
+		
+        Notification notification = new Notification(R.drawable.icon, text,
+                System.currentTimeMillis());
+		if (prefs.getBoolean("notify_with_sound", true)) {
+	        notification.defaults |= Notification.DEFAULT_SOUND;
+		}
+		if (prefs.getBoolean("notify_with_vibration", true)) {
+			/*long[] vib = {23,28,27,143,20,30,26,364,22,26,
+						  28,26,28,26,28,26,29,25,27,27,
+						  27,27,28,28,28,28,28,27,27,26,27};
+			notification.vibrate = vib;*/
+			notification.defaults |= Notification.DEFAULT_VIBRATE;
+		}
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, MainActivity.class), 0);
+
+        notification.setLatestEventInfo(this,  this.getString(R.string.app_name), text, contentIntent);
+
+        notificationManager.notify(R.id.about, notification);
+    }
+    
+    private class DataRetrieverTask extends AsyncTask<String, String, Void> {
+    	private Class<?> cls;
+    	private ArrayList<String> errors;
+    	private Bank bank;
+    	private int bankcount;
+    	private Resources res;
+
+    	public DataRetrieverTask() {
+    	}
+    	protected void onPreExecute() {
+    	}
+
+    	protected Void doInBackground(final String... args) {
+    		Log.d("doinback", "round");
+    		errors = new ArrayList<String>();
+    		Boolean refreshWidgets = false;
+    		DBAdapter db;
+    		Cursor c;
+    		db = new DBAdapter(AutoRefreshService.this);
+    		db.open();
+    		c = db.fetchBanks();
+    		if (c == null) {
+    			return null;
+    		}
+    		bankcount = c.getCount();
+    		
+    		Double currentBalance;
+    		int clmId = c.getColumnIndex("_id");
+    		int clmBanktype = c.getColumnIndex("banktype");
+    		int clmBalance = c.getColumnIndex("balance");
+    		int clmUsername = c.getColumnIndex("username");
+    		int clmPassword = c.getColumnIndex("password");
+    		int clmDisabled = c.getColumnIndex("disabled");
+    		int i = 0; 
+    		while (!c.isLast() && !c.isAfterLast()) {
+    			c.moveToNext();
+    			//publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
+    			//showNotification("Uppdaterar "+c.getString(clmBanktype));
+    			if (c.getInt(clmDisabled) == 1) {
+    				Log.d("AA", c.getString(clmBanktype)+" ("+c.getString(clmUsername)+") is disabled. Skipping refresh.");
+    				continue;
+    			}
+				Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
+    			try {
+    				currentBalance = c.getDouble(clmBalance);
+    				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
+    				bank = (Bank) cls.newInstance();
+    				bank.update(c.getString(clmUsername), c.getString(clmPassword), AutoRefreshService.this);
+    				Log.d("aa",bank.getBalance().toString());
+					Double diff =  bank.getBalance().doubleValue() - currentBalance;
+    				if (diff != 0) {
+    					showNotification(c.getString(clmBanktype)+ ": "+ ((diff > 0) ? "+" : "") + Helpers.formatBalance(diff) + " ("+Helpers.formatBalance(bank.getBalance())+")");
+    					refreshWidgets = true;
+    				}
+    				db.updateBank(bank, c.getLong(clmId));
+    				i++;
+    			} 
+    			catch (BankException e) {
+    				db.disableBank(c.getLong(clmId));
+    			}
+    			catch (ClassNotFoundException e) {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			} catch (IllegalAccessException e) {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			} catch (InstantiationException e) {
+    				// TODO Auto-generated catch block
+    				e.printStackTrace();
+    			}
+    			
+    		}
+    		
+			if (refreshWidgets) {
+				sendWidgetRefresh(AutoRefreshService.this);
+			}
+    		publishProgress(new String[] {new Integer(i).toString(), ""});
+    		c.close();
+    		db.close();
+    		return null;
+    	}
+
+    	protected void onProgressUpdate(String... args) {
+    	}
+    	protected void onPostExecute(final Void unused) {
+    		if (this.errors != null && !this.errors.isEmpty()) {
+    			StringBuilder errormsg = new StringBuilder();
+    			errormsg.append(res.getText(R.string.accounts_were_not_updated)+":\n");
+    			for (String err : errors)
+    			{
+    			  errormsg.append(err);
+    			  errormsg.append("\n");
+    			}
+    			Log.d("aa", errormsg.toString());
+    		}
+    		AutoRefreshService.this.stopSelf();
+    	}
+    }	
+
+    
+    public static void sendWidgetRefresh(Context context) {
+        Intent updateIntent = new Intent(WIDGET_REFRESH);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(
+        		context, 0, updateIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+            try {
+				pendingIntent.send();
+			} catch (CanceledException e) {
+				// TODO Auto-generated catch block
+				Log.e("", e.getMessage(), e);
+			}
+    }    
+    
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/BankLansforsakringar.java
index 5109d27..6d85943 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -27,7 +27,7 @@ public class BankLansforsakringar implements Bank {
 	private Banks banktype = Banks.LANSFORSAKRINGAR;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalance = Pattern.compile("<a.+?DataTable1:(\\d+):account[^>]+>([^<]+)</a>.+?<spa.+?>.+?</span></td>.*?<spa.+?>(.+?)</span></td>", Pattern.CASE_INSENSITIVE);
+	private Pattern reBalance = Pattern.compile("&AccountNumber=([0-9]+)[^>]+><span[^>]+>([^<]+)</.*?span></td.*?<span[^>]+>([0-9 .,-]+)</span", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
 	
@@ -80,7 +80,8 @@ public class BankLansforsakringar implements Bank {
 			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
 			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
 			postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
-			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));			
+			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));
+			Log.d("Bankdroid", "Posting data to: " + urlopen.getCurrentURI());
 			response = urlopen.open(urlopen.getCurrentURI(), postData);
 			
 			if (response.contains("Felaktig inloggning")) {
@@ -97,8 +98,11 @@ public class BankLansforsakringar implements Bank {
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
 			}
-			String accurl = Html.fromHtml(matcher.group(1)).toString(); 
-			urlopen.open(accurl+"&_token="+token);
+			String accurl = Html.fromHtml(matcher.group(1)).toString();
+			accurl += "&_token=" + token;
+			Log.d("Bankdroid", "Account url: " + accurl);
+			response = urlopen.open(accurl);
+			Log.d("Bankdroid", "Response: "+ response);
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index a6284b8..182ac64 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -51,7 +51,8 @@ public class BankSwedbank implements Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
+			balance = new BigDecimal(0);
+			/*response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
 			matcher = reCSRF.matcher(response);
 			if (!matcher.find()) {
 				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
@@ -66,10 +67,12 @@ public class BankSwedbank implements Bank {
 			if (response.contains("misslyckats")) {
 				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
-			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");*/
+			response = urlopen.open("http://x.x00.us/android/bankdroid/swedbank_oversikt.htm");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
+				balance = balance.add(Helpers.parseBalance(matcher.group(3)));
 			}
 			// Konungens konto
 			//accounts.add(new Account("Personkonto", new BigDecimal("1485351"), "0"));
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
index 3ac40ba..b7336d4 100644
--- src/com/liato/bankdroid/BankdroidWidgetProvider.java
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -1,37 +1,130 @@
 package com.liato.bankdroid;
 
+import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProvider;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.util.Log;
 import android.widget.RemoteViews;
 
 public class BankdroidWidgetProvider extends AppWidgetProvider {
 
-    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
-        /*final int N = appWidgetIds.length;
+	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+		final int N = appWidgetIds.length;
 
         // Perform this loop procedure for each App Widget that belongs to this provider
         for (int i=0; i<N; i++) {
             int appWidgetId = appWidgetIds[i];
-
+            Log.d("Widget", "onUpdate: "+i);
             // Create an Intent to launch ExampleActivity
-            Intent intent = new Intent(context, ExampleActivity.class);
-            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+            //Intent intent = new Intent(context, ExampleActivity.class);
+            //PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
 
             // Get the layout for the App Widget and attach an on-click listener to the button
-            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
-            views.setOnClickPendingIntent(R.id.button, pendingIntent);
+            //RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
+            //views.setOnClickPendingIntent(R.id.button, pendingIntent);
 
             // Tell the AppWidgetManager to perform an update on the current App Widget
-            appWidgetManager.updateAppWidget(appWidgetId, views);
-        }*/
-    }
-    
-    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
-            int appWidgetId, AccountsAdapter.Item item) {
-        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
-        views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
-        views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
-        appWidgetManager.updateAppWidget(appWidgetId, views);
-    }    
-}
\ No newline at end of file
+            //appWidgetManager.updateAppWidget(appWidgetId, views);
+        }
+	}
+
+	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
+			int appWidgetId, AccountsAdapter.Item item) {
+		Log.d("Widget", "Widget created");
+		AccountsAdapter.Group group = item.getGroup();
+		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
+		views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
+		views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
+		views.setImageViewResource(R.id.imgWidgetIcon, context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
+
+        Intent intent = new Intent(context, LoginActivity.class);
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+        views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent);
+		appWidgetManager.updateAppWidget(appWidgetId, views);
+	}
+
+	static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
+			int appWidgetId) {
+		Log.d("BankdroidWigetProvider", "Updating widget: "+appWidgetId);
+		String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId);
+		if (accountId == null) {
+			Log.d("BankdroidWidgetProvider", "Widget not found. ID: "+appWidgetId);
+			return;
+		}
+		DBAdapter dba = new DBAdapter(context);
+		dba.open();
+		Cursor c = dba.getAccount(accountId);
+		if (c == null) {
+			Log.d("BankdroidWidgetProvider", "Account not found in db: "+accountId);
+			return;
+		}
+		int clmBalance = c.getColumnIndex("balance");
+		int clmId = c.getColumnIndex("id");
+		int clmName = c.getColumnIndex("name");
+		int clmBankId = c.getColumnIndex("bankid");
+		Double balance = c.getDouble(clmBalance);
+		String name = c.getString(clmName);
+		String id = c.getString(clmId);
+		Long bankId = c.getLong(clmBankId);
+		AccountsAdapter.Item account = new AccountsAdapter.Item(name, balance, id);
+		c = dba.getBank(bankId);
+		if (c == null) {
+			Log.d("BankdroidWidgetProvider", "Bank not found: " + bankId);
+			return;
+		}
+		
+		int clmType = c.getColumnIndex("banktype");
+		clmBalance = c.getColumnIndex("balance");
+		clmName = c.getColumnIndex("username");
+		name = c.getString(clmName);
+		String type = c.getString(clmType);
+		balance = c.getDouble(clmBalance);
+		AccountsAdapter.Group group = new AccountsAdapter.Group(name, type, balance, account);
+		account.setGroup(group);
+		c.close();
+		dba.close();
+		updateAppWidget(context, appWidgetManager,
+				appWidgetId, account);
+	}
+	
+	
+	public void onReceive(Context context, Intent intent) {
+		// v1.5 fix that doesn't call onDelete Action
+		final String action = intent.getAction();
+		if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
+			final int appWidgetId = intent.getExtras().getInt( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+			if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+				this.onDeleted(context, new int[] { appWidgetId });
+			}
+		}
+		else {
+			super.onReceive(context, intent);
+		}
+
+		
+		Log.d("BankdroidWidgetProvider", "intent=" + intent);
+		
+		if (action.equals(AutoRefreshService.WIDGET_REFRESH)) {
+            AppWidgetManager appWM = AppWidgetManager.getInstance(context);
+        	int[] appWidgetIds = appWM.getAppWidgetIds(new ComponentName(context, BankdroidWidgetProvider.class));
+        	final int N = appWidgetIds.length;
+    		for (int i = 0; i < N; i++) {
+    			int appWidgetId = appWidgetIds[i];
+    			updateAppWidget(context, appWM, appWidgetId);
+    		}
+		}
+    }	
+
+	@Override
+	public void onDeleted(Context context, int[] appWidgetIds) {
+		final int N = appWidgetIds.length;
+		for (int i = 0; i < N; i++) {
+			WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]);
+		}
+	}
+
+}
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index 27a4c4b..3b20c9f 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -173,4 +173,14 @@ public class DBAdapter {
     public Cursor getBank(long bankId) {
     	return getBank(new Long(bankId).toString());
     }
+
+    public Cursor getAccount(String id) {
+    	Cursor c = mDb.query("accounts", new String[] {"id", "balance", "name", "bankid"}, "id='"+id+"'", null, null, null, null);
+    	if (c != null) {
+    		c.moveToFirst();
+    	}
+		return c;
+    }
+    
+
 }
diff --git src/com/liato/bankdroid/DataRetrieverTask.java src/com/liato/bankdroid/DataRetrieverTask.java
new file mode 100644
index 0000000..986374e
--- /dev/null
+++ src/com/liato/bankdroid/DataRetrieverTask.java
@@ -0,0 +1,118 @@
+package com.liato.bankdroid;
+
+import java.util.ArrayList;
+
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class DataRetrieverTask extends AsyncTask<String, String, Void> {
+	private ProgressDialog dialog;
+	private Class<?> cls;
+	private ArrayList<String> errors;
+	private Bank bank;
+	private MainActivity parent;
+	private int bankcount;
+	private Resources res;
+
+	public DataRetrieverTask(MainActivity parent) {
+		this.parent = parent;
+		this.res = parent.getResources();
+		this.dialog =  new ProgressDialog(parent);
+	}
+	protected void onPreExecute() {
+		this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n ");
+		this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+		this.dialog.setCancelable(false);
+		this.dialog.show();
+	}
+
+	protected Void doInBackground(final String... args) {
+		errors = new ArrayList<String>();
+		DBAdapter db;
+		Cursor c;
+		db = new DBAdapter(parent);
+		db.open();
+		c = db.fetchBanks();
+		if (c == null) {
+			return null;
+		}
+		bankcount = c.getCount();
+		this.dialog.setMax(bankcount);
+		int clmId = c.getColumnIndex("_id");
+		int clmBanktype = c.getColumnIndex("banktype");
+		int clmBalance = c.getColumnIndex("balance");
+		int clmUsername = c.getColumnIndex("username");
+		int clmPassword = c.getColumnIndex("password");
+		int clmDisabled = c.getColumnIndex("disabled");
+		int i = 0; 
+		while (!c.isLast() && !c.isAfterLast()) {
+			c.moveToNext();
+			publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
+			if (c.getInt(clmDisabled) == 1) {
+				Log.d("AA", c.getString(clmBanktype)+" ("+c.getString(clmUsername)+") is disabled. Skipping refresh.");
+				continue;
+			}
+			Log.d("AA", "Refreshing "+c.getString(clmBanktype)+" ("+c.getString(clmUsername)+").");
+			try {				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
+				bank = (Bank) cls.newInstance();
+				bank.update(c.getString(clmUsername), c.getString(clmPassword), parent);
+				db.updateBank(bank, new Long(c.getString(clmId)));
+				i++;
+			} 
+			catch (BankException e) {
+				this.errors.add(c.getString(clmBanktype)+" ("+c.getString(clmUsername));
+				db.disableBank(c.getLong(clmId));
+			}
+			catch (ClassNotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (InstantiationException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		publishProgress(new String[] {new Integer(i).toString(), ""});
+		c.close();
+		db.close();
+		return null;
+	}
+
+	protected void onProgressUpdate(String... args) {
+		this.dialog.setProgress(new Integer(args[0]));
+		this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n"+args[1]);
+	}
+	protected void onPostExecute(final Void unused) {
+		parent.refreshView();
+		if (this.dialog.isShowing()) {
+			this.dialog.dismiss();
+		}
+		
+		if (this.errors != null && !this.errors.isEmpty()) {
+			StringBuilder errormsg = new StringBuilder();
+			errormsg.append(res.getText(R.string.accounts_were_not_updated)+":\n");
+			for (String err : errors)
+			{
+			  errormsg.append(err);
+			  errormsg.append("\n");
+			}
+			AlertDialog.Builder builder = new AlertDialog.Builder(parent);
+			builder.setMessage(errormsg.toString()).setTitle(res.getText(R.string.errors_when_updating))
+			.setIcon(android.R.drawable.ic_dialog_alert)
+			.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+				public void onClick(DialogInterface dialog, int id) {
+					dialog.cancel();
+				}
+			});
+			AlertDialog alert = builder.create();
+			alert.show();
+		}
+	}
+}	
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 2e3d137..988c104 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -15,6 +15,9 @@ public class Helpers {
 		Locale locale = new Locale("sv", "SE");
 		return NumberFormat.getCurrencyInstance(locale).format(balance).replace("kr", "SEK");
 	}
+	public static String formatBalance(Double balance) {
+		return formatBalance(new BigDecimal(balance));
+	}
 	public static String toAscii(String s) {
 		s = s.replaceAll("[åÅ]", "a").replaceAll("[äÄ]", "a").replaceAll("[öÖ]", "o").replaceAll(" ", "_");
 		s = s.replaceAll("[^a-zA-Z0-9_]", "");
diff --git src/com/liato/bankdroid/LockableActivity.java src/com/liato/bankdroid/LockableActivity.java
new file mode 100644
index 0000000..79c35f9
--- /dev/null
+++ src/com/liato/bankdroid/LockableActivity.java
@@ -0,0 +1,50 @@
+package com.liato.bankdroid;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+
+public class LockableActivity extends Activity {
+	private SharedPreferences prefs;
+	private Editor editor;
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+	}
+
+	@Override
+	protected void onPause() {
+		super.onPause();
+		if (!isProtected()) return;
+		editor = prefs.edit();
+		editor.putLong("locked_at", System.currentTimeMillis());
+		editor.commit();
+	}
+
+	@Override
+	protected void onResume() {
+		super.onResume();
+		if (!isProtected()) return;
+		long currentTime = System.currentTimeMillis();
+		long lockedAt = prefs.getLong("locked_at", currentTime-10000);
+		long timedif = currentTime - lockedAt;
+		if (timedif > 3000) {
+			Intent intent = new Intent(this, LoginActivity.class);
+			startActivity(intent);
+			finish();
+		}
+	}
+	
+	private boolean isProtected() {
+		String access_code = prefs.getString("access_code", "");
+		if (access_code.length() > 0) return true;
+		return false;
+		
+	}
+
+}
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 94ba009..241c8db 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -4,15 +4,11 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 
-import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.ProgressDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.res.Resources;
 import android.database.Cursor;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -26,7 +22,7 @@ import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
-public class MainActivity extends Activity {
+public class MainActivity extends LockableActivity {
 	/** Called when the activity is first created. */
 	private DBAdapter dba;
 
@@ -48,7 +44,7 @@ public class MainActivity extends Activity {
 		refreshView();
 	}
 
-	private void refreshView() {
+	public void refreshView() {
 		dba = new DBAdapter(this);
 		dba.open();
 		Cursor curBanks = dba.fetchBanks();
@@ -89,6 +85,7 @@ public class MainActivity extends Activity {
 		}
 		curBanks.close();
 		dba.close();
+		AutoRefreshService.sendWidgetRefresh(this);
 	}
 	public boolean onCreateOptionsMenu(Menu menu) {
 		super.onCreateOptionsMenu(menu);
@@ -221,105 +218,7 @@ public class MainActivity extends Activity {
 		}		
 	}
 
-	private class DataRetrieverTask extends AsyncTask<String, String, Void> {
-		private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
-		private Class<?> cls;
-		private ArrayList<String> errors;
-		private Bank bank;
-		private MainActivity parent;
-		private int bankcount;
-		private Resources res;
 
-		public DataRetrieverTask(MainActivity parent) {
-			this.parent = parent;
-			this.res = parent.getResources();
-		}
-		protected void onPreExecute() {
-			this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n ");
-			this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-			this.dialog.setCancelable(false);
-			this.dialog.show();
-		}
-
-		protected Void doInBackground(final String... args) {
-			errors = new ArrayList<String>();
-			DBAdapter db;
-			Cursor c;
-			db = new DBAdapter(parent);
-			db.open();
-			c = db.fetchBanks();
-			if (c == null) {
-				return null;
-			}
-			bankcount = c.getCount();
-			this.dialog.setMax(bankcount);
-			int clmId = c.getColumnIndex("_id");
-			int clmBanktype = c.getColumnIndex("banktype");
-			int clmBalance = c.getColumnIndex("balance");
-			int clmUsername = c.getColumnIndex("username");
-			int clmPassword = c.getColumnIndex("password");
-			int i = 0; 
-			while (!c.isLast() && !c.isAfterLast()) {
-				c.moveToNext();
-				publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
-				try {
-					cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
-					bank = (Bank) cls.newInstance();
-					bank.update(c.getString(clmUsername), c.getString(clmPassword), parent);
-					db.updateBank(bank, new Long(c.getString(clmId)));
-					i++;
-				} 
-				catch (BankException e) {
-					this.errors.add(c.getString(clmBanktype)+" ("+c.getString(clmUsername));
-				}
-				catch (ClassNotFoundException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				} catch (IllegalAccessException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				} catch (InstantiationException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			}
-			publishProgress(new String[] {new Integer(i).toString(), ""});
-			c.close();
-			db.close();
-			return null;
-		}
-
-		protected void onProgressUpdate(String... args) {
-			this.dialog.setProgress(new Integer(args[0]));
-			this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n"+args[1]);
-		}
-		protected void onPostExecute(final Void unused) {
-			parent.refreshView();
-			if (this.dialog.isShowing()) {
-				this.dialog.dismiss();
-			}
-			
-			if (this.errors != null && !this.errors.isEmpty()) {
-				StringBuilder errormsg = new StringBuilder();
-				errormsg.append(res.getText(R.string.accounts_were_not_updated)+":\n");
-				for (String err : errors)
-				{
-				  errormsg.append(err);
-				  errormsg.append("\n");
-				}
-				AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
-				builder.setMessage(errormsg.toString()).setTitle(res.getText(R.string.errors_when_updating))
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
-						dialog.cancel();
-					}
-				});
-				AlertDialog alert = builder.create();
-				alert.show();
-			}
-		}
-	}	
 	
 	private class Group {
 		private String name;
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
index 7475d7e..00e31b0 100644
--- src/com/liato/bankdroid/SettingsActivity.java
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -1,7 +1,7 @@
 package com.liato.bankdroid;
 
 import java.util.ArrayList;
-import android.app.Activity;
+
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.os.Bundle;
@@ -10,12 +10,14 @@ import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
 import android.widget.EditText;
 import android.widget.Spinner;
 import android.widget.AdapterView.OnItemSelectedListener;
 
-public class SettingsActivity extends Activity implements OnClickListener, OnItemSelectedListener {
+public class SettingsActivity extends LockableActivity implements OnClickListener, OnItemSelectedListener {
 	private SharedPreferences prefs;
+	private Integer refreshrate;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
@@ -23,46 +25,34 @@ public class SettingsActivity extends Activity implements OnClickListener, OnIte
 		setContentView(R.layout.settings);
 		prefs = PreferenceManager.getDefaultSharedPreferences(this);
 		ArrayList<Pair<String, Integer>> items = new ArrayList<Pair<String, Integer>>();
-		items.add(new Pair<String, Integer>("Disabled", -1));
-		items.add(new Pair<String, Integer>("15 minutes", 10));
-		items.add(new Pair<String, Integer>("30 minutes", 30));
-		items.add(new Pair<String, Integer>("1 hour", 60));
-		items.add(new Pair<String, Integer>("2 hours", 60*2));
-		items.add(new Pair<String, Integer>("4 hours", 60*4));
-		items.add(new Pair<String, Integer>("8 hours", 60*8));
+		items.add(new Pair<String, Integer>(getString(R.string.disabled), -1));
+		items.add(new Pair<String, Integer>("15 "+getString(R.string.minutes), 15));
+		items.add(new Pair<String, Integer>("30 "+getString(R.string.minutes), 30));
+		items.add(new Pair<String, Integer>("1 "+getString(R.string.hour), 60));
+		items.add(new Pair<String, Integer>("2 "+getString(R.string.hours), 60*2));
+		items.add(new Pair<String, Integer>("4 "+getString(R.string.hours), 60*4));
+		items.add(new Pair<String, Integer>("8 "+getString(R.string.hours), 60*8));
+		items.add(new Pair<String, Integer>("16 "+getString(R.string.hours), 60*16));
+		items.add(new Pair<String, Integer>(getString(R.string.daily), 60*24));
 
 		Spinner spnFrequency = (Spinner)findViewById(R.id.spnUpdateFrequency);
 		ArrayAdapter<Pair<String, Integer>> adapter = new ArrayAdapter<Pair<String, Integer>>(this,
 				android.R.layout.simple_spinner_item, items);
 		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 		spnFrequency.setAdapter(adapter);
+		int refreshrate = prefs.getInt("refreshrate", -1);
+		for (int i = 0; i < items.size(); i++) {
+			if (items.get(i).getValue() == refreshrate) {
+				spnFrequency.setSelection(i);
+				break;
+			}
+			
+		}
 		spnFrequency.setOnItemSelectedListener(this);
 
 		findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
 		findViewById(R.id.btnSettingsOk).setOnClickListener(this);
-		
-
-		((EditText)findViewById(R.id.edtAccessCode)).setText(prefs.getString("access_code", ""));
-		//Resources r = getResources();
-
-		/*Bundle extras = getIntent().getExtras(); 
-		if (extras != null) {
-			BANKID = extras.getString("id");
-			if (BANKID != null) {
-				DBAdapter db = new DBAdapter(this);
-				db.open();
-				Cursor c = db.getBank(BANKID);
-				if (c != null) {
-					((EditText)findViewById(R.id.edtBankeditUsername)).setText(c.getString(c.getColumnIndex("username")));
-					((EditText)findViewById(R.id.edtBankeditPassword)).setText(c.getString(c.getColumnIndex("password")));
-					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
-					int i = items.indexOf(SELECTED_BANK);
-					spnBanks.setSelection(i);
-					c.close();
-				}
-				db.close();
-			}
-		}*/
+		findViewById(R.id.chkNotifyOnChange).setOnClickListener(this);
 	}
 	
 	private class Pair<T, S> {
@@ -94,96 +84,41 @@ public class SettingsActivity extends Activity implements OnClickListener, OnIte
 		else if (v.getId() == R.id.btnSettingsOk){
 			Editor editor = prefs.edit();
 			editor.putString("access_code", ((EditText)findViewById(R.id.edtAccessCode)).getText().toString());
+			editor.putBoolean("notify_on_change", ((CheckBox)findViewById(R.id.chkNotifyOnChange)).isChecked());
+			editor.putBoolean("notify_with_sound", ((CheckBox)findViewById(R.id.chkWithSound)).isChecked());
+			editor.putBoolean("notify_with_vibration", ((CheckBox)findViewById(R.id.chkWithVibration)).isChecked());
+			editor.putInt("refreshrate", refreshrate);
 			editor.commit();
+			StartupReceiver.setAlarm(this);
 			this.finish();
-			//new DataRetrieverTask(this).execute(SELECTED_BANK, ((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim(), ((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+		}
+		else if (v.getId() == R.id.chkNotifyOnChange) {
+			findViewById(R.id.chkWithSound).setEnabled(((CheckBox)v).isChecked());
+			findViewById(R.id.chkWithVibration).setEnabled(((CheckBox)v).isChecked());
 		}
 
 	}
 
 	@Override
 	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
-		//SELECTED_BANK = parentView.getItemAtPosition(pos).toString();
+		Pair<String, Integer> pair = (Pair<String, Integer>)parentView.getItemAtPosition(pos);
+		refreshrate = pair.getValue();
 	}
-
+	
+	
 	@Override
 	public void onNothingSelected(AdapterView<?> arg) {
 	}
-
-	/*private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
-		private final ProgressDialog dialog = new ProgressDialog(SettingsActivity.this);
-		private Class<?> cls;
-		private Exception exc = null;
-		private Bank bank;
-		private SettingsActivity parent;
-		private Resources res;
-
-		public DataRetrieverTask(SettingsActivity parent) {
-			this.parent = parent;
-			this.res = parent.getResources();
-			
-		}
-		protected void onPreExecute() {
-			this.dialog.setMessage(res.getText(R.string.logging_in));
-			this.dialog.show();
-		}
-
-		protected Void doInBackground(final String... args) {
-			try {
-				cls = Class.forName("com.liato.bankdroid.Bank"+args[0]);
-				bank = (Bank) cls.newInstance();
-				bank.update(args[1], args[2]);
-				DBAdapter dba = new DBAdapter(SettingsActivity.this);
-				dba.open();
-				if (BANKID != null) {
-					dba.updateBank(bank, new Long(BANKID));
-				}
-				else {
-					dba.createBank(bank);
-				}
-				dba.close();
-			} 
-			catch (BankException e) {
-				this.exc = e;
-			}
-			catch (ClassNotFoundException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (InstantiationException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-			return null;
-		}
-
-		protected void onPostExecute(final Void unused) {
-			if (this.dialog.isShowing()) {
-				this.dialog.dismiss();
-			}
-			if (this.exc != null) {
-				AlertDialog.Builder builder = new AlertDialog.Builder(SettingsActivity.this);
-				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
-				.setIcon(android.R.drawable.ic_dialog_alert)
-				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
-					public void onClick(DialogInterface dialog, int id) {
-						dialog.cancel();
-					}
-				});
-				AlertDialog alert = builder.create();
-				alert.show();
-			}
-			else {
-				parent.finish();
-			}
-		}
-	}*/
 	
 	@Override
 	protected void onResume() {
 		super.onResume();
+		((EditText)findViewById(R.id.edtAccessCode)).setText(prefs.getString("access_code", ""));
+		((CheckBox)findViewById(R.id.chkNotifyOnChange)).setChecked(prefs.getBoolean("notify_on_change", true));
+		((CheckBox)findViewById(R.id.chkWithSound)).setChecked(prefs.getBoolean("notify_with_sound", true));
+		((CheckBox)findViewById(R.id.chkWithSound)).setEnabled(prefs.getBoolean("notify_on_change", true));
+		((CheckBox)findViewById(R.id.chkWithVibration)).setChecked(prefs.getBoolean("notify_with_vibration", true));
+		((CheckBox)findViewById(R.id.chkWithVibration)).setEnabled(prefs.getBoolean("notify_on_change", true));
 	}
 
 	@Override
diff --git src/com/liato/bankdroid/StartupReceiver.java src/com/liato/bankdroid/StartupReceiver.java
new file mode 100644
index 0000000..aea19e5
--- /dev/null
+++ src/com/liato/bankdroid/StartupReceiver.java
@@ -0,0 +1,42 @@
+package com.liato.bankdroid;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.SystemClock;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.widget.Toast;
+
+public class StartupReceiver extends BroadcastReceiver{
+	@Override
+	public void onReceive(Context context, Intent intent) {
+		//Intent serviceIntent = new Intent();
+		//serviceIntent.setAction("AutoRefreshService");
+		//Log.d("","starting service");
+		//context.startService(serviceIntent);
+		setAlarm(context);
+	}
+	
+	public static void setAlarm(Context context) {
+		PendingIntent alarmSender;
+		alarmSender = PendingIntent.getService(context, 0, new Intent(context, AutoRefreshService.class), 0);
+		
+		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+		Integer refreshrate = prefs.getInt("refreshrate", -1);
+        AlarmManager am = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
+        if (refreshrate < 0) {
+        	am.cancel(alarmSender);
+        	Log.d("","Alarm disabled.");
+        }
+        else {
+	        long firstTime = SystemClock.elapsedRealtime();
+	        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime+refreshrate*1000, refreshrate*1000, alarmSender);
+        	Log.d("","Alarm set to "+refreshrate.toString()+" minutes.");
+        }
+	
+	}
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
index e98ee06..39ef7cc 100644
--- src/com/liato/bankdroid/WidgetConfigureActivity.java
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -50,9 +50,8 @@ public class WidgetConfigureActivity extends Activity {
 				
 	            final Context context = WidgetConfigureActivity.this;
 	            AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
-	            SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
-	            prefs.putString(WIDGET_PREFIX + mAppWidgetId, item.getId());
-	            prefs.commit();
+
+	            WidgetConfigureActivity.setAccountId(context, mAppWidgetId, item.getId());
 
 	            // Push widget update to surface with newly set prefix
 	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
@@ -73,7 +72,25 @@ public class WidgetConfigureActivity extends Activity {
 		super.onResume();
 		refreshView();
 	}
+	
+	public static String getAccountId(Context context, int appWidgetId) {
+		SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0);
+		return prefs.getString(WIDGET_PREFIX + appWidgetId, null);
+	}
+
+	public static void setAccountId(Context context, int appWidgetId, String value) {
+        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+        prefs.putString(WIDGET_PREFIX + appWidgetId, value);
+        prefs.commit();
+	}
 
+	public static void delAccountId(Context context, int appWidgetId) {
+        SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+        prefs.remove(WIDGET_PREFIX + appWidgetId);
+        prefs.commit();
+	}
+	
+	
 	private void refreshView() {
 		dba = new DBAdapter(this);
 		dba.open();

commit 8c4a7aba9ad42640ea17f9460c3aa870a09d1a37
Author: liato <x@x00.us>
Date:   Wed May 26 00:50:05 2010 +0200

    Updated gitignore

diff --git .gitignore .gitignore
index af9564f..0d88f61 100644
--- .gitignore
+++ .gitignore
@@ -13,4 +13,5 @@ Desktop.ini
 bin
 gen
 local.properties
-*.jar
\ No newline at end of file
+*.jar
+dev/
\ No newline at end of file
diff --git README.rst README.rst
index 9c0069d..7ac9f97 100644
--- README.rst
+++ README.rst
@@ -1 +1 @@
-Don't look at me!
+Bankdroid is a an application for android devices... Swedbank, Nordea and ICA Banken.
\ No newline at end of file

commit 2af11061e4ab513052c7830a57559ee49a8a07a2
Author: liato <x@x00.us>
Date:   Sun May 23 15:41:11 2010 +0200

    Fixed lansforsakringar, hopefully.

diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/BankLansforsakringar.java
index 2322ae3..5109d27 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -27,8 +27,9 @@ public class BankLansforsakringar implements Bank {
 	private Banks banktype = Banks.LANSFORSAKRINGAR;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reBalance = Pattern.compile("<a.+?DataTable1:(\\d+):account[^>]+>([^<]+)</a>.+?<spa.+?>([0-9 -,.]+)</span></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalance = Pattern.compile("<a.+?DataTable1:(\\d+):account[^>]+>([^<]+)</a>.+?<spa.+?>.+?</span></td>.*?<spa.+?>(.+?)</span></td>", Pattern.CASE_INSENSITIVE);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
+	private Pattern reUrl = Pattern.compile("<li class=\"bank\">\\s*<a href=\"([^\"]+)\"", Pattern.CASE_INSENSITIVE);
 	
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
@@ -92,7 +93,12 @@ public class BankLansforsakringar implements Bank {
 			}
 			String token = matcher.group(1);
 
-			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&newUc=true&isTopLevel=true&_token="+token);
+			matcher = reUrl.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" accounts url.");
+			}
+			String accurl = Html.fromHtml(matcher.group(1)).toString(); 
+			urlopen.open(accurl+"&_token="+token);
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));

commit 60a12f4a6960050b7cb2f7322c8ebaf4b0616a20
Author: liato <x@x00.us>
Date:   Sat May 22 16:07:10 2010 +0200

    Use token on requests to lansforsakringar.

diff --git AndroidManifest.xml AndroidManifest.xml
index 25d7abf..e7f8d03 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.0.4" android:versionCode="9">
+	package="com.liato.bankdroid" android:versionName="1.0.4" android:versionCode="10">
 	<application android:icon="@drawable/icon" android:label="@string/app_name">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"
diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/BankLansforsakringar.java
index a00766d..2322ae3 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -27,7 +27,6 @@ public class BankLansforsakringar implements Bank {
 	private Banks banktype = Banks.LANSFORSAKRINGAR;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reError = Pattern.compile("ErrMessage.+?>([^<]+)",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reBalance = Pattern.compile("<a.+?DataTable1:(\\d+):account[^>]+>([^<]+)</a>.+?<spa.+?>([0-9 -,.]+)</span></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	
@@ -79,15 +78,21 @@ public class BankLansforsakringar implements Bank {
 			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
 			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
 			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
-			
+			postData.add(new BasicNameValuePair("btnLogIn.x", "12"));
+			postData.add(new BasicNameValuePair("btnLogIn.y", "34"));			
 			response = urlopen.open(urlopen.getCurrentURI(), postData);
 			
-			matcher = reError.matcher(response);
-			if (matcher.find()) {
+			if (response.contains("Felaktig inloggning")) {
 				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
 
-			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&newUc=true&isTopLevel=true");
+			matcher = reToken.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" token.");
+			}
+			String token = matcher.group(1);
+
+			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&newUc=true&isTopLevel=true&_token="+token);
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index 8d922e7..e677c19 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -73,6 +73,9 @@ public class BankNordea implements Bank {
 			while (matcherAccounts.find() && matcherBalance.find()) {
 				accounts.add(new Account(Html.fromHtml(matcherAccounts.group(2)).toString(), Helpers.parseBalance(matcherBalance.group(1)), matcherAccounts.group(2).trim()));
 			}
+			// Konungens konto
+			//accounts.add(new Account("Personkonto", new BigDecimal("568269.37"), "1"));
+			//accounts.add(new Account("Kapitalkonto", new BigDecimal("25789000.00"), "1"));
 		} catch (ClientProtocolException e) {
 			e.printStackTrace();
 		} catch (IOException e) {
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index 9e0958b..a6284b8 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -71,6 +71,9 @@ public class BankSwedbank implements Bank {
 			while (matcher.find()) {
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 			}
+			// Konungens konto
+			//accounts.add(new Account("Personkonto", new BigDecimal("1485351"), "0"));
+			//accounts.add(new Account("Sparkonto", new BigDecimal("8590700"), "1"));
 		} catch (ClientProtocolException e) {
 			e.printStackTrace();
 		} catch (IOException e) {

commit 3468cc80db1cc13feb15883b8966716f7a15b9ac
Author: liato <x@x00.us>
Date:   Fri May 21 07:01:28 2010 +0200

    Completed english translation.

diff --git res/values/strings.xml res/values/strings.xml
index 13c592f..9cea6b6 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -31,7 +31,7 @@
 	<string name="pin_desc">Enter an access code if you want to password protect the application and widgets.</string>
 	<string name="notify_on_change">Notify on changes</string>
 	
-    <string name="login">Logga in</string>
-    <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
+    <string name="login">Login</string>
+    <string name="invalid_access_code">Invalid access code. Try again.</string>
 	    
 </resources>

commit 45ddd8646c430d74043a5c32a0d3612ee6296afc
Author: liato <x@x00.us>
Date:   Fri May 21 06:58:31 2010 +0200

    Added english localization.

diff --git res/menu/menu.xml res/menu-sv/menu.xml
similarity index 100%
copy from res/menu/menu.xml
copy to res/menu-sv/menu.xml
diff --git res/menu/menu.xml res/menu/menu.xml
index 00d8188..71d8be9 100644
--- res/menu/menu.xml
+++ res/menu/menu.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
-	<item android:id="@+id/accounts" android:title="Konton" android:icon="@android:drawable/ic_menu_agenda"/>
-	<item android:id="@+id/settings" android:title="Inställningar" android:icon="@android:drawable/ic_menu_preferences"/>
-	<item android:id="@+id/about" android:title="Om" android:icon="@android:drawable/ic_menu_info_details" />
-	<item android:id="@+id/exit" android:title="Avsluta" android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+	<item android:id="@+id/accounts" android:title="Accounts" android:icon="@android:drawable/ic_menu_agenda"/>
+	<item android:id="@+id/settings" android:title="Settings" android:icon="@android:drawable/ic_menu_preferences"/>
+	<item android:id="@+id/about" android:title="About" android:icon="@android:drawable/ic_menu_info_details" />
+	<item android:id="@+id/exit" android:title="Exit" android:icon="@android:drawable/ic_menu_close_clear_cancel" />
 </menu>
\ No newline at end of file
diff --git res/values/strings.xml res/values-sv/strings.xml
similarity index 87%
copy from res/values/strings.xml
copy to res/values-sv/strings.xml
index be2606b..bba8df5 100644
--- res/values/strings.xml
+++ res/values-sv/strings.xml
@@ -1,14 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="app_name">Bankdroid</string>
-    <string name="acounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
+    
+    <string name="accounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
     <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
-    <string name="errors_when_updating">Fel vid uppdatering"</string>
+    <string name="errors_when_updating">Fel vid uppdatering</string>
     <string name="logging_in">Loggar in...</string>
     <string name="could_not_create_account">Kunde ej skapa konto</string>
     <string name="menu_edit">Redigera</string>
     <string name="menu_remove">Radera</string>
     <string name="invalid_username_password">Personnummer och lösenord stämmer ej.</string>
+    <string name="unable_to_find">Kunde ej hitta</string>
     
     <string name="username">Personnummer</string>
     <string name="password">Lösenord</string>
diff --git res/values/strings.xml res/values/strings.xml
index be2606b..13c592f 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,34 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="app_name">Bankdroid</string>
-    <string name="acounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
-    <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
-    <string name="errors_when_updating">Fel vid uppdatering"</string>
-    <string name="logging_in">Loggar in...</string>
-    <string name="could_not_create_account">Kunde ej skapa konto</string>
-    <string name="menu_edit">Redigera</string>
-    <string name="menu_remove">Radera</string>
-    <string name="invalid_username_password">Personnummer och lösenord stämmer ej.</string>
+    <string name="accounts_were_not_updated">Balance for the following accounts could not be updated</string>
+    <string name="updating_account_balance">Refreshing account balance...</string>
+    <string name="errors_when_updating">Errors while refreshing</string>
+    <string name="logging_in">Signing in...</string>
+    <string name="could_not_create_account">Could not create account</string>
+    <string name="menu_edit">Edit</string>
+    <string name="menu_remove">Remove</string>
+    <string name="invalid_username_password">Invalid username or password.</string>
+    <string name="unable_to_find">Unable to find</string>
     
-    <string name="username">Personnummer</string>
-    <string name="password">Lösenord</string>
+    <string name="username">Username</string>
+    <string name="password">Password</string>
     <string name="bank">Bank</string>
 
-    <string name="cancel">Avbryt</string>
-    <string name="save">Spara</string>
+    <string name="cancel">Cancel</string>
+    <string name="save">Save</string>
     
-	<string name="add_new_account">Lägg till ett nytt bankkonto</string>
-	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
+	<string name="add_new_account">Add new bank account</string>
+	<string name="banks_instructions">You have not added any bank accounts yet. Press the button to add a new account.</string>
 	
-	<string name="main_instructions">Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto.</string>
-	<string name="refresh_balance">Uppdatera saldoinformation</string>
+	<string name="main_instructions">You have not added any bank accounts yet, press the "Accounts" button in the menu to add a new account.</string>
+	<string name="refresh_balance">Refresh account balance</string>
 
-	<string name="choose_an_account">Välj ett konto</string>
+	<string name="choose_an_account">Choose an account</string>
 	
-	<string name="update_frequency">Uppdateringsfrekvens</string>
-	<string name="access_code">PIN-kod</string>
-	<string name="pin_desc">Ange en PIN-kod om du vill lösenordsskydda applikationen och tillhörande widgets.</string>
-	<string name="notify_on_change">Notifiera vid kontohändelser</string>
+	<string name="update_frequency">Update frequency</string>
+	<string name="access_code">Access code</string>
+	<string name="pin_desc">Enter an access code if you want to password protect the application and widgets.</string>
+	<string name="notify_on_change">Notify on changes</string>
 	
     <string name="login">Logga in</string>
     <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index 4ce2fa1..c0d3583 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -104,7 +104,7 @@ public class AccountActivity extends Activity implements OnClickListener, OnItem
 			try {
 				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(args[0]));
 				bank = (Bank) cls.newInstance();
-				bank.update(args[1], args[2]);
+				bank.update(args[1], args[2], parent);
 				DBAdapter dba = new DBAdapter(AccountActivity.this);
 				dba.open();
 				if (BANKID != null) {
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
index 36df4e2..de0658f 100644
--- src/com/liato/bankdroid/Bank.java
+++ src/com/liato/bankdroid/Bank.java
@@ -3,6 +3,8 @@ package com.liato.bankdroid;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 
+import android.content.Context;
+
 public interface Bank {
 	ArrayList<Account> getAccounts();
 	String getUsername();
@@ -10,5 +12,5 @@ public interface Bank {
 	Banks getType();
 	BigDecimal getBalance();
 	void update() throws BankException;
-	void update(String username, String password) throws BankException;
+	void update(String username, String password, Context context) throws BankException;
 }
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
index 63278c7..a4836ff 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankICA.java
@@ -11,13 +11,15 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
+import android.content.Context;
+import android.content.res.Resources;
 import android.text.Html;
-import android.util.Log;
-
 import com.liato.urllib.Urllib;
 
 public class BankICA implements Bank {
 
+	private Context context;
+	private Resources res;
 	private String username;
 	private String password;
 	private Banks banktype = Banks.ICA;
@@ -32,18 +34,21 @@ public class BankICA implements Bank {
 	public BankICA() {
 	}
 
-	public BankICA(String username, String password) throws BankException {
-		this.update(username, password);
+	public BankICA(String username, String password, Context context) throws BankException {
+		this.update(username, password, context);
 	}
 
-	public void update(String username, String password) throws BankException {
+	public void update(String username, String password, Context context) throws BankException {
+		this.context = context;
+		this.res = this.context.getResources();
+
 		this.username = username;
 		this.password = password;
 		this.update();
 	}
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("Personnummer och lösenord stämmer ej.");//res.getText(R.string.invalid_username_password));
+			throw new BankException(res.getText(R.string.invalid_username_password).toString());
 		}
 
 		Urllib urlopen = new Urllib();
@@ -53,12 +58,12 @@ public class BankICA implements Bank {
 			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx");
 			matcher = reViewState.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse data.");
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" viewstate.");
 			}
 			String strViewState = matcher.group(1);
 			matcher = reEventValidation.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse data.");
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" eventvalidation.");
 			}
 			String strEventValidation = matcher.group(1);
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
diff --git src/com/liato/bankdroid/BankLansforsakringar.java src/com/liato/bankdroid/BankLansforsakringar.java
index 8ab67f0..a00766d 100644
--- src/com/liato/bankdroid/BankLansforsakringar.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -11,6 +11,8 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
+import android.content.Context;
+import android.content.res.Resources;
 import android.text.Html;
 import android.util.Log;
 
@@ -18,6 +20,8 @@ import com.liato.urllib.Urllib;
 
 public class BankLansforsakringar implements Bank {
 
+	private Context context;
+	private Resources res;
 	private String username;
 	private String password;
 	private Banks banktype = Banks.LANSFORSAKRINGAR;
@@ -33,18 +37,21 @@ public class BankLansforsakringar implements Bank {
 	public BankLansforsakringar() {
 	}
 
-	public BankLansforsakringar(String username, String password) throws BankException {
-		this.update(username, password);
+	public BankLansforsakringar(String username, String password, Context context) throws BankException {
+		this.update(username, password, context);
 	}
 
-	public void update(String username, String password) throws BankException {
+	public void update(String username, String password, Context context) throws BankException {
+		this.context = context;
+		this.res = this.context.getResources();
+
 		this.username = username;
 		this.password = password;
 		this.update();
 	}
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("Personnummer och lösenord stämmer ej.");//res.getText(R.string.invalid_username_password));
+			throw new BankException(res.getText(R.string.invalid_username_password).toString());
 		}
 
 		Urllib urlopen = new Urllib();
@@ -54,19 +61,15 @@ public class BankLansforsakringar implements Bank {
 			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
 			matcher = reViewState.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse ViewState.");
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" ViewState.");
 			}
 			String strViewState = matcher.group(1);
 			matcher = reEventValidation.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse EventValidation.");
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" EventValidation.");
 			}
 			String strEventValidation = matcher.group(1);
 			
-			matcher = reEventValidation.matcher(response);
-			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse EventValidation.");
-			}			
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
 			postData.add(new BasicNameValuePair("inputPersonalNumber", username));
 			postData.add(new BasicNameValuePair("inputPinCode", password));
@@ -81,7 +84,7 @@ public class BankLansforsakringar implements Bank {
 			
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
-				throw new BankException("Personnummer och lösenord stämmer ej.");
+				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
 
 			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&newUc=true&isTopLevel=true");
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index f726ae1..8d922e7 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -11,11 +11,15 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
+import android.content.Context;
+import android.content.res.Resources;
 import android.text.Html;
 import com.liato.urllib.Urllib;
 
 public class BankNordea implements Bank {
 
+	private Context context;
+	private Resources res;
 	private String username;
 	private String password;
 	private Banks banktype = Banks.NORDEA;
@@ -29,18 +33,21 @@ public class BankNordea implements Bank {
 	public BankNordea() {
 	}
 
-	public BankNordea(String username, String password) throws BankException {
-		this.update(username, password);
+	public BankNordea(String username, String password, Context context) throws BankException {
+		this.update(username, password, context);
 	}
 
-	public void update(String username, String password) throws BankException {
+	public void update(String username, String password, Context context) throws BankException {
+		this.context = context;
+		this.res = this.context.getResources();
+		
 		this.username = username;
 		this.password = password;
 		this.update();
 	}
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("Personnummer och l�senord st�mmer ej.");
+			throw new BankException(res.getText(R.string.invalid_username_password).toString());
 		}
 		Urllib urlopen = new Urllib();
 		String response = null;
@@ -57,7 +64,7 @@ public class BankNordea implements Bank {
 			response = urlopen.open("https://gfs.nb.se/bin2/gfskod", postData);
 
 			if (!response.contains("reDirect")) {
-				throw new BankException("Personnummer och lösenord stämmer ej.");
+				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
 
 			response = urlopen.open("https://gfs.nb.se/bin2/gfskod?OBJECT=KF00T&show_button=No");
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index 353103a..9e0958b 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -11,11 +11,15 @@ import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
+import android.content.Context;
+import android.content.res.Resources;
 import android.text.Html;
 import com.liato.urllib.Urllib;
 
 public class BankSwedbank implements Bank {
-
+	
+	private Context context;
+	private Resources res;
 	private String username;
 	private String password;
 	private Banks banktype = Banks.SWEDBANK;
@@ -25,14 +29,16 @@ public class BankSwedbank implements Bank {
 	private BigDecimal balance = new BigDecimal(0);
 
 	public BankSwedbank() {
-
 	}
 
-	public BankSwedbank(String username, String password) throws BankException {
-		this.update(username, password);
+	public BankSwedbank(String username, String password, Context context) throws BankException {
+		this.update(username, password, context);
 	}
 
-	public void update(String username, String password) throws BankException {
+	public void update(String username, String password, Context context) throws BankException {
+		this.context = context;
+		this.res = this.context.getResources();
+		
 		this.username = username;
 		this.password = password;
 		this.update();
@@ -40,7 +46,7 @@ public class BankSwedbank implements Bank {
 
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("Personnummer och l�senord st�mmer ej.");
+			throw new BankException(res.getText(R.string.invalid_username_password).toString());
 		}        Urllib urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
@@ -48,7 +54,7 @@ public class BankSwedbank implements Bank {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
 			matcher = reCSRF.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect. CSRF token was not found.");
+				throw new BankException(res.getText(R.string.unable_to_find).toString()+" CSRF token.");
 			}
 			String csrftoken = matcher.group(1);
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
@@ -58,7 +64,7 @@ public class BankSwedbank implements Bank {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
 
 			if (response.contains("misslyckats")) {
-				throw new BankException("Personnummer och l�senord st�mmer ej.");
+				throw new BankException(res.getText(R.string.invalid_username_password).toString());
 			}
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
 			matcher = reAccounts.matcher(response);
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index b0cd895..94ba009 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -265,7 +265,7 @@ public class MainActivity extends Activity {
 				try {
 					cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
 					bank = (Bank) cls.newInstance();
-					bank.update(c.getString(clmUsername), c.getString(clmPassword));
+					bank.update(c.getString(clmUsername), c.getString(clmPassword), parent);
 					db.updateBank(bank, new Long(c.getString(clmId)));
 					i++;
 				} 
@@ -301,7 +301,7 @@ public class MainActivity extends Activity {
 			
 			if (this.errors != null && !this.errors.isEmpty()) {
 				StringBuilder errormsg = new StringBuilder();
-				errormsg.append(res.getText(R.string.acounts_were_not_updated)+":\n");
+				errormsg.append(res.getText(R.string.accounts_were_not_updated)+":\n");
 				for (String err : errors)
 				{
 				  errormsg.append(err);

commit b254fb51807bbfd5eb4fe5c66be90316de5a421f
Author: liato <x@x00.us>
Date:   Fri May 21 01:59:43 2010 +0200

    Bump version.

diff --git AndroidManifest.xml AndroidManifest.xml
index d35e698..25d7abf 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.0.3" android:versionCode="8">
+	package="com.liato.bankdroid" android:versionName="1.0.4" android:versionCode="9">
 	<application android:icon="@drawable/icon" android:label="@string/app_name">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".LoginActivity"

commit e59f76ea2b777cc8d6fc1c1fe0e5d5bf522c7488
Author: liato <x@x00.us>
Date:   Fri May 21 01:58:38 2010 +0200

    Added untested support for Lansforsakringar.

diff --git logos.psd logos.psd
index 0a75234..719f812 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/lansforsakringar.png res/drawable/lansforsakringar.png
new file mode 100644
index 0000000..8498a63
Binary files /dev/null and res/drawable/lansforsakringar.png differ
diff --git res/xml/appwidget_info.xml res/xml/appwidget_info.xml
new file mode 100644
index 0000000..1729ee9
--- /dev/null
+++ res/xml/appwidget_info.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="146dp"
+    android:minHeight="72dp"
+    android:updatePeriodMillis="0"
+    android:initialLayout="@layout/widget"
+    android:configure="com.liato.bankdroid.WidgetConfigureActivity" >
+</appwidget-provider>
\ No newline at end of file
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index 54340a9..4ce2fa1 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -102,7 +102,7 @@ public class AccountActivity extends Activity implements OnClickListener, OnItem
 
 		protected Void doInBackground(final String... args) {
 			try {
-				cls = Class.forName("com.liato.bankdroid.Bank"+args[0]);
+				cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(args[0]));
 				bank = (Bank) cls.newInstance();
 				bank.update(args[1], args[2]);
 				DBAdapter dba = new DBAdapter(AccountActivity.this);
diff --git src/com/liato/bankdroid/AccountsActivity.java src/com/liato/bankdroid/AccountsActivity.java
index 54f0ceb..260d656 100644
--- src/com/liato/bankdroid/AccountsActivity.java
+++ src/com/liato/bankdroid/AccountsActivity.java
@@ -112,7 +112,7 @@ public class AccountsActivity extends Activity {
 			ImageView icon = (ImageView)view.findViewById(R.id.imgListitemBanks);
 			((TextView)view.findViewById(R.id.txtListitemAccountname)).setText(cursor.getString(cursor.getColumnIndex("username")));
 			((TextView)view.findViewById(R.id.txtListitemBankname)).setText(cursor.getString(cursor.getColumnIndex("banktype")));
-			icon.setImageResource(getResources().getIdentifier("drawable/"+cursor.getString(cursor.getColumnIndex("banktype")).toLowerCase(), null, getPackageName()));
+			icon.setImageResource(getResources().getIdentifier("drawable/"+Helpers.toAscii(cursor.getString(cursor.getColumnIndex("banktype")).toLowerCase()), null, getPackageName()));
 			view.setTag(cursor.getInt(cursor.getColumnIndex("_id")));
 		}
 
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
index 3f8127a..4329c4d 100644
--- src/com/liato/bankdroid/AccountsAdapter.java
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -32,7 +32,7 @@ public class AccountsAdapter extends BaseAdapter {
 		((TextView)v.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getName());
 		((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
 		((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
-		icon.setImageResource(context.getResources().getIdentifier("drawable/"+group.getType().toLowerCase(), null, context.getPackageName()));
+		icon.setImageResource(context.getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, context.getPackageName()));
 		return v;
 	}
 
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
index 66561a5..63278c7 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankICA.java
@@ -77,7 +77,6 @@ public class BankICA implements Bank {
 			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
-				Log.d("BankICA", "Saldo: "+matcher.group(3));
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
 			}
 		} catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankLansforsakringar.java
similarity index 62%
copy from src/com/liato/bankdroid/BankICA.java
copy to src/com/liato/bankdroid/BankLansforsakringar.java
index 66561a5..8ab67f0 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankLansforsakringar.java
@@ -16,23 +16,24 @@ import android.util.Log;
 
 import com.liato.urllib.Urllib;
 
-public class BankICA implements Bank {
+public class BankLansforsakringar implements Bank {
 
 	private String username;
 	private String password;
-	private Banks banktype = Banks.ICA;
+	private Banks banktype = Banks.LANSFORSAKRINGAR;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reError = Pattern.compile("ErrMessage.+?>([^<]+)",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalance = Pattern.compile("<a.+?DataTable1:(\\d+):account[^>]+>([^<]+)</a>.+?<spa.+?>([0-9 -,.]+)</span></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reToken = Pattern.compile("var\\s+token\\s*=\\s*'([^']+)'", Pattern.CASE_INSENSITIVE);
 	
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
-	public BankICA() {
+	public BankLansforsakringar() {
 	}
 
-	public BankICA(String username, String password) throws BankException {
+	public BankLansforsakringar(String username, String password) throws BankException {
 		this.update(username, password);
 	}
 
@@ -50,34 +51,42 @@ public class BankICA implements Bank {
 		String response = null;
 		Matcher matcher;
 		try {
-			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx");
+			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/login/privat");
 			matcher = reViewState.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse data.");
+				throw new BankException("Could not connect to the bank. Unable to parse ViewState.");
 			}
 			String strViewState = matcher.group(1);
 			matcher = reEventValidation.matcher(response);
 			if (!matcher.find()) {
-				throw new BankException("Could not connect to the bank. Unable to parse data.");
+				throw new BankException("Could not connect to the bank. Unable to parse EventValidation.");
 			}
 			String strEventValidation = matcher.group(1);
+			
+			matcher = reEventValidation.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException("Could not connect to the bank. Unable to parse EventValidation.");
+			}			
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("pnr_phone", username));
-			postData.add(new BasicNameValuePair("pwd_phone", password));
-			postData.add(new BasicNameValuePair("btnLogin", "Logga in"));
+			postData.add(new BasicNameValuePair("inputPersonalNumber", username));
+			postData.add(new BasicNameValuePair("inputPinCode", password));
+			postData.add(new BasicNameValuePair("selMechanism", "PIN-kod"));
 			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
 			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
-			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx", postData);
+			postData.add(new BasicNameValuePair("__LASTFOCUS", ""));
+			postData.add(new BasicNameValuePair("__EVENTTARGET", ""));
+			postData.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
+			
+			response = urlopen.open(urlopen.getCurrentURI(), postData);
 			
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
-				throw new BankException(Html.fromHtml(matcher.group(1).trim()).toString());
+				throw new BankException("Personnummer och lösenord stämmer ej.");
 			}
 
-			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
+			response = urlopen.open("https://secure246.lansforsakringar.se/lfportal/appmanager/privat/main?_nfpb=true&_pageLabel=bank_konto&newUc=true&isTopLevel=true");
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
-				Log.d("BankICA", "Saldo: "+matcher.group(3));
 				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
 			}
 		} catch (ClientProtocolException e) {
diff --git src/com/liato/bankdroid/Banks.java src/com/liato/bankdroid/Banks.java
index 72b3a01..1ccf90a 100644
--- src/com/liato/bankdroid/Banks.java
+++ src/com/liato/bankdroid/Banks.java
@@ -1,9 +1,10 @@
 package com.liato.bankdroid;
 
 public enum Banks {
-	SWEDBANK 	("Swedbank"),
-	NORDEA		("Nordea"),
-	ICA			("ICA");
+	SWEDBANK 			("Swedbank"),
+	NORDEA				("Nordea"),
+	ICA					("ICA"),
+	LANSFORSAKRINGAR 	("Länsförsäkringar");
 
 	private String value;
 	private Banks(String value) {
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
index 14b475c..2e3d137 100644
--- src/com/liato/bankdroid/Helpers.java
+++ src/com/liato/bankdroid/Helpers.java
@@ -7,6 +7,7 @@ import java.util.Locale;
 public class Helpers {
 	public static BigDecimal parseBalance(String balance) {
 		balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
+		balance = balance.replaceAll("[a-zA-Z]*", "");
 		balance = balance.replace(",", ".");
 		return new BigDecimal(balance);
 	}
@@ -14,4 +15,9 @@ public class Helpers {
 		Locale locale = new Locale("sv", "SE");
 		return NumberFormat.getCurrencyInstance(locale).format(balance).replace("kr", "SEK");
 	}
+	public static String toAscii(String s) {
+		s = s.replaceAll("[åÅ]", "a").replaceAll("[äÄ]", "a").replaceAll("[öÖ]", "o").replaceAll(" ", "_");
+		s = s.replaceAll("[^a-zA-Z0-9_]", "");
+		return s;
+	}
 }
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 14c4534..b0cd895 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -152,7 +152,7 @@ public class MainActivity extends Activity {
 			((TextView)v.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getName());
 			((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
 			((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
-			icon.setImageResource(getResources().getIdentifier("drawable/"+group.getType().toLowerCase(), null, getPackageName()));
+			icon.setImageResource(getResources().getIdentifier("drawable/"+Helpers.toAscii(group.getType().toLowerCase()), null, getPackageName()));
 			return v;
 		}
 
@@ -263,7 +263,7 @@ public class MainActivity extends Activity {
 				c.moveToNext();
 				publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
 				try {
-					cls = Class.forName("com.liato.bankdroid.Bank"+c.getString(clmBanktype));
+					cls = Class.forName("com.liato.bankdroid.Bank"+Helpers.toAscii(c.getString(clmBanktype)));
 					bank = (Bank) cls.newInstance();
 					bank.update(c.getString(clmUsername), c.getString(clmPassword));
 					db.updateBank(bank, new Long(c.getString(clmId)));
@@ -301,7 +301,7 @@ public class MainActivity extends Activity {
 			
 			if (this.errors != null && !this.errors.isEmpty()) {
 				StringBuilder errormsg = new StringBuilder();
-				errormsg.append(res.getText(R.string.acounts_were_not_updated));
+				errormsg.append(res.getText(R.string.acounts_were_not_updated)+":\n");
 				for (String err : errors)
 				{
 				  errormsg.append(err);
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
index d310aca..4a91561 100644
--- src/com/liato/urllib/Urllib.java
+++ src/com/liato/urllib/Urllib.java
@@ -3,21 +3,32 @@ package com.liato.urllib;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+
+import org.apache.http.HttpHost;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.ResponseHandler;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.impl.client.BasicResponseHandler;
 import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+
+import android.util.Log;
 
 public class Urllib {
 	private DefaultHttpClient httpclient;
+	private HttpContext context;
+	private String currentURI;
 	
     public Urllib() {
     	httpclient = new DefaultHttpClient();
+    	context = new BasicHttpContext();
     }
     
     public String open(String url) throws ClientProtocolException, IOException {
@@ -25,23 +36,37 @@ public class Urllib {
     }
     
     public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
-    	//HttpResponse response;
+    	this.currentURI = url;
     	String response;
     	ResponseHandler<String> responseHandler = new BasicResponseHandler();
     	if (postData.isEmpty()) {
     		HttpGet urlConnection = new HttpGet(url);
-    		response = httpclient.execute(urlConnection, responseHandler);
+    		response = httpclient.execute(urlConnection, responseHandler, context); 
     	}
     	else {
     		HttpPost urlConnection = new HttpPost(url);
     		urlConnection.setEntity(new UrlEncodedFormEntity(postData, HTTP.UTF_8));
-    		response = httpclient.execute(urlConnection, responseHandler);
+    		response = httpclient.execute(urlConnection, responseHandler, context); 
     	}
 
+        HttpUriRequest currentReq = (HttpUriRequest)context.getAttribute(ExecutionContext.HTTP_REQUEST);
+        HttpHost currentHost = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
+        this.currentURI = currentHost.toURI() + currentReq.getURI();
+    	
     	return response;
     }
     
     public void close() {
         httpclient.getConnectionManager().shutdown();
     }
+    
+    public HttpContext getContext() {
+    	return context;
+    }
+    
+    public String getCurrentURI() {
+    	return currentURI;
+    }
+    
+    
 }
\ No newline at end of file

commit 43c837ec0455db00057f3dd51ef1a400241c5efc
Author: liato <x@x00.us>
Date:   Sun May 16 14:42:45 2010 +0200

    Added option to set a password.

diff --git AndroidManifest.xml AndroidManifest.xml
index bb7740a..d35e698 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,19 +1,23 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.0.2" android:versionCode="7">
+	package="com.liato.bankdroid" android:versionName="1.0.3" android:versionCode="8">
 	<application android:icon="@drawable/icon" android:label="@string/app_name">
 		<activity android:label="@string/app_name"
-			android:multiprocess="false" android:name=".MainActivity"
+			android:multiprocess="false" android:name=".LoginActivity"
 			android:alwaysRetainTaskState="true">
 			<intent-filter>
 				<action android:name="android.intent.action.MAIN" />
 				<category android:name="android.intent.category.LAUNCHER" />
 			</intent-filter>
 		</activity>
+		<activity android:name=".MainActivity" android:label="@string/app_name">
+		</activity>
 		<activity android:name=".AccountsActivity" android:label="@string/app_name">
 		</activity>
 		<activity android:name=".AccountActivity" android:label="@string/app_name">
 		</activity>
+		<activity android:name=".SettingsActivity" android:label="@string/app_name">
+		</activity>
 		<!--
 		<activity android:name=".WidgetConfigureActivity" android:theme="@android:style/Theme.Dialog">
 			<intent-filter>
diff --git res/drawable/ic_bullet_key_permission.png res/drawable/ic_bullet_key_permission.png
new file mode 100644
index 0000000..c8a4939
Binary files /dev/null and res/drawable/ic_bullet_key_permission.png differ
diff --git res/drawable/ic_menu_forward.png res/drawable/ic_menu_forward.png
new file mode 100644
index 0000000..0936fac
Binary files /dev/null and res/drawable/ic_menu_forward.png differ
diff --git res/drawable/ic_menu_refresh.png res/drawable/ic_menu_refresh.png
new file mode 100644
index 0000000..77d70dd
Binary files /dev/null and res/drawable/ic_menu_refresh.png differ
diff --git res/layout/login.xml res/layout/login.xml
new file mode 100644
index 0000000..b52a009
--- /dev/null
+++ res/layout/login.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp" android:layout_gravity="center_vertical" android:gravity="center_vertical">
+
+
+<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:typeface="sans" android:gravity="center_horizontal" android:layout_gravity="center_horizontal" android:text="BANKDROID" android:layout_width="fill_parent" android:visibility="visible" android:textColor="#fff" android:textSize="42dp"></TextView><LinearLayout android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_width="fill_parent"><ImageView android:id="@+id/ImageView01" android:background="@drawable/icon_large" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:visibility="visible"></ImageView><LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent"><EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:inputType="textPassword" android:layout_gravity="center_vertical" android:hint="@string/access_code" android:id="@+id/edtAccessCode"></EditText><Button android:id="@+id/btnLogin" android:layout_gravity="right|center_vertical" android:layout_width="fill_parent" android:layout_height="52dp" android:drawableRight="@drawable/ic_menu_forward"></Button></LinearLayout>
+</LinearLayout>
+
+
+
+
+
+
+<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/txtResult" android:textColor="#CC4B28" android:text="@string/invalid_access_code" android:gravity="center_vertical" android:drawableLeft="@drawable/ic_bullet_key_permission" android:layout_gravity="center_horizontal" android:visibility="invisible"></TextView>
+</LinearLayout>
diff --git res/layout/main.xml res/layout/main.xml
index 7aa5961..078eac5 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -22,10 +22,9 @@
 		android:layout_weight="1" android:layout_height="wrap_content"
 		android:layout_alignParentBottom="true">
 		<Button
-			android:drawableLeft="@android:drawable/ic_menu_rotate"
 			android:layout_width="fill_parent"
 			android:layout_height="wrap_content"
 			android:layout_gravity="bottom"
-			android:id="@+id/btnAccountsRefresh" android:visibility="gone" android:text="@string/refresh_balance"/>
+			android:id="@+id/btnAccountsRefresh" android:visibility="gone" android:text="@string/refresh_balance" android:drawableLeft="@drawable/ic_menu_refresh"/>
 	</LinearLayout>
 </RelativeLayout>
diff --git res/layout/settings.xml res/layout/settings.xml
new file mode 100644
index 0000000..61e9299
--- /dev/null
+++ res/layout/settings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical" android:layout_width="fill_parent"
+	android:layout_height="fill_parent" android:paddingLeft="10dp"
+	android:paddingRight="10dp" android:paddingTop="10dp">
+
+	<TextView android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:typeface="sans"
+		android:textSize="20sp" android:text="@string/access_code" />
+	<EditText android:layout_height="wrap_content"
+		android:layout_width="fill_parent" android:inputType="textPassword" android:id="@+id/edtAccessCode"></EditText>
+
+	<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/txtSettingsPinDesc" android:text="@string/pin_desc" android:textSize="12sp" android:textColor="#A4A4A4" android:drawableLeft="@android:drawable/ic_dialog_info" android:drawablePadding="5dp" android:layout_marginBottom="3dp"></TextView><TextView android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:typeface="sans"
+		android:textSize="20sp" android:text="@string/update_frequency" android:visibility="invisible"/>
+	<Spinner android:layout_height="wrap_content"
+		android:layout_width="fill_parent" android:id="@+id/spnUpdateFrequency" android:visibility="invisible"></Spinner>
+
+
+	
+	
+
+	<LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="10dp"><CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/notify_on_change" android:id="@+id/chkNotifyOnChange" android:visibility="invisible"></CheckBox></LinearLayout><TableLayout android:id="@+id/TableLayout01"
+		android:layout_width="fill_parent" android:stretchColumns="*"
+		android:gravity="bottom" android:layout_height="fill_parent">
+		<TableRow android:id="@+id/TableRow01" android:layout_height="wrap_content"
+			android:layout_width="fill_parent">
+			<Button android:layout_height="wrap_content"
+				android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
+				android:layout_width="fill_parent" android:id="@+id/btnSettingsCancel"
+				android:text="@string/cancel"></Button>
+			<Button android:layout_height="wrap_content"
+				android:drawableLeft="@android:drawable/ic_menu_save"
+				android:layout_width="fill_parent" android:id="@+id/btnSettingsOk"
+				android:text="@string/save"></Button>
+		</TableRow>
+	</TableLayout>
+
+
+
+
+
+</LinearLayout>
diff --git res/layout/widget.xml res/layout/widget.xml
new file mode 100644
index 0000000..1137d0b
--- /dev/null
+++ res/layout/widget.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_gravity="center_horizontal" android:background="@drawable/widget_2x1" android:layout_height="100dp" android:layout_width="160dp">
+
+    <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/layWidgetRow01" android:layout_marginTop="-5dp"><ImageView android:layout_above="@+id/txtListitemAccountsItemAccountname" android:layout_width="22dp" android:layout_height="22dp" android:background="@drawable/nordea" android:id="@+id/imgWidgetIcon" android:layout_gravity="center_vertical"></ImageView><TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/txtWidgetAccountname" android:text="Kapitalkonto" android:layout_gravity="center_vertical" android:textColor="#a8a3a3" android:textSize="11dp" android:inputType="none" android:layout_marginLeft="2dp"></TextView></LinearLayout><LinearLayout android:id="@+id/layWidgetRow02" android:layout_below="@+id/layWidgetRow01" android:layout_width="fill_parent" android:layout_height="fill_parent"><TextView android:textColor="#fff" android:inputType="none" android:layout_height="fill_parent" android:layout_gravity="center_vertical|center_horizontal" android:layout_width="fill_parent" android:ellipsize="none" android:gravity="center_vertical|center_horizontal" android:textSize="15dp" android:text="129 500,00 SEK" android:layout_marginTop="-4dp" android:id="@+id/txtWidgetAccountbalance"/></LinearLayout>
+
+    
+    
+        
+
+
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git res/values/strings.xml res/values/strings.xml
index 78afc87..be2606b 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -24,5 +24,13 @@
 	<string name="refresh_balance">Uppdatera saldoinformation</string>
 
 	<string name="choose_an_account">Välj ett konto</string>
+	
+	<string name="update_frequency">Uppdateringsfrekvens</string>
+	<string name="access_code">PIN-kod</string>
+	<string name="pin_desc">Ange en PIN-kod om du vill lösenordsskydda applikationen och tillhörande widgets.</string>
+	<string name="notify_on_change">Notifiera vid kontohändelser</string>
+	
+    <string name="login">Logga in</string>
+    <string name="invalid_access_code">Ogiltig PIN-kod. Försök igen.</string>
 	    
 </resources>
diff --git src/com/liato/bankdroid/LoginActivity.java src/com/liato/bankdroid/LoginActivity.java
new file mode 100644
index 0000000..362fd37
--- /dev/null
+++ src/com/liato/bankdroid/LoginActivity.java
@@ -0,0 +1,54 @@
+package com.liato.bankdroid;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class LoginActivity extends Activity {
+	private SharedPreferences prefs;
+	private String access_code;
+
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+	
+		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		access_code = prefs.getString("access_code", "");
+		if (access_code.length() > 0) {
+			setContentView(R.layout.login);
+			((Button)findViewById(R.id.btnLogin)).setOnClickListener(new View.OnClickListener() {
+				public void onClick(View v) {
+					if (((EditText)findViewById(R.id.edtAccessCode)).getText().toString().equals(access_code)) {
+						loginSuccess();
+					}
+					else {
+						TextView txtResult = (TextView)findViewById(R.id.txtResult);
+				    	txtResult.setVisibility(TextView.VISIBLE);
+				    	AlphaAnimation anim = new AlphaAnimation(1, 0);
+				    	anim.setFillAfter(true);
+				    	anim.setStartOffset(5000);
+					    anim.setDuration(1000);
+				    	txtResult.startAnimation(anim);
+				 
+					}
+				}
+			});	
+		}
+		else {
+			loginSuccess();
+		}
+	}
+	
+	private void loginSuccess() {
+		Intent intent = new Intent(this, MainActivity.class);
+		this.startActivity(intent);
+		this.finish();
+		return;
+	}
+}
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 5ddb0d0..14c4534 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -29,11 +29,12 @@ import android.widget.TextView;
 public class MainActivity extends Activity {
 	/** Called when the activity is first created. */
 	private DBAdapter dba;
+
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
+	
 		setContentView(R.layout.main);
-		
 		Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
 		btnRefresh.setOnClickListener(new View.OnClickListener() {
 			public void onClick(View v) {
@@ -98,13 +99,18 @@ public class MainActivity extends Activity {
 
 
 	public boolean onOptionsItemSelected (MenuItem item){
+		Intent intent;
 		switch (item.getItemId()) {
 		case R.id.exit:
 			this.finish();
 			return true;
 		case R.id.accounts:
-			Intent intentAccounts = new Intent(this, AccountsActivity.class);
-			this.startActivity(intentAccounts);
+			intent = new Intent(this, AccountsActivity.class);
+			this.startActivity(intent);
+			return true;
+		case R.id.settings:
+			intent = new Intent(this, SettingsActivity.class);
+			this.startActivity(intent);
 			return true;
 		case R.id.about:
 			AlertDialog.Builder builder = new AlertDialog.Builder(this);
diff --git src/com/liato/bankdroid/SettingsActivity.java src/com/liato/bankdroid/SettingsActivity.java
new file mode 100644
index 0000000..7475d7e
--- /dev/null
+++ src/com/liato/bankdroid/SettingsActivity.java
@@ -0,0 +1,198 @@
+package com.liato.bankdroid;
+
+import java.util.ArrayList;
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+public class SettingsActivity extends Activity implements OnClickListener, OnItemSelectedListener {
+	private SharedPreferences prefs;
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.settings);
+		prefs = PreferenceManager.getDefaultSharedPreferences(this);
+		ArrayList<Pair<String, Integer>> items = new ArrayList<Pair<String, Integer>>();
+		items.add(new Pair<String, Integer>("Disabled", -1));
+		items.add(new Pair<String, Integer>("15 minutes", 10));
+		items.add(new Pair<String, Integer>("30 minutes", 30));
+		items.add(new Pair<String, Integer>("1 hour", 60));
+		items.add(new Pair<String, Integer>("2 hours", 60*2));
+		items.add(new Pair<String, Integer>("4 hours", 60*4));
+		items.add(new Pair<String, Integer>("8 hours", 60*8));
+
+		Spinner spnFrequency = (Spinner)findViewById(R.id.spnUpdateFrequency);
+		ArrayAdapter<Pair<String, Integer>> adapter = new ArrayAdapter<Pair<String, Integer>>(this,
+				android.R.layout.simple_spinner_item, items);
+		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+		spnFrequency.setAdapter(adapter);
+		spnFrequency.setOnItemSelectedListener(this);
+
+		findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
+		findViewById(R.id.btnSettingsOk).setOnClickListener(this);
+		
+
+		((EditText)findViewById(R.id.edtAccessCode)).setText(prefs.getString("access_code", ""));
+		//Resources r = getResources();
+
+		/*Bundle extras = getIntent().getExtras(); 
+		if (extras != null) {
+			BANKID = extras.getString("id");
+			if (BANKID != null) {
+				DBAdapter db = new DBAdapter(this);
+				db.open();
+				Cursor c = db.getBank(BANKID);
+				if (c != null) {
+					((EditText)findViewById(R.id.edtBankeditUsername)).setText(c.getString(c.getColumnIndex("username")));
+					((EditText)findViewById(R.id.edtBankeditPassword)).setText(c.getString(c.getColumnIndex("password")));
+					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
+					int i = items.indexOf(SELECTED_BANK);
+					spnBanks.setSelection(i);
+					c.close();
+				}
+				db.close();
+			}
+		}*/
+	}
+	
+	private class Pair<T, S> {
+		private T key;
+		private S value;
+		public Pair(T key, S value) { 
+			this.key = key;
+			this.value = value;   
+		}
+
+		public T getKey() {
+			return key;
+		}
+
+		public S getValue() {
+			return value;
+		}
+
+		public String toString() { 
+			return (String) getKey(); 
+		}
+	}
+
+	@Override
+	public void onClick(View v) {
+		if (v.getId() == R.id.btnSettingsCancel) {
+			this.finish();
+		}
+		else if (v.getId() == R.id.btnSettingsOk){
+			Editor editor = prefs.edit();
+			editor.putString("access_code", ((EditText)findViewById(R.id.edtAccessCode)).getText().toString());
+			editor.commit();
+			this.finish();
+			//new DataRetrieverTask(this).execute(SELECTED_BANK, ((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim(), ((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+		}
+
+	}
+
+	@Override
+	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
+		//SELECTED_BANK = parentView.getItemAtPosition(pos).toString();
+	}
+
+	@Override
+	public void onNothingSelected(AdapterView<?> arg) {
+	}
+
+	/*private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
+		private final ProgressDialog dialog = new ProgressDialog(SettingsActivity.this);
+		private Class<?> cls;
+		private Exception exc = null;
+		private Bank bank;
+		private SettingsActivity parent;
+		private Resources res;
+
+		public DataRetrieverTask(SettingsActivity parent) {
+			this.parent = parent;
+			this.res = parent.getResources();
+			
+		}
+		protected void onPreExecute() {
+			this.dialog.setMessage(res.getText(R.string.logging_in));
+			this.dialog.show();
+		}
+
+		protected Void doInBackground(final String... args) {
+			try {
+				cls = Class.forName("com.liato.bankdroid.Bank"+args[0]);
+				bank = (Bank) cls.newInstance();
+				bank.update(args[1], args[2]);
+				DBAdapter dba = new DBAdapter(SettingsActivity.this);
+				dba.open();
+				if (BANKID != null) {
+					dba.updateBank(bank, new Long(BANKID));
+				}
+				else {
+					dba.createBank(bank);
+				}
+				dba.close();
+			} 
+			catch (BankException e) {
+				this.exc = e;
+			}
+			catch (ClassNotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (InstantiationException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return null;
+		}
+
+		protected void onPostExecute(final Void unused) {
+			if (this.dialog.isShowing()) {
+				this.dialog.dismiss();
+			}
+			if (this.exc != null) {
+				AlertDialog.Builder builder = new AlertDialog.Builder(SettingsActivity.this);
+				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
+				.setIcon(android.R.drawable.ic_dialog_alert)
+				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+					public void onClick(DialogInterface dialog, int id) {
+						dialog.cancel();
+					}
+				});
+				AlertDialog alert = builder.create();
+				alert.show();
+			}
+			else {
+				parent.finish();
+			}
+		}
+	}*/
+	
+	@Override
+	protected void onResume() {
+		super.onResume();
+	}
+
+	@Override
+	protected void onPause() {
+		super.onPause();
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState) {
+		super.onSaveInstanceState(outState);
+	}   
+}

commit 4692fa11e5d31c29a3f4c9a802f1a14c1edd0f08
Author: liato <x@x00.us>
Date:   Thu May 13 06:39:33 2010 +0200

    Fixed swedbank csrf-token parsing.

diff --git AndroidManifest.xml AndroidManifest.xml
index 17ceae9..bb7740a 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.liato.bankdroid" android:versionName="1.0.1" android:versionCode="6">
+	package="com.liato.bankdroid" android:versionName="1.0.2" android:versionCode="7">
 	<application android:icon="@drawable/icon" android:label="@string/app_name">
 		<activity android:label="@string/app_name"
 			android:multiprocess="false" android:name=".MainActivity"
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index 369d08d..353103a 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -19,7 +19,7 @@ public class BankSwedbank implements Bank {
 	private String username;
 	private String password;
 	private Banks banktype = Banks.SWEDBANK;
-	private Pattern reCSRF = Pattern.compile("csrf_token\"\\s*value=\"([^\"]+)\"");
+	private Pattern reCSRF = Pattern.compile("csrf_token\".*?value=\"([^\"]+)\"");
 	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);

commit 7db5dd20172193f9e4db692bd241efd121744a66
Author: liato <x@x00.us>
Date:   Mon May 10 19:19:35 2010 +0200

    Added support for ICABanken.

diff --git AndroidManifest.xml AndroidManifest.xml
index c504130..17ceae9 100644
--- AndroidManifest.xml
+++ AndroidManifest.xml
@@ -1,26 +1,34 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.liato.bankdroid"
-      android:versionCode="1"
-      android:versionName="1.0">
-    <application android:icon="@drawable/icon" android:label="@string/app_name">
-        <activity android:label="@string/app_name" android:multiprocess="false" android:name=".MainActivity" android:alwaysRetainTaskState="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-		<activity android:name=".AccountsActivity"
-			android:label="@string/app_name">
+	package="com.liato.bankdroid" android:versionName="1.0.1" android:versionCode="6">
+	<application android:icon="@drawable/icon" android:label="@string/app_name">
+		<activity android:label="@string/app_name"
+			android:multiprocess="false" android:name=".MainActivity"
+			android:alwaysRetainTaskState="true">
+			<intent-filter>
+				<action android:name="android.intent.action.MAIN" />
+				<category android:name="android.intent.category.LAUNCHER" />
+			</intent-filter>
 		</activity>
-		<activity android:name=".AccountActivity"
-			android:label="@string/app_name">
+		<activity android:name=".AccountsActivity" android:label="@string/app_name">
 		</activity>
-    
-</application>
-    <uses-sdk android:minSdkVersion="3" />
-
-
-<uses-permission android:name="android.permission.INTERNET"></uses-permission>
-
+		<activity android:name=".AccountActivity" android:label="@string/app_name">
+		</activity>
+		<!--
+		<activity android:name=".WidgetConfigureActivity" android:theme="@android:style/Theme.Dialog">
+			<intent-filter>
+				<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+			</intent-filter>
+		</activity>
+		<receiver android:name="BankdroidWidgetProvider">
+			<intent-filter>
+				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+			</intent-filter>
+			<meta-data android:name="android.appwidget.provider"
+				android:resource="@xml/appwidget_info" />
+		</receiver>
+		-->
+	</application>
+	<uses-sdk android:minSdkVersion="3" />
+	<uses-permission android:name="android.permission.INTERNET"></uses-permission>
 </manifest> 
\ No newline at end of file
diff --git res/values/strings.xml res/values/strings.xml
index 7331c09..78afc87 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -21,5 +21,8 @@
 	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
 	
 	<string name="main_instructions">Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto.</string>
-	<string name="refresh_balance">Uppdatera saldoinformation</string>    
+	<string name="refresh_balance">Uppdatera saldoinformation</string>
+
+	<string name="choose_an_account">Välj ett konto</string>
+	    
 </resources>
diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
index e0a67c0..f2b1bdf 100644
--- src/com/liato/bankdroid/Account.java
+++ src/com/liato/bankdroid/Account.java
@@ -5,10 +5,12 @@ import java.math.BigDecimal;
 public class Account {
 	private String name;
 	private BigDecimal balance;
+	private String id;
 
-	public Account(String name, BigDecimal balance) {
+	public Account(String name, BigDecimal balance, String id) {
 		this.name = name;
 		this.balance = balance;
+		this.id = id;
 	}
 
 	public void setBalance(BigDecimal balance) {
@@ -22,4 +24,8 @@ public class Account {
 	public String getName() {
 		return name;
 	}
+	
+	public String getId() {
+		return id;
+	}
 }
diff --git src/com/liato/bankdroid/AccountsAdapter.java src/com/liato/bankdroid/AccountsAdapter.java
new file mode 100644
index 0000000..3f8127a
--- /dev/null
+++ src/com/liato/bankdroid/AccountsAdapter.java
@@ -0,0 +1,155 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class AccountsAdapter extends BaseAdapter {
+	private ArrayList<Group> groups;
+	private Context context;
+
+	public AccountsAdapter(Context context) {
+		this.context = context;
+		this.groups = new ArrayList<Group>();
+	}
+
+	public void addGroup(Group group) {
+		groups.add(group);
+	}
+
+	public View newGroupView(Group group, ViewGroup parent) {
+		LayoutInflater inflater = LayoutInflater.from(context);
+		View v = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
+		ImageView icon = (ImageView)v.findViewById(R.id.imgListitemAccountsGroup);
+		((TextView)v.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getName());
+		((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
+		((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
+		icon.setImageResource(context.getResources().getIdentifier("drawable/"+group.getType().toLowerCase(), null, context.getPackageName()));
+		return v;
+	}
+
+	public View newItemView(Item item, ViewGroup parent) {
+		LayoutInflater inflater = LayoutInflater.from(context);
+		View v = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
+		((TextView)v.findViewById(R.id.txtListitemAccountsItemAccountname)).setText(item.getName());
+		((TextView)v.findViewById(R.id.txtListitemAccountsItemBalance)).setText(Helpers.formatBalance(item.getBalance()));
+		//v.setOnClickListener(this);
+		return v;
+	}
+
+	@Override
+	public int getCount() {
+		int c = 0;
+		for(Group g : groups) {
+			c += g.getItems().size()+1;
+		}
+		return c;
+	}
+
+	@Override
+	public Object getItem(int position) {
+		if (groups.size() == 0) {
+			return null;
+		}
+		if (position == 0) {
+			return groups.get(0);
+		}
+
+		int i = 0;
+		for (Group g : groups) {
+			if (position == i) {
+				return g;
+			}
+			else if (position <= (g.getItems().size()+i)) {
+				return g.getItems().get(position-i-1);
+			}
+			i += g.getItems().size()+1;
+		}
+
+		return(null);
+	}
+
+	@Override
+	public long getItemId(int position) {
+		return position;
+	}
+
+	@Override
+	public View getView(int position, View convertView, ViewGroup parent) {
+		Object item = getItem(position);
+		if (item == null) {
+			return null;
+		}
+		if (item instanceof Group) {
+			return newGroupView((Group)item, parent);
+		}
+		else if (item instanceof Item) {
+			return newItemView((Item)item, parent);
+		}
+		return null;
+	}
+
+	public boolean isEnabled(int position) {
+		if (getItem(position) instanceof Item) {
+			return true;
+		}
+		return false;
+	}
+
+	public final static class Group {
+		private String name;
+		private String type;
+		private BigDecimal total;
+		private List<Item> items;
+		public Group(String name, String type, Double total, List<Item> items) {
+			this.name = name;
+			this.type = type;
+			this.items = items;
+			this.total = new BigDecimal(total);
+		}
+		public String getName() {
+			return name;
+		}
+		public String getType() {
+			return type;
+		}
+		public BigDecimal getTotal() {
+			return total;
+		}
+		public List<Item> getItems() {
+			return items;
+		}
+
+	}
+
+	public final static class Item {
+		private String name;
+		private BigDecimal balance;
+		private String id;
+		public Item (String name, Double balance, String id) {
+			this.name = name;
+			this.balance = new BigDecimal(balance);
+			this.id = id;
+		}
+		public String getName() {
+			return name;
+		}
+		public BigDecimal getBalance() {
+			return balance;
+		}
+		public String getId() {
+			return id;
+		}
+	}	
+
+}
+
+
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
index 6439e48..66561a5 100644
--- src/com/liato/bankdroid/BankICA.java
+++ src/com/liato/bankdroid/BankICA.java
@@ -12,6 +12,8 @@ import org.apache.http.client.ClientProtocolException;
 import org.apache.http.message.BasicNameValuePair;
 
 import android.text.Html;
+import android.util.Log;
+
 import com.liato.urllib.Urllib;
 
 public class BankICA implements Bank {
@@ -21,8 +23,8 @@ public class BankICA implements Bank {
 	private Banks banktype = Banks.ICA;
 	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
 	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
-	private Pattern reError = Pattern.compile("<label\\sclass=\"error\">([^>]+)</label>");
-	//private Pattern reBalance = Pattern.compile("REGEX TILL KONTO�VERSIKT");
+	private Pattern reError = Pattern.compile("<label\\s+class=\"error\">(.+?)</label>",Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reBalance = Pattern.compile("account\\.aspx\\?id=([^\"]+).+?>([^<]+)</a.+?Saldo([0-9 .,-]+)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
 	
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
@@ -41,10 +43,9 @@ public class BankICA implements Bank {
 	}
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("");//res.getText(R.string.invalid_username_password));
+			throw new BankException("Personnummer och lösenord stämmer ej.");//res.getText(R.string.invalid_username_password));
 		}
-		throw new BankException("St�d f�r ICA-banken kommer inom kort.");
-		/*
+
 		Urllib urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
@@ -61,25 +62,23 @@ public class BankICA implements Bank {
 			}
 			String strEventValidation = matcher.group(1);
 			List <NameValuePair> postData = new ArrayList <NameValuePair>();
-			postData.add(new BasicNameValuePair("xyz", username));
-			postData.add(new BasicNameValuePair("zyx", password));
+			postData.add(new BasicNameValuePair("pnr_phone", username));
+			postData.add(new BasicNameValuePair("pwd_phone", password));
+			postData.add(new BasicNameValuePair("btnLogin", "Logga in"));
 			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
 			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
 			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx", postData);
-
+			
 			matcher = reError.matcher(response);
 			if (matcher.find()) {
 				throw new BankException(Html.fromHtml(matcher.group(1).trim()).toString());
 			}
 
-			if (!response.contains("reDirect")) {
-				throw new BankException("Personnummer och l�senord st�mmer ej.");
-			}
-
-			response = urlopen.open("URL TILL KONTO�VERSIKT");
+			response = urlopen.open("https://mobil.icabanken.se/account/overview.aspx");
 			matcher = reBalance.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2))));
+				Log.d("BankICA", "Saldo: "+matcher.group(3));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString().trim(), Helpers.parseBalance(matcher.group(3).trim()), matcher.group(1).trim()));
 			}
 		} catch (ClientProtocolException e) {
 			e.printStackTrace();
@@ -89,7 +88,7 @@ public class BankICA implements Bank {
 		finally {
 			urlopen.close();
 		}
-		*/
+
 	}
 
 
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
index cef7dd1..f726ae1 100644
--- src/com/liato/bankdroid/BankNordea.java
+++ src/com/liato/bankdroid/BankNordea.java
@@ -20,7 +20,9 @@ public class BankNordea implements Bank {
 	private String password;
 	private Banks banktype = Banks.NORDEA;
 	private Pattern reBalance = Pattern.compile("(?is)nowrap>(.+?)SEK<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
-	private Pattern reAccounts = Pattern.compile("(?is)Kontoutdraget';.*?>(.*?)</a></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	//private Pattern reAccounts = Pattern.compile("(?is)Kontoutdraget';.*?>(.*?)</a></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("sendAccount\\('SEK',\\s*'[^']+',\\s*'[^']+',\\s*'([^']+)',\\s*'([^']+)'\\)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -38,7 +40,7 @@ public class BankNordea implements Bank {
 	}
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("Personnummer och l�senord st�mmer ej.");
+			throw new BankException("Personnummer och l�senord st�mmer ej.");
 		}
 		Urllib urlopen = new Urllib();
 		String response = null;
@@ -55,14 +57,14 @@ public class BankNordea implements Bank {
 			response = urlopen.open("https://gfs.nb.se/bin2/gfskod", postData);
 
 			if (!response.contains("reDirect")) {
-				throw new BankException("Personnummer och l�senord st�mmer ej.");
+				throw new BankException("Personnummer och lösenord stämmer ej.");
 			}
 
 			response = urlopen.open("https://gfs.nb.se/bin2/gfskod?OBJECT=KF00T&show_button=No");
 			matcherBalance = reBalance.matcher(response);
 			matcherAccounts = reAccounts.matcher(response);
 			while (matcherAccounts.find() && matcherBalance.find()) {
-				accounts.add(new Account(Html.fromHtml(matcherAccounts.group(1)).toString(), Helpers.parseBalance(matcherBalance.group(1))));
+				accounts.add(new Account(Html.fromHtml(matcherAccounts.group(2)).toString(), Helpers.parseBalance(matcherBalance.group(1)), matcherAccounts.group(2).trim()));
 			}
 		} catch (ClientProtocolException e) {
 			e.printStackTrace();
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
index 0dee400..369d08d 100644
--- src/com/liato/bankdroid/BankSwedbank.java
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -20,7 +20,7 @@ public class BankSwedbank implements Bank {
 	private String password;
 	private Banks banktype = Banks.SWEDBANK;
 	private Pattern reCSRF = Pattern.compile("csrf_token\"\\s*value=\"([^\"]+)\"");
-	private Pattern reAccounts = Pattern.compile("<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
+	private Pattern reAccounts = Pattern.compile("account\\.html\\?id=([^\"]+)\">\\s*<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
 	private ArrayList<Account> accounts = new ArrayList<Account>();
 	private BigDecimal balance = new BigDecimal(0);
 
@@ -40,7 +40,7 @@ public class BankSwedbank implements Bank {
 
 	public void update() throws BankException {
 		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
-			throw new BankException("Personnummer och l�senord st�mmer ej.");
+			throw new BankException("Personnummer och l�senord st�mmer ej.");
 		}        Urllib urlopen = new Urllib();
 		String response = null;
 		Matcher matcher;
@@ -58,12 +58,12 @@ public class BankSwedbank implements Bank {
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
 
 			if (response.contains("misslyckats")) {
-				throw new BankException("Personnummer och l�senord st�mmer ej.");
+				throw new BankException("Personnummer och l�senord st�mmer ej.");
 			}
 			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
 			matcher = reAccounts.matcher(response);
 			while (matcher.find()) {
-				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2))));
+				accounts.add(new Account(Html.fromHtml(matcher.group(2)).toString(), Helpers.parseBalance(matcher.group(3)), matcher.group(1).trim()));
 			}
 		} catch (ClientProtocolException e) {
 			e.printStackTrace();
diff --git src/com/liato/bankdroid/BankdroidWidgetProvider.java src/com/liato/bankdroid/BankdroidWidgetProvider.java
new file mode 100644
index 0000000..3ac40ba
--- /dev/null
+++ src/com/liato/bankdroid/BankdroidWidgetProvider.java
@@ -0,0 +1,37 @@
+package com.liato.bankdroid;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.Context;
+import android.widget.RemoteViews;
+
+public class BankdroidWidgetProvider extends AppWidgetProvider {
+
+    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+        /*final int N = appWidgetIds.length;
+
+        // Perform this loop procedure for each App Widget that belongs to this provider
+        for (int i=0; i<N; i++) {
+            int appWidgetId = appWidgetIds[i];
+
+            // Create an Intent to launch ExampleActivity
+            Intent intent = new Intent(context, ExampleActivity.class);
+            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+
+            // Get the layout for the App Widget and attach an on-click listener to the button
+            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
+            views.setOnClickPendingIntent(R.id.button, pendingIntent);
+
+            // Tell the AppWidgetManager to perform an update on the current App Widget
+            appWidgetManager.updateAppWidget(appWidgetId, views);
+        }*/
+    }
+    
+    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
+            int appWidgetId, AccountsAdapter.Item item) {
+        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
+        views.setTextViewText(R.id.txtWidgetAccountname, item.getName());
+        views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(item.getBalance()));
+        appWidgetManager.updateAppWidget(appWidgetId, views);
+    }    
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
index ee94591..27a4c4b 100644
--- src/com/liato/bankdroid/DBAdapter.java
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -13,12 +13,12 @@ import android.util.Log;
 
 public class DBAdapter {
 
-    private static final String TAG = "NotesDbAdapter";
+    private static final String TAG = "DBAdapter";
     private DatabaseHelper mDbHelper;
     private SQLiteDatabase mDb;
     
     private static final String DATABASE_NAME = "data";
-    private static final int DATABASE_VERSION = 2;
+    private static final int DATABASE_VERSION = 3;
 
     private final Context mCtx;
 
@@ -34,7 +34,7 @@ public class DBAdapter {
             		+ "balance real not null, "
                     + "banktype text not null, username text not null, "
                     + "password text not null, disabled integer);");
-            db.execSQL("create table accounts (bankid integer not null, balance real not null, name text not null);");
+            db.execSQL("create table accounts (bankid integer not null, id text not null, balance real not null, name text not null);");
         }
 
         @Override
@@ -120,7 +120,7 @@ public class DBAdapter {
      * @return Cursor over all accounts belonging to a bank
      */
     public Cursor fetchAccounts(long bankId) {
-        return mDb.query("accounts", new String[] {"bankid", "balance", "name"}, "bankid="+bankId, null, null, null, null);
+        return mDb.query("accounts", new String[] {"bankid", "balance", "name", "id"}, "bankid="+bankId, null, null, null, null);
     }
 
     public long updateBank(Bank bank, long bankId) {
@@ -147,6 +147,7 @@ public class DBAdapter {
 	            vals.put("bankid", bankId);
 	            vals.put("balance", acc.getBalance().doubleValue());
 	            vals.put("name", acc.getName());
+	            vals.put("id", new Long(bankId).toString()+"_"+acc.getId());
 	            mDb.insert("accounts", null, vals);	        	
 	        }
 	        ContentValues v = new ContentValues();
diff --git src/com/liato/bankdroid/WidgetConfigureActivity.java src/com/liato/bankdroid/WidgetConfigureActivity.java
new file mode 100644
index 0000000..e98ee06
--- /dev/null
+++ src/com/liato/bankdroid/WidgetConfigureActivity.java
@@ -0,0 +1,125 @@
+package com.liato.bankdroid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.Activity;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class WidgetConfigureActivity extends Activity {
+    private static final String WIDGET_PREFIX = "widget_";
+    private DBAdapter dba;
+	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+	
+	public WidgetConfigureActivity() {
+		super();
+	}
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.main);
+		this.setTitle(this.getString(R.string.choose_an_account));
+        setResult(RESULT_CANCELED);
+		((Button)findViewById(R.id.btnAccountsRefresh)).setVisibility(View.GONE);
+
+        Intent intent = getIntent();
+        Bundle extras = intent.getExtras();
+        if (extras != null) {
+            mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+        }
+        if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+            finish();
+        }		
+
+        ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+		lv.setOnItemClickListener(new OnItemClickListener() {
+			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+				Log.d("!", "CLICK!");
+				
+	            final Context context = WidgetConfigureActivity.this;
+	            AccountsAdapter.Item item = (AccountsAdapter.Item)parent.getItemAtPosition(position);
+	            SharedPreferences.Editor prefs = context.getSharedPreferences("widget_prefs", 0).edit();
+	            prefs.putString(WIDGET_PREFIX + mAppWidgetId, item.getId());
+	            prefs.commit();
+
+	            // Push widget update to surface with newly set prefix
+	            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+	            BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager,
+	                    mAppWidgetId, item);
+
+	            Intent resultValue = new Intent();
+	            resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+	            setResult(RESULT_OK, resultValue);
+	            finish();
+			}
+		});
+
+	
+	}	
+	
+	public void onResume() {
+		super.onResume();
+		refreshView();
+	}
+
+	private void refreshView() {
+		dba = new DBAdapter(this);
+		dba.open();
+		Cursor curBanks = dba.fetchBanks();
+		Cursor curAccounts;
+
+		if (curBanks != null && !curBanks.isLast() && !curBanks.isAfterLast()) {
+			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
+			startManagingCursor(curBanks);
+			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+			AccountsAdapter adapter = new AccountsAdapter(this);
+
+			int clmId = curBanks.getColumnIndex("_id"); 
+			int clmBanktype = curBanks.getColumnIndex("banktype");
+			int clmUsername = curBanks.getColumnIndex("username");
+			int clmBankbalance = curBanks.getColumnIndex("balance");
+			List<AccountsAdapter.Item> items;
+			AccountsAdapter.Group bank;
+
+			while (!curBanks.isLast() && !curBanks.isAfterLast()) {
+				items = new ArrayList<AccountsAdapter.Item>();
+				curBanks.moveToNext();
+				curAccounts = dba.fetchAccounts(curBanks.getLong(clmId));
+				int clmBalance = curAccounts.getColumnIndex("balance"); 
+				int clmName = curAccounts.getColumnIndex("name");
+				int clmAccId = curAccounts.getColumnIndex("id");
+				int acc_count = curAccounts.getCount();
+				if (curAccounts != null && acc_count != 0) {
+					while (!curAccounts.isLast()) {
+						curAccounts.moveToNext();
+						items.add(new AccountsAdapter.Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance), curAccounts.getString(clmAccId)));
+					}
+				}
+				bank = new AccountsAdapter.Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items);
+				adapter.addGroup(bank);
+				curAccounts.close();
+			}
+			lv.setAdapter(adapter);
+		}
+		curBanks.close();
+		dba.close();
+	}
+
+	public void onDestroy() {
+		super.onDestroy();
+	}
+
+
+}
diff --git widgets.psd widgets.psd
index c134b34..e4711fb 100644
Binary files widgets.psd and widgets.psd differ

commit 2b2be2cd0d14705ce5d860ff5609271b3d9ff14a
Author: liato <x@x00.us>
Date:   Sat May 8 22:55:45 2010 +0200

    Moved strings to xml. Added a bit of untested code to ICAbanken.

diff --git icabanken.psd icabanken.psd
new file mode 100644
index 0000000..1d99439
Binary files /dev/null and icabanken.psd differ
diff --git logos.psd logos.psd
index 014ccaf..0a75234 100644
Binary files logos.psd and logos.psd differ
diff --git res/drawable/ica.png res/drawable/ica.png
new file mode 100644
index 0000000..529263c
Binary files /dev/null and res/drawable/ica.png differ
diff --git res/drawable/widget_2x1.9.png res/drawable/widget_2x1.9.png
new file mode 100644
index 0000000..6512bee
Binary files /dev/null and res/drawable/widget_2x1.9.png differ
diff --git res/layout/bank.xml res/layout/bank.xml
index 98e2621..0b0c9a1 100644
--- res/layout/bank.xml
+++ res/layout/bank.xml
@@ -5,17 +5,17 @@
     android:layout_height="fill_parent" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp">
 <TextView  
     android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" android:text="Personnummer" android:typeface="sans" android:textSize="20sp"/>
+    android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/username"/>
 
 <EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditUsername" android:digits="0123456789-" android:inputType="phone"></EditText><TextView  
     android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="Lösenord"/><EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="Bank"/>
+    android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/password"/><EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="@string/bank"/>
 
 
 <Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:stretchColumns="*" android:gravity="bottom" android:layout_height="fill_parent">
 			<TableRow android:id="@+id/TableRow01" android:layout_height="wrap_content" android:layout_width="fill_parent">
-				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel" android:layout_width="fill_parent" android:id="@+id/btnSettingsCancel" android:text="Avbryt"></Button>
-				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_save" android:layout_width="fill_parent" android:id="@+id/btnSettingsOk" android:text="Spara"></Button>
+				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel" android:layout_width="fill_parent" android:id="@+id/btnSettingsCancel" android:text="@string/cancel"></Button>
+				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_save" android:layout_width="fill_parent" android:id="@+id/btnSettingsOk" android:text="@string/save"></Button>
 			</TableRow>
 		</TableLayout>
 </LinearLayout>
diff --git res/layout/banks.xml res/layout/banks.xml
index 6fffef6..cff98b1 100644
--- res/layout/banks.xml
+++ res/layout/banks.xml
@@ -1,2 +1,2 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:tag="rv"><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank." android:id="@+id/txtBanksDesc" android:visibility="visible" android:layout_margin="10dp" /><ListView android:layout_width="fill_parent" android:id="@+id/lstvBanksList" android:layout_height="fill_parent" android:fitsSystemWindows="true" android:layout_above="@+id/LinearLayout01"></ListView><LinearLayout android:id="@+id/LinearLayout01" android:gravity="bottom" android:layout_width="fill_parent" android:layout_weight="1" android:layout_height="wrap_content" android:layout_alignParentBottom="true"><Button android:id="@+id/btnBanksNewaccount" android:drawableLeft="@android:drawable/ic_menu_add" android:text="Lägg till ett nytt bankkonto" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginLeft="10dp" android:layout_marginRight="10dp"></Button></LinearLayout></RelativeLayout>
+<RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:tag="rv"><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/txtBanksDesc" android:visibility="visible" android:layout_margin="10dp" android:text="@string/banks_instructions"/><ListView android:layout_width="fill_parent" android:id="@+id/lstvBanksList" android:layout_height="fill_parent" android:fitsSystemWindows="true" android:layout_above="@+id/LinearLayout01"></ListView><LinearLayout android:id="@+id/LinearLayout01" android:gravity="bottom" android:layout_width="fill_parent" android:layout_weight="1" android:layout_height="wrap_content" android:layout_alignParentBottom="true"><Button android:id="@+id/btnBanksNewaccount" android:drawableLeft="@android:drawable/ic_menu_add" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:text="@string/add_new_account"></Button></LinearLayout></RelativeLayout>
diff --git res/layout/main.xml res/layout/main.xml
index 1cef90f..7aa5961 100644
--- res/layout/main.xml
+++ res/layout/main.xml
@@ -7,10 +7,9 @@
 	<TextView
 		android:layout_width="fill_parent"
 		android:layout_height="wrap_content"
-		android:text="Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto."
 		android:id="@+id/txtAccountsDesc"
 		android:visibility="visible"
-		android:layout_margin="10dp" />
+		android:layout_margin="10dp" android:text="@string/main_instructions"/>
 	<ListView
 		android:layout_width="fill_parent"
 		android:id="@+id/lstAccountsList"
@@ -24,10 +23,9 @@
 		android:layout_alignParentBottom="true">
 		<Button
 			android:drawableLeft="@android:drawable/ic_menu_rotate"
-			android:text="Uppdatera saldoinformation"
 			android:layout_width="fill_parent"
 			android:layout_height="wrap_content"
 			android:layout_gravity="bottom"
-			android:id="@+id/btnAccountsRefresh" android:visibility="gone"/>
+			android:id="@+id/btnAccountsRefresh" android:visibility="gone" android:text="@string/refresh_balance"/>
 	</LinearLayout>
 </RelativeLayout>
diff --git res/values/strings.xml res/values/strings.xml
index d8f7fb1..7331c09 100644
--- res/values/strings.xml
+++ res/values/strings.xml
@@ -1,5 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="hello">Hello World, main!</string>
     <string name="app_name">Bankdroid</string>
+    <string name="acounts_were_not_updated">Saldon för följande konton har ej uppdaterats</string>
+    <string name="updating_account_balance">Uppdaterar saldoinformation...</string>
+    <string name="errors_when_updating">Fel vid uppdatering"</string>
+    <string name="logging_in">Loggar in...</string>
+    <string name="could_not_create_account">Kunde ej skapa konto</string>
+    <string name="menu_edit">Redigera</string>
+    <string name="menu_remove">Radera</string>
+    <string name="invalid_username_password">Personnummer och lösenord stämmer ej.</string>
+    
+    <string name="username">Personnummer</string>
+    <string name="password">Lösenord</string>
+    <string name="bank">Bank</string>
+
+    <string name="cancel">Avbryt</string>
+    <string name="save">Spara</string>
+    
+	<string name="add_new_account">Lägg till ett nytt bankkonto</string>
+	<string name="banks_instructions">Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank.</string>
+	
+	<string name="main_instructions">Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto.</string>
+	<string name="refresh_balance">Uppdatera saldoinformation</string>    
 </resources>
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
index 6e254d5..54340a9 100644
--- src/com/liato/bankdroid/AccountActivity.java
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -7,10 +7,10 @@ import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.content.DialogInterface;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
@@ -54,7 +54,6 @@ public class AccountActivity extends Activity implements OnClickListener, OnItem
 					((EditText)findViewById(R.id.edtBankeditPassword)).setText(c.getString(c.getColumnIndex("password")));
 					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
 					int i = items.indexOf(SELECTED_BANK);
-					Log.d("a", "Index "+i);
 					spnBanks.setSelection(i);
 					c.close();
 				}
@@ -89,12 +88,15 @@ public class AccountActivity extends Activity implements OnClickListener, OnItem
 		private Exception exc = null;
 		private Bank bank;
 		private AccountActivity parent;
+		private Resources res;
 
 		public DataRetrieverTask(AccountActivity parent) {
 			this.parent = parent;
+			this.res = parent.getResources();
+			
 		}
 		protected void onPreExecute() {
-			this.dialog.setMessage("Loggar in...");
+			this.dialog.setMessage(res.getText(R.string.logging_in));
 			this.dialog.show();
 		}
 
@@ -135,7 +137,7 @@ public class AccountActivity extends Activity implements OnClickListener, OnItem
 			}
 			if (this.exc != null) {
 				AlertDialog.Builder builder = new AlertDialog.Builder(AccountActivity.this);
-				builder.setMessage(this.exc.getMessage()).setTitle("Kunde ej skapa konto")
+				builder.setMessage(this.exc.getMessage()).setTitle(res.getText(R.string.could_not_create_account))
 				.setIcon(android.R.drawable.ic_dialog_alert)
 				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
 					public void onClick(DialogInterface dialog, int id) {
diff --git src/com/liato/bankdroid/AccountsActivity.java src/com/liato/bankdroid/AccountsActivity.java
index a41fd00..54f0ceb 100644
--- src/com/liato/bankdroid/AccountsActivity.java
+++ src/com/liato/bankdroid/AccountsActivity.java
@@ -3,6 +3,7 @@ package com.liato.bankdroid;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.view.ContextMenu;
@@ -25,11 +26,13 @@ public class AccountsActivity extends Activity {
 	private DBAdapter dba;
 	private Cursor c;
 	private ListView lv;
+	private Resources res;
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setContentView(R.layout.banks);
 		Button btnNewacc = (Button)findViewById(R.id.btnBanksNewaccount);
+		res = this.getResources();
 		btnNewacc.setOnClickListener(new View.OnClickListener() {
 			public void onClick(View v) {
 				Intent intentAccount = new Intent(AccountsActivity.this, AccountActivity.class);
@@ -53,8 +56,8 @@ public class AccountsActivity extends Activity {
 			public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
 				AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
 				menu.setHeaderTitle(((TextView)info.targetView.findViewById(R.id.txtListitemBankname)).getText());
-				menu.add(0, 0, 0, "Redigera");
-				menu.add(0, 1, 0, "Radera");
+				menu.add(0, 0, 0, res.getText(R.string.menu_edit));
+				menu.add(0, 1, 0, res.getText(R.string.menu_remove));
 			}
 		});
 	}
diff --git src/com/liato/bankdroid/BankICA.java src/com/liato/bankdroid/BankICA.java
new file mode 100644
index 0000000..6439e48
--- /dev/null
+++ src/com/liato/bankdroid/BankICA.java
@@ -0,0 +1,120 @@
+package com.liato.bankdroid;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.text.Html;
+import com.liato.urllib.Urllib;
+
+public class BankICA implements Bank {
+
+	private String username;
+	private String password;
+	private Banks banktype = Banks.ICA;
+	private Pattern reEventValidation = Pattern.compile("__EVENTVALIDATION\"\\s+value=\"([^\"]+)\"");
+	private Pattern reViewState = Pattern.compile("__VIEWSTATE\"\\s+value=\"([^\"]+)\"");
+	private Pattern reError = Pattern.compile("<label\\sclass=\"error\">([^>]+)</label>");
+	//private Pattern reBalance = Pattern.compile("REGEX TILL KONTO�VERSIKT");
+	
+	private ArrayList<Account> accounts = new ArrayList<Account>();
+	private BigDecimal balance = new BigDecimal(0);
+
+	public BankICA() {
+	}
+
+	public BankICA(String username, String password) throws BankException {
+		this.update(username, password);
+	}
+
+	public void update(String username, String password) throws BankException {
+		this.username = username;
+		this.password = password;
+		this.update();
+	}
+	public void update() throws BankException {
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new BankException("");//res.getText(R.string.invalid_username_password));
+		}
+		throw new BankException("St�d f�r ICA-banken kommer inom kort.");
+		/*
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx");
+			matcher = reViewState.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException("Could not connect to the bank. Unable to parse data.");
+			}
+			String strViewState = matcher.group(1);
+			matcher = reEventValidation.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException("Could not connect to the bank. Unable to parse data.");
+			}
+			String strEventValidation = matcher.group(1);
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("xyz", username));
+			postData.add(new BasicNameValuePair("zyx", password));
+			postData.add(new BasicNameValuePair("__VIEWSTATE", strViewState));
+			postData.add(new BasicNameValuePair("__EVENTVALIDATION", strEventValidation));
+			response = urlopen.open("https://mobil.icabanken.se/login/login.aspx", postData);
+
+			matcher = reError.matcher(response);
+			if (matcher.find()) {
+				throw new BankException(Html.fromHtml(matcher.group(1).trim()).toString());
+			}
+
+			if (!response.contains("reDirect")) {
+				throw new BankException("Personnummer och l�senord st�mmer ej.");
+			}
+
+			response = urlopen.open("URL TILL KONTO�VERSIKT");
+			matcher = reBalance.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2))));
+			}
+		} catch (ClientProtocolException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		finally {
+			urlopen.close();
+		}
+		*/
+	}
+
+
+	@Override
+	public ArrayList<Account> getAccounts() {
+		return this.accounts;
+	}
+
+	@Override
+	public String getPassword() {
+		return password;
+	}
+
+	@Override
+	public Banks getType() {
+		return banktype;
+	}
+
+	@Override
+	public String getUsername() {
+		return username;
+	}
+	
+	@Override
+	public BigDecimal getBalance() {
+		return balance;
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/Banks.java src/com/liato/bankdroid/Banks.java
index da4cdc5..72b3a01 100644
--- src/com/liato/bankdroid/Banks.java
+++ src/com/liato/bankdroid/Banks.java
@@ -2,7 +2,8 @@ package com.liato.bankdroid;
 
 public enum Banks {
 	SWEDBANK 	("Swedbank"),
-	NORDEA		("Nordea");
+	NORDEA		("Nordea"),
+	ICA			("ICA");
 
 	private String value;
 	private Banks(String value) {
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index 12b40d5..5ddb0d0 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -10,6 +10,7 @@ import android.app.ProgressDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -221,12 +222,14 @@ public class MainActivity extends Activity {
 		private Bank bank;
 		private MainActivity parent;
 		private int bankcount;
+		private Resources res;
 
 		public DataRetrieverTask(MainActivity parent) {
 			this.parent = parent;
+			this.res = parent.getResources();
 		}
 		protected void onPreExecute() {
-			this.dialog.setMessage("Uppdaterar saldoinformation...\n ");
+			this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n ");
 			this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
 			this.dialog.setCancelable(false);
 			this.dialog.show();
@@ -282,7 +285,7 @@ public class MainActivity extends Activity {
 
 		protected void onProgressUpdate(String... args) {
 			this.dialog.setProgress(new Integer(args[0]));
-			this.dialog.setMessage("Uppdaterar saldoinformation...\n"+args[1]);
+			this.dialog.setMessage(res.getText(R.string.updating_account_balance)+"\n"+args[1]);
 		}
 		protected void onPostExecute(final Void unused) {
 			parent.refreshView();
@@ -292,14 +295,14 @@ public class MainActivity extends Activity {
 			
 			if (this.errors != null && !this.errors.isEmpty()) {
 				StringBuilder errormsg = new StringBuilder();
-				errormsg.append("Saldon f�r f�ljande konton har ej uppdaterats:");
+				errormsg.append(res.getText(R.string.acounts_were_not_updated));
 				for (String err : errors)
 				{
 				  errormsg.append(err);
 				  errormsg.append("\n");
 				}
 				AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
-				builder.setMessage(errormsg.toString()).setTitle("Fel vid uppdatering")
+				builder.setMessage(errormsg.toString()).setTitle(res.getText(R.string.errors_when_updating))
 				.setIcon(android.R.drawable.ic_dialog_alert)
 				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
 					public void onClick(DialogInterface dialog, int id) {
diff --git widgets.psd widgets.psd
new file mode 100644
index 0000000..c134b34
Binary files /dev/null and widgets.psd differ

commit 6e8bd36986647f39888e99c394379daadf319c82
Author: liato <x@x00.us>
Date:   Thu May 6 05:18:50 2010 +0200

    Error dialog doesn't show up on every update any more.

diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
index d5fe675..12b40d5 100644
--- src/com/liato/bankdroid/MainActivity.java
+++ src/com/liato/bankdroid/MainActivity.java
@@ -290,7 +290,7 @@ public class MainActivity extends Activity {
 				this.dialog.dismiss();
 			}
 			
-			if (this.errors != null) {
+			if (this.errors != null && !this.errors.isEmpty()) {
 				StringBuilder errormsg = new StringBuilder();
 				errormsg.append("Saldon f�r f�ljande konton har ej uppdaterats:");
 				for (String err : errors)
@@ -309,9 +309,6 @@ public class MainActivity extends Activity {
 				AlertDialog alert = builder.create();
 				alert.show();
 			}
-			else {
-				parent.finish();
-			}
 		}
 	}	
 	

commit 9317c23be047e80d8dcb844d248cd310203fb35c
Author: liato <x@x00.us>
Date:   Thu May 6 05:00:01 2010 +0200

    Version 1

diff --git .classpath .classpath
new file mode 100644
index 0000000..609aa00
--- /dev/null
+++ .classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git .project .project
new file mode 100644
index 0000000..93f3488
--- /dev/null
+++ .project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Bankdroid</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git .settings/org.eclipse.ltk.core.refactoring.prefs .settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..7ba30a7
--- /dev/null
+++ .settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,3 @@
+#Sun May 02 21:44:53 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git AndroidManifest.xml AndroidManifest.xml
new file mode 100644
index 0000000..c504130
--- /dev/null
+++ AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.liato.bankdroid"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <application android:icon="@drawable/icon" android:label="@string/app_name">
+        <activity android:label="@string/app_name" android:multiprocess="false" android:name=".MainActivity" android:alwaysRetainTaskState="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+		<activity android:name=".AccountsActivity"
+			android:label="@string/app_name">
+		</activity>
+		<activity android:name=".AccountActivity"
+			android:label="@string/app_name">
+		</activity>
+    
+</application>
+    <uses-sdk android:minSdkVersion="3" />
+
+
+<uses-permission android:name="android.permission.INTERNET"></uses-permission>
+
+</manifest> 
\ No newline at end of file
diff --git default.properties default.properties
new file mode 100644
index 0000000..a1ef8e9
--- /dev/null
+++ default.properties
@@ -0,0 +1,13 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+# 
+# This file must be checked in Version Control Systems.
+# 
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Indicates whether an apk should be generated for each density.
+split.density=false
+# Project target.
+target=android-3
diff --git logos.psd logos.psd
new file mode 100644
index 0000000..014ccaf
Binary files /dev/null and logos.psd differ
diff --git res/drawable/icon.png res/drawable/icon.png
new file mode 100644
index 0000000..82a54c6
Binary files /dev/null and res/drawable/icon.png differ
diff --git res/drawable/nordea.png res/drawable/nordea.png
new file mode 100644
index 0000000..42662e2
Binary files /dev/null and res/drawable/nordea.png differ
diff --git res/drawable/swedbank.png res/drawable/swedbank.png
new file mode 100644
index 0000000..e7cb3e2
Binary files /dev/null and res/drawable/swedbank.png differ
diff --git res/drawable/title_bar_medium.9.png res/drawable/title_bar_medium.9.png
new file mode 100644
index 0000000..311a54a
Binary files /dev/null and res/drawable/title_bar_medium.9.png differ
diff --git res/layout/bank.xml res/layout/bank.xml
new file mode 100644
index 0000000..98e2621
--- /dev/null
+++ res/layout/bank.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp">
+<TextView  
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content" android:text="Personnummer" android:typeface="sans" android:textSize="20sp"/>
+
+<EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditUsername" android:digits="0123456789-" android:inputType="phone"></EditText><TextView  
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="Lösenord"/><EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtBankeditPassword" android:inputType="textPassword"></EditText><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:typeface="sans" android:textSize="20sp" android:text="Bank"/>
+
+
+<Spinner android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/spnBankeditBanklist"></Spinner><TableLayout android:id="@+id/TableLayout01" android:layout_width="fill_parent" android:stretchColumns="*" android:gravity="bottom" android:layout_height="fill_parent">
+			<TableRow android:id="@+id/TableRow01" android:layout_height="wrap_content" android:layout_width="fill_parent">
+				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel" android:layout_width="fill_parent" android:id="@+id/btnSettingsCancel" android:text="Avbryt"></Button>
+				<Button android:layout_height="wrap_content" android:drawableLeft="@android:drawable/ic_menu_save" android:layout_width="fill_parent" android:id="@+id/btnSettingsOk" android:text="Spara"></Button>
+			</TableRow>
+		</TableLayout>
+</LinearLayout>
diff --git res/layout/banks.xml res/layout/banks.xml
new file mode 100644
index 0000000..6fffef6
--- /dev/null
+++ res/layout/banks.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:tag="rv"><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Du har inte lagt till någon bank ännu, tryck på knappen för att lägga till en bank." android:id="@+id/txtBanksDesc" android:visibility="visible" android:layout_margin="10dp" /><ListView android:layout_width="fill_parent" android:id="@+id/lstvBanksList" android:layout_height="fill_parent" android:fitsSystemWindows="true" android:layout_above="@+id/LinearLayout01"></ListView><LinearLayout android:id="@+id/LinearLayout01" android:gravity="bottom" android:layout_width="fill_parent" android:layout_weight="1" android:layout_height="wrap_content" android:layout_alignParentBottom="true"><Button android:id="@+id/btnBanksNewaccount" android:drawableLeft="@android:drawable/ic_menu_add" android:text="Lägg till ett nytt bankkonto" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginLeft="10dp" android:layout_marginRight="10dp"></Button></LinearLayout></RelativeLayout>
diff --git res/layout/listitem_accounts_group.xml res/layout/listitem_accounts_group.xml
new file mode 100644
index 0000000..170c6fa
--- /dev/null
+++ res/layout/listitem_accounts_group.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:background="@drawable/title_bar_medium" android:layout_height="62dp" android:clickable="false" android:paddingBottom="5dp" android:paddingLeft="5dp" android:paddingTop="5dp" android:paddingRight="10dp">
+
+    <ImageView
+        android:id="@+id/imgListitemAccountsGroup"
+
+        android:layout_height="fill_parent"
+
+        android:layout_alignParentTop="true"
+        android:layout_alignParentBottom="true"
+        android:layout_marginRight="2dp"
+
+        android:src="@drawable/icon" android:layout_alignParentLeft="true" android:padding="0dp" android:layout_marginLeft="0dp" android:layout_width="48dp" android:maxHeight="48dp" android:maxWidth="48dp" android:minHeight="48dp" android:minWidth="48dp"/>
+
+    <TextView
+        android:id="@+id/txtListitemAccountsGroupBankname"
+
+        android:layout_height="26dip" 
+
+        android:layout_toRightOf="@id/imgListitemAccountsGroup"
+        android:layout_alignParentBottom="true"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:gravity="center_vertical" android:text="Banknamn" android:textColor="#000" android:layout_width="wrap_content" android:layout_alignParentRight="false"/>
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+
+        android:layout_toRightOf="@id/imgListitemAccountsGroup"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:layout_above="@id/txtListitemAccountsGroupBankname"
+        android:layout_alignWithParentIfMissing="true"
+
+        android:gravity="center_vertical"
+        android:id="@+id/txtListitemAccountsGroupAccountname" android:textSize="23sp" android:text="Personnummer" android:textColor="#000"/>
+    <TextView
+        android:id="@+id/txtListitemAccountsGroupTotal"
+        android:layout_height="26dip" 
+        android:layout_alignParentBottom="true"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:gravity="center_vertical" android:text="00000 SEK" android:layout_width="wrap_content" android:layout_alignParentRight="true" android:textColor="#333"/>
+        
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/listitem_accounts_item.xml res/layout/listitem_accounts_item.xml
new file mode 100644
index 0000000..25f1022
--- /dev/null
+++ res/layout/listitem_accounts_item.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:background="#000" android:layout_height="35dp" android:layout_gravity="center_horizontal" android:paddingLeft="15dp" android:paddingRight="10dp">
+
+    <TextView
+        android:layout_alignParentBottom="true"
+        android:ellipsize="marquee"
+        android:gravity="center_vertical" android:layout_width="wrap_content" android:layout_alignParentRight="false" android:textColor="#fff" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:id="@+id/txtListitemAccountsItemAccountname" android:inputType="none" android:text="Kontonamn" android:textStyle="bold" android:layout_height="fill_parent"/>
+
+    
+    <TextView
+        android:layout_alignParentBottom="true"
+        android:ellipsize="marquee"
+        android:text="00000 SEK" android:layout_width="wrap_content" android:layout_alignParentRight="true" android:textColor="#fff" android:layout_alignParentTop="true" android:id="@+id/txtListitemAccountsItemBalance" android:inputType="none" android:layout_toRightOf="@+id/txtListitemAccountsItemAccountname" android:gravity="right|center_vertical" android:layout_height="fill_parent"/>
+        
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/listitem_banks.xml res/layout/listitem_banks.xml
new file mode 100644
index 0000000..d9a1bbc
--- /dev/null
+++ res/layout/listitem_banks.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight" android:paddingBottom="5dp" android:paddingTop="5dp">
+
+    <ImageView
+        android:id="@+id/imgListitemBanks"
+
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+
+        android:layout_alignParentTop="true"
+        android:layout_alignParentBottom="true"
+        android:layout_marginRight="2dp"
+
+        android:src="@drawable/icon" android:maxHeight="32dp" android:maxWidth="32dp"/>
+
+    <TextView
+        android:id="@+id/txtListitemBankname"
+
+        android:layout_width="fill_parent"
+        android:layout_height="26dip" 
+
+        android:layout_toRightOf="@id/imgListitemBanks"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:gravity="center_vertical" android:text="Banknamn"/>
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+
+        android:layout_toRightOf="@id/imgListitemBanks"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:layout_above="@id/txtListitemBankname"
+        android:layout_alignWithParentIfMissing="true"
+
+        android:gravity="center_vertical"
+        android:id="@+id/txtListitemAccountname" android:textSize="23sp" android:text="Personnummer"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git res/layout/main.xml res/layout/main.xml
new file mode 100644
index 0000000..1cef90f
--- /dev/null
+++ res/layout/main.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:id="@+id/RelativeLayout01"
+	android:layout_width="wrap_content"
+	android:layout_height="fill_parent">
+	<TextView
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:text="Du har inte lagt till någon bank ännu, gå till menyn och tryck på konton för att lägga till ett nytt bankkonto."
+		android:id="@+id/txtAccountsDesc"
+		android:visibility="visible"
+		android:layout_margin="10dp" />
+	<ListView
+		android:layout_width="fill_parent"
+		android:id="@+id/lstAccountsList"
+		android:layout_height="fill_parent"
+		android:fitsSystemWindows="true"
+		android:layout_above="@+id/LinearLayout02" />
+	<LinearLayout
+		android:id="@+id/LinearLayout02"
+		android:gravity="bottom" android:layout_width="fill_parent"
+		android:layout_weight="1" android:layout_height="wrap_content"
+		android:layout_alignParentBottom="true">
+		<Button
+			android:drawableLeft="@android:drawable/ic_menu_rotate"
+			android:text="Uppdatera saldoinformation"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:layout_gravity="bottom"
+			android:id="@+id/btnAccountsRefresh" android:visibility="gone"/>
+	</LinearLayout>
+</RelativeLayout>
diff --git res/menu/menu.xml res/menu/menu.xml
new file mode 100644
index 0000000..00d8188
--- /dev/null
+++ res/menu/menu.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+	<item android:id="@+id/accounts" android:title="Konton" android:icon="@android:drawable/ic_menu_agenda"/>
+	<item android:id="@+id/settings" android:title="Inställningar" android:icon="@android:drawable/ic_menu_preferences"/>
+	<item android:id="@+id/about" android:title="Om" android:icon="@android:drawable/ic_menu_info_details" />
+	<item android:id="@+id/exit" android:title="Avsluta" android:icon="@android:drawable/ic_menu_close_clear_cancel" />
+</menu>
\ No newline at end of file
diff --git res/values/strings.xml res/values/strings.xml
new file mode 100644
index 0000000..d8f7fb1
--- /dev/null
+++ res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="hello">Hello World, main!</string>
+    <string name="app_name">Bankdroid</string>
+</resources>
diff --git src/com/liato/bankdroid/Account.java src/com/liato/bankdroid/Account.java
new file mode 100644
index 0000000..e0a67c0
--- /dev/null
+++ src/com/liato/bankdroid/Account.java
@@ -0,0 +1,25 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+
+public class Account {
+	private String name;
+	private BigDecimal balance;
+
+	public Account(String name, BigDecimal balance) {
+		this.name = name;
+		this.balance = balance;
+	}
+
+	public void setBalance(BigDecimal balance) {
+		this.balance = balance;
+	}
+
+	public BigDecimal getBalance() {
+		return balance;
+	}
+
+	public String getName() {
+		return name;
+	}
+}
diff --git src/com/liato/bankdroid/AccountActivity.java src/com/liato/bankdroid/AccountActivity.java
new file mode 100644
index 0000000..6e254d5
--- /dev/null
+++ src/com/liato/bankdroid/AccountActivity.java
@@ -0,0 +1,168 @@
+package com.liato.bankdroid;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+public class AccountActivity extends Activity implements OnClickListener, OnItemSelectedListener {
+	private String SELECTED_BANK;
+	private String BANKID;
+
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.bank);
+		ArrayList<String> items = new ArrayList<String>();
+		for(Banks bank: Banks.values()) {
+			items.add(bank.toString());
+		}
+		Collections.sort(items);
+		Spinner spnBanks = (Spinner)findViewById(R.id.spnBankeditBanklist);
+		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+				android.R.layout.simple_spinner_item, items);
+		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+		spnBanks.setAdapter(adapter);
+		spnBanks.setOnItemSelectedListener(this);
+
+		findViewById(R.id.btnSettingsCancel).setOnClickListener(this);
+		findViewById(R.id.btnSettingsOk).setOnClickListener(this);
+
+		Bundle extras = getIntent().getExtras(); 
+		if (extras != null) {
+			BANKID = extras.getString("id");
+			if (BANKID != null) {
+				DBAdapter db = new DBAdapter(this);
+				db.open();
+				Cursor c = db.getBank(BANKID);
+				if (c != null) {
+					((EditText)findViewById(R.id.edtBankeditUsername)).setText(c.getString(c.getColumnIndex("username")));
+					((EditText)findViewById(R.id.edtBankeditPassword)).setText(c.getString(c.getColumnIndex("password")));
+					SELECTED_BANK = c.getString(c.getColumnIndex("banktype"));
+					int i = items.indexOf(SELECTED_BANK);
+					Log.d("a", "Index "+i);
+					spnBanks.setSelection(i);
+					c.close();
+				}
+				db.close();
+			}
+		}
+	}
+
+	@Override
+	public void onClick(View v) {
+		if (v.getId() == R.id.btnSettingsCancel) {
+			this.finish();
+		}
+		else if (v.getId() == R.id.btnSettingsOk){
+			new DataRetrieverTask(this).execute(SELECTED_BANK, ((EditText) findViewById(R.id.edtBankeditUsername)).getText().toString().trim(), ((EditText) findViewById(R.id.edtBankeditPassword)).getText().toString().trim());
+		}
+
+	}
+
+	@Override
+	public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int pos, long id) {
+		SELECTED_BANK = parentView.getItemAtPosition(pos).toString();
+	}
+
+	@Override
+	public void onNothingSelected(AdapterView<?> arg) {
+	}
+
+	private class DataRetrieverTask extends AsyncTask<String, Void, Void> {
+		private final ProgressDialog dialog = new ProgressDialog(AccountActivity.this);
+		private Class<?> cls;
+		private Exception exc = null;
+		private Bank bank;
+		private AccountActivity parent;
+
+		public DataRetrieverTask(AccountActivity parent) {
+			this.parent = parent;
+		}
+		protected void onPreExecute() {
+			this.dialog.setMessage("Loggar in...");
+			this.dialog.show();
+		}
+
+		protected Void doInBackground(final String... args) {
+			try {
+				cls = Class.forName("com.liato.bankdroid.Bank"+args[0]);
+				bank = (Bank) cls.newInstance();
+				bank.update(args[1], args[2]);
+				DBAdapter dba = new DBAdapter(AccountActivity.this);
+				dba.open();
+				if (BANKID != null) {
+					dba.updateBank(bank, new Long(BANKID));
+				}
+				else {
+					dba.createBank(bank);
+				}
+				dba.close();
+			} 
+			catch (BankException e) {
+				this.exc = e;
+			}
+			catch (ClassNotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (InstantiationException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return null;
+		}
+
+		protected void onPostExecute(final Void unused) {
+			if (this.dialog.isShowing()) {
+				this.dialog.dismiss();
+			}
+			if (this.exc != null) {
+				AlertDialog.Builder builder = new AlertDialog.Builder(AccountActivity.this);
+				builder.setMessage(this.exc.getMessage()).setTitle("Kunde ej skapa konto")
+				.setIcon(android.R.drawable.ic_dialog_alert)
+				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+					public void onClick(DialogInterface dialog, int id) {
+						dialog.cancel();
+					}
+				});
+				AlertDialog alert = builder.create();
+				alert.show();
+			}
+			else {
+				parent.finish();
+			}
+		}
+	}
+	
+	@Override
+	protected void onResume() {
+		super.onResume();
+	}
+
+	@Override
+	protected void onPause() {
+		super.onPause();
+	}
+
+	@Override
+	protected void onSaveInstanceState(Bundle outState) {
+		super.onSaveInstanceState(outState);
+	}   
+}
diff --git src/com/liato/bankdroid/AccountsActivity.java src/com/liato/bankdroid/AccountsActivity.java
new file mode 100644
index 0000000..a41fd00
--- /dev/null
+++ src/com/liato/bankdroid/AccountsActivity.java
@@ -0,0 +1,124 @@
+package com.liato.bankdroid;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnCreateContextMenuListener;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.CursorAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class AccountsActivity extends Activity {
+	private DBAdapter dba;
+	private Cursor c;
+	private ListView lv;
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.banks);
+		Button btnNewacc = (Button)findViewById(R.id.btnBanksNewaccount);
+		btnNewacc.setOnClickListener(new View.OnClickListener() {
+			public void onClick(View v) {
+				Intent intentAccount = new Intent(AccountsActivity.this, AccountActivity.class);
+				startActivity(intentAccount);
+			}
+		});
+	}
+
+	public void onResume() {
+		super.onResume();
+		lv = (ListView)findViewById(R.id.lstvBanksList);
+
+		refreshView();
+		lv.setOnItemClickListener(new OnItemClickListener() {
+			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+				view.showContextMenu();
+			}
+		});
+		lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
+			@Override
+			public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+				AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
+				menu.setHeaderTitle(((TextView)info.targetView.findViewById(R.id.txtListitemBankname)).getText());
+				menu.add(0, 0, 0, "Redigera");
+				menu.add(0, 1, 0, "Radera");
+			}
+		});
+	}
+
+	private void refreshView() {
+		dba = new DBAdapter(this);
+		dba.open();
+		c = dba.fetchBanks();
+		if (c != null && !c.isLast() && !c.isAfterLast()) {
+			findViewById(R.id.txtBanksDesc).setVisibility(View.GONE);
+			startManagingCursor(c);
+			BanksCursorAdapter bca = new BanksCursorAdapter(this, c);
+			lv.setAdapter(bca);
+		}
+		dba.close();
+	}
+
+	public boolean onContextItemSelected(MenuItem item) {
+		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+		View v = (View)info.targetView;
+
+		switch (item.getItemId()) { 
+		case 0: 
+			Intent intent = new Intent(AccountsActivity.this, AccountActivity.class);
+			intent.putExtra("id", v.getTag().toString());
+			startActivity(intent);
+			return true; 
+		case 1: 
+			DBAdapter db = new DBAdapter(this);
+			db.open();
+			db.deleteBank(new Long(v.getTag().toString()));
+			db.close();
+			refreshView();
+			return true; 
+		} 
+		return false; 
+	}	
+
+	public void onDestroy() {
+		if (!c.isClosed()) {
+			c.close();
+		}
+		dba.close();
+		super.onDestroy();
+	}
+	private class BanksCursorAdapter extends CursorAdapter {
+		public BanksCursorAdapter(Context context, Cursor c) {
+			super(context, c);
+		}
+
+		public void bindView(View view, Context context, Cursor cursor) {
+			ImageView icon = (ImageView)view.findViewById(R.id.imgListitemBanks);
+			((TextView)view.findViewById(R.id.txtListitemAccountname)).setText(cursor.getString(cursor.getColumnIndex("username")));
+			((TextView)view.findViewById(R.id.txtListitemBankname)).setText(cursor.getString(cursor.getColumnIndex("banktype")));
+			icon.setImageResource(getResources().getIdentifier("drawable/"+cursor.getString(cursor.getColumnIndex("banktype")).toLowerCase(), null, getPackageName()));
+			view.setTag(cursor.getInt(cursor.getColumnIndex("_id")));
+		}
+
+		@Override
+		public View newView(Context context, Cursor cursor, ViewGroup parent) {
+			LayoutInflater inflater = LayoutInflater.from(context);
+			View v = inflater.inflate(R.layout.listitem_banks, parent, false);
+			bindView(v, context, cursor);
+			return v;
+		}
+	}
+}
diff --git src/com/liato/bankdroid/Bank.java src/com/liato/bankdroid/Bank.java
new file mode 100644
index 0000000..36df4e2
--- /dev/null
+++ src/com/liato/bankdroid/Bank.java
@@ -0,0 +1,14 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+
+public interface Bank {
+	ArrayList<Account> getAccounts();
+	String getUsername();
+	String getPassword();
+	Banks getType();
+	BigDecimal getBalance();
+	void update() throws BankException;
+	void update(String username, String password) throws BankException;
+}
diff --git src/com/liato/bankdroid/BankException.java src/com/liato/bankdroid/BankException.java
new file mode 100644
index 0000000..9dce865
--- /dev/null
+++ src/com/liato/bankdroid/BankException.java
@@ -0,0 +1,8 @@
+package com.liato.bankdroid;
+
+public class BankException extends Exception {
+	private static final long serialVersionUID = 1L;
+	public BankException(String message) {
+		super(message);
+	}
+}
diff --git src/com/liato/bankdroid/BankNordea.java src/com/liato/bankdroid/BankNordea.java
new file mode 100644
index 0000000..cef7dd1
--- /dev/null
+++ src/com/liato/bankdroid/BankNordea.java
@@ -0,0 +1,103 @@
+package com.liato.bankdroid;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.text.Html;
+import com.liato.urllib.Urllib;
+
+public class BankNordea implements Bank {
+
+	private String username;
+	private String password;
+	private Banks banktype = Banks.NORDEA;
+	private Pattern reBalance = Pattern.compile("(?is)nowrap>(.+?)SEK<", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private Pattern reAccounts = Pattern.compile("(?is)Kontoutdraget';.*?>(.*?)</a></td>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+	private ArrayList<Account> accounts = new ArrayList<Account>();
+	private BigDecimal balance = new BigDecimal(0);
+
+	public BankNordea() {
+	}
+
+	public BankNordea(String username, String password) throws BankException {
+		this.update(username, password);
+	}
+
+	public void update(String username, String password) throws BankException {
+		this.username = username;
+		this.password = password;
+		this.update();
+	}
+	public void update() throws BankException {
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new BankException("Personnummer och l�senord st�mmer ej.");
+		}
+		Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcherBalance;
+		Matcher matcherAccounts;
+		try {
+			response = urlopen.open("https://gfs.nb.se/bin2/gfskod?OBJECT=KK20");
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("kundnr", username));
+			postData.add(new BasicNameValuePair("pinkod", password));
+			postData.add(new BasicNameValuePair("OBJECT", "TT00"));
+			postData.add(new BasicNameValuePair("prev_link", "https://gfs.nb.se/privat/bank/login_kod2.html"));
+			postData.add(new BasicNameValuePair("CHECKCODE", "checkcode"));
+			response = urlopen.open("https://gfs.nb.se/bin2/gfskod", postData);
+
+			if (!response.contains("reDirect")) {
+				throw new BankException("Personnummer och l�senord st�mmer ej.");
+			}
+
+			response = urlopen.open("https://gfs.nb.se/bin2/gfskod?OBJECT=KF00T&show_button=No");
+			matcherBalance = reBalance.matcher(response);
+			matcherAccounts = reAccounts.matcher(response);
+			while (matcherAccounts.find() && matcherBalance.find()) {
+				accounts.add(new Account(Html.fromHtml(matcherAccounts.group(1)).toString(), Helpers.parseBalance(matcherBalance.group(1))));
+			}
+		} catch (ClientProtocolException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+
+
+	@Override
+	public ArrayList<Account> getAccounts() {
+		return this.accounts;
+	}
+
+	@Override
+	public String getPassword() {
+		return password;
+	}
+
+	@Override
+	public Banks getType() {
+		return banktype;
+	}
+
+	@Override
+	public String getUsername() {
+		return username;
+	}
+	
+	@Override
+	public BigDecimal getBalance() {
+		return balance;
+	}	
+}
\ No newline at end of file
diff --git src/com/liato/bankdroid/BankSwedbank.java src/com/liato/bankdroid/BankSwedbank.java
new file mode 100644
index 0000000..0dee400
--- /dev/null
+++ src/com/liato/bankdroid/BankSwedbank.java
@@ -0,0 +1,105 @@
+package com.liato.bankdroid;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.message.BasicNameValuePair;
+
+import android.text.Html;
+import com.liato.urllib.Urllib;
+
+public class BankSwedbank implements Bank {
+
+	private String username;
+	private String password;
+	private Banks banktype = Banks.SWEDBANK;
+	private Pattern reCSRF = Pattern.compile("csrf_token\"\\s*value=\"([^\"]+)\"");
+	private Pattern reAccounts = Pattern.compile("<span.*?/span>([^<]+) <.*?secondary\">([0-9 .,-]+)</span");
+	private ArrayList<Account> accounts = new ArrayList<Account>();
+	private BigDecimal balance = new BigDecimal(0);
+
+	public BankSwedbank() {
+
+	}
+
+	public BankSwedbank(String username, String password) throws BankException {
+		this.update(username, password);
+	}
+
+	public void update(String username, String password) throws BankException {
+		this.username = username;
+		this.password = password;
+		this.update();
+	}
+
+	public void update() throws BankException {
+		if (username == null || password == null || username.length() == 0 || password.length() == 0) {
+			throw new BankException("Personnummer och l�senord st�mmer ej.");
+		}        Urllib urlopen = new Urllib();
+		String response = null;
+		Matcher matcher;
+		try {
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/login.html");
+			matcher = reCSRF.matcher(response);
+			if (!matcher.find()) {
+				throw new BankException("Could not connect. CSRF token was not found.");
+			}
+			String csrftoken = matcher.group(1);
+			List <NameValuePair> postData = new ArrayList <NameValuePair>();
+			postData.add(new BasicNameValuePair("xyz", username));
+			postData.add(new BasicNameValuePair("zyx", password));
+			postData.add(new BasicNameValuePair("_csrf_token", csrftoken));
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank/login.html", postData);
+
+			if (response.contains("misslyckats")) {
+				throw new BankException("Personnummer och l�senord st�mmer ej.");
+			}
+			response = urlopen.open("https://mobilbank.swedbank.se/banking/swedbank-light/accounts.html");
+			matcher = reAccounts.matcher(response);
+			while (matcher.find()) {
+				accounts.add(new Account(Html.fromHtml(matcher.group(1)).toString(), Helpers.parseBalance(matcher.group(2))));
+			}
+		} catch (ClientProtocolException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		finally {
+			urlopen.close();
+		}
+
+	}
+
+
+	@Override
+	public ArrayList<Account> getAccounts() {
+		return this.accounts;
+	}
+
+	@Override
+	public String getPassword() {
+		return password;
+	}
+
+	@Override
+	public Banks getType() {
+		return banktype;
+	}
+
+	@Override
+	public String getUsername() {
+		return username;
+	}
+
+	@Override
+	public BigDecimal getBalance() {
+		return balance;
+	}
+
+}
diff --git src/com/liato/bankdroid/Banks.java src/com/liato/bankdroid/Banks.java
new file mode 100644
index 0000000..da4cdc5
--- /dev/null
+++ src/com/liato/bankdroid/Banks.java
@@ -0,0 +1,17 @@
+package com.liato.bankdroid;
+
+public enum Banks {
+	SWEDBANK 	("Swedbank"),
+	NORDEA		("Nordea");
+
+	private String value;
+	private Banks(String value) {
+		this.value = value;
+	}
+	public String toString() {
+		return value;
+	}
+	public String getId() {
+		return value.toLowerCase();
+	}
+}
diff --git src/com/liato/bankdroid/DBAdapter.java src/com/liato/bankdroid/DBAdapter.java
new file mode 100644
index 0000000..ee94591
--- /dev/null
+++ src/com/liato/bankdroid/DBAdapter.java
@@ -0,0 +1,175 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+
+public class DBAdapter {
+
+    private static final String TAG = "NotesDbAdapter";
+    private DatabaseHelper mDbHelper;
+    private SQLiteDatabase mDb;
+    
+    private static final String DATABASE_NAME = "data";
+    private static final int DATABASE_VERSION = 2;
+
+    private final Context mCtx;
+
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+
+        DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("create table banks (_id integer primary key autoincrement, "
+            		+ "balance real not null, "
+                    + "banktype text not null, username text not null, "
+                    + "password text not null, disabled integer);");
+            db.execSQL("create table accounts (bankid integer not null, balance real not null, name text not null);");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                    + newVersion + ", which will destroy all old data");
+            db.execSQL("DROP TABLE IF EXISTS banks;");
+            db.execSQL("DROP TABLE IF EXISTS accounts;");
+            onCreate(db);
+        }
+    }
+
+    /**
+     * Constructor - takes the context to allow the database to be
+     * opened/created
+     * 
+     * @param ctx the Context within which to work
+     */
+    public DBAdapter(Context ctx) {
+        this.mCtx = ctx;
+    }
+
+    /**
+     * Open the notes database. If it cannot be opened, try to create a new
+     * instance of the database. If it cannot be created, throw an exception to
+     * signal the failure
+     * 
+     * @return this (self reference, allowing this to be chained in an
+     *         initialization call)
+     * @throws SQLException if the database could be neither opened or created
+     */
+    public DBAdapter open() throws SQLException {
+        mDbHelper = new DatabaseHelper(mCtx);
+        mDb = mDbHelper.getWritableDatabase();
+        return this;
+    }
+    
+    public void close() {
+        mDbHelper.close();
+    }
+
+
+    public long createBank(Bank bank) {
+    	return updateBank(bank, -1);
+    }
+
+    
+    /**
+     * Delete the bank with the given bankId
+     * 
+     * @param bankId id of bank to delete
+     */
+    public int deleteBank(long bankId) {
+        int c = mDb.delete("banks", "_id=" + bankId, null);
+        c += this.deleteAccounts(bankId);
+        return c;
+    }
+    
+    /**
+     * Delete the accounts for the given bankIdbank with the given rowId
+     * 
+     * @param bankId id of bank to delete
+     */    
+    public int deleteAccounts(long bankId) {
+        int c = mDb.delete("accounts", "bankid=" + bankId, null);
+        return c;
+    }
+
+    		
+    /**
+     * Return a Cursor over the list of all banks in the database
+     * 
+     * @return Cursor over all banks
+     */
+    public Cursor fetchBanks() {
+        return mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password", "disabled"}, null, null, null, null, "_id asc");
+    }
+
+    
+    /**
+     * Return a Cursor over the list of all accounts belonging to a bank
+     * 
+     * @return Cursor over all accounts belonging to a bank
+     */
+    public Cursor fetchAccounts(long bankId) {
+        return mDb.query("accounts", new String[] {"bankid", "balance", "name"}, "bankid="+bankId, null, null, null, null);
+    }
+
+    public long updateBank(Bank bank, long bankId) {
+    	ContentValues initialValues = new ContentValues();
+        initialValues.put("banktype", bank.getType().toString());
+        initialValues.put("username", bank.getUsername());
+        initialValues.put("password", bank.getPassword());
+        initialValues.put("disabled", 0);
+        initialValues.put("balance", 0);
+        BigDecimal total = new BigDecimal(0);
+        
+        if (bankId == -1) {
+        	bankId = mDb.insert("banks", null, initialValues);
+        }
+        else {
+        	mDb.update("banks", initialValues, "_id="+bankId, null);
+            deleteAccounts(bankId);
+        }
+        if (bankId != -1) {
+	        ArrayList<Account> accounts = bank.getAccounts();
+	        for(Account acc : accounts) {
+	        	total = total.add(acc.getBalance());
+	            ContentValues vals = new ContentValues();
+	            vals.put("bankid", bankId);
+	            vals.put("balance", acc.getBalance().doubleValue());
+	            vals.put("name", acc.getName());
+	            mDb.insert("accounts", null, vals);	        	
+	        }
+	        ContentValues v = new ContentValues();
+	        v.put("balance", total.doubleValue());
+	        mDb.update("banks", v, "_id="+bankId, null);
+        }
+        return bankId;
+    }
+    
+    public void disableBank(long bankId) {
+        ContentValues initialValues = new ContentValues();
+        initialValues.put("disabled", 1);    	
+    }
+    
+    public Cursor getBank(String bankId) {
+    	Cursor c = mDb.query("banks", new String[] {"_id", "balance", "banktype", "username", "password"}, "_id="+bankId, null, null, null, null);
+    	if (c != null) {
+    		c.moveToFirst();
+    	}
+		return c;
+    }
+    
+    public Cursor getBank(long bankId) {
+    	return getBank(new Long(bankId).toString());
+    }
+}
diff --git src/com/liato/bankdroid/Helpers.java src/com/liato/bankdroid/Helpers.java
new file mode 100644
index 0000000..14b475c
--- /dev/null
+++ src/com/liato/bankdroid/Helpers.java
@@ -0,0 +1,17 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+public class Helpers {
+	public static BigDecimal parseBalance(String balance) {
+		balance = balance.replaceAll("(?:\\.|&nbsp;| )*", "");
+		balance = balance.replace(",", ".");
+		return new BigDecimal(balance);
+	}
+	public static String formatBalance(BigDecimal balance) {
+		Locale locale = new Locale("sv", "SE");
+		return NumberFormat.getCurrencyInstance(locale).format(balance).replace("kr", "SEK");
+	}
+}
diff --git src/com/liato/bankdroid/MainActivity.java src/com/liato/bankdroid/MainActivity.java
new file mode 100644
index 0000000..d5fe675
--- /dev/null
+++ src/com/liato/bankdroid/MainActivity.java
@@ -0,0 +1,359 @@
+package com.liato.bankdroid;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class MainActivity extends Activity {
+	/** Called when the activity is first created. */
+	private DBAdapter dba;
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.main);
+		
+		Button btnRefresh = (Button)findViewById(R.id.btnAccountsRefresh);
+		btnRefresh.setOnClickListener(new View.OnClickListener() {
+			public void onClick(View v) {
+				new DataRetrieverTask(MainActivity.this).execute();
+			}
+		});		
+	}
+
+	public void onResume() {
+		super.onResume();
+		refreshView();
+	}
+
+	private void refreshView() {
+		dba = new DBAdapter(this);
+		dba.open();
+		Cursor curBanks = dba.fetchBanks();
+		Cursor curAccounts;
+
+		if (curBanks != null && !curBanks.isLast() && !curBanks.isAfterLast()) {
+			findViewById(R.id.txtAccountsDesc).setVisibility(View.GONE);
+			findViewById(R.id.btnAccountsRefresh).setVisibility(View.VISIBLE);
+			startManagingCursor(curBanks);
+			ListView lv = (ListView)findViewById(R.id.lstAccountsList);
+			AccountsAdapter adapter = new AccountsAdapter(this);
+
+			int clmId = curBanks.getColumnIndex("_id"); 
+			int clmBanktype = curBanks.getColumnIndex("banktype");
+			int clmUsername = curBanks.getColumnIndex("username");
+			int clmBankbalance = curBanks.getColumnIndex("balance");
+			List<Item> items;
+			Group bank;
+
+			while (!curBanks.isLast() && !curBanks.isAfterLast()) {
+				items = new ArrayList<Item>();
+				curBanks.moveToNext();
+				curAccounts = dba.fetchAccounts(curBanks.getLong(clmId));
+				int clmBalance = curAccounts.getColumnIndex("balance"); 
+				int clmName = curAccounts.getColumnIndex("name");
+				int acc_count = curAccounts.getCount();
+				if (curAccounts != null && acc_count != 0) {
+					while (!curAccounts.isLast()) {
+						curAccounts.moveToNext();
+						items.add(new Item(curAccounts.getString(clmName), curAccounts.getDouble(clmBalance)));
+					}
+				}
+				bank = new Group(curBanks.getString(clmUsername), curBanks.getString(clmBanktype), curBanks.getDouble(clmBankbalance), items);
+				adapter.addGroup(bank);
+				curAccounts.close();
+			}
+			lv.setAdapter(adapter);
+		}
+		curBanks.close();
+		dba.close();
+	}
+	public boolean onCreateOptionsMenu(Menu menu) {
+		super.onCreateOptionsMenu(menu);
+		MenuInflater inflater = new MenuInflater(this);
+		inflater.inflate(R.menu.menu, menu);
+		return true;
+	}
+
+
+	public boolean onOptionsItemSelected (MenuItem item){
+		switch (item.getItemId()) {
+		case R.id.exit:
+			this.finish();
+			return true;
+		case R.id.accounts:
+			Intent intentAccounts = new Intent(this, AccountsActivity.class);
+			this.startActivity(intentAccounts);
+			return true;
+		case R.id.about:
+			AlertDialog.Builder builder = new AlertDialog.Builder(this);
+			builder.setMessage("Omnomnomnom")
+			.setCancelable(true)
+			.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+				public void onClick(DialogInterface dialog, int id) {
+					dialog.cancel();
+				}
+			});
+			AlertDialog alert = builder.create();
+			alert.show();
+			return true;
+		}
+		return false;
+	}
+
+	public void onDestroy() {
+		super.onDestroy();
+	}
+
+	private class AccountsAdapter extends BaseAdapter {
+		private ArrayList<Group> groups;
+		private Context context;
+
+		public AccountsAdapter(Context context) {
+			this.context = context;
+			this.groups = new ArrayList<Group>();
+		}
+
+		public void addGroup(Group group) {
+			groups.add(group);
+		}
+
+		public View newGroupView(Group group, ViewGroup parent) {
+			LayoutInflater inflater = LayoutInflater.from(context);
+			View v = inflater.inflate(R.layout.listitem_accounts_group, parent, false);
+			ImageView icon = (ImageView)v.findViewById(R.id.imgListitemAccountsGroup);
+			((TextView)v.findViewById(R.id.txtListitemAccountsGroupAccountname)).setText(group.getName());
+			((TextView)v.findViewById(R.id.txtListitemAccountsGroupBankname)).setText(group.getType());
+			((TextView)v.findViewById(R.id.txtListitemAccountsGroupTotal)).setText(Helpers.formatBalance(group.getTotal()));
+			icon.setImageResource(getResources().getIdentifier("drawable/"+group.getType().toLowerCase(), null, getPackageName()));
+			return v;
+		}
+
+		public View newItemView(Item item, ViewGroup parent) {
+			LayoutInflater inflater = LayoutInflater.from(context);
+			View v = inflater.inflate(R.layout.listitem_accounts_item, parent, false);
+			((TextView)v.findViewById(R.id.txtListitemAccountsItemAccountname)).setText(item.getName());
+			((TextView)v.findViewById(R.id.txtListitemAccountsItemBalance)).setText(Helpers.formatBalance(item.getBalance()));
+			return v;
+		}
+
+		@Override
+		public int getCount() {
+			int c = 0;
+			for(Group g : groups) {
+				c += g.getItems().size()+1;
+			}
+			return c;
+		}
+
+		@Override
+		public Object getItem(int position) {
+			if (groups.size() == 0) {
+				return null;
+			}
+			if (position == 0) {
+				return groups.get(0);
+			}
+
+			int i = 0;
+			for (Group g : groups) {
+				if (position == i) {
+					return g;
+				}
+				else if (position <= (g.getItems().size()+i)) {
+					return g.getItems().get(position-i-1);
+				}
+				i += g.getItems().size()+1;
+			}
+
+			return(null);
+		}
+
+		@Override
+		public long getItemId(int position) {
+			return position;
+		}
+
+		@Override
+		public View getView(int position, View convertView, ViewGroup parent) {
+			Object item = getItem(position);
+			if (item == null) {
+				return null;
+			}
+			if (item instanceof Group) {
+				return newGroupView((Group)item, parent);
+			}
+			else if (item instanceof Item) {
+				return newItemView((Item)item, parent);
+			}
+			return null;
+		}
+
+		public boolean isEnabled(int position) {
+			return false;
+		}		
+	}
+
+	private class DataRetrieverTask extends AsyncTask<String, String, Void> {
+		private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
+		private Class<?> cls;
+		private ArrayList<String> errors;
+		private Bank bank;
+		private MainActivity parent;
+		private int bankcount;
+
+		public DataRetrieverTask(MainActivity parent) {
+			this.parent = parent;
+		}
+		protected void onPreExecute() {
+			this.dialog.setMessage("Uppdaterar saldoinformation...\n ");
+			this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+			this.dialog.setCancelable(false);
+			this.dialog.show();
+		}
+
+		protected Void doInBackground(final String... args) {
+			errors = new ArrayList<String>();
+			DBAdapter db;
+			Cursor c;
+			db = new DBAdapter(parent);
+			db.open();
+			c = db.fetchBanks();
+			if (c == null) {
+				return null;
+			}
+			bankcount = c.getCount();
+			this.dialog.setMax(bankcount);
+			int clmId = c.getColumnIndex("_id");
+			int clmBanktype = c.getColumnIndex("banktype");
+			int clmBalance = c.getColumnIndex("balance");
+			int clmUsername = c.getColumnIndex("username");
+			int clmPassword = c.getColumnIndex("password");
+			int i = 0; 
+			while (!c.isLast() && !c.isAfterLast()) {
+				c.moveToNext();
+				publishProgress(new String[] {new Integer(i).toString(), c.getString(clmBanktype)+" ("+c.getString(clmUsername)+")"});
+				try {
+					cls = Class.forName("com.liato.bankdroid.Bank"+c.getString(clmBanktype));
+					bank = (Bank) cls.newInstance();
+					bank.update(c.getString(clmUsername), c.getString(clmPassword));
+					db.updateBank(bank, new Long(c.getString(clmId)));
+					i++;
+				} 
+				catch (BankException e) {
+					this.errors.add(c.getString(clmBanktype)+" ("+c.getString(clmUsername));
+				}
+				catch (ClassNotFoundException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (IllegalAccessException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (InstantiationException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			publishProgress(new String[] {new Integer(i).toString(), ""});
+			c.close();
+			db.close();
+			return null;
+		}
+
+		protected void onProgressUpdate(String... args) {
+			this.dialog.setProgress(new Integer(args[0]));
+			this.dialog.setMessage("Uppdaterar saldoinformation...\n"+args[1]);
+		}
+		protected void onPostExecute(final Void unused) {
+			parent.refreshView();
+			if (this.dialog.isShowing()) {
+				this.dialog.dismiss();
+			}
+			
+			if (this.errors != null) {
+				StringBuilder errormsg = new StringBuilder();
+				errormsg.append("Saldon f�r f�ljande konton har ej uppdaterats:");
+				for (String err : errors)
+				{
+				  errormsg.append(err);
+				  errormsg.append("\n");
+				}
+				AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
+				builder.setMessage(errormsg.toString()).setTitle("Fel vid uppdatering")
+				.setIcon(android.R.drawable.ic_dialog_alert)
+				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
+					public void onClick(DialogInterface dialog, int id) {
+						dialog.cancel();
+					}
+				});
+				AlertDialog alert = builder.create();
+				alert.show();
+			}
+			else {
+				parent.finish();
+			}
+		}
+	}	
+	
+	private class Group {
+		private String name;
+		private String type;
+		private BigDecimal total;
+		private List<Item> items;
+		public Group(String name, String type, Double total, List<Item> items) {
+			this.name = name;
+			this.type = type;
+			this.items = items;
+			this.total = new BigDecimal(total);
+		}
+		public String getName() {
+			return name;
+		}
+		public String getType() {
+			return type;
+		}
+		public BigDecimal getTotal() {
+			return total;
+		}
+		public List<Item> getItems() {
+			return items;
+		}
+
+	}
+
+	private class Item {
+		private String name;
+		private BigDecimal balance;
+		public Item (String name, Double balance) {
+			this.name = name;
+			this.balance = new BigDecimal(balance);
+		}
+		public String getName() {
+			return name;
+		}
+		public BigDecimal getBalance() {
+			return balance;
+		}
+	}
+
+}
\ No newline at end of file
diff --git src/com/liato/urllib/Urllib.java src/com/liato/urllib/Urllib.java
new file mode 100644
index 0000000..d310aca
--- /dev/null
+++ src/com/liato/urllib/Urllib.java
@@ -0,0 +1,47 @@
+package com.liato.urllib;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.HTTP;
+
+public class Urllib {
+	private DefaultHttpClient httpclient;
+	
+    public Urllib() {
+    	httpclient = new DefaultHttpClient();
+    }
+    
+    public String open(String url) throws ClientProtocolException, IOException {
+    	return this.open(url, new ArrayList <NameValuePair>());
+    }
+    
+    public String open(String url, List<NameValuePair> postData) throws ClientProtocolException, IOException {
+    	//HttpResponse response;
+    	String response;
+    	ResponseHandler<String> responseHandler = new BasicResponseHandler();
+    	if (postData.isEmpty()) {
+    		HttpGet urlConnection = new HttpGet(url);
+    		response = httpclient.execute(urlConnection, responseHandler);
+    	}
+    	else {
+    		HttpPost urlConnection = new HttpPost(url);
+    		urlConnection.setEntity(new UrlEncodedFormEntity(postData, HTTP.UTF_8));
+    		response = httpclient.execute(urlConnection, responseHandler);
+    	}
+
+    	return response;
+    }
+    
+    public void close() {
+        httpclient.getConnectionManager().shutdown();
+    }
+}
\ No newline at end of file

commit 6d815a06cc429f7b52985dcf61d8b05a9540f022
Author: liato <x@x00.us>
Date:   Mon Apr 19 18:56:41 2010 +0200

    Added .gitignore.

diff --git .gitignore .gitignore
new file mode 100644
index 0000000..af9564f
--- /dev/null
+++ .gitignore
@@ -0,0 +1,16 @@
+.metadata
+tmp/**
+.DS_Store
+*.tmp
+*.bak
+tmp/**/*
+*.swp
+*~.nib
+Thumbs.db
+Desktop.ini
+*~
+*.apk
+bin
+gen
+local.properties
+*.jar
\ No newline at end of file

commit a99a1cb02c6e8805ba5658d8c5d007c16d3303e9
Author: liato <x@x00.us>
Date:   Mon Apr 19 18:54:25 2010 +0200

    !

diff --git README.rst README.rst
new file mode 100644
index 0000000..9c0069d
--- /dev/null
+++ README.rst
@@ -0,0 +1 @@
+Don't look at me!
